// Archive/NsisIn.h #ifndef __ARCHIVE_NSIS_IN_H #define __ARCHIVE_NSIS_IN_H #include "Common/MyCom.h" #include "Common/IntToString.h" #include "Common/Buffer.h" #include "../../IStream.h" #include "NsisDecode.h" #include "../../Common/CreateCoder.h" // #define NSIS_SCRIPT namespace NArchive { namespace NNsis { const int kSignatureSize = 16; extern Byte kSignature[kSignatureSize]; const UInt32 kFlagsMask = 0xF; namespace NFlags { const UInt32 kUninstall = 1; const UInt32 kSilent = 2; const UInt32 kNoCrc = 4; const UInt32 kForceCrc = 8; } struct CFirstHeader { UInt32 Flags; UInt32 HeaderLength; UInt32 ArchiveSize; bool ThereIsCrc() const { if ((Flags & NFlags::kForceCrc ) != 0) return true; return ((Flags & NFlags::kNoCrc) == 0); } UInt32 GetDataSize() const { return ArchiveSize - (ThereIsCrc() ? 4 : 0); } }; struct CBlockHeader { UInt32 Offset; UInt32 Num; }; struct CItem { AString Prefix; AString Name; UInt32 Pos; bool SizeIsDefined; bool CompressedSizeIsDefined; bool EstimatedSizeIsDefined; UInt32 Size; UInt32 CompressedSize; UInt32 EstimatedSize; FILETIME DateTime; UInt32 DictionarySize; bool IsCompressed; bool UseFilter; CItem(): UseFilter(false), SizeIsDefined(false), EstimatedSizeIsDefined(false), IsCompressed(true), CompressedSizeIsDefined(false), Size(0) {} bool IsINSTDIR() const { if (Prefix.Length() < 3) return false; return true; } AString GetReducedName() const { AString prefix = Prefix; if (prefix.Length() > 0) if (prefix[prefix.Length() - 1] != '\\') prefix += '\\'; AString s2 = prefix + Name; const int len = 9; if (s2.Left(len).CompareNoCase("$INSTDIR\\") == 0) s2 = s2.Mid(len); return s2; } }; class CInArchive { UInt64 _archiveSize; CMyComPtr _stream; Byte ReadByte(); UInt32 ReadUInt32(); HRESULT Open2( DECL_EXTERNAL_CODECS_LOC_VARS2 ); void ReadBlockHeader(CBlockHeader &bh); AString ReadString(UInt32 pos); AString ReadString2(UInt32 pos); HRESULT ReadEntries(const CBlockHeader &bh); HRESULT Parse(); CByteBuffer _data; UInt64 _size; size_t _posInData; UInt32 _stringsPos; bool _headerIsCompressed; UInt32 _nonSolidStartOffset; public: HRESULT Open( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, const UInt64 *maxCheckStartPosition); void Clear(); UInt64 StreamOffset; CDecoder Decoder; CObjectVector Items; bool IsSolid; CFirstHeader FirstHeader; NMethodType::EEnum Method; bool UseFilter; UInt32 DictionarySize; bool FilterFlag; #ifdef NSIS_SCRIPT AString Script; #endif UInt32 GetOffset() const { return IsSolid ? 4 : 0; } UInt64 GetDataPos(int index) { const CItem &item = Items[index]; return GetOffset() + FirstHeader.HeaderLength + item.Pos; } UInt64 GetPosOfSolidItem(int index) const { const CItem &item = Items[index]; return 4 + FirstHeader.HeaderLength + item.Pos; } UInt64 GetPosOfNonSolidItem(int index) const { const CItem &item = Items[index]; return StreamOffset + _nonSolidStartOffset + 4 + item.Pos; } void Release() { Decoder.Release(); } }; UInt32 GetUInt32FromMemLE(const Byte *p); }} #endif