1 // 7zHandler.cpp
2
3 #include "StdAfx.h"
4
5 #include "../../../../C/CpuArch.h"
6
7 #include "../../../Common/ComTry.h"
8 #include "../../../Common/IntToString.h"
9
10 #ifndef Z7_7Z_SET_PROPERTIES
11 #include "../../../Windows/System.h"
12 #endif
13
14 #include "../Common/ItemNameUtils.h"
15
16 #include "7zHandler.h"
17 #include "7zProperties.h"
18
19 #ifdef Z7_7Z_SET_PROPERTIES
20 #ifdef Z7_EXTRACT_ONLY
21 #include "../Common/ParseProperties.h"
22 #endif
23 #endif
24
25 using namespace NWindows;
26 using namespace NCOM;
27
28 namespace NArchive {
29 namespace N7z {
30
CHandler()31 CHandler::CHandler()
32 {
33 #ifndef Z7_NO_CRYPTO
34 _isEncrypted = false;
35 _passwordIsDefined = false;
36 #endif
37
38 #ifdef Z7_EXTRACT_ONLY
39
40 _crcSize = 4;
41
42 #ifdef Z7_7Z_SET_PROPERTIES
43 _useMultiThreadMixer = true;
44 #endif
45
46 #endif
47 }
48
Z7_COM7F_IMF(CHandler::GetNumberOfItems (UInt32 * numItems))49 Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
50 {
51 *numItems = _db.Files.Size();
52 return S_OK;
53 }
54
55 #ifdef Z7_SFX
56
57 IMP_IInArchive_ArcProps_NO_Table
58
Z7_COM7F_IMF(CHandler::GetNumberOfProperties (UInt32 * numProps))59 Z7_COM7F_IMF(CHandler::GetNumberOfProperties(UInt32 *numProps))
60 {
61 *numProps = 0;
62 return S_OK;
63 }
64
Z7_COM7F_IMF(CHandler::GetPropertyInfo (UInt32,BSTR *,PROPID *,VARTYPE *))65 Z7_COM7F_IMF(CHandler::GetPropertyInfo(UInt32 /* index */,
66 BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */))
67 {
68 return E_NOTIMPL;
69 }
70
71 #else
72
73 static const Byte kArcProps[] =
74 {
75 kpidHeadersSize,
76 kpidMethod,
77 kpidSolid,
78 kpidNumBlocks
79 // , kpidIsTree
80 };
81
82 IMP_IInArchive_ArcProps
83
GetHex(unsigned value)84 static inline char GetHex(unsigned value)
85 {
86 return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
87 }
88
ConvertMethodIdToString_Back(char * s,UInt64 id)89 static unsigned ConvertMethodIdToString_Back(char *s, UInt64 id)
90 {
91 int len = 0;
92 do
93 {
94 s[--len] = GetHex((unsigned)id & 0xF); id >>= 4;
95 s[--len] = GetHex((unsigned)id & 0xF); id >>= 4;
96 }
97 while (id != 0);
98 return (unsigned)-len;
99 }
100
ConvertMethodIdToString(AString & res,UInt64 id)101 static void ConvertMethodIdToString(AString &res, UInt64 id)
102 {
103 const unsigned kLen = 32;
104 char s[kLen];
105 unsigned len = kLen - 1;
106 s[len] = 0;
107 res += s + len - ConvertMethodIdToString_Back(s + len, id);
108 }
109
110
GetStringForSizeValue(char * s,UInt32 val)111 static char *GetStringForSizeValue(char *s, UInt32 val)
112 {
113 for (unsigned i = 0; i < 32; i++)
114 if (((UInt32)1 << i) == val)
115 {
116 if (i >= 10)
117 {
118 *s++= (char)('0' + i / 10);
119 i %= 10;
120 }
121 *s++ = (char)('0' + i);
122 *s = 0;
123 return s;
124 }
125
126 char c = 'b';
127 if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
128 else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
129 s = ConvertUInt32ToString(val, s);
130 *s++ = c;
131 *s = 0;
132 return s;
133 }
134
135
GetLzma2String(char * s,unsigned d)136 static void GetLzma2String(char *s, unsigned d)
137 {
138 if (d > 40)
139 {
140 *s = 0;
141 return;
142 // s = MyStpCpy(s, "unsup");
143 }
144 else if ((d & 1) == 0)
145 d = (d >> 1) + 12;
146 else
147 {
148 // s = GetStringForSizeValue(s, (UInt32)3 << ((d >> 1) + 11));
149 d = (d >> 1) + 1;
150 char c = 'k';
151 if (d >= 10)
152 {
153 c = 'm';
154 d -= 10;
155 }
156 s = ConvertUInt32ToString((UInt32)3 << d, s);
157 *s++ = c;
158 *s = 0;
159 return;
160 }
161 ConvertUInt32ToString(d, s);
162 }
163
164
165 /*
166 static inline void AddHexToString(UString &res, Byte value)
167 {
168 res += GetHex((Byte)(value >> 4));
169 res += GetHex((Byte)(value & 0xF));
170 }
171 */
172
AddProp32(char * s,const char * name,UInt32 v)173 static char *AddProp32(char *s, const char *name, UInt32 v)
174 {
175 *s++ = ':';
176 s = MyStpCpy(s, name);
177 return ConvertUInt32ToString(v, s);
178 }
179
AddMethodName(AString & s,UInt64 id)180 void CHandler::AddMethodName(AString &s, UInt64 id)
181 {
182 AString name;
183 FindMethod(EXTERNAL_CODECS_VARS id, name);
184 if (name.IsEmpty())
185 ConvertMethodIdToString(s, id);
186 else
187 s += name;
188 }
189
190 #endif
191
Z7_COM7F_IMF(CHandler::GetArchiveProperty (PROPID propID,PROPVARIANT * value))192 Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
193 {
194 #ifndef Z7_SFX
195 COM_TRY_BEGIN
196 #endif
197 NCOM::CPropVariant prop;
198 switch (propID)
199 {
200 #ifndef Z7_SFX
201 case kpidMethod:
202 {
203 AString s;
204 const CParsedMethods &pm = _db.ParsedMethods;
205 FOR_VECTOR (i, pm.IDs)
206 {
207 UInt64 id = pm.IDs[i];
208 s.Add_Space_if_NotEmpty();
209 char temp[16];
210 if (id == k_LZMA2)
211 {
212 s += "LZMA2:";
213 GetLzma2String(temp, pm.Lzma2Prop);
214 s += temp;
215 }
216 else if (id == k_LZMA)
217 {
218 s += "LZMA:";
219 GetStringForSizeValue(temp, pm.LzmaDic);
220 s += temp;
221 }
222 /*
223 else if (id == k_ZSTD)
224 {
225 s += "ZSTD";
226 }
227 */
228 else
229 AddMethodName(s, id);
230 }
231 prop = s;
232 break;
233 }
234 case kpidSolid: prop = _db.IsSolid(); break;
235 case kpidNumBlocks: prop = (UInt32)_db.NumFolders; break;
236 case kpidHeadersSize: prop = _db.HeadersSize; break;
237 case kpidPhySize: prop = _db.PhySize; break;
238 case kpidOffset: if (_db.ArcInfo.StartPosition != 0) prop = _db.ArcInfo.StartPosition; break;
239 /*
240 case kpidIsTree: if (_db.IsTree) prop = true; break;
241 case kpidIsAltStream: if (_db.ThereAreAltStreams) prop = true; break;
242 case kpidIsAux: if (_db.IsTree) prop = true; break;
243 */
244 // case kpidError: if (_db.ThereIsHeaderError) prop = "Header error"; break;
245 #endif
246
247 case kpidWarningFlags:
248 {
249 UInt32 v = 0;
250 if (_db.StartHeaderWasRecovered) v |= kpv_ErrorFlags_HeadersError;
251 if (_db.UnsupportedFeatureWarning) v |= kpv_ErrorFlags_UnsupportedFeature;
252 if (v != 0)
253 prop = v;
254 break;
255 }
256
257 case kpidErrorFlags:
258 {
259 UInt32 v = 0;
260 if (!_db.IsArc) v |= kpv_ErrorFlags_IsNotArc;
261 if (_db.ThereIsHeaderError) v |= kpv_ErrorFlags_HeadersError;
262 if (_db.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
263 // if (_db.UnsupportedVersion) v |= kpv_ErrorFlags_Unsupported;
264 if (_db.UnsupportedFeatureError) v |= kpv_ErrorFlags_UnsupportedFeature;
265 prop = v;
266 break;
267 }
268
269 case kpidReadOnly:
270 {
271 if (!_db.CanUpdate())
272 prop = true;
273 break;
274 }
275 default: break;
276 }
277 return prop.Detach(value);
278 #ifndef Z7_SFX
279 COM_TRY_END
280 #endif
281 }
282
SetFileTimeProp_From_UInt64Def(PROPVARIANT * prop,const CUInt64DefVector & v,unsigned index)283 static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, unsigned index)
284 {
285 UInt64 value;
286 if (v.GetItem(index, value))
287 PropVarEm_Set_FileTime64_Prec(prop, value, k_PropVar_TimePrec_100ns);
288 }
289
IsFolderEncrypted(CNum folderIndex) const290 bool CHandler::IsFolderEncrypted(CNum folderIndex) const
291 {
292 if (folderIndex == kNumNoIndex)
293 return false;
294 const size_t startPos = _db.FoCodersDataOffset[folderIndex];
295 const Byte *p = _db.CodersData.ConstData() + startPos;
296 const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos;
297 CInByte2 inByte;
298 inByte.Init(p, size);
299
300 CNum numCoders = inByte.ReadNum();
301 for (; numCoders != 0; numCoders--)
302 {
303 const Byte mainByte = inByte.ReadByte();
304 const unsigned idSize = (mainByte & 0xF);
305 const Byte *longID = inByte.GetPtr();
306 UInt64 id64 = 0;
307 for (unsigned j = 0; j < idSize; j++)
308 id64 = ((id64 << 8) | longID[j]);
309 inByte.SkipDataNoCheck(idSize);
310 if (id64 == k_AES)
311 return true;
312 if ((mainByte & 0x20) != 0)
313 inByte.SkipDataNoCheck(inByte.ReadNum());
314 }
315 return false;
316 }
317
Z7_COM7F_IMF(CHandler::GetNumRawProps (UInt32 * numProps))318 Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps))
319 {
320 *numProps = 0;
321 return S_OK;
322 }
323
Z7_COM7F_IMF(CHandler::GetRawPropInfo (UInt32,BSTR * name,PROPID * propID))324 Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID))
325 {
326 *name = NULL;
327 *propID = kpidNtSecure;
328 return S_OK;
329 }
330
Z7_COM7F_IMF(CHandler::GetParent (UInt32,UInt32 * parent,UInt32 * parentType))331 Z7_COM7F_IMF(CHandler::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType))
332 {
333 /*
334 const CFileItem &file = _db.Files[index];
335 *parentType = (file.IsAltStream ? NParentType::kAltStream : NParentType::kDir);
336 *parent = (UInt32)(Int32)file.Parent;
337 */
338 *parentType = NParentType::kDir;
339 *parent = (UInt32)(Int32)-1;
340 return S_OK;
341 }
342
Z7_COM7F_IMF(CHandler::GetRawProp (UInt32 index,PROPID propID,const void ** data,UInt32 * dataSize,UInt32 * propType))343 Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType))
344 {
345 *data = NULL;
346 *dataSize = 0;
347 *propType = 0;
348
349 if (/* _db.IsTree && propID == kpidName ||
350 !_db.IsTree && */ propID == kpidPath)
351 {
352 if (_db.NameOffsets && _db.NamesBuf)
353 {
354 const size_t offset = _db.NameOffsets[index];
355 const size_t size = (_db.NameOffsets[index + 1] - offset) * 2;
356 if (size < ((UInt32)1 << 31))
357 {
358 *data = (const void *)(_db.NamesBuf.ConstData() + offset * 2);
359 *dataSize = (UInt32)size;
360 *propType = NPropDataType::kUtf16z;
361 }
362 }
363 return S_OK;
364 }
365 /*
366 if (propID == kpidNtSecure)
367 {
368 if (index < (UInt32)_db.SecureIDs.Size())
369 {
370 int id = _db.SecureIDs[index];
371 size_t offs = _db.SecureOffsets[id];
372 size_t size = _db.SecureOffsets[id + 1] - offs;
373 if (size >= 0)
374 {
375 *data = _db.SecureBuf + offs;
376 *dataSize = (UInt32)size;
377 *propType = NPropDataType::kRaw;
378 }
379 }
380 }
381 */
382 return S_OK;
383 }
384
385 #ifndef Z7_SFX
386
SetMethodToProp(CNum folderIndex,PROPVARIANT * prop) const387 HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
388 {
389 PropVariant_Clear(prop);
390 if (folderIndex == kNumNoIndex)
391 return S_OK;
392 // for (int ttt = 0; ttt < 1; ttt++) {
393 const unsigned kTempSize = 256;
394 char temp[kTempSize];
395 unsigned pos = kTempSize;
396 temp[--pos] = 0;
397
398 const size_t startPos = _db.FoCodersDataOffset[folderIndex];
399 const Byte *p = _db.CodersData.ConstData() + startPos;
400 const size_t size = _db.FoCodersDataOffset[folderIndex + 1] - startPos;
401 CInByte2 inByte;
402 inByte.Init(p, size);
403
404 // numCoders == 0 ???
405 CNum numCoders = inByte.ReadNum();
406 bool needSpace = false;
407
408 for (; numCoders != 0; numCoders--, needSpace = true)
409 {
410 if (pos < 32) // max size of property
411 break;
412 const Byte mainByte = inByte.ReadByte();
413 UInt64 id64 = 0;
414 const unsigned idSize = (mainByte & 0xF);
415 const Byte *longID = inByte.GetPtr();
416 for (unsigned j = 0; j < idSize; j++)
417 id64 = ((id64 << 8) | longID[j]);
418 inByte.SkipDataNoCheck(idSize);
419
420 if ((mainByte & 0x10) != 0)
421 {
422 inByte.ReadNum(); // NumInStreams
423 inByte.ReadNum(); // NumOutStreams
424 }
425
426 CNum propsSize = 0;
427 const Byte *props = NULL;
428 if ((mainByte & 0x20) != 0)
429 {
430 propsSize = inByte.ReadNum();
431 props = inByte.GetPtr();
432 inByte.SkipDataNoCheck(propsSize);
433 }
434
435 const char *name = NULL;
436 char s[32];
437 s[0] = 0;
438
439 if (id64 <= (UInt32)0xFFFFFFFF)
440 {
441 const UInt32 id = (UInt32)id64;
442 if (id == k_LZMA)
443 {
444 name = "LZMA";
445 if (propsSize == 5)
446 {
447 const UInt32 dicSize = GetUi32((const Byte *)props + 1);
448 char *dest = GetStringForSizeValue(s, dicSize);
449 UInt32 d = props[0];
450 if (d != 0x5D)
451 {
452 const UInt32 lc = d % 9;
453 d /= 9;
454 const UInt32 pb = d / 5;
455 const UInt32 lp = d % 5;
456 if (lc != 3) dest = AddProp32(dest, "lc", lc);
457 if (lp != 0) dest = AddProp32(dest, "lp", lp);
458 if (pb != 2) dest = AddProp32(dest, "pb", pb);
459 }
460 }
461 }
462 else if (id == k_LZMA2)
463 {
464 name = "LZMA2";
465 if (propsSize == 1)
466 GetLzma2String(s, props[0]);
467 }
468 else if (id == k_PPMD)
469 {
470 name = "PPMD";
471 if (propsSize == 5)
472 {
473 char *dest = s;
474 *dest++ = 'o';
475 dest = ConvertUInt32ToString(*props, dest);
476 dest = MyStpCpy(dest, ":mem");
477 GetStringForSizeValue(dest, GetUi32(props + 1));
478 }
479 }
480 else if (id == k_Delta)
481 {
482 name = "Delta";
483 if (propsSize == 1)
484 ConvertUInt32ToString((UInt32)props[0] + 1, s);
485 }
486 else if (id == k_ARM64 || id == k_RISCV)
487 {
488 name = id == k_ARM64 ? "ARM64" : "RISCV";
489 if (propsSize == 4)
490 ConvertUInt32ToString(GetUi32(props), s);
491 /*
492 else if (propsSize != 0)
493 MyStringCopy(s, "unsupported");
494 */
495 }
496 else if (id == k_BCJ2) name = "BCJ2";
497 else if (id == k_BCJ) name = "BCJ";
498 else if (id == k_AES)
499 {
500 name = "7zAES";
501 if (propsSize >= 1)
502 {
503 const Byte firstByte = props[0];
504 const UInt32 numCyclesPower = firstByte & 0x3F;
505 ConvertUInt32ToString(numCyclesPower, s);
506 }
507 }
508 }
509
510 if (name)
511 {
512 const unsigned nameLen = MyStringLen(name);
513 const unsigned propsLen = MyStringLen(s);
514 unsigned totalLen = nameLen + propsLen;
515 if (propsLen != 0)
516 totalLen++;
517 if (needSpace)
518 totalLen++;
519 if (totalLen + 5 >= pos)
520 break;
521 pos -= totalLen;
522 MyStringCopy(temp + pos, name);
523 if (propsLen != 0)
524 {
525 char *dest = temp + pos + nameLen;
526 *dest++ = ':';
527 MyStringCopy(dest, s);
528 }
529 if (needSpace)
530 temp[pos + totalLen - 1] = ' ';
531 }
532 else
533 {
534 AString methodName;
535 FindMethod(EXTERNAL_CODECS_VARS id64, methodName);
536 if (needSpace)
537 temp[--pos] = ' ';
538 if (methodName.IsEmpty())
539 pos -= ConvertMethodIdToString_Back(temp + pos, id64);
540 else
541 {
542 const unsigned len = methodName.Len();
543 if (len + 5 > pos)
544 break;
545 pos -= len;
546 for (unsigned i = 0; i < len; i++)
547 temp[pos + i] = methodName[i];
548 }
549 }
550 }
551
552 if (numCoders != 0 && pos >= 4)
553 {
554 temp[--pos] = ' ';
555 temp[--pos] = '.';
556 temp[--pos] = '.';
557 temp[--pos] = '.';
558 }
559
560 return PropVarEm_Set_Str(prop, temp + pos);
561 // }
562 }
563
564 #endif
565
Z7_COM7F_IMF(CHandler::GetProperty (UInt32 index,PROPID propID,PROPVARIANT * value))566 Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
567 {
568 RINOK(PropVariant_Clear(value))
569 // COM_TRY_BEGIN
570 // NCOM::CPropVariant prop;
571
572 /*
573 const CRef2 &ref2 = _refs[index];
574 if (ref2.Refs.IsEmpty())
575 return E_FAIL;
576 const CRef &ref = ref2.Refs.Front();
577 */
578
579 const CFileItem &item = _db.Files[index];
580 const UInt32 index2 = index;
581
582 switch (propID)
583 {
584 case kpidIsDir: PropVarEm_Set_Bool(value, item.IsDir); break;
585 case kpidSize:
586 {
587 PropVarEm_Set_UInt64(value, item.Size);
588 // prop = ref2.Size;
589 break;
590 }
591 case kpidPackSize:
592 {
593 // prop = ref2.PackSize;
594 {
595 const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
596 if (folderIndex != kNumNoIndex)
597 {
598 if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2)
599 PropVarEm_Set_UInt64(value, _db.GetFolderFullPackSize(folderIndex));
600 /*
601 else
602 PropVarEm_Set_UInt64(value, 0);
603 */
604 }
605 else
606 PropVarEm_Set_UInt64(value, 0);
607 }
608 break;
609 }
610 // case kpidIsAux: prop = _db.IsItemAux(index2); break;
611 case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) PropVarEm_Set_UInt64(value, v); break; }
612 case kpidCTime: SetFileTimeProp_From_UInt64Def(value, _db.CTime, index2); break;
613 case kpidATime: SetFileTimeProp_From_UInt64Def(value, _db.ATime, index2); break;
614 case kpidMTime: SetFileTimeProp_From_UInt64Def(value, _db.MTime, index2); break;
615 case kpidAttrib: if (_db.Attrib.ValidAndDefined(index2)) PropVarEm_Set_UInt32(value, _db.Attrib.Vals[index2]); break;
616 case kpidCRC: if (item.CrcDefined) PropVarEm_Set_UInt32(value, item.Crc); break;
617 case kpidEncrypted: PropVarEm_Set_Bool(value, IsFolderEncrypted(_db.FileIndexToFolderIndexMap[index2])); break;
618 case kpidIsAnti: PropVarEm_Set_Bool(value, _db.IsItemAnti(index2)); break;
619 /*
620 case kpidIsAltStream: prop = item.IsAltStream; break;
621 case kpidNtSecure:
622 {
623 int id = _db.SecureIDs[index];
624 size_t offs = _db.SecureOffsets[id];
625 size_t size = _db.SecureOffsets[id + 1] - offs;
626 if (size >= 0)
627 {
628 prop.SetBlob(_db.SecureBuf + offs, (ULONG)size);
629 }
630 break;
631 }
632 */
633
634 case kpidPath: return _db.GetPath_Prop(index, value);
635
636 #ifndef Z7_SFX
637
638 case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value);
639 case kpidBlock:
640 {
641 const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
642 if (folderIndex != kNumNoIndex)
643 PropVarEm_Set_UInt32(value, (UInt32)folderIndex);
644 }
645 break;
646 #ifdef Z7_7Z_SHOW_PACK_STREAMS_SIZES
647 case kpidPackedSize0:
648 case kpidPackedSize1:
649 case kpidPackedSize2:
650 case kpidPackedSize3:
651 case kpidPackedSize4:
652 {
653 const CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
654 if (folderIndex != kNumNoIndex)
655 {
656 if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
657 _db.FoStartPackStreamIndex[folderIndex + 1] -
658 _db.FoStartPackStreamIndex[folderIndex] > (propID - kpidPackedSize0))
659 {
660 PropVarEm_Set_UInt64(value, _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0));
661 }
662 }
663 else
664 PropVarEm_Set_UInt64(value, 0);
665 }
666 break;
667 #endif
668
669 #endif
670 default: break;
671 }
672 // return prop.Detach(value);
673 return S_OK;
674 // COM_TRY_END
675 }
676
Z7_COM7F_IMF(CHandler::Open (IInStream * stream,const UInt64 * maxCheckStartPosition,IArchiveOpenCallback * openArchiveCallback))677 Z7_COM7F_IMF(CHandler::Open(IInStream *stream,
678 const UInt64 *maxCheckStartPosition,
679 IArchiveOpenCallback *openArchiveCallback))
680 {
681 COM_TRY_BEGIN
682 Close();
683 #ifndef Z7_SFX
684 _fileInfoPopIDs.Clear();
685 #endif
686
687 try
688 {
689 CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
690
691 #ifndef Z7_NO_CRYPTO
692 CMyComPtr<ICryptoGetTextPassword> getTextPassword;
693 if (openArchiveCallback)
694 openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
695 #endif
696
697 CInArchive archive(
698 #ifdef Z7_7Z_SET_PROPERTIES
699 _useMultiThreadMixer
700 #else
701 true
702 #endif
703 );
704 _db.IsArc = false;
705 RINOK(archive.Open(stream, maxCheckStartPosition))
706 _db.IsArc = true;
707
708 HRESULT result = archive.ReadDatabase(
709 EXTERNAL_CODECS_VARS
710 _db
711 #ifndef Z7_NO_CRYPTO
712 , getTextPassword, _isEncrypted, _passwordIsDefined, _password
713 #endif
714 );
715 RINOK(result)
716
717 _inStream = stream;
718 }
719 catch(...)
720 {
721 Close();
722 // return E_INVALIDARG;
723 // return S_FALSE;
724 // we must return out_of_memory here
725 return E_OUTOFMEMORY;
726 }
727 // _inStream = stream;
728 #ifndef Z7_SFX
729 FillPopIDs();
730 #endif
731 return S_OK;
732 COM_TRY_END
733 }
734
Z7_COM7F_IMF(CHandler::Close ())735 Z7_COM7F_IMF(CHandler::Close())
736 {
737 COM_TRY_BEGIN
738 _inStream.Release();
739 _db.Clear();
740 #ifndef Z7_NO_CRYPTO
741 _isEncrypted = false;
742 _passwordIsDefined = false;
743 _password.Wipe_and_Empty();
744 #endif
745 return S_OK;
746 COM_TRY_END
747 }
748
749 #ifdef Z7_7Z_SET_PROPERTIES
750 #ifdef Z7_EXTRACT_ONLY
751
Z7_COM7F_IMF(CHandler::SetProperties (const wchar_t * const * names,const PROPVARIANT * values,UInt32 numProps))752 Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps))
753 {
754 COM_TRY_BEGIN
755
756 InitCommon();
757 _useMultiThreadMixer = true;
758
759 for (UInt32 i = 0; i < numProps; i++)
760 {
761 UString name = names[i];
762 name.MakeLower_Ascii();
763 if (name.IsEmpty())
764 return E_INVALIDARG;
765 const PROPVARIANT &value = values[i];
766 UInt32 number;
767 const unsigned index = ParseStringToUInt32(name, number);
768 if (index == 0)
769 {
770 if (name.IsEqualTo("mtf"))
771 {
772 RINOK(PROPVARIANT_to_bool(value, _useMultiThreadMixer))
773 continue;
774 }
775 {
776 HRESULT hres;
777 if (SetCommonProperty(name, value, hres))
778 {
779 RINOK(hres)
780 continue;
781 }
782 }
783 return E_INVALIDARG;
784 }
785 }
786 return S_OK;
787 COM_TRY_END
788 }
789
790 #endif
791 #endif
792
793 IMPL_ISetCompressCodecsInfo
794
795 }}
796