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 30 #define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined 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 CFolders 43 { 44 CNum NumPackStreams; 45 CNum NumFolders; 46 47 CObjArray<UInt64> PackPositions; // NumPackStreams + 1 48 // CUInt32DefVector PackCRCs; // we don't use PackCRCs now 49 50 CUInt32DefVector FolderCRCs; // NumFolders 51 CObjArray<CNum> NumUnpackStreamsVector; // NumFolders 52 53 CObjArray<UInt64> CoderUnpackSizes; // including unpack sizes of bind coders 54 CObjArray<CNum> FoToCoderUnpackSizes; // NumFolders + 1 55 CObjArray<CNum> FoStartPackStreamIndex; // NumFolders + 1 56 CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders 57 58 CObjArray<size_t> FoCodersDataOffset; // NumFolders + 1 59 CByteBuffer CodersData; 60 61 CParsedMethods ParsedMethods; 62 63 void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const; 64 GetNumFolderUnpackSizesCFolders65 unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const 66 { 67 return FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]; 68 } 69 GetFolderUnpackSizeCFolders70 UInt64 GetFolderUnpackSize(unsigned folderIndex) const 71 { 72 return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]]; 73 } 74 GetStreamPackSizeCFolders75 UInt64 GetStreamPackSize(unsigned index) const 76 { 77 return PackPositions[index + 1] - PackPositions[index]; 78 } 79 ClearCFolders80 void Clear() 81 { 82 NumPackStreams = 0; 83 PackPositions.Free(); 84 // PackCRCs.Clear(); 85 86 NumFolders = 0; 87 FolderCRCs.Clear(); 88 NumUnpackStreamsVector.Free(); 89 CoderUnpackSizes.Free(); 90 FoToCoderUnpackSizes.Free(); 91 FoStartPackStreamIndex.Free(); 92 FoToMainUnpackSizeIndex.Free(); 93 FoCodersDataOffset.Free(); 94 CodersData.Free(); 95 } 96 }; 97 98 struct CDatabase: public CFolders 99 { 100 CRecordVector<CFileItem> Files; 101 102 CUInt64DefVector CTime; 103 CUInt64DefVector ATime; 104 CUInt64DefVector MTime; 105 CUInt64DefVector StartPos; 106 CRecordVector<bool> IsAnti; 107 /* 108 CRecordVector<bool> IsAux; 109 CByteBuffer SecureBuf; 110 CRecordVector<UInt32> SecureIDs; 111 */ 112 113 CByteBuffer NamesBuf; 114 CObjArray<size_t> NameOffsets; // numFiles + 1, offsets of utf-16 symbols 115 116 /* 117 void ClearSecure() 118 { 119 SecureBuf.Free(); 120 SecureIDs.Clear(); 121 } 122 */ 123 ClearCDatabase124 void Clear() 125 { 126 CFolders::Clear(); 127 // ClearSecure(); 128 129 NamesBuf.Free(); 130 NameOffsets.Free(); 131 132 Files.Clear(); 133 CTime.Clear(); 134 ATime.Clear(); 135 MTime.Clear(); 136 StartPos.Clear(); 137 IsAnti.Clear(); 138 // IsAux.Clear(); 139 } 140 IsSolidCDatabase141 bool IsSolid() const 142 { 143 for (CNum i = 0; i < NumFolders; i++) 144 if (NumUnpackStreamsVector[i] > 1) 145 return true; 146 return false; 147 } IsItemAntiCDatabase148 bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); } 149 // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); } 150 GetNameCDatabase151 const void * GetName(unsigned index) const 152 { 153 if (!NameOffsets || !NamesBuf) 154 return NULL; 155 return (const void *)((const Byte *)NamesBuf + NameOffsets[index] * 2); 156 }; 157 158 void GetPath(unsigned index, UString &path) const; 159 HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw(); 160 }; 161 162 struct CInArchiveInfo 163 { 164 CArchiveVersion Version; 165 UInt64 StartPosition; 166 UInt64 StartPositionAfterHeader; 167 UInt64 DataStartPosition; 168 UInt64 DataStartPosition2; 169 CRecordVector<UInt64> FileInfoPopIDs; 170 ClearCInArchiveInfo171 void Clear() 172 { 173 StartPosition = 0; 174 StartPositionAfterHeader = 0; 175 DataStartPosition = 0; 176 DataStartPosition2 = 0; 177 FileInfoPopIDs.Clear(); 178 } 179 }; 180 181 struct CDbEx: public CDatabase 182 { 183 CInArchiveInfo ArcInfo; 184 CRecordVector<CNum> FolderStartFileIndex; 185 CRecordVector<CNum> FileIndexToFolderIndexMap; 186 187 UInt64 HeadersSize; 188 UInt64 PhySize; 189 190 /* 191 CRecordVector<size_t> SecureOffsets; 192 bool IsTree; 193 bool ThereAreAltStreams; 194 */ 195 196 bool IsArc; 197 bool PhySizeWasConfirmed; 198 199 bool ThereIsHeaderError; 200 bool UnexpectedEnd; 201 // bool UnsupportedVersion; 202 203 bool StartHeaderWasRecovered; 204 bool UnsupportedFeatureWarning; 205 bool UnsupportedFeatureError; 206 207 /* 208 void ClearSecureEx() 209 { 210 ClearSecure(); 211 SecureOffsets.Clear(); 212 } 213 */ 214 ClearCDbEx215 void Clear() 216 { 217 IsArc = false; 218 PhySizeWasConfirmed = false; 219 220 ThereIsHeaderError = false; 221 UnexpectedEnd = false; 222 // UnsupportedVersion = false; 223 224 StartHeaderWasRecovered = false; 225 UnsupportedFeatureError = false; 226 UnsupportedFeatureWarning = false; 227 228 /* 229 IsTree = false; 230 ThereAreAltStreams = false; 231 */ 232 233 CDatabase::Clear(); 234 235 // SecureOffsets.Clear(); 236 ArcInfo.Clear(); 237 FolderStartFileIndex.Clear(); 238 FileIndexToFolderIndexMap.Clear(); 239 240 HeadersSize = 0; 241 PhySize = 0; 242 } 243 244 void FillLinks(); 245 GetFolderStreamPosCDbEx246 UInt64 GetFolderStreamPos(unsigned folderIndex, unsigned indexInFolder) const 247 { 248 return ArcInfo.DataStartPosition + 249 PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder]; 250 } 251 GetFolderFullPackSizeCDbEx252 UInt64 GetFolderFullPackSize(unsigned folderIndex) const 253 { 254 return 255 PackPositions[FoStartPackStreamIndex[folderIndex + 1]] - 256 PackPositions[FoStartPackStreamIndex[folderIndex]]; 257 } 258 GetFolderPackStreamSizeCDbEx259 UInt64 GetFolderPackStreamSize(unsigned folderIndex, unsigned streamIndex) const 260 { 261 unsigned i = FoStartPackStreamIndex[folderIndex] + streamIndex; 262 return PackPositions[i + 1] - PackPositions[i]; 263 } 264 GetFilePackSizeCDbEx265 UInt64 GetFilePackSize(CNum fileIndex) const 266 { 267 CNum folderIndex = FileIndexToFolderIndexMap[fileIndex]; 268 if (folderIndex != kNumNoIndex) 269 if (FolderStartFileIndex[folderIndex] == fileIndex) 270 return GetFolderFullPackSize(folderIndex); 271 return 0; 272 } 273 }; 274 275 const unsigned kNumBufLevelsMax = 4; 276 277 struct CInByte2 278 { 279 const Byte *_buffer; 280 public: 281 size_t _size; 282 size_t _pos; 283 GetRemCInByte2284 size_t GetRem() const { return _size - _pos; } GetPtrCInByte2285 const Byte *GetPtr() const { return _buffer + _pos; } InitCInByte2286 void Init(const Byte *buffer, size_t size) 287 { 288 _buffer = buffer; 289 _size = size; 290 _pos = 0; 291 } 292 Byte ReadByte(); 293 void ReadBytes(Byte *data, size_t size); SkipDataNoCheckCInByte2294 void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; } 295 void SkipData(UInt64 size); 296 297 void SkipData(); SkipRemCInByte2298 void SkipRem() { _pos = _size; } 299 UInt64 ReadNumber(); 300 CNum ReadNum(); 301 UInt32 ReadUInt32(); 302 UInt64 ReadUInt64(); 303 304 void ParseFolder(CFolder &folder); 305 }; 306 307 class CStreamSwitch; 308 309 const UInt32 kHeaderSize = 32; 310 311 class CInArchive 312 { 313 friend class CStreamSwitch; 314 315 CMyComPtr<IInStream> _stream; 316 317 unsigned _numInByteBufs; 318 CInByte2 _inByteVector[kNumBufLevelsMax]; 319 320 CInByte2 *_inByteBack; 321 bool ThereIsHeaderError; 322 323 UInt64 _arhiveBeginStreamPosition; 324 UInt64 _fileEndPosition; 325 326 Byte _header[kHeaderSize]; 327 328 UInt64 HeadersSize; 329 330 void AddByteStream(const Byte *buffer, size_t size); 331 DeleteByteStream(bool needUpdatePos)332 void DeleteByteStream(bool needUpdatePos) 333 { 334 _numInByteBufs--; 335 if (_numInByteBufs > 0) 336 { 337 _inByteBack = &_inByteVector[_numInByteBufs - 1]; 338 if (needUpdatePos) 339 _inByteBack->_pos += _inByteVector[_numInByteBufs]._pos; 340 } 341 } 342 343 private: 344 HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit); 345 ReadBytes(Byte * data,size_t size)346 void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); } ReadByte()347 Byte ReadByte() { return _inByteBack->ReadByte(); } ReadNumber()348 UInt64 ReadNumber() { return _inByteBack->ReadNumber(); } ReadNum()349 CNum ReadNum() { return _inByteBack->ReadNum(); } ReadID()350 UInt64 ReadID() { return _inByteBack->ReadNumber(); } ReadUInt32()351 UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); } ReadUInt64()352 UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); } SkipData(UInt64 size)353 void SkipData(UInt64 size) { _inByteBack->SkipData(size); } SkipData()354 void SkipData() { _inByteBack->SkipData(); } 355 void WaitId(UInt64 id); 356 357 void ReadArchiveProperties(CInArchiveInfo &archiveInfo); 358 void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs); 359 360 void ReadPackInfo(CFolders &f); 361 362 void ReadUnpackInfo( 363 const CObjectVector<CByteBuffer> *dataVector, 364 CFolders &folders); 365 366 void ReadSubStreamsInfo( 367 CFolders &folders, 368 CRecordVector<UInt64> &unpackSizes, 369 CUInt32DefVector &digests); 370 371 void ReadStreamsInfo( 372 const CObjectVector<CByteBuffer> *dataVector, 373 UInt64 &dataOffset, 374 CFolders &folders, 375 CRecordVector<UInt64> &unpackSizes, 376 CUInt32DefVector &digests); 377 378 void ReadBoolVector(unsigned numItems, CBoolVector &v); 379 void ReadBoolVector2(unsigned numItems, CBoolVector &v); 380 void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector, 381 CUInt64DefVector &v, unsigned numItems); 382 HRESULT ReadAndDecodePackedStreams( 383 DECL_EXTERNAL_CODECS_LOC_VARS 384 UInt64 baseOffset, UInt64 &dataOffset, 385 CObjectVector<CByteBuffer> &dataVector 386 _7Z_DECODER_CRYPRO_VARS_DECL 387 ); 388 HRESULT ReadHeader( 389 DECL_EXTERNAL_CODECS_LOC_VARS 390 CDbEx &db 391 _7Z_DECODER_CRYPRO_VARS_DECL 392 ); 393 HRESULT ReadDatabase2( 394 DECL_EXTERNAL_CODECS_LOC_VARS 395 CDbEx &db 396 _7Z_DECODER_CRYPRO_VARS_DECL 397 ); 398 public: CInArchive()399 CInArchive(): _numInByteBufs(0) { } 400 HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive 401 void Close(); 402 403 HRESULT ReadDatabase( 404 DECL_EXTERNAL_CODECS_LOC_VARS 405 CDbEx &db 406 _7Z_DECODER_CRYPRO_VARS_DECL 407 ); 408 }; 409 410 }} 411 412 #endif 413