1 // 7zIn.h 2 3 #ifndef __7Z_IN_H 4 #define __7Z_IN_H 5 6 #include "../../../Common/MyCom.h" 7 8 #include "../../../Windows/PropVariant.h" 9 10 #include "../../IPassword.h" 11 #include "../../IStream.h" 12 13 #include "../../Common/CreateCoder.h" 14 #include "../../Common/InBuffer.h" 15 16 #include "7zItem.h" 17 18 namespace NArchive { 19 namespace N7z { 20 21 /* 22 We don't need to init isEncrypted and passwordIsDefined 23 We must upgrade them only */ 24 25 #ifdef _NO_CRYPTO 26 #define _7Z_DECODER_CRYPRO_VARS_DECL 27 #define _7Z_DECODER_CRYPRO_VARS 28 #else 29 #define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password 30 #define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password 31 #endif 32 33 struct CParsedMethods 34 { 35 Byte Lzma2Prop; 36 UInt32 LzmaDic; 37 CRecordVector<UInt64> IDs; 38 CParsedMethodsCParsedMethods39 CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {} 40 }; 41 42 struct CFolderEx: public CFolder 43 { 44 unsigned UnpackCoder; 45 }; 46 47 struct CFolders 48 { 49 CNum NumPackStreams; 50 CNum NumFolders; 51 52 CObjArray<UInt64> PackPositions; // NumPackStreams + 1 53 // CUInt32DefVector PackCRCs; // we don't use PackCRCs now 54 55 CUInt32DefVector FolderCRCs; // NumFolders 56 CObjArray<CNum> NumUnpackStreamsVector; // NumFolders 57 58 CObjArray<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders 59 CObjArray<CNum> FoToCoderUnpackSizes; // NumFolders + 1 60 CObjArray<CNum> FoStartPackStreamIndex; // NumFolders + 1 61 CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders 62 63 CObjArray<size_t> FoCodersDataOffset; // NumFolders + 1 64 CByteBuffer CodersData; 65 66 CParsedMethods ParsedMethods; 67 68 void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const; ParseFolderExCFolders69 void ParseFolderEx(unsigned folderIndex, CFolderEx &folder) const 70 { 71 ParseFolderInfo(folderIndex, folder); 72 folder.UnpackCoder = FoToMainUnpackSizeIndex[folderIndex]; 73 } 74 GetNumFolderUnpackSizesCFolders75 unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const 76 { 77 return (unsigned)(FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]); 78 } 79 GetFolderUnpackSizeCFolders80 UInt64 GetFolderUnpackSize(unsigned folderIndex) const 81 { 82 return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]]; 83 } 84 GetStreamPackSizeCFolders85 UInt64 GetStreamPackSize(unsigned index) const 86 { 87 return PackPositions[index + 1] - PackPositions[index]; 88 } 89 CFoldersCFolders90 CFolders(): NumPackStreams(0), NumFolders(0) {} 91 ClearCFolders92 void Clear() 93 { 94 NumPackStreams = 0; 95 PackPositions.Free(); 96 // PackCRCs.Clear(); 97 98 NumFolders = 0; 99 FolderCRCs.Clear(); 100 NumUnpackStreamsVector.Free(); 101 CoderUnpackSizes.Free(); 102 FoToCoderUnpackSizes.Free(); 103 FoStartPackStreamIndex.Free(); 104 FoToMainUnpackSizeIndex.Free(); 105 FoCodersDataOffset.Free(); 106 CodersData.Free(); 107 } 108 }; 109 110 struct CDatabase: public CFolders 111 { 112 CRecordVector<CFileItem> Files; 113 114 CUInt64DefVector CTime; 115 CUInt64DefVector ATime; 116 CUInt64DefVector MTime; 117 CUInt64DefVector StartPos; 118 CUInt32DefVector Attrib; 119 CBoolVector IsAnti; 120 /* 121 CBoolVector IsAux; 122 CByteBuffer SecureBuf; 123 CRecordVector<UInt32> SecureIDs; 124 */ 125 126 CByteBuffer NamesBuf; 127 CObjArray<size_t> NameOffsets; // numFiles + 1, offsets of utf-16 symbols 128 129 /* 130 void ClearSecure() 131 { 132 SecureBuf.Free(); 133 SecureIDs.Clear(); 134 } 135 */ 136 ClearCDatabase137 void Clear() 138 { 139 CFolders::Clear(); 140 // ClearSecure(); 141 142 NamesBuf.Free(); 143 NameOffsets.Free(); 144 145 Files.Clear(); 146 CTime.Clear(); 147 ATime.Clear(); 148 MTime.Clear(); 149 StartPos.Clear(); 150 Attrib.Clear(); 151 IsAnti.Clear(); 152 // IsAux.Clear(); 153 } 154 IsSolidCDatabase155 bool IsSolid() const 156 { 157 for (CNum i = 0; i < NumFolders; i++) 158 if (NumUnpackStreamsVector[i] > 1) 159 return true; 160 return false; 161 } IsItemAntiCDatabase162 bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } 163 // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); } 164 165 /* 166 const void* GetName(unsigned index) const 167 { 168 if (!NameOffsets || !NamesBuf) 169 return NULL; 170 return (void *)((const Byte *)NamesBuf + NameOffsets[index] * 2); 171 }; 172 */ 173 void GetPath(unsigned index, UString &path) const; 174 HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw(); 175 }; 176 177 struct CInArchiveInfo 178 { 179 CArchiveVersion Version; 180 UInt64 StartPosition; 181 UInt64 StartPositionAfterHeader; 182 UInt64 DataStartPosition; 183 UInt64 DataStartPosition2; 184 CRecordVector<UInt64> FileInfoPopIDs; 185 ClearCInArchiveInfo186 void Clear() 187 { 188 StartPosition = 0; 189 StartPositionAfterHeader = 0; 190 DataStartPosition = 0; 191 DataStartPosition2 = 0; 192 FileInfoPopIDs.Clear(); 193 } 194 }; 195 196 struct CDbEx: public CDatabase 197 { 198 CInArchiveInfo ArcInfo; 199 200 CObjArray<CNum> FolderStartFileIndex; 201 CObjArray<CNum> FileIndexToFolderIndexMap; 202 203 UInt64 HeadersSize; 204 UInt64 PhySize; 205 206 /* 207 CRecordVector<size_t> SecureOffsets; 208 bool IsTree; 209 bool ThereAreAltStreams; 210 */ 211 212 bool IsArc; 213 bool PhySizeWasConfirmed; 214 215 bool ThereIsHeaderError; 216 bool UnexpectedEnd; 217 // bool UnsupportedVersion; 218 219 bool StartHeaderWasRecovered; 220 bool UnsupportedFeatureWarning; 221 bool UnsupportedFeatureError; 222 223 /* 224 void ClearSecureEx() 225 { 226 ClearSecure(); 227 SecureOffsets.Clear(); 228 } 229 */ 230 ClearCDbEx231 void Clear() 232 { 233 IsArc = false; 234 PhySizeWasConfirmed = false; 235 236 ThereIsHeaderError = false; 237 UnexpectedEnd = false; 238 // UnsupportedVersion = false; 239 240 StartHeaderWasRecovered = false; 241 UnsupportedFeatureError = false; 242 UnsupportedFeatureWarning = false; 243 244 /* 245 IsTree = false; 246 ThereAreAltStreams = false; 247 */ 248 249 CDatabase::Clear(); 250 251 // SecureOffsets.Clear(); 252 ArcInfo.Clear(); 253 FolderStartFileIndex.Free(); 254 FileIndexToFolderIndexMap.Free(); 255 256 HeadersSize = 0; 257 PhySize = 0; 258 } 259 260 void FillLinks(); 261 GetFolderStreamPosCDbEx262 UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const 263 { 264 return ArcInfo.DataStartPosition + 265 PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder]; 266 } 267 GetFolderFullPackSizeCDbEx268 UInt64 GetFolderFullPackSize(CNum folderIndex) const 269 { 270 return 271 PackPositions[FoStartPackStreamIndex[folderIndex + 1]] - 272 PackPositions[FoStartPackStreamIndex[folderIndex]]; 273 } 274 GetFolderPackStreamSizeCDbEx275 UInt64 GetFolderPackStreamSize(CNum folderIndex, unsigned streamIndex) const 276 { 277 size_t i = FoStartPackStreamIndex[folderIndex] + streamIndex; 278 return PackPositions[i + 1] - PackPositions[i]; 279 } 280 GetFilePackSizeCDbEx281 UInt64 GetFilePackSize(CNum fileIndex) const 282 { 283 CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; 284 if (folderIndex != kNumNoIndex) 285 if (FolderStartFileIndex[folderIndex] == fileIndex) 286 return GetFolderFullPackSize(folderIndex); 287 return 0; 288 } 289 }; 290 291 const unsigned kNumBufLevelsMax = 4; 292 293 struct CInByte2 294 { 295 const Byte *_buffer; 296 public: 297 size_t _size; 298 size_t _pos; 299 GetRemCInByte2300 size_t GetRem() const { return _size - _pos; } GetPtrCInByte2301 const Byte *GetPtr() const { return _buffer + _pos; } InitCInByte2302 void Init(const Byte *buffer, size_t size) 303 { 304 _buffer = buffer; 305 _size = size; 306 _pos = 0; 307 } 308 Byte ReadByte(); 309 void ReadBytes(Byte *data, size_t size); SkipDataNoCheckCInByte2310 void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; } 311 void SkipData(UInt64 size); 312 313 void SkipData(); SkipRemCInByte2314 void SkipRem() { _pos = _size; } 315 UInt64 ReadNumber(); 316 CNum ReadNum(); 317 UInt32 ReadUInt32(); 318 UInt64 ReadUInt64(); 319 320 void ParseFolder(CFolder &folder); 321 }; 322 323 class CStreamSwitch; 324 325 const UInt32 kHeaderSize = 32; 326 327 class CInArchive 328 { 329 friend class CStreamSwitch; 330 331 CMyComPtr<IInStream> _stream; 332 333 unsigned _numInByteBufs; 334 CInByte2 _inByteVector[kNumBufLevelsMax]; 335 336 CInByte2 *_inByteBack; 337 bool ThereIsHeaderError; 338 339 UInt64 _arhiveBeginStreamPosition; 340 UInt64 _fileEndPosition; 341 342 Byte _header[kHeaderSize]; 343 344 UInt64 HeadersSize; 345 346 bool _useMixerMT; 347 348 void AddByteStream(const Byte *buffer, size_t size); 349 DeleteByteStream(bool needUpdatePos)350 void DeleteByteStream(bool needUpdatePos) 351 { 352 _numInByteBufs--; 353 if (_numInByteBufs > 0) 354 { 355 _inByteBack = &_inByteVector[_numInByteBufs - 1]; 356 if (needUpdatePos) 357 _inByteBack->_pos += _inByteVector[_numInByteBufs]._pos; 358 } 359 } 360 361 HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); 362 ReadBytes(Byte * data,size_t size)363 void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); } ReadByte()364 Byte ReadByte() { return _inByteBack->ReadByte(); } ReadNumber()365 UInt64 ReadNumber() { return _inByteBack->ReadNumber(); } ReadNum()366 CNum ReadNum() { return _inByteBack->ReadNum(); } ReadID()367 UInt64 ReadID() { return _inByteBack->ReadNumber(); } ReadUInt32()368 UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); } ReadUInt64()369 UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); } SkipData(UInt64 size)370 void SkipData(UInt64 size) { _inByteBack->SkipData(size); } SkipData()371 void SkipData() { _inByteBack->SkipData(); } 372 void WaitId(UInt64 id); 373 374 void Read_UInt32_Vector(CUInt32DefVector &v); 375 376 void ReadArchiveProperties(CInArchiveInfo &archiveInfo); 377 void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs); 378 379 void ReadPackInfo(CFolders &f); 380 381 void ReadUnpackInfo( 382 const CObjectVector<CByteBuffer> *dataVector, 383 CFolders &folders); 384 385 void ReadSubStreamsInfo( 386 CFolders &folders, 387 CRecordVector<UInt64> &unpackSizes, 388 CUInt32DefVector &digests); 389 390 void ReadStreamsInfo( 391 const CObjectVector<CByteBuffer> *dataVector, 392 UInt64 &dataOffset, 393 CFolders &folders, 394 CRecordVector<UInt64> &unpackSizes, 395 CUInt32DefVector &digests); 396 397 void ReadBoolVector(unsigned numItems, CBoolVector &v); 398 void ReadBoolVector2(unsigned numItems, CBoolVector &v); 399 void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector, 400 CUInt64DefVector &v, unsigned numItems); 401 HRESULT ReadAndDecodePackedStreams( 402 DECL_EXTERNAL_CODECS_LOC_VARS 403 UInt64 baseOffset, UInt64 &dataOffset, 404 CObjectVector<CByteBuffer> &dataVector 405 _7Z_DECODER_CRYPRO_VARS_DECL 406 ); 407 HRESULT ReadHeader( 408 DECL_EXTERNAL_CODECS_LOC_VARS 409 CDbEx &db 410 _7Z_DECODER_CRYPRO_VARS_DECL 411 ); 412 HRESULT ReadDatabase2( 413 DECL_EXTERNAL_CODECS_LOC_VARS 414 CDbEx &db 415 _7Z_DECODER_CRYPRO_VARS_DECL 416 ); 417 public: CInArchive(bool useMixerMT)418 CInArchive(bool useMixerMT): 419 _numInByteBufs(0), 420 _useMixerMT(useMixerMT) 421 {} 422 423 HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive 424 void Close(); 425 426 HRESULT ReadDatabase( 427 DECL_EXTERNAL_CODECS_LOC_VARS 428 CDbEx &db 429 _7Z_DECODER_CRYPRO_VARS_DECL 430 ); 431 }; 432 433 }} 434 435 #endif 436