1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
|
// NsisIn.h
#ifndef __ARCHIVE_NSIS_IN_H
#define __ARCHIVE_NSIS_IN_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"
/* 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 size_t kScriptSizeLimit = 1 << 27;
const unsigned kSignatureSize = 16;
extern const Byte kSignature[kSignatureSize];
#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
{
const UInt32 kUninstall = 1;
const UInt32 kSilent = 2;
const UInt32 kNoCrc = 4;
const UInt32 kForceCrc = 8;
}
struct CFirstHeader
{
UInt32 Flags;
UInt32 HeaderSize;
UInt32 ArcSize;
bool ThereIsCrc() const
{
return
(Flags & NFlags::kForceCrc) != 0 ||
(Flags & NFlags::kNoCrc) == 0;
}
UInt32 GetDataSize() const { return ArcSize - (ThereIsCrc() ? 4 : 0); }
};
struct CBlockHeader
{
UInt32 Offset;
UInt32 Num;
void Parse(const Byte *p)
{
Offset = GetUi32(p);
Num = GetUi32(p + 4);
}
};
struct CItem
{
bool IsCompressed;
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;
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.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
{
public:
#ifdef NSIS_SCRIPT
CDynLimBuf Script;
#endif
CByteBuffer _data;
CObjectVector<CItem> Items;
bool IsUnicode;
private:
UInt32 _stringsPos; // relative to _data
UInt32 NumStringChars;
size_t _size; // it's Header Size
AString Raw_AString;
UString Raw_UString;
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;
#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;
CByteBuffer ExeStub;
CFirstHeader FirstHeader;
NMethodType::EEnum Method;
UInt32 DictionarySize;
bool IsSolid;
bool UseFilter;
bool FilterFlag;
bool IsInstaller;
AString Name;
AString BrandingText;
UStringVector UPrefixes;
AStringVector APrefixes;
#ifdef NSIS_SCRIPT
CObjectVector<CLicenseFile> LicenseFiles;
#endif
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 * const *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()
{
bool useFilter;
return Decoder.Init(_stream, useFilter);
}
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 GetOffset() + FirstHeader.HeaderSize + item.Pos;
}
*/
UInt64 GetPosOfSolidItem(unsigned index) const
{
const CItem &item = Items[index];
return 4 + (UInt64)FirstHeader.HeaderSize + item.Pos;
}
UInt64 GetPosOfNonSolidItem(unsigned index) const
{
const CItem &item = Items[index];
return DataStreamOffset + _nonSolidStartOffset + 4 + item.Pos;
}
void Release()
{
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 (s[0] == L'\\')
s.DeleteFrontal(1);
}
if (item.IsUninstaller && ExeStub.Size() == 0)
s += L".nsis";
return s;
}
UString ConvertToUnicode(const AString &s) const;
CInArchive()
#ifdef NSIS_SCRIPT
: Script(kScriptSizeLimit)
#endif
{}
};
}}
#endif
|