1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// 7zIn.cpp 2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h" 4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 5cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#ifdef _WIN32 6cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include <wchar.h> 7cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#else 8cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include <ctype.h> 9cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#endif 10cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../../C/7zCrc.h" 12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../../../C/CpuArch.h" 13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/StreamObjects.h" 15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../Common/StreamUtils.h" 16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zDecode.h" 18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "7zIn.h" 19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define Get16(p) GetUi16(p) 21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define Get32(p) GetUi32(p) 22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define Get64(p) GetUi64(p) 23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader 25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _SFX 26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define FORMAT_7Z_RECOVERY 27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 29cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyusing namespace NWindows; 30cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyusing namespace NCOM; 31cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 32baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NArchive { 33baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace N7z { 34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 35cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic void BoolVector_Fill_False(CBoolVector &v, unsigned size) 36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 37cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky v.ClearAndSetSize(size); 38cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bool *p = &v[0]; 39cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (unsigned i = 0; i < size; i++) 40cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky p[i] = false; 41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 43baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CInArchiveException {}; 44cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyclass CUnsupportedFeatureException: public CInArchiveException {}; 45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 46baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void ThrowException() { throw CInArchiveException(); } 47baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline void ThrowEndOfData() { ThrowException(); } 48cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); } 49baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline void ThrowIncorrect() { ThrowException(); } 50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 51baa3858d3f5d128a5c8466b700098109edcad5f2repo syncclass CStreamSwitch 52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CInArchive *_archive; 54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool _needRemove; 55cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bool _needUpdatePos; 56baa3858d3f5d128a5c8466b700098109edcad5f2repo syncpublic: 57cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CStreamSwitch(): _needRemove(false), _needUpdatePos(false) {} 58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ~CStreamSwitch() { Remove(); } 59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void Remove(); 60cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky void Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos); 61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void Set(CInArchive *archive, const CByteBuffer &byteBuffer); 62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync void Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector); 63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}; 64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 65baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CStreamSwitch::Remove() 66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_needRemove) 68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 69cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (_archive->_inByteBack->GetRem() != 0) 70cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _archive->ThereIsHeaderError = true; 71cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _archive->DeleteByteStream(_needUpdatePos); 72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _needRemove = false; 73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 76cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CStreamSwitch::Set(CInArchive *archive, const Byte *data, size_t size, bool needUpdatePos) 77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Remove(); 79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _archive = archive; 80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _archive->AddByteStream(data, size); 81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _needRemove = true; 82cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _needUpdatePos = needUpdatePos; 83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 85baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) 86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 87cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Set(archive, byteBuffer, byteBuffer.Size(), false); 88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 90baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *dataVector) 91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Remove(); 93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte external = archive->ReadByte(); 94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (external != 0) 95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 96f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (!dataVector) 97f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka ThrowIncorrect(); 98cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum dataIndex = archive->ReadNum(); 99cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (dataIndex >= dataVector->Size()) 100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowIncorrect(); 101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Set(archive, (*dataVector)[dataIndex]); 102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 105cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::AddByteStream(const Byte *buf, size_t size) 106cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 107cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (_numInByteBufs == kNumBufLevelsMax) 108cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect(); 109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _inByteBack = &_inByteVector[_numInByteBufs++]; 110cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _inByteBack->Init(buf, size); 111cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 112cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 113cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 114baa3858d3f5d128a5c8466b700098109edcad5f2repo syncByte CInByte2::ReadByte() 115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_pos >= _size) 117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowEndOfData(); 118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return _buffer[_pos++]; 119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 121baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInByte2::ReadBytes(Byte *data, size_t size) 122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 123f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (size == 0) 124f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return; 125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size > _size - _pos) 126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowEndOfData(); 127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky memcpy(data, _buffer + _pos, size); 128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _pos += size; 129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 131baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInByte2::SkipData(UInt64 size) 132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (size > _size - _pos) 134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowEndOfData(); 135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _pos += (size_t)size; 136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 138baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInByte2::SkipData() 139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SkipData(ReadNumber()); 141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 143cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed) 144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 145cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (size == 0) 146cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 147cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky processed = 0; 148cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return 0; 149cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 150f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 151f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka unsigned b = *p++; 152cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size--; 153f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 154f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if ((b & 0x80) == 0) 155cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 156cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky processed = 1; 157f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka return b; 158cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 159f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 160cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (size == 0) 161cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 162cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky processed = 0; 163cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return 0; 164cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 165f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 166cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 value = (UInt64)*p; 167cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky p++; 168cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size--; 169f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 170cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (unsigned i = 1; i < 8; i++) 171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 172f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka unsigned mask = (unsigned)0x80 >> i; 173f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if ((b & mask) == 0) 174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 175f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka UInt64 high = b & (mask - 1); 176f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka value |= (high << (i * 8)); 177cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky processed = i + 1; 178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return value; 179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 180f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 181cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (size == 0) 182cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 183cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky processed = 0; 184cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return 0; 185cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 186f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 187cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky value |= ((UInt64)*p << (i * 8)); 188cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky p++; 189cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size--; 190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 191f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 192cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky processed = 9; 193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return value; 194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 196cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyUInt64 CInByte2::ReadNumber() 197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 198cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t processed; 199cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 res = ReadNumberSpec(_buffer + _pos, _size - _pos, processed); 200cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processed == 0) 201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowEndOfData(); 202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _pos += processed; 203cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return res; 204cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 205cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 206baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCNum CInByte2::ReadNum() 207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 208cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky /* 209cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (_pos < _size) 210cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 211cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Byte val = _buffer[_pos]; 212cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if ((unsigned)val < 0x80) 213cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 214cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _pos++; 215cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return (unsigned)val; 216cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 217cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 218cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky */ 219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 value = ReadNumber(); 220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (value > kNumMax) 221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowUnsupported(); 222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (CNum)value; 223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 225baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt32 CInByte2::ReadUInt32() 226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_pos + 4 > _size) 228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowEndOfData(); 229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 res = Get32(_buffer + _pos); 230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _pos += 4; 231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return res; 232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 234baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUInt64 CInByte2::ReadUInt64() 235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (_pos + 8 > _size) 237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowEndOfData(); 238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 res = Get64(_buffer + _pos); 239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _pos += 8; 240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return res; 241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 243cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define CHECK_SIGNATURE if (p[0] != '7' || p[1] != 'z' || p[2] != 0xBC || p[3] != 0xAF || p[4] != 0x27 || p[5] != 0x1C) return false; 244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 245baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline bool TestSignature(const Byte *p) 246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 247cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CHECK_SIGNATURE 248cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return CrcCalc(p + 12, 20) == Get32(p + 8); 249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef FORMAT_7Z_RECOVERY 252baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline bool TestSignature2(const Byte *p) 253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 254cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CHECK_SIGNATURE; 255cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (CrcCalc(p + 12, 20) == Get32(p + 8)) 256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return true; 257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (unsigned i = 8; i < kHeaderSize; i++) 258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (p[i] != 0) 259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return false; 260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return (p[6] != 0 || p[7] != 0); 261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#else 263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define TestSignature2(p) TestSignature(p) 264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif 265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 266baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) 267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(ReadStream_FALSE(stream, _header, kHeaderSize)); 269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (TestSignature2(_header)) 271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 272cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0) 273cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_FALSE; 274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 275cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const UInt32 kBufSize = 1 << 15; 276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CByteArr buf(kBufSize); 277cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky memcpy(buf, _header, kHeaderSize); 278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 offset = 0; 279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 282cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 readSize = kBufSize - kHeaderSize; 283f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (searchHeaderSizeLimit) 284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 285cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 rem = *searchHeaderSizeLimit - offset; 286cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (readSize > rem) 287cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky readSize = (UInt32)rem; 288cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (readSize == 0) 289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_FALSE; 290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 291f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 292cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 processed = 0; 293cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(stream->Read(buf + kHeaderSize, readSize, &processed)); 294cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (processed == 0) 295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_FALSE; 296f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 297cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (UInt32 pos = 0;;) 298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const Byte *p = buf + pos + 1; 300cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const Byte *lim = buf + processed; 301cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (; p <= lim; p += 4) 302cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 303cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (p[0] == '7') break; 304cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (p[1] == '7') { p += 1; break; } 305cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (p[2] == '7') { p += 2; break; } 306cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (p[3] == '7') { p += 3; break; } 307cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky }; 308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (p > lim) 309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 310cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky pos = (UInt32)(p - buf); 311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (TestSignature(p)) 312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky memcpy(_header, p, kHeaderSize); 314cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _arhiveBeginStreamPosition += offset + pos; 315cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL); 316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 318f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 319cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky offset += processed; 320cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky memmove(buf, buf + processed, kHeaderSize); 321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// S_FALSE means that file is not archive 325baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) 326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HeadersSize = 0; 328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Close(); 329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition)) 330cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition)) 331cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL)) 332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit)); 333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _stream = stream; 334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 337baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::Close() 338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 339cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _numInByteBufs = 0; 340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync _stream.Release(); 341cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThereIsHeaderError = false; 342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 344baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */) 345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (ReadID() == NID::kEnd) 349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SkipData(); 351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 354cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky// CFolder &folder can be non empty. So we must set all fields 355cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 356cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInByte2::ParseFolder(CFolder &folder) 357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 358f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka UInt32 numCoders = ReadNum(); 359f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 360f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (numCoders == 0) 361f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka ThrowUnsupported(); 362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 363cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folder.Coders.SetSize(numCoders); 364cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 365f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka UInt32 numInStreams = 0; 366f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka UInt32 i; 367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numCoders; i++) 368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 369cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CCoderInfo &coder = folder.Coders[i]; 370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte mainByte = ReadByte(); 372cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if ((mainByte & 0xC0) != 0) 373cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowUnsupported(); 374cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned idSize = (mainByte & 0xF); 375cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (idSize > 8 || idSize > GetRem()) 376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowUnsupported(); 377cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const Byte *longID = GetPtr(); 378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 id = 0; 379cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (unsigned j = 0; j < idSize; j++) 380cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky id = ((id << 8) | longID[j]); 381cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky SkipDataNoCheck(idSize); 382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync coder.MethodID = id; 383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((mainByte & 0x10) != 0) 385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 386f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka coder.NumStreams = ReadNum(); 387f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka /* numOutStreams = */ ReadNum(); 388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 391f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka coder.NumStreams = 1; 392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 393f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if ((mainByte & 0x20) != 0) 395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CNum propsSize = ReadNum(); 397cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky coder.Props.Alloc((size_t)propsSize); 398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReadBytes((Byte *)coder.Props, (size_t)propsSize); 399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 400cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky else 401cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky coder.Props.Free(); 402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 403f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka numInStreams += coder.NumStreams; 404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 406f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka UInt32 numBonds = numCoders - 1; 407f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka folder.Bonds.SetSize(numBonds); 408f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (i = 0; i < numBonds; i++) 409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 410f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka CBond &bp = folder.Bonds[i]; 411f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka bp.PackIndex = ReadNum(); 412f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka bp.UnpackIndex = ReadNum(); 413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 415f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (numInStreams < numBonds) 416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowUnsupported(); 417f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka UInt32 numPackStreams = numInStreams - numBonds; 418cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folder.PackStreams.SetSize(numPackStreams); 419f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numPackStreams == 1) 421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numInStreams; i++) 423f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (folder.FindBond_for_PackStream(i) < 0) 424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 425cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folder.PackStreams[0] = i; 426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 428cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (i == numInStreams) 429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowUnsupported(); 430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numPackStreams; i++) 433cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folder.PackStreams[i] = ReadNum(); 434cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 435cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 436cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CFolders::ParseFolderInfo(unsigned folderIndex, CFolder &folder) const 437cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 438cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t startPos = FoCodersDataOffset[folderIndex]; 439cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CInByte2 inByte; 440cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky inByte.Init(CodersData + startPos, FoCodersDataOffset[folderIndex + 1] - startPos); 441cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky inByte.ParseFolder(folder); 442cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (inByte.GetRem() != 0) 443cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky throw 20120424; 444cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 445cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 446cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 447cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CDatabase::GetPath(unsigned index, UString &path) const 448cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 449cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky path.Empty(); 450cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!NameOffsets || !NamesBuf) 451cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return; 452cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 453cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t offset = NameOffsets[index]; 454f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka size_t size = NameOffsets[index + 1] - offset; 455cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 456f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (size >= (1 << 28)) 457cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return; 458cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 459f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka wchar_t *s = path.GetBuf((unsigned)size - 1); 460cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 461cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const Byte *p = ((const Byte *)NamesBuf + offset * 2); 462cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 463cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky #if defined(_WIN32) && defined(MY_CPU_LE) 464cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 465cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky wmemcpy(s, (const wchar_t *)p, size); 466cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 467cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky #else 468cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 469cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (size_t i = 0; i < size; i++) 470cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 471cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky *s = Get16(p); 472cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky p += 2; 473cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky s++; 474cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 475cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 476cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky #endif 477cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 478f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka path.ReleaseBuf_SetLen((unsigned)size - 1); 479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 481cd66d540cead3f8200b0c73bad9c276d67896c3dDavid SrbeckyHRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw() 482cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{ 483cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky PropVariant_Clear(path); 484cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!NameOffsets || !NamesBuf) 485cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 486cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 487cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t offset = NameOffsets[index]; 488cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t size = NameOffsets[index + 1] - offset; 489cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 490cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (size >= (1 << 14)) 491cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 492cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 493cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1)); 494cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky wchar_t *s = path->bstrVal; 495cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 496cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const Byte *p = ((const Byte *)NamesBuf + offset * 2); 497cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 498cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (size_t i = 0; i < size; i++) 499cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 500cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky wchar_t c = Get16(p); 501cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky p += 2; 502cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky #if WCHAR_PATH_SEPARATOR != L'/' 503cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (c == L'/') 504cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky c = WCHAR_PATH_SEPARATOR; 505cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky #endif 506cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky *s++ = c; 507cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 508cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 509cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 510cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 511cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky /* 512cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned cur = index; 513cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned size = 0; 514cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 515cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (int i = 0;; i++) 516cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 517cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t len = NameOffsets[cur + 1] - NameOffsets[cur]; 518cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size += (unsigned)len; 519cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (i > 256 || len > (1 << 14) || size > (1 << 14)) 520cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return PropVarEm_Set_Str(path, "[TOO-LONG]"); 521cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky cur = Files[cur].Parent; 522cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (cur < 0) 523cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky break; 524cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 525cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size--; 526cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 527cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(PropVarEm_Alloc_Bstr(path, size)); 528cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky wchar_t *s = path->bstrVal; 529cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky s += size; 530cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky *s = 0; 531cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky cur = index; 532cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 533cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (;;) 534cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 535cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned len = (unsigned)(NameOffsets[cur + 1] - NameOffsets[cur] - 1); 536cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const Byte *p = (const Byte *)NamesBuf + (NameOffsets[cur + 1] * 2) - 2; 537f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (; len != 0; len--) 538cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 539cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky p -= 2; 540cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky --s; 541cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky wchar_t c = Get16(p); 542cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (c == '/') 543cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky c = WCHAR_PATH_SEPARATOR; 544cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky *s = c; 545cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 546f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 547cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const CFileItem &file = Files[cur]; 548cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky cur = file.Parent; 549cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (cur < 0) 550cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 551cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky *(--s) = (file.IsAltStream ? ':' : WCHAR_PATH_SEPARATOR); 552cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 553cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky */ 554cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky} 555cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 556cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::WaitId(UInt64 id) 557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type = ReadID(); 561cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (type == id) 562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == NID::kEnd) 564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowIncorrect(); 565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SkipData(); 566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 569cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs) 570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 571cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadBoolVector2(numItems, crcs.Defs); 572cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky crcs.Vals.ClearAndSetSize(numItems); 573cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 *p = &crcs.Vals[0]; 574cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const bool *defs = &crcs.Defs[0]; 575cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (unsigned i = 0; i < numItems; i++) 576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt32 crc = 0; 578cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (defs[i]) 579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync crc = ReadUInt32(); 580cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky p[i] = crc; 581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 584f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#define k_Scan_NumCoders_MAX 64 585f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka#define k_Scan_NumCodersStreams_in_Folder_MAX 64 586f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 587cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::ReadPackInfo(CFolders &f) 588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CNum numPackStreams = ReadNum(); 590cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 591cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky WaitId(NID::kSize); 592cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky f.PackPositions.Alloc(numPackStreams + 1); 593cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky f.NumPackStreams = numPackStreams; 594cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 sum = 0; 595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (CNum i = 0; i < numPackStreams; i++) 596cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 597cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky f.PackPositions[i] = sum; 598cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 packSize = ReadNumber(); 599cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky sum += packSize; 600cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (sum < packSize) 601cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect(); 602cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 603cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky f.PackPositions[numPackStreams] = sum; 604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type; 606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync type = ReadID(); 609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == NID::kEnd) 610cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return; 611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == NID::kCRC) 612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 613cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CUInt32DefVector PackCRCs; 614cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadHashDigests(numPackStreams, PackCRCs); 615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 616baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SkipData(); 618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 621baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::ReadUnpackInfo( 622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CObjectVector<CByteBuffer> *dataVector, 623cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CFolders &folders) 624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 625cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky WaitId(NID::kFolder); 626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CNum numFolders = ReadNum(); 627baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 628cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum numCodersOutStreams = 0; 629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CStreamSwitch streamSwitch; 631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync streamSwitch.Set(this, dataVector); 632cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const Byte *startBufPtr = _inByteBack->GetPtr(); 633cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.NumFolders = numFolders; 634cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 635cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.FoStartPackStreamIndex.Alloc(numFolders + 1); 636cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.FoToMainUnpackSizeIndex.Alloc(numFolders); 637cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.FoCodersDataOffset.Alloc(numFolders + 1); 638cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.FoToCoderUnpackSizes.Alloc(numFolders + 1); 639cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 640f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka CBoolVector StreamUsed; 641f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka CBoolVector CoderUsed; 642cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 643cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum packStreamIndex = 0; 644cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum fo; 645cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CInByte2 *inByte = _inByteBack; 646f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 647cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (fo = 0; fo < numFolders; fo++) 648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 649cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 indexOfMainStream = 0; 650cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 numPackStreams = 0; 651cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr; 652cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 653cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum numInStreams = 0; 654cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum numCoders = inByte->ReadNum(); 655f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 656f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) 657f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka ThrowUnsupported(); 658f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 659cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (CNum ci = 0; ci < numCoders; ci++) 660cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 661cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Byte mainByte = inByte->ReadByte(); 662cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if ((mainByte & 0xC0) != 0) 663cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowUnsupported(); 664f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 665cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned idSize = (mainByte & 0xF); 666cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (idSize > 8) 667cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowUnsupported(); 668cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (idSize > inByte->GetRem()) 669cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowEndOfData(); 670cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const Byte *longID = inByte->GetPtr(); 671cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 id = 0; 672cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (unsigned j = 0; j < idSize; j++) 673cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky id = ((id << 8) | longID[j]); 674cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky inByte->SkipDataNoCheck(idSize); 675cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (folders.ParsedMethods.IDs.Size() < 128) 676cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.ParsedMethods.IDs.AddToUniqueSorted(id); 677f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 678cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum coderInStreams = 1; 679cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if ((mainByte & 0x10) != 0) 680cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 681cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky coderInStreams = inByte->ReadNum(); 682f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX) 683f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka ThrowUnsupported(); 684f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (inByte->ReadNum() != 1) 685f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka ThrowUnsupported(); 686cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 687f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 688cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky numInStreams += coderInStreams; 689f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX) 690cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowUnsupported(); 691f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 692cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if ((mainByte & 0x20) != 0) 693cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 694cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum propsSize = inByte->ReadNum(); 695cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (propsSize > inByte->GetRem()) 696cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowEndOfData(); 697cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (id == k_LZMA2 && propsSize == 1) 698cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 699cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky Byte v = *_inByteBack->GetPtr(); 700cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (folders.ParsedMethods.Lzma2Prop < v) 701cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.ParsedMethods.Lzma2Prop = v; 702cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 703cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky else if (id == k_LZMA && propsSize == 5) 704cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 705cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 dicSize = GetUi32(_inByteBack->GetPtr() + 1); 706cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (folders.ParsedMethods.LzmaDic < dicSize) 707cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.ParsedMethods.LzmaDic = dicSize; 708cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 709cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky inByte->SkipDataNoCheck((size_t)propsSize); 710cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 711cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 712cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 713f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (numCoders == 1 && numInStreams == 1) 714cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 715cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky indexOfMainStream = 0; 716cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky numPackStreams = 1; 717cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 718cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky else 719cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 720cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 i; 721f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka CNum numBonds = numCoders - 1; 722f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (numInStreams < numBonds) 723cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowUnsupported(); 724cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 725f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka BoolVector_Fill_False(StreamUsed, numInStreams); 726f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka BoolVector_Fill_False(CoderUsed, numCoders); 727cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 728f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (i = 0; i < numBonds; i++) 729cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 730cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum index = ReadNum(); 731f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (index >= numInStreams || StreamUsed[index]) 732cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowUnsupported(); 733f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka StreamUsed[index] = true; 734f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 735cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky index = ReadNum(); 736f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (index >= numCoders || CoderUsed[index]) 737cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowUnsupported(); 738f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka CoderUsed[index] = true; 739cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 740cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 741f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka numPackStreams = numInStreams - numBonds; 742cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 743cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (numPackStreams != 1) 744cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < numPackStreams; i++) 745f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka { 746f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka CNum index = inByte->ReadNum(); // PackStreams 747f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (index >= numInStreams || StreamUsed[index]) 748f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka ThrowUnsupported(); 749f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka StreamUsed[index] = true; 750f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka } 751cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 752f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (i = 0; i < numCoders; i++) 753f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (!CoderUsed[i]) 754cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 755cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky indexOfMainStream = i; 756cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky break; 757cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 758f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 759f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (i == numCoders) 760cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowUnsupported(); 761cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 762f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 763cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams; 764f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka numCodersOutStreams += numCoders; 765cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.FoStartPackStreamIndex[fo] = packStreamIndex; 766f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (numPackStreams > folders.NumPackStreams - packStreamIndex) 767f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka ThrowIncorrect(); 768cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky packStreamIndex += numPackStreams; 769cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream; 770baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 771f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 772cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t dataSize = _inByteBack->GetPtr() - startBufPtr; 773cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams; 774cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.FoStartPackStreamIndex[fo] = packStreamIndex; 775cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr; 776cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.CodersData.CopyFrom(startBufPtr, dataSize); 777f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 778f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka // if (folders.NumPackStreams != packStreamIndex) ThrowUnsupported(); 779baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 780baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 781cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky WaitId(NID::kCodersUnpackSize); 782cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.CoderUnpackSizes.Alloc(numCodersOutStreams); 783cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (CNum i = 0; i < numCodersOutStreams; i++) 784cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.CoderUnpackSizes[i] = ReadNumber(); 785baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 786baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 787baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 788baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type = ReadID(); 789baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == NID::kEnd) 790baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 791baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == NID::kCRC) 792baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 793cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadHashDigests(numFolders, folders.FolderCRCs); 794baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 795baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 796baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SkipData(); 797baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 799baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 800baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::ReadSubStreamsInfo( 801cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CFolders &folders, 802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt64> &unpackSizes, 803cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CUInt32DefVector &digests) 804baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 805cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.NumUnpackStreamsVector.Alloc(folders.NumFolders); 806cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum i; 807cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < folders.NumFolders; i++) 808cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.NumUnpackStreamsVector[i] = 1; 809cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 810baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type; 811cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 812baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync type = ReadID(); 815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == NID::kNumUnpackStream) 816baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 817cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < folders.NumFolders; i++) 818cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.NumUnpackStreamsVector[i] = ReadNum(); 819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 820baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 821cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (type == NID::kCRC || type == NID::kSize || type == NID::kEnd) 822baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync SkipData(); 824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 826cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (type == NID::kSize) 827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 828cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < folders.NumFolders; i++) 829cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 830cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // v3.13 incorrectly worked with empty folders 831cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // v4.07: we check that folder is empty 832cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum numSubstreams = folders.NumUnpackStreamsVector[i]; 833cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (numSubstreams == 0) 834cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky continue; 835cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 sum = 0; 836cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (CNum j = 1; j < numSubstreams; j++) 837baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 838baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 size = ReadNumber(); 839baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unpackSizes.Add(size); 840baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sum += size; 841cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (sum < size) 842cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect(); 843baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 844cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 folderUnpackSize = folders.GetFolderUnpackSize(i); 845cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (folderUnpackSize < sum) 846cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect(); 847cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unpackSizes.Add(folderUnpackSize - sum); 848cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 849baa3858d3f5d128a5c8466b700098109edcad5f2repo sync type = ReadID(); 850cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 851cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky else 852cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 853cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < folders.NumFolders; i++) 854cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 855cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky /* v9.26 - v9.29 incorrectly worked: 856cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (folders.NumUnpackStreamsVector[i] == 0), it threw error */ 857cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum val = folders.NumUnpackStreamsVector[i]; 858cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (val > 1) 859cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect(); 860cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (val == 1) 861cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unpackSizes.Add(folders.GetFolderUnpackSize(i)); 862cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 863cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 864baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 865cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned numDigests = 0; 866cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < folders.NumFolders; i++) 867baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 868cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum numSubstreams = folders.NumUnpackStreamsVector[i]; 869cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (numSubstreams != 1 || !folders.FolderCRCs.ValidAndDefined(i)) 870baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numDigests += numSubstreams; 871baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 872baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 873baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 874baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 875cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (type == NID::kEnd) 876cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky break; 877baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == NID::kCRC) 878baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 879cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // CUInt32DefVector digests2; 880cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // ReadHashDigests(numDigests, digests2); 881cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CBoolVector digests2; 882cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadBoolVector2(numDigests, digests2); 883cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 884cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky digests.ClearAndSetSize(unpackSizes.Size()); 885cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 886cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned k = 0; 887cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned k2 = 0; 888cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 889cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < folders.NumFolders; i++) 890baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 891cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum numSubstreams = folders.NumUnpackStreamsVector[i]; 892cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) 893baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 894cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky digests.Defs[k] = true; 895cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky digests.Vals[k] = folders.FolderCRCs.Vals[i]; 896cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky k++; 897cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 898cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky else for (CNum j = 0; j < numSubstreams; j++) 899cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 900cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bool defined = digests2[k2++]; 901cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky digests.Defs[k] = defined; 902cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 crc = 0; 903cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (defined) 904cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky crc = ReadUInt32(); 905cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky digests.Vals[k] = crc; 906cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky k++; 907baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 908baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 909cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // if (k != unpackSizes.Size()) throw 1234567; 910baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 911cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky else 912cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky SkipData(); 913cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 914cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky type = ReadID(); 915cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 916cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 917cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (digests.Defs.Size() != unpackSizes.Size()) 918cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 919cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky digests.ClearAndSetSize(unpackSizes.Size()); 920cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned k = 0; 921cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < folders.NumFolders; i++) 922baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 923cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum numSubstreams = folders.NumUnpackStreamsVector[i]; 924cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (numSubstreams == 1 && folders.FolderCRCs.ValidAndDefined(i)) 925baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 926cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky digests.Defs[k] = true; 927cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky digests.Vals[k] = folders.FolderCRCs.Vals[i]; 928cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky k++; 929cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 930cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky else for (CNum j = 0; j < numSubstreams; j++) 931cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 932cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky digests.Defs[k] = false; 933cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky digests.Vals[k] = 0; 934cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky k++; 935baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 936baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 937baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 938baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 939baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 940baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::ReadStreamsInfo( 941baa3858d3f5d128a5c8466b700098109edcad5f2repo sync const CObjectVector<CByteBuffer> *dataVector, 942baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 &dataOffset, 943cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CFolders &folders, 944baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt64> &unpackSizes, 945cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CUInt32DefVector &digests) 946baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 947cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 type = ReadID(); 948cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 949cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (type == NID::kPackInfo) 950baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 951cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky dataOffset = ReadNumber(); 952cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadPackInfo(folders); 953cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky type = ReadID(); 954cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 955cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 956cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (type == NID::kUnpackInfo) 957cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 958cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadUnpackInfo(dataVector, folders); 959cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky type = ReadID(); 960cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 961cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 962cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (folders.NumFolders != 0 && !folders.PackPositions) 963cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 964cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // if there are folders, we need PackPositions also 965cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.PackPositions.Alloc(1); 966cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.PackPositions[0] = 0; 967cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 968cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 969cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (type == NID::kSubStreamsInfo) 970cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 971cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadSubStreamsInfo(folders, unpackSizes, digests); 972cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky type = ReadID(); 973cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 974cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky else 975cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 976cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.NumUnpackStreamsVector.Alloc(folders.NumFolders); 977cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky /* If digests.Defs.Size() == 0, it means that there are no crcs. 978cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky So we don't need to fill digests with values. */ 979cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // digests.Vals.ClearAndSetSize(folders.NumFolders); 980cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // BoolVector_Fill_False(digests.Defs, folders.NumFolders); 981cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (CNum i = 0; i < folders.NumFolders; i++) 982baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 983cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folders.NumUnpackStreamsVector[i] = 1; 984cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unpackSizes.Add(folders.GetFolderUnpackSize(i)); 985cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // digests.Vals[i] = 0; 986baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 987baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 988cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 989cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (type != NID::kEnd) 990cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect(); 991baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 992baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 993cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::ReadBoolVector(unsigned numItems, CBoolVector &v) 994baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 995cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky v.ClearAndSetSize(numItems); 996baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte b = 0; 997baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte mask = 0; 998cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bool *p = &v[0]; 999cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (unsigned i = 0; i < numItems; i++) 1000baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1001baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (mask == 0) 1002baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1003baa3858d3f5d128a5c8466b700098109edcad5f2repo sync b = ReadByte(); 1004baa3858d3f5d128a5c8466b700098109edcad5f2repo sync mask = 0x80; 1005baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1006cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky p[i] = ((b & mask) != 0); 1007baa3858d3f5d128a5c8466b700098109edcad5f2repo sync mask >>= 1; 1008baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1009baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1010baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1011cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CInArchive::ReadBoolVector2(unsigned numItems, CBoolVector &v) 1012baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1013baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte allAreDefined = ReadByte(); 1014baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (allAreDefined == 0) 1015baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1016baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReadBoolVector(numItems, v); 1017baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return; 1018baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1019cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky v.ClearAndSetSize(numItems); 1020cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bool *p = &v[0]; 1021cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (unsigned i = 0; i < numItems; i++) 1022cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky p[i] = true; 1023baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1024baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1025baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector, 1026cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CUInt64DefVector &v, unsigned numItems) 1027baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1028cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadBoolVector2(numItems, v.Defs); 1029baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1030baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CStreamSwitch streamSwitch; 1031baa3858d3f5d128a5c8466b700098109edcad5f2repo sync streamSwitch.Set(this, &dataVector); 1032cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 1033cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky v.Vals.ClearAndSetSize(numItems); 1034cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 *p = &v.Vals[0]; 1035cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const bool *defs = &v.Defs[0]; 1036baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1037cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (unsigned i = 0; i < numItems; i++) 1038baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1039baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 t = 0; 1040cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (defs[i]) 1041baa3858d3f5d128a5c8466b700098109edcad5f2repo sync t = ReadUInt64(); 1042cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky p[i] = t; 1043baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1044baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1045baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1046baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::ReadAndDecodePackedStreams( 1047baa3858d3f5d128a5c8466b700098109edcad5f2repo sync DECL_EXTERNAL_CODECS_LOC_VARS 1048baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 baseOffset, 1049baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector 1050cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _7Z_DECODER_CRYPRO_VARS_DECL 1051baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ) 1052baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1053cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CFolders folders; 1054baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt64> unpackSizes; 1055cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CUInt32DefVector digests; 1056baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1057baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReadStreamsInfo(NULL, 1058baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dataOffset, 1059baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folders, 1060baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unpackSizes, 1061baa3858d3f5d128a5c8466b700098109edcad5f2repo sync digests); 1062baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1063f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka CDecoder decoder(_useMixerMT); 1064cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 1065cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (CNum i = 0; i < folders.NumFolders; i++) 1066baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1067cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CByteBuffer &data = dataVector.AddNew(); 1068cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 unpackSize64 = folders.GetFolderUnpackSize(i); 1069baa3858d3f5d128a5c8466b700098109edcad5f2repo sync size_t unpackSize = (size_t)unpackSize64; 1070baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (unpackSize != unpackSize64) 1071baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowUnsupported(); 1072cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky data.Alloc(unpackSize); 1073baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1074baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBufPtrSeqOutStream *outStreamSpec = new CBufPtrSeqOutStream; 1075baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; 1076baa3858d3f5d128a5c8466b700098109edcad5f2repo sync outStreamSpec->Init(data, unpackSize); 1077baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1078baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT result = decoder.Decode( 1079f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka EXTERNAL_CODECS_LOC_VARS 1080f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _stream, baseOffset + dataOffset, 1081f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka folders, i, 1082f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka NULL, // *unpackSize 1083f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 1084f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka outStream, 1085f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka NULL, // *compressProgress 1086f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka NULL // **inStreamMainRes 1087f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 1088f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka _7Z_DECODER_CRYPRO_VARS 1089f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka #if !defined(_7ZIP_ST) && !defined(_SFX) 1090f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka , false // mtMode 1091f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka , 1 // numThreads 1092f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka #endif 1093baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ); 1094baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(result); 1095baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1096cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (folders.FolderCRCs.ValidAndDefined(i)) 1097cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i]) 1098baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowIncorrect(); 1099baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1100f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 1101f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (folders.PackPositions) 1102f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka HeadersSize += folders.PackPositions[folders.NumPackStreams]; 1103f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 1104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 1105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1107baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::ReadHeader( 1108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync DECL_EXTERNAL_CODECS_LOC_VARS 1109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CDbEx &db 1110cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _7Z_DECODER_CRYPRO_VARS_DECL 1111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ) 1112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type = ReadID(); 1114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == NID::kArchiveProperties) 1116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1117cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadArchiveProperties(db.ArcInfo); 1118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync type = ReadID(); 1119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector<CByteBuffer> dataVector; 1122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == NID::kAdditionalStreamsInfo) 1124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT result = ReadAndDecodePackedStreams( 1126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync EXTERNAL_CODECS_LOC_VARS 1127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.StartPositionAfterHeader, 1128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.DataStartPosition2, 1129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dataVector 1130cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _7Z_DECODER_CRYPRO_VARS 1131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ); 1132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(result); 1133cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.DataStartPosition2 += db.ArcInfo.StartPositionAfterHeader; 1134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync type = ReadID(); 1135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CRecordVector<UInt64> unpackSizes; 1138cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CUInt32DefVector digests; 1139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type == NID::kMainStreamsInfo) 1141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReadStreamsInfo(&dataVector, 1143cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.DataStartPosition, 1144cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky (CFolders &)db, 1145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync unpackSizes, 1146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync digests); 1147cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.DataStartPosition += db.ArcInfo.StartPositionAfterHeader; 1148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync type = ReadID(); 1149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db.Files.Clear(); 1152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1153cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (type == NID::kFilesInfo) 1154cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1156f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka const CNum numFiles = ReadNum(); 1157cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.Files.ClearAndSetSize(numFiles); 1158cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky /* 1159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db.Files.Reserve(numFiles); 1160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CNum i; 1161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFiles; i++) 1162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db.Files.Add(CFileItem()); 1163cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky */ 1164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1165cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.FileInfoPopIDs.Add(NID::kSize); 1166cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // if (!db.PackSizes.IsEmpty()) 1167cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.FileInfoPopIDs.Add(NID::kPackInfo); 1168f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (numFiles > 0 && !digests.Defs.IsEmpty()) 1169cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC); 1170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBoolVector emptyStreamVector; 1172cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles); 1173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBoolVector emptyFileVector; 1174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBoolVector antiFileVector; 1175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CNum numEmptyStreams = 0; 1176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 1178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1179f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka const UInt64 type2 = ReadID(); 1180f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (type2 == NID::kEnd) 1181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 size = ReadNumber(); 1183cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (size > _inByteBack->GetRem()) 1184cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect(); 1185cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CStreamSwitch switchProp; 1186cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky switchProp.Set(this, _inByteBack->GetPtr(), (size_t)size, true); 1187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool addPropIdToList = true; 1188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool isKnownType = true; 1189f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (type2 > ((UInt32)1 << 30)) 1190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync isKnownType = false; 1191f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka else switch ((UInt32)type2) 1192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NID::kName: 1194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CStreamSwitch streamSwitch; 1196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync streamSwitch.Set(this, &dataVector); 1197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t rem = _inByteBack->GetRem(); 1198cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.NamesBuf.Alloc(rem); 1199cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadBytes(db.NamesBuf, rem); 1200cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.NameOffsets.Alloc(db.Files.Size() + 1); 1201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t pos = 0; 1202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned i; 1203cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < db.Files.Size(); i++) 1204cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1205cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t curRem = (rem - pos) / 2; 1206cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos); 1207cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t j; 1208cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (j = 0; j < curRem && buf[j] != 0; j++); 1209cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (j == curRem) 1210cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowEndOfData(); 1211cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.NameOffsets[i] = pos / 2; 1212cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky pos += j * 2 + 2; 1213cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1214cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.NameOffsets[i] = pos / 2; 1215cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (pos != rem) 1216cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThereIsHeaderError = true; 1217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1219cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky case NID::kWinAttrib: 1220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CBoolVector boolVector; 1222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReadBoolVector2(db.Files.Size(), boolVector); 1223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CStreamSwitch streamSwitch; 1224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync streamSwitch.Set(this, &dataVector); 1225f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (CNum i = 0; i < numFiles; i++) 1226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CFileItem &file = db.Files[i]; 1228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file.AttribDefined = boolVector[i]; 1229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (file.AttribDefined) 1230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file.Attrib = ReadUInt32(); 1231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1234cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky /* 1235cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky case NID::kIsAux: 1236cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1237cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadBoolVector(db.Files.Size(), db.IsAux); 1238cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky break; 1239cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1240cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky case NID::kParent: 1241cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1242cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.IsTree = true; 1243cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // CBoolVector boolVector; 1244cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // ReadBoolVector2(db.Files.Size(), boolVector); 1245cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // CStreamSwitch streamSwitch; 1246cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // streamSwitch.Set(this, &dataVector); 1247cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CBoolVector boolVector; 1248cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadBoolVector2(db.Files.Size(), boolVector); 1249cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 1250cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ThereAreAltStreams = false; 1251cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < numFiles; i++) 1252cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1253cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CFileItem &file = db.Files[i]; 1254cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // file.Parent = -1; 1255cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // if (boolVector[i]) 1256cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky file.Parent = (int)ReadUInt32(); 1257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky file.IsAltStream = !boolVector[i]; 1258cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (file.IsAltStream) 1259cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ThereAreAltStreams = true; 1260cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1261cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky break; 1262cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1263cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky */ 1264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NID::kEmptyStream: 1265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ReadBoolVector(numFiles, emptyStreamVector); 1267cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky numEmptyStreams = 0; 1268f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka for (CNum i = 0; i < (CNum)emptyStreamVector.Size(); i++) 1269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (emptyStreamVector[i]) 1270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numEmptyStreams++; 1271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync BoolVector_Fill_False(emptyFileVector, numEmptyStreams); 1273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync BoolVector_Fill_False(antiFileVector, numEmptyStreams); 1274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break; 1278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break; 1279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (unsigned)numFiles); break; 1280cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (unsigned)numFiles); break; 1281cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (unsigned)numFiles); break; 1282cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (unsigned)numFiles); break; 1283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync case NID::kDummy: 1284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (UInt64 j = 0; j < size; j++) 1286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (ReadByte() != 0) 1287cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThereIsHeaderError = true; 1288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync addPropIdToList = false; 1289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1291cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky /* 1292cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky case NID::kNtSecure: 1293cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1294cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky try 1295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1296cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1297cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CStreamSwitch streamSwitch; 1298cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky streamSwitch.Set(this, &dataVector); 1299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 numDescriptors = ReadUInt32(); 1300cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t offset = 0; 1301cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.SecureOffsets.Clear(); 1302cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < numDescriptors; i++) 1303cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1304cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 size = ReadUInt32(); 1305cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.SecureOffsets.Add(offset); 1306cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky offset += size; 1307cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // ThrowIncorrect();; 1309cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.SecureOffsets.Add(offset); 1310cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.SecureBuf.SetCapacity(offset); 1311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < numDescriptors; i++) 1312cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky offset = db.SecureOffsets[i]; 1314cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset); 1315cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1316cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.SecureIDs.Clear(); 1317cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (unsigned i = 0; i < db.Files.Size(); i++) 1318cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1319cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.SecureIDs.Add(ReadNum()); 1320cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // db.SecureIDs.Add(ReadUInt32()); 1321cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1322cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // ReadUInt32(); 1323cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (_inByteBack->GetRem() != 0) 1324cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect();; 1325cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1326cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1327cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky catch(CInArchiveException &) 1328cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1329cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThereIsHeaderError = true; 1330cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky addPropIdToList = isKnownType = false; 1331cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ClearSecure(); 1332cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1333cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky break; 1334cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1335cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky */ 1336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync default: 1337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync addPropIdToList = isKnownType = false; 1338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (isKnownType) 1340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1341cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (addPropIdToList) 1342f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka db.ArcInfo.FileInfoPopIDs.Add(type2); 1343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1345cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1346cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.UnsupportedFeatureWarning = true; 1347cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _inByteBack->SkipRem(); 1348cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1349f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka // SkipData worked incorrectly in some versions before v4.59 (7zVer <= 0.02) 1350cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (_inByteBack->GetRem() != 0) 1351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowIncorrect(); 1352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1354cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky type = ReadID(); // Read (NID::kEnd) end of headers 1355cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 1356f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka if (numFiles - numEmptyStreams != unpackSizes.Size()) 1357f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka ThrowUnsupported(); 1358f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 1359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CNum emptyFileIndex = 0; 1360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CNum sizeIndex = 0; 1361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CNum numAntiItems = 0; 1363f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 1364f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka CNum i; 1365f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 1366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numEmptyStreams; i++) 1367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (antiFileVector[i]) 1368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync numAntiItems++; 1369f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 1370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (i = 0; i < numFiles; i++) 1371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CFileItem &file = db.Files[i]; 1373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync bool isAnti; 1374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file.HasStream = !emptyStreamVector[i]; 1375cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky file.Crc = 0; 1376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (file.HasStream) 1377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file.IsDir = false; 1379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync isAnti = false; 1380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file.Size = unpackSizes[sizeIndex]; 1381cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky file.CrcDefined = digests.ValidAndDefined(sizeIndex); 1382cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (file.CrcDefined) 1383cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky file.Crc = digests.Vals[sizeIndex]; 1384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync sizeIndex++; 1385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file.IsDir = !emptyFileVector[emptyFileIndex]; 1389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync isAnti = antiFileVector[emptyFileIndex]; 1390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync emptyFileIndex++; 1391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file.Size = 0; 1392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync file.CrcDefined = false; 1393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (numAntiItems != 0) 1395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db.IsAnti.Add(isAnti); 1396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1398cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.FillLinks(); 1399cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky /* 1400cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (type != NID::kEnd) 1401cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect(); 1402cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (_inByteBack->GetRem() != 0) 1403cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect(); 1404cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky */ 1405cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_OK; 1406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1408cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid CDbEx::FillLinks() 1409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1410f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka FolderStartFileIndex.Alloc(NumFolders); 1411f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka FileIndexToFolderIndexMap.Alloc(Files.Size()); 1412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1413cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CNum folderIndex = 0; 1414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CNum indexInFolder = 0; 1415cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned i; 1416f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 1417cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = 0; i < Files.Size(); i++) 1418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1419cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky bool emptyStream = !Files[i].HasStream; 1420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (indexInFolder == 0) 1421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1422cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (emptyStream) 1423cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1424cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky FileIndexToFolderIndexMap[i] = kNumNoIndex; 1425cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky continue; 1426cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync // v3.13 incorrectly worked with empty folders 1428cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // v4.07: we skip empty folders 1429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync for (;;) 1430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1431cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (folderIndex >= NumFolders) 1432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowIncorrect(); 1433cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky FolderStartFileIndex[folderIndex] = i; 1434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (NumUnpackStreamsVector[folderIndex] != 0) 1435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync break; 1436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folderIndex++; 1437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1439cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky FileIndexToFolderIndexMap[i] = folderIndex; 1440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (emptyStream) 1441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync continue; 1442cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (++indexInFolder >= NumUnpackStreamsVector[folderIndex]) 1443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync folderIndex++; 1445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync indexInFolder = 0; 1446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1448cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 1449cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (indexInFolder != 0) 1450cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folderIndex++; 1451cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky /* 1452cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (indexInFolder != 0) 1453cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect(); 1454cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky */ 1455f955a79a9fffb09826cf7547f70d08c3798a2f50Tetsuo Osaka 1456cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (;;) 1457cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1458cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (folderIndex >= NumFolders) 1459cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return; 1460cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky FolderStartFileIndex[folderIndex] = i; 1461cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky /* 1462cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (NumUnpackStreamsVector[folderIndex] != 0) 1463cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowIncorrect();; 1464cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky */ 1465cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky folderIndex++; 1466cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1469baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::ReadDatabase2( 1470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync DECL_EXTERNAL_CODECS_LOC_VARS 1471cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CDbEx &db 1472cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _7Z_DECODER_CRYPRO_VARS_DECL 1473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ) 1474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db.Clear(); 1476cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.StartPosition = _arhiveBeginStreamPosition; 1477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1478cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.Version.Major = _header[6]; 1479cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.Version.Minor = _header[7]; 1480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1481cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (db.ArcInfo.Version.Major != kMajorVersion) 1482cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1483cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // db.UnsupportedVersion = true; 1484cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_FALSE; 1485cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1487cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 nextHeaderOffset = Get64(_header + 12); 1488cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 nextHeaderSize = Get64(_header + 20); 1489cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 nextHeaderCRC = Get32(_header + 28); 1490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #ifdef FORMAT_7Z_RECOVERY 1492cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt32 crcFromArc = Get32(_header + 8); 1493cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (crcFromArc == 0 && nextHeaderOffset == 0 && nextHeaderSize == 0 && nextHeaderCRC == 0) 1494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1495cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 cur, fileSize; 1496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &cur)); 1497cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky const unsigned kCheckSize = 512; 1498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync Byte buf[kCheckSize]; 1499cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize)); 1500cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky UInt64 rem = fileSize - cur; 1501cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned checkSize = kCheckSize; 1502cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (rem < kCheckSize) 1503cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky checkSize = (unsigned)(rem); 1504cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (checkSize < 3) 1505cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_FALSE; 1506cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(_stream->Seek(fileSize - checkSize, STREAM_SEEK_SET, NULL)); 1507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize)); 1508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1509cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (buf[checkSize - 1] != 0) 1510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_FALSE; 1511cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 1512cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky unsigned i; 1513cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky for (i = checkSize - 2;; i--) 1514cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1515cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo || 1516cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo) 1517cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky break; 1518cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (i == 0) 1519cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_FALSE; 1520cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextHeaderSize = checkSize - i; 1522cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky nextHeaderOffset = rem - nextHeaderSize; 1523baa3858d3f5d128a5c8466b700098109edcad5f2repo sync nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize); 1524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL)); 1525cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.StartHeaderWasRecovered = true; 1526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync else 1528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync #endif 1529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1530cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // Crc was tested already at signature check 1531cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky // if (CrcCalc(_header + 12, 20) != crcFromArchive) ThrowIncorrect(); 1532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1534cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize; 1535cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.PhySize = kHeaderSize; 1536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1537cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.IsArc = false; 1538cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if ((Int64)nextHeaderOffset < 0 || 1539cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky nextHeaderSize > ((UInt64)1 << 62)) 1540cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_FALSE; 1541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (nextHeaderSize == 0) 1542cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1543cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (nextHeaderOffset != 0) 1544cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_FALSE; 1545cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.IsArc = true; 1546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 1547cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1548cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 1549cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!db.StartHeaderWasRecovered) 1550cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.IsArc = true; 1551cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 1552cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky HeadersSize += kHeaderSize + nextHeaderSize; 1553cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize; 1554cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (_fileEndPosition - db.ArcInfo.StartPositionAfterHeader < nextHeaderOffset + nextHeaderSize) 1555cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1556cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.UnexpectedEnd = true; 1557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_FALSE; 1558cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL)); 1560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1561cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky size_t nextHeaderSize_t = (size_t)nextHeaderSize; 1562cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (nextHeaderSize_t != nextHeaderSize) 1563cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return E_OUTOFMEMORY; 1564cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CByteBuffer buffer2(nextHeaderSize_t); 1565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1566cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky RINOK(ReadStream_FALSE(_stream, buffer2, nextHeaderSize_t)); 1567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1568cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (CrcCalc(buffer2, nextHeaderSize_t) != nextHeaderCRC) 1569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowIncorrect(); 1570cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 1571cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (!db.StartHeaderWasRecovered) 1572cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.PhySizeWasConfirmed = true; 1573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CStreamSwitch streamSwitch; 1575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync streamSwitch.Set(this, buffer2); 1576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync CObjectVector<CByteBuffer> dataVector; 1578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync UInt64 type = ReadID(); 1580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type != NID::kHeader) 1581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (type != NID::kEncodedHeader) 1583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowIncorrect(); 1584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync HRESULT result = ReadAndDecodePackedStreams( 1585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync EXTERNAL_CODECS_LOC_VARS 1586cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.StartPositionAfterHeader, 1587cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ArcInfo.DataStartPosition2, 1588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync dataVector 1589cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _7Z_DECODER_CRYPRO_VARS 1590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ); 1591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync RINOK(result); 1592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (dataVector.Size() == 0) 1593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return S_OK; 1594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (dataVector.Size() > 1) 1595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowIncorrect(); 1596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync streamSwitch.Remove(); 1597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync streamSwitch.Set(this, dataVector.Front()); 1598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync if (ReadID() != NID::kHeader) 1599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ThrowIncorrect(); 1600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1601baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1602cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.IsArc = true; 1603cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky 1604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db.HeadersSize = HeadersSize; 1605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync return ReadHeader( 1607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync EXTERNAL_CODECS_LOC_VARS 1608baa3858d3f5d128a5c8466b700098109edcad5f2repo sync db 1609cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _7Z_DECODER_CRYPRO_VARS 1610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ); 1611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1613baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CInArchive::ReadDatabase( 1614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync DECL_EXTERNAL_CODECS_LOC_VARS 1615cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky CDbEx &db 1616cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _7Z_DECODER_CRYPRO_VARS_DECL 1617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ) 1618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{ 1619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync try 1620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync { 1621cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky HRESULT res = ReadDatabase2( 1622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync EXTERNAL_CODECS_LOC_VARS db 1623cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky _7Z_DECODER_CRYPRO_VARS 1624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync ); 1625cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (ThereIsHeaderError) 1626cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ThereIsHeaderError = true; 1627cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky if (res == E_NOTIMPL) 1628cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky ThrowUnsupported(); 1629cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return res; 1630cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1631cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky catch(CUnsupportedFeatureException &) 1632cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1633cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.UnsupportedFeatureError = true; 1634cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_FALSE; 1635cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky } 1636cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky catch(CInArchiveException &) 1637cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky { 1638cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky db.ThereIsHeaderError = true; 1639cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky return S_FALSE; 1640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync } 1641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} 1642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync 1643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}} 1644