mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-09 06:07:05 -06:00
9.34
This commit is contained in:
committed by
Kornel Lesiński
parent
83f8ddcc5b
commit
f08f4dcc3c
431
CPP/7zip/Archive/Nsis/NsisIn.h
Executable file → Normal file
431
CPP/7zip/Archive/Nsis/NsisIn.h
Executable file → Normal file
@@ -3,21 +3,28 @@
|
||||
#ifndef __ARCHIVE_NSIS_IN_H
|
||||
#define __ARCHIVE_NSIS_IN_H
|
||||
|
||||
#include "Common/Buffer.h"
|
||||
#include "Common/MyCom.h"
|
||||
#include "Common/StringConvert.h"
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
#include "../../../Common/DynLimBuf.h"
|
||||
#include "../../../Common/MyBuffer.h"
|
||||
#include "../../../Common/MyCom.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
#include "../../../Common/UTFConvert.h"
|
||||
|
||||
#include "NsisDecode.h"
|
||||
|
||||
// #define NSIS_SCRIPT
|
||||
/* If NSIS_SCRIPT is defined, it will decompile NSIS script to [NSIS].nsi file.
|
||||
The code is much larger in that case. */
|
||||
|
||||
#define NSIS_SCRIPT
|
||||
|
||||
namespace NArchive {
|
||||
namespace NNsis {
|
||||
|
||||
const int kSignatureSize = 16;
|
||||
#define NSIS_SIGNATURE { 0xEF, 0xBE, 0xAD, 0xDE, 0x4E, 0x75, 0x6C, 0x6C, 0x73, 0x6F, 0x66, 0x74, 0x49, 0x6E, 0x73, 0x74}
|
||||
const size_t kScriptSizeLimit = 1 << 27;
|
||||
|
||||
extern Byte kSignature[kSignatureSize];
|
||||
const unsigned kSignatureSize = 16;
|
||||
#define NSIS_SIGNATURE { 0xEF, 0xBE, 0xAD, 0xDE, 'N', 'u', 'l', 'l', 's', 'o', 'f', 't', 'I', 'n', 's', 't' }
|
||||
|
||||
const UInt32 kFlagsMask = 0xF;
|
||||
namespace NFlags
|
||||
@@ -31,18 +38,17 @@ namespace NFlags
|
||||
struct CFirstHeader
|
||||
{
|
||||
UInt32 Flags;
|
||||
UInt32 HeaderLength;
|
||||
|
||||
UInt32 ArchiveSize;
|
||||
UInt32 HeaderSize;
|
||||
UInt32 ArcSize;
|
||||
|
||||
bool ThereIsCrc() const
|
||||
{
|
||||
if ((Flags & NFlags::kForceCrc ) != 0)
|
||||
return true;
|
||||
return ((Flags & NFlags::kNoCrc) == 0);
|
||||
return
|
||||
(Flags & NFlags::kForceCrc) != 0 ||
|
||||
(Flags & NFlags::kNoCrc) == 0;
|
||||
}
|
||||
|
||||
UInt32 GetDataSize() const { return ArchiveSize - (ThereIsCrc() ? 4 : 0); }
|
||||
UInt32 GetDataSize() const { return ArcSize - (ThereIsCrc() ? 4 : 0); }
|
||||
};
|
||||
|
||||
|
||||
@@ -50,123 +56,330 @@ struct CBlockHeader
|
||||
{
|
||||
UInt32 Offset;
|
||||
UInt32 Num;
|
||||
|
||||
void Parse(const Byte *p)
|
||||
{
|
||||
Offset = GetUi32(p);
|
||||
Num = GetUi32(p + 4);
|
||||
}
|
||||
};
|
||||
|
||||
struct CItem
|
||||
{
|
||||
AString PrefixA;
|
||||
UString PrefixU;
|
||||
AString NameA;
|
||||
UString NameU;
|
||||
FILETIME MTime;
|
||||
bool IsUnicode;
|
||||
bool UseFilter;
|
||||
bool IsCompressed;
|
||||
bool SizeIsDefined;
|
||||
bool CompressedSizeIsDefined;
|
||||
bool EstimatedSizeIsDefined;
|
||||
bool Size_Defined;
|
||||
bool CompressedSize_Defined;
|
||||
bool EstimatedSize_Defined;
|
||||
bool Attrib_Defined;
|
||||
bool IsUninstaller;
|
||||
// bool UseFilter;
|
||||
|
||||
UInt32 Attrib;
|
||||
UInt32 Pos;
|
||||
UInt32 Size;
|
||||
UInt32 CompressedSize;
|
||||
UInt32 EstimatedSize;
|
||||
UInt32 DictionarySize;
|
||||
|
||||
CItem(): IsUnicode(false), UseFilter(false), IsCompressed(true), SizeIsDefined(false),
|
||||
CompressedSizeIsDefined(false), EstimatedSizeIsDefined(false), Size(0), DictionarySize(1) {}
|
||||
UInt32 PatchSize; // for Uninstaller.exe
|
||||
int Prefix; // - 1 means no prefix
|
||||
|
||||
FILETIME MTime;
|
||||
AString NameA;
|
||||
UString NameU;
|
||||
|
||||
CItem():
|
||||
IsCompressed(true),
|
||||
Size_Defined(false),
|
||||
CompressedSize_Defined(false),
|
||||
EstimatedSize_Defined(false),
|
||||
Attrib_Defined(false),
|
||||
IsUninstaller(false),
|
||||
// UseFilter(false),
|
||||
Attrib(0),
|
||||
Pos(0),
|
||||
Size(0),
|
||||
CompressedSize(0),
|
||||
EstimatedSize(0),
|
||||
DictionarySize(1),
|
||||
PatchSize(0),
|
||||
Prefix(-1)
|
||||
{
|
||||
MTime.dwLowDateTime = 0;
|
||||
MTime.dwHighDateTime = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
bool IsINSTDIR() const
|
||||
{
|
||||
return (PrefixA.Length() >= 3 || PrefixU.Length() >= 3);
|
||||
}
|
||||
|
||||
UString GetReducedName(bool unicode) const
|
||||
{
|
||||
UString s;
|
||||
if (unicode)
|
||||
s = PrefixU;
|
||||
else
|
||||
s = MultiByteToUnicodeString(PrefixA);
|
||||
if (s.Length() > 0)
|
||||
if (s.Back() != L'\\')
|
||||
s += L'\\';
|
||||
if (unicode)
|
||||
s += NameU;
|
||||
else
|
||||
s += MultiByteToUnicodeString(NameA);
|
||||
const int len = 9;
|
||||
if (s.Left(len).CompareNoCase(L"$INSTDIR\\") == 0)
|
||||
s = s.Mid(len);
|
||||
return s;
|
||||
return (PrefixA.Len() >= 3 || PrefixU.Len() >= 3);
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
enum ENsisType
|
||||
{
|
||||
k_NsisType_Nsis2,
|
||||
k_NsisType_Nsis3,
|
||||
k_NsisType_Park1, // Park 2.46.1-
|
||||
k_NsisType_Park2, // Park 2.46.2 : GetFontVersion
|
||||
k_NsisType_Park3 // Park 2.46.3+ : GetFontName
|
||||
};
|
||||
|
||||
#ifdef NSIS_SCRIPT
|
||||
|
||||
struct CSection
|
||||
{
|
||||
UInt32 InstallTypes; // bits set for each of the different install_types, if any.
|
||||
UInt32 Flags; // SF_* - defined above
|
||||
UInt32 StartCmdIndex; // code;
|
||||
UInt32 NumCommands; // code_size;
|
||||
UInt32 SizeKB;
|
||||
UInt32 Name;
|
||||
|
||||
void Parse(const Byte *data);
|
||||
};
|
||||
|
||||
struct CLicenseFile
|
||||
{
|
||||
UInt32 Offset;
|
||||
UInt32 Size;
|
||||
AString Name;
|
||||
CByteBuffer Text;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class CInArchive
|
||||
{
|
||||
UInt64 _archiveSize;
|
||||
CMyComPtr<IInStream> _stream;
|
||||
|
||||
Byte ReadByte();
|
||||
UInt32 ReadUInt32();
|
||||
HRESULT Open2(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS2
|
||||
);
|
||||
void ReadBlockHeader(CBlockHeader &bh);
|
||||
AString ReadStringA(UInt32 pos) const;
|
||||
UString ReadStringU(UInt32 pos) const;
|
||||
AString ReadString2A(UInt32 pos) const;
|
||||
UString ReadString2U(UInt32 pos) const;
|
||||
AString ReadString2(UInt32 pos) const;
|
||||
AString ReadString2Qw(UInt32 pos) const;
|
||||
HRESULT ReadEntries(const CBlockHeader &bh);
|
||||
HRESULT Parse();
|
||||
|
||||
public:
|
||||
#ifdef NSIS_SCRIPT
|
||||
CDynLimBuf Script;
|
||||
#endif
|
||||
CByteBuffer _data;
|
||||
UInt64 _size;
|
||||
CObjectVector<CItem> Items;
|
||||
bool IsUnicode;
|
||||
private:
|
||||
UInt32 _stringsPos; // relative to _data
|
||||
UInt32 NumStringChars;
|
||||
size_t _size; // it's Header Size
|
||||
|
||||
size_t _posInData;
|
||||
AString Raw_AString;
|
||||
UString Raw_UString;
|
||||
|
||||
UInt32 _stringsPos;
|
||||
ENsisType NsisType;
|
||||
bool IsNsis200; // NSIS 2.03 and before
|
||||
bool IsNsis225; // NSIS 2.25 and before
|
||||
|
||||
bool LogCmdIsEnabled;
|
||||
int BadCmd; // -1: no bad command; in another cases lowest bad command id
|
||||
|
||||
bool IsPark() const { return NsisType >= k_NsisType_Park1; }
|
||||
|
||||
UInt64 _fileSize;
|
||||
|
||||
bool _headerIsCompressed;
|
||||
UInt32 _nonSolidStartOffset;
|
||||
public:
|
||||
HRESULT Open(
|
||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||
IInStream *inStream, const UInt64 *maxCheckStartPosition);
|
||||
void Clear();
|
||||
|
||||
UInt64 StreamOffset;
|
||||
#ifdef NSIS_SCRIPT
|
||||
|
||||
CByteBuffer strUsed;
|
||||
|
||||
CBlockHeader bhPages;
|
||||
CBlockHeader bhSections;
|
||||
CBlockHeader bhCtlColors;
|
||||
CBlockHeader bhData;
|
||||
UInt32 AfterHeaderSize;
|
||||
CByteBuffer _afterHeader;
|
||||
|
||||
UInt32 SectionSize;
|
||||
const Byte *_mainLang;
|
||||
UInt32 _numLangStrings;
|
||||
AString LangComment;
|
||||
CRecordVector<UInt32> langStrIDs;
|
||||
UInt32 numOnFunc;
|
||||
UInt32 onFuncOffset;
|
||||
// CRecordVector<UInt32> OnFuncs;
|
||||
unsigned _numRootLicenses;
|
||||
CRecordVector<UInt32> noParseStringIndexes;
|
||||
AString _tempString_for_GetVar;
|
||||
AString _tempString_for_AddFuncName;
|
||||
AString _tempString;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
public:
|
||||
CMyComPtr<IInStream> _stream; // it's limited stream that contains only NSIS archive
|
||||
UInt64 StartOffset; // offset in original stream.
|
||||
UInt64 DataStreamOffset; // = sizeof(FirstHeader) = offset of Header in _stream
|
||||
|
||||
bool IsArc;
|
||||
|
||||
CDecoder Decoder;
|
||||
CObjectVector<CItem> Items;
|
||||
CByteBuffer ExeStub;
|
||||
CFirstHeader FirstHeader;
|
||||
NMethodType::EEnum Method;
|
||||
UInt32 DictionarySize;
|
||||
bool IsSolid;
|
||||
bool UseFilter;
|
||||
bool FilterFlag;
|
||||
bool IsUnicode;
|
||||
|
||||
bool IsInstaller;
|
||||
AString Name;
|
||||
AString BrandingText;
|
||||
UStringVector UPrefixes;
|
||||
AStringVector APrefixes;
|
||||
|
||||
#ifdef NSIS_SCRIPT
|
||||
AString Script;
|
||||
CObjectVector<CLicenseFile> LicenseFiles;
|
||||
#endif
|
||||
UInt32 GetOffset() const { return IsSolid ? 4 : 0; }
|
||||
UInt64 GetDataPos(int index)
|
||||
|
||||
private:
|
||||
void GetShellString(AString &s, unsigned index1, unsigned index2);
|
||||
void GetNsisString_Raw(const Byte *s);
|
||||
void GetNsisString_Unicode_Raw(const Byte *s);
|
||||
void ReadString2_Raw(UInt32 pos);
|
||||
bool IsGoodString(UInt32 param) const;
|
||||
bool AreTwoParamStringsEqual(UInt32 param1, UInt32 param2) const;
|
||||
|
||||
void Add_LangStr(AString &res, UInt32 id);
|
||||
|
||||
#ifdef NSIS_SCRIPT
|
||||
|
||||
void Add_UInt(UInt32 v);
|
||||
void AddLicense(UInt32 param, Int32 langID);
|
||||
|
||||
void Add_LangStr_Simple(UInt32 id);
|
||||
void Add_FuncName(const UInt32 *labels, UInt32 index);
|
||||
void AddParam_Func(const UInt32 *labels, UInt32 index);
|
||||
void Add_LabelName(UInt32 index);
|
||||
|
||||
void Add_Color2(UInt32 v);
|
||||
void Add_ColorParam(UInt32 v);
|
||||
void Add_Color(UInt32 index);
|
||||
|
||||
void Add_ButtonID(UInt32 buttonID);
|
||||
|
||||
void Add_ShowWindow_Cmd(UInt32 cmd);
|
||||
void Add_TypeFromList(const char **table, unsigned tableSize, UInt32 type);
|
||||
void Add_ExecFlags(UInt32 flagsType);
|
||||
void Add_SectOp(UInt32 opType);
|
||||
|
||||
void Add_Var(UInt32 index);
|
||||
void AddParam_Var(UInt32 value);
|
||||
void AddParam_UInt(UInt32 value);
|
||||
|
||||
void Add_GotoVar(UInt32 param);
|
||||
void Add_GotoVar1(UInt32 param);
|
||||
void Add_GotoVars2(const UInt32 *params);
|
||||
|
||||
|
||||
|
||||
bool PrintSectionBegin(const CSection §, unsigned index);
|
||||
void PrintSectionEnd();
|
||||
|
||||
void GetNsisString(AString &res, const Byte *s);
|
||||
void GetNsisString_Unicode(AString &res, const Byte *s);
|
||||
UInt32 GetNumUsedVars() const;
|
||||
void ReadString2(AString &s, UInt32 pos);
|
||||
|
||||
void MessageBox_MB_Part(UInt32 param);
|
||||
void AddParam(UInt32 pos);
|
||||
void AddOptionalParam(UInt32 pos);
|
||||
void AddParams(const UInt32 *params, unsigned num);
|
||||
void AddPageOption1(UInt32 param, const char *name);
|
||||
void AddPageOption(const UInt32 *params, unsigned num, const char *name);
|
||||
void AddOptionalParams(const UInt32 *params, unsigned num);
|
||||
void AddRegRoot(UInt32 value);
|
||||
|
||||
|
||||
void ClearLangComment();
|
||||
void Separator();
|
||||
void Space();
|
||||
void Tab();
|
||||
void Tab(bool commented);
|
||||
void BigSpaceComment();
|
||||
void SmallSpaceComment();
|
||||
void AddCommentAndString(const char *s);
|
||||
void AddError(const char *s);
|
||||
void AddErrorLF(const char *s);
|
||||
void CommentOpen();
|
||||
void CommentClose();
|
||||
void AddLF();
|
||||
void AddQuotes();
|
||||
void TabString(const char *s);
|
||||
void AddStringLF(const char *s);
|
||||
void NewLine();
|
||||
void PrintNumComment(const char *name, UInt32 value);
|
||||
void Add_QuStr(const AString &s);
|
||||
void SpaceQuStr(const AString &s);
|
||||
bool CompareCommands(const Byte *rawCmds, const Byte *sequence, size_t numCommands);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef NSIS_SCRIPT
|
||||
unsigned GetNumSupportedCommands() const;
|
||||
#endif
|
||||
|
||||
UInt32 GetCmd(UInt32 a);
|
||||
void FindBadCmd(const CBlockHeader &bh, const Byte *);
|
||||
void DetectNsisType(const CBlockHeader &bh, const Byte *);
|
||||
|
||||
HRESULT ReadEntries(const CBlockHeader &bh);
|
||||
HRESULT SortItems();
|
||||
HRESULT Parse();
|
||||
HRESULT Open2(const Byte *data, size_t size);
|
||||
void Clear2();
|
||||
|
||||
void GetVar2(AString &res, UInt32 index);
|
||||
void GetVar(AString &res, UInt32 index);
|
||||
Int32 GetVarIndex(UInt32 strPos) const;
|
||||
Int32 GetVarIndex(UInt32 strPos, UInt32 &resOffset) const;
|
||||
Int32 GetVarIndexFinished(UInt32 strPos, Byte endChar, UInt32 &resOffset) const;
|
||||
bool IsVarStr(UInt32 strPos, UInt32 varIndex) const;
|
||||
bool IsAbsolutePathVar(UInt32 strPos) const;
|
||||
void SetItemName(CItem &item, UInt32 strPos);
|
||||
|
||||
public:
|
||||
HRESULT Open(IInStream *inStream, const UInt64 *maxCheckStartPosition);
|
||||
AString GetFormatDescription() const;
|
||||
HRESULT InitDecoder()
|
||||
{
|
||||
const CItem &item = Items[index];
|
||||
return GetOffset() + FirstHeader.HeaderLength + item.Pos;
|
||||
bool useFilter;
|
||||
return Decoder.Init(_stream, useFilter);
|
||||
}
|
||||
|
||||
UInt64 GetPosOfSolidItem(int index) const
|
||||
HRESULT SeekTo_DataStreamOffset()
|
||||
{
|
||||
return _stream->Seek(DataStreamOffset, STREAM_SEEK_SET, NULL);
|
||||
}
|
||||
|
||||
HRESULT SeekToNonSolidItem(unsigned index)
|
||||
{
|
||||
return _stream->Seek(GetPosOfNonSolidItem(index), STREAM_SEEK_SET, NULL);
|
||||
}
|
||||
|
||||
void Clear();
|
||||
|
||||
bool IsDirectString_Equal(UInt32 offset, const char *s) const;
|
||||
/*
|
||||
UInt64 GetDataPos(unsigned index)
|
||||
{
|
||||
const CItem &item = Items[index];
|
||||
return 4 + FirstHeader.HeaderLength + item.Pos;
|
||||
return GetOffset() + FirstHeader.HeaderSize + item.Pos;
|
||||
}
|
||||
*/
|
||||
|
||||
UInt64 GetPosOfSolidItem(unsigned index) const
|
||||
{
|
||||
const CItem &item = Items[index];
|
||||
return 4 + (UInt64)FirstHeader.HeaderSize + item.Pos;
|
||||
}
|
||||
|
||||
UInt64 GetPosOfNonSolidItem(int index) const
|
||||
UInt64 GetPosOfNonSolidItem(unsigned index) const
|
||||
{
|
||||
const CItem &item = Items[index];
|
||||
return StreamOffset + _nonSolidStartOffset + 4 + item.Pos;
|
||||
return DataStreamOffset + _nonSolidStartOffset + 4 + item.Pos;
|
||||
}
|
||||
|
||||
void Release()
|
||||
@@ -174,6 +387,52 @@ public:
|
||||
Decoder.Release();
|
||||
}
|
||||
|
||||
bool IsTruncated() const { return (_fileSize - StartOffset < FirstHeader.ArcSize); }
|
||||
|
||||
UString GetReducedName(unsigned index) const
|
||||
{
|
||||
const CItem &item = Items[index];
|
||||
|
||||
UString s;
|
||||
if (item.Prefix >= 0)
|
||||
{
|
||||
if (IsUnicode)
|
||||
s = UPrefixes[item.Prefix];
|
||||
else
|
||||
s = MultiByteToUnicodeString(APrefixes[item.Prefix]);
|
||||
if (s.Len() > 0)
|
||||
if (s.Back() != L'\\')
|
||||
s += L'\\';
|
||||
}
|
||||
|
||||
if (IsUnicode)
|
||||
{
|
||||
s += item.NameU;
|
||||
if (item.NameU.IsEmpty())
|
||||
s += L"file";
|
||||
}
|
||||
else
|
||||
{
|
||||
s += MultiByteToUnicodeString(item.NameA);
|
||||
if (item.NameA.IsEmpty())
|
||||
s += L"file";
|
||||
}
|
||||
|
||||
const char *kRemoveStr = "$INSTDIR\\";
|
||||
if (s.IsPrefixedBy_Ascii_NoCase(kRemoveStr))
|
||||
s.Delete(0, MyStringLen(kRemoveStr));
|
||||
if (item.IsUninstaller && ExeStub.Size() == 0)
|
||||
s += L".nsis";
|
||||
return s;
|
||||
}
|
||||
|
||||
UString ConvertToUnicode(const AString &s) const;
|
||||
|
||||
CInArchive()
|
||||
#ifdef NSIS_SCRIPT
|
||||
: Script(kScriptSizeLimit)
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user