mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-09 00:07:00 -06:00
Initialer Commit
This commit is contained in:
251
CPP/7zip/Archive/Nsis/NsisDecode.cpp
Normal file
251
CPP/7zip/Archive/Nsis/NsisDecode.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
// NsisDecode.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
#include "NsisDecode.h"
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
#include "../../Common/MethodId.h"
|
||||
|
||||
#include "../../Compress/BcjCoder.h"
|
||||
#include "../../Compress/BZip2Decoder.h"
|
||||
#include "../../Compress/DeflateDecoder.h"
|
||||
|
||||
#define Get32(p) GetUi32(p)
|
||||
|
||||
namespace NArchive {
|
||||
namespace NNsis {
|
||||
|
||||
HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter)
|
||||
{
|
||||
useFilter = false;
|
||||
|
||||
if (_decoderInStream)
|
||||
if (Method != _curMethod)
|
||||
Release();
|
||||
_curMethod = Method;
|
||||
if (!_codecInStream)
|
||||
{
|
||||
switch (Method)
|
||||
{
|
||||
// case NMethodType::kCopy: return E_NOTIMPL;
|
||||
case NMethodType::kDeflate: _codecInStream = new NCompress::NDeflate::NDecoder::CNsisCOMCoder(); break;
|
||||
case NMethodType::kBZip2: _codecInStream = new NCompress::NBZip2::CNsisDecoder(); break;
|
||||
case NMethodType::kLZMA:
|
||||
_lzmaDecoder = new NCompress::NLzma::CDecoder();
|
||||
_codecInStream = _lzmaDecoder;
|
||||
break;
|
||||
default: return E_NOTIMPL;
|
||||
}
|
||||
}
|
||||
|
||||
if (FilterFlag)
|
||||
{
|
||||
Byte flag;
|
||||
RINOK(ReadStream_FALSE(inStream, &flag, 1));
|
||||
if (flag > 1)
|
||||
return E_NOTIMPL;
|
||||
useFilter = (flag != 0);
|
||||
}
|
||||
|
||||
if (!useFilter)
|
||||
_decoderInStream = _codecInStream;
|
||||
else
|
||||
{
|
||||
if (!_filterInStream)
|
||||
{
|
||||
_filter = new CFilterCoder(false);
|
||||
_filterInStream = _filter;
|
||||
_filter->Filter = new NCompress::NBcj::CCoder(false);
|
||||
}
|
||||
RINOK(_filter->SetInStream(_codecInStream));
|
||||
_decoderInStream = _filterInStream;
|
||||
}
|
||||
|
||||
if (Method == NMethodType::kLZMA)
|
||||
{
|
||||
const unsigned kPropsSize = LZMA_PROPS_SIZE;
|
||||
Byte props[kPropsSize];
|
||||
RINOK(ReadStream_FALSE(inStream, props, kPropsSize));
|
||||
RINOK(_lzmaDecoder->SetDecoderProperties2((const Byte *)props, kPropsSize));
|
||||
}
|
||||
|
||||
{
|
||||
CMyComPtr<ICompressSetInStream> setInStream;
|
||||
_codecInStream.QueryInterface(IID_ICompressSetInStream, &setInStream);
|
||||
if (!setInStream)
|
||||
return E_NOTIMPL;
|
||||
RINOK(setInStream->SetInStream(inStream));
|
||||
}
|
||||
|
||||
{
|
||||
CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
|
||||
_codecInStream.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
|
||||
if (!setOutStreamSize)
|
||||
return E_NOTIMPL;
|
||||
RINOK(setOutStreamSize->SetOutStreamSize(NULL));
|
||||
}
|
||||
|
||||
if (useFilter)
|
||||
{
|
||||
RINOK(_filter->SetOutStreamSize(NULL));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const UInt32 kMask_IsCompressed = (UInt32)1 << 31;
|
||||
|
||||
HRESULT CDecoder::SetToPos(UInt64 pos, ICompressProgressInfo *progress)
|
||||
{
|
||||
if (StreamPos > pos)
|
||||
return E_FAIL;
|
||||
UInt64 inSizeStart = 0;
|
||||
if (_lzmaDecoder)
|
||||
inSizeStart = _lzmaDecoder->GetInputProcessedSize();
|
||||
UInt64 offset = 0;
|
||||
while (StreamPos < pos)
|
||||
{
|
||||
size_t size = (size_t)MyMin(pos - StreamPos, (UInt64)Buffer.Size());
|
||||
RINOK(Read(Buffer, &size));
|
||||
if (size == 0)
|
||||
return S_FALSE;
|
||||
StreamPos += size;
|
||||
offset += size;
|
||||
|
||||
UInt64 inSize = 0;
|
||||
if (_lzmaDecoder)
|
||||
inSize = _lzmaDecoder->GetInputProcessedSize() - inSizeStart;
|
||||
RINOK(progress->SetRatioInfo(&inSize, &offset));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unpackSize,
|
||||
ISequentialOutStream *realOutStream, ICompressProgressInfo *progress,
|
||||
UInt32 &packSizeRes, UInt32 &unpackSizeRes)
|
||||
{
|
||||
CLimitedSequentialInStream *limitedStreamSpec = NULL;
|
||||
CMyComPtr<ISequentialInStream> limitedStream;
|
||||
packSizeRes = 0;
|
||||
unpackSizeRes = 0;
|
||||
|
||||
if (Solid)
|
||||
{
|
||||
Byte temp[4];
|
||||
size_t processedSize = 4;
|
||||
RINOK(Read(temp, &processedSize));
|
||||
if (processedSize != 4)
|
||||
return S_FALSE;
|
||||
StreamPos += processedSize;
|
||||
UInt32 size = Get32(temp);
|
||||
if (unpackSizeDefined && size != unpackSize)
|
||||
return S_FALSE;
|
||||
unpackSize = size;
|
||||
unpackSizeDefined = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte temp[4];
|
||||
RINOK(ReadStream_FALSE(InputStream, temp, 4));
|
||||
StreamPos += 4;
|
||||
UInt32 size = Get32(temp);
|
||||
|
||||
if ((size & kMask_IsCompressed) == 0)
|
||||
{
|
||||
if (unpackSizeDefined && size != unpackSize)
|
||||
return S_FALSE;
|
||||
packSizeRes = size;
|
||||
if (outBuf)
|
||||
outBuf->Alloc(size);
|
||||
|
||||
UInt64 offset = 0;
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
UInt32 curSize = (UInt32)MyMin((size_t)size, Buffer.Size());
|
||||
UInt32 processedSize;
|
||||
RINOK(InputStream->Read(Buffer, curSize, &processedSize));
|
||||
if (processedSize == 0)
|
||||
return S_FALSE;
|
||||
if (outBuf)
|
||||
memcpy((Byte *)*outBuf + (size_t)offset, Buffer, processedSize);
|
||||
offset += processedSize;
|
||||
size -= processedSize;
|
||||
StreamPos += processedSize;
|
||||
unpackSizeRes += processedSize;
|
||||
if (realOutStream)
|
||||
RINOK(WriteStream(realOutStream, Buffer, processedSize));
|
||||
RINOK(progress->SetRatioInfo(&offset, &offset));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
size &= ~kMask_IsCompressed;
|
||||
packSizeRes = size;
|
||||
limitedStreamSpec = new CLimitedSequentialInStream;
|
||||
limitedStream = limitedStreamSpec;
|
||||
limitedStreamSpec->SetStream(InputStream);
|
||||
limitedStreamSpec->Init(size);
|
||||
{
|
||||
bool useFilter;
|
||||
RINOK(Init(limitedStream, useFilter));
|
||||
}
|
||||
}
|
||||
|
||||
if (outBuf)
|
||||
{
|
||||
if (!unpackSizeDefined)
|
||||
return S_FALSE;
|
||||
outBuf->Alloc(unpackSize);
|
||||
}
|
||||
|
||||
UInt64 inSizeStart = 0;
|
||||
if (_lzmaDecoder)
|
||||
inSizeStart = _lzmaDecoder->GetInputProcessedSize();
|
||||
|
||||
// we don't allow files larger than 4 GB;
|
||||
if (!unpackSizeDefined)
|
||||
unpackSize = 0xFFFFFFFF;
|
||||
UInt32 offset = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
size_t rem = unpackSize - offset;
|
||||
if (rem == 0)
|
||||
break;
|
||||
size_t size = Buffer.Size();
|
||||
if (size > rem)
|
||||
size = rem;
|
||||
RINOK(Read(Buffer, &size));
|
||||
if (size == 0)
|
||||
{
|
||||
if (unpackSizeDefined)
|
||||
return S_FALSE;
|
||||
break;
|
||||
}
|
||||
if (outBuf)
|
||||
memcpy((Byte *)*outBuf + (size_t)offset, Buffer, size);
|
||||
StreamPos += size;
|
||||
offset += (UInt32)size;
|
||||
|
||||
UInt64 inSize = 0; // it can be improved: we need inSize for Deflate and BZip2 too.
|
||||
if (_lzmaDecoder)
|
||||
inSize = _lzmaDecoder->GetInputProcessedSize() - inSizeStart;
|
||||
if (Solid)
|
||||
packSizeRes = (UInt32)inSize;
|
||||
unpackSizeRes += (UInt32)size;
|
||||
|
||||
UInt64 outSize = offset;
|
||||
RINOK(progress->SetRatioInfo(&inSize, &outSize));
|
||||
if (realOutStream)
|
||||
RINOK(WriteStream(realOutStream, Buffer, size));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}}
|
||||
76
CPP/7zip/Archive/Nsis/NsisDecode.h
Normal file
76
CPP/7zip/Archive/Nsis/NsisDecode.h
Normal file
@@ -0,0 +1,76 @@
|
||||
// NsisDecode.h
|
||||
|
||||
#ifndef __NSIS_DECODE_H
|
||||
#define __NSIS_DECODE_H
|
||||
|
||||
#include "../../../Common/MyBuffer.h"
|
||||
|
||||
#include "../../Common/FilterCoder.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
#include "../../Compress/LzmaDecoder.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NNsis {
|
||||
|
||||
namespace NMethodType
|
||||
{
|
||||
enum EEnum
|
||||
{
|
||||
kCopy,
|
||||
kDeflate,
|
||||
kBZip2,
|
||||
kLZMA
|
||||
};
|
||||
}
|
||||
|
||||
/* 7-Zip installers 4.38 - 9.08 used modified version of NSIS that
|
||||
supported BCJ filter for better compression ratio.
|
||||
We support such modified NSIS archives. */
|
||||
|
||||
class CDecoder
|
||||
{
|
||||
NMethodType::EEnum _curMethod; // method of created decoder
|
||||
|
||||
CFilterCoder *_filter;
|
||||
CMyComPtr<ISequentialInStream> _filterInStream;
|
||||
CMyComPtr<ISequentialInStream> _codecInStream;
|
||||
CMyComPtr<ISequentialInStream> _decoderInStream;
|
||||
|
||||
NCompress::NLzma::CDecoder *_lzmaDecoder;
|
||||
|
||||
public:
|
||||
CMyComPtr<IInStream> InputStream; // for non-solid
|
||||
UInt64 StreamPos; // the pos in unpacked for solid, the pos in Packed for non-solid
|
||||
|
||||
NMethodType::EEnum Method;
|
||||
bool FilterFlag;
|
||||
bool Solid;
|
||||
|
||||
CByteBuffer Buffer; // temp buf.
|
||||
|
||||
void Release()
|
||||
{
|
||||
_filterInStream.Release();
|
||||
_codecInStream.Release();
|
||||
_decoderInStream.Release();
|
||||
InputStream.Release();
|
||||
_lzmaDecoder = NULL;
|
||||
}
|
||||
|
||||
HRESULT Init(ISequentialInStream *inStream, bool &useFilter);
|
||||
HRESULT Read(void *data, size_t *processedSize)
|
||||
{
|
||||
return ReadStream(_decoderInStream, data, processedSize);;
|
||||
}
|
||||
|
||||
|
||||
HRESULT SetToPos(UInt64 pos, ICompressProgressInfo *progress); // for solid
|
||||
HRESULT Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unpackSize,
|
||||
ISequentialOutStream *realOutStream, ICompressProgressInfo *progress,
|
||||
UInt32 &packSizeRes, UInt32 &unpackSizeRes);
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
680
CPP/7zip/Archive/Nsis/NsisHandler.cpp
Normal file
680
CPP/7zip/Archive/Nsis/NsisHandler.cpp
Normal file
@@ -0,0 +1,680 @@
|
||||
// NSisHandler.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
#include "../../../Common/ComTry.h"
|
||||
#include "../../../Common/IntToString.h"
|
||||
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "../../Common/ProgressUtils.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
#include "../Common/ItemNameUtils.h"
|
||||
|
||||
#include "NsisHandler.h"
|
||||
|
||||
#define Get32(p) GetUi32(p)
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
namespace NArchive {
|
||||
namespace NNsis {
|
||||
|
||||
static const char *kBcjMethod = "BCJ";
|
||||
static const char *kUnknownMethod = "Unknown";
|
||||
|
||||
static const char * const kMethods[] =
|
||||
{
|
||||
"Copy"
|
||||
, "Deflate"
|
||||
, "BZip2"
|
||||
, "LZMA"
|
||||
};
|
||||
|
||||
static const Byte kProps[] =
|
||||
{
|
||||
kpidPath,
|
||||
kpidSize,
|
||||
kpidPackSize,
|
||||
kpidMTime,
|
||||
kpidAttrib,
|
||||
kpidMethod,
|
||||
kpidSolid,
|
||||
kpidOffset
|
||||
};
|
||||
|
||||
static const Byte kArcProps[] =
|
||||
{
|
||||
kpidMethod,
|
||||
kpidSolid,
|
||||
kpidHeadersSize,
|
||||
kpidEmbeddedStubSize,
|
||||
kpidSubType
|
||||
// kpidCodePage
|
||||
};
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
|
||||
static AString UInt32ToString(UInt32 val)
|
||||
{
|
||||
char s[16];
|
||||
ConvertUInt32ToString(val, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
static AString GetStringForSizeValue(UInt32 val)
|
||||
{
|
||||
for (int i = 31; i >= 0; i--)
|
||||
if (((UInt32)1 << i) == val)
|
||||
return UInt32ToString(i);
|
||||
char c = 'b';
|
||||
if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
|
||||
else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
|
||||
return UInt32ToString(val) + c;
|
||||
}
|
||||
|
||||
static AString GetMethod(bool useFilter, NMethodType::EEnum method, UInt32 dict)
|
||||
{
|
||||
AString s;
|
||||
if (useFilter)
|
||||
{
|
||||
s += kBcjMethod;
|
||||
s.Add_Space();
|
||||
}
|
||||
s += ((unsigned)method < ARRAY_SIZE(kMethods)) ? kMethods[(unsigned)method] : kUnknownMethod;
|
||||
if (method == NMethodType::kLZMA)
|
||||
{
|
||||
s += ':';
|
||||
s += GetStringForSizeValue(dict);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
AString CHandler::GetMethod(NMethodType::EEnum method, bool useItemFilter, UInt32 dictionary) const
|
||||
{
|
||||
AString s;
|
||||
if (_archive.IsSolid && _archive.UseFilter || !_archive.IsSolid && useItemFilter)
|
||||
{
|
||||
s += kBcjMethod;
|
||||
s.Add_Space();
|
||||
}
|
||||
s += (method < ARRAY_SIZE(kMethods)) ? kMethods[method] : kUnknownMethod;
|
||||
if (method == NMethodType::kLZMA)
|
||||
{
|
||||
s += ':';
|
||||
s += GetStringForSizeValue(_archive.IsSolid ? _archive.DictionarySize: dictionary);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NCOM::CPropVariant prop;
|
||||
switch (propID)
|
||||
{
|
||||
// case kpidCodePage: if (_archive.IsUnicode) prop = "UTF-16"; break;
|
||||
case kpidSubType:
|
||||
{
|
||||
AString s = _archive.GetFormatDescription();
|
||||
if (!_archive.IsInstaller)
|
||||
{
|
||||
s.Add_Space_if_NotEmpty();
|
||||
s += "(Uninstall)";
|
||||
}
|
||||
if (!s.IsEmpty())
|
||||
prop = s;
|
||||
break;
|
||||
}
|
||||
|
||||
case kpidMethod: prop = _methodString; break;
|
||||
case kpidSolid: prop = _archive.IsSolid; break;
|
||||
case kpidOffset: prop = _archive.StartOffset; break;
|
||||
case kpidPhySize: prop = (UInt64)((UInt64)_archive.ExeStub.Size() + _archive.FirstHeader.ArcSize); break;
|
||||
case kpidEmbeddedStubSize: prop = (UInt64)_archive.ExeStub.Size(); break;
|
||||
case kpidHeadersSize: prop = _archive.FirstHeader.HeaderSize; break;
|
||||
|
||||
case kpidErrorFlags:
|
||||
{
|
||||
UInt32 v = 0;
|
||||
if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc;
|
||||
if (_archive.IsTruncated()) v |= kpv_ErrorFlags_UnexpectedEnd;
|
||||
prop = v;
|
||||
break;
|
||||
}
|
||||
|
||||
case kpidName:
|
||||
{
|
||||
AString s;
|
||||
|
||||
#ifdef NSIS_SCRIPT
|
||||
if (!_archive.Name.IsEmpty())
|
||||
s = _archive.Name;
|
||||
if (!_archive.IsInstaller)
|
||||
{
|
||||
if (!s.IsEmpty())
|
||||
s += '.';
|
||||
s += "Uninstall";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s.IsEmpty())
|
||||
s = _archive.IsInstaller ? "Install" : "Uninstall";
|
||||
s += (_archive.ExeStub.Size() == 0) ? ".nsis" : ".exe";
|
||||
|
||||
prop = _archive.ConvertToUnicode(s);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef NSIS_SCRIPT
|
||||
case kpidShortComment:
|
||||
{
|
||||
if (!_archive.BrandingText.IsEmpty())
|
||||
prop = _archive.ConvertToUnicode(_archive.BrandingText);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback * /* openArchiveCallback */)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
Close();
|
||||
{
|
||||
if (_archive.Open(stream, maxCheckStartPosition) != S_OK)
|
||||
return S_FALSE;
|
||||
{
|
||||
UInt32 dict = _archive.DictionarySize;
|
||||
if (!_archive.IsSolid)
|
||||
{
|
||||
FOR_VECTOR (i, _archive.Items)
|
||||
{
|
||||
const CItem &item = _archive.Items[i];
|
||||
if (item.DictionarySize > dict)
|
||||
dict = item.DictionarySize;
|
||||
}
|
||||
}
|
||||
_methodString = GetMethod(_archive.UseFilter, _archive.Method, dict);
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_archive.Clear();
|
||||
_archive.Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = _archive.Items.Size()
|
||||
#ifdef NSIS_SCRIPT
|
||||
+ 1 + _archive.LicenseFiles.Size();
|
||||
#endif
|
||||
;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
bool CHandler::GetUncompressedSize(unsigned index, UInt32 &size) const
|
||||
{
|
||||
size = 0;
|
||||
const CItem &item = _archive.Items[index];
|
||||
if (item.Size_Defined)
|
||||
size = item.Size;
|
||||
else if (_archive.IsSolid && item.EstimatedSize_Defined)
|
||||
size = item.EstimatedSize;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CHandler::GetCompressedSize(unsigned index, UInt32 &size) const
|
||||
{
|
||||
size = 0;
|
||||
const CItem &item = _archive.Items[index];
|
||||
if (item.CompressedSize_Defined)
|
||||
size = item.CompressedSize;
|
||||
else
|
||||
{
|
||||
if (_archive.IsSolid)
|
||||
{
|
||||
if (index == 0)
|
||||
size = _archive.FirstHeader.GetDataSize();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!item.IsCompressed)
|
||||
size = item.Size;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NCOM::CPropVariant prop;
|
||||
#ifdef NSIS_SCRIPT
|
||||
if (index >= (UInt32)_archive.Items.Size())
|
||||
{
|
||||
if (index == (UInt32)_archive.Items.Size())
|
||||
{
|
||||
switch (propID)
|
||||
{
|
||||
case kpidPath: prop = "[NSIS].nsi"; break;
|
||||
case kpidSize:
|
||||
case kpidPackSize: prop = (UInt64)_archive.Script.Len(); break;
|
||||
case kpidSolid: prop = false; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const CLicenseFile &lic = _archive.LicenseFiles[index - (_archive.Items.Size() + 1)];
|
||||
switch (propID)
|
||||
{
|
||||
case kpidPath: prop = lic.Name; break;
|
||||
case kpidSize:
|
||||
case kpidPackSize: prop = (UInt64)lic.Size; break;
|
||||
case kpidSolid: prop = false; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
const CItem &item = _archive.Items[index];
|
||||
switch (propID)
|
||||
{
|
||||
case kpidOffset: prop = item.Pos; break;
|
||||
case kpidPath:
|
||||
{
|
||||
UString s = NItemName::WinNameToOSName(_archive.GetReducedName(index));
|
||||
if (!s.IsEmpty())
|
||||
prop = (const wchar_t *)s;
|
||||
break;
|
||||
}
|
||||
case kpidSize:
|
||||
{
|
||||
UInt32 size;
|
||||
if (GetUncompressedSize(index, size))
|
||||
prop = (UInt64)size;
|
||||
break;
|
||||
}
|
||||
case kpidPackSize:
|
||||
{
|
||||
UInt32 size;
|
||||
if (GetCompressedSize(index, size))
|
||||
prop = (UInt64)size;
|
||||
break;
|
||||
}
|
||||
case kpidMTime:
|
||||
{
|
||||
if (item.MTime.dwHighDateTime > 0x01000000 &&
|
||||
item.MTime.dwHighDateTime < 0xFF000000)
|
||||
prop = item.MTime;
|
||||
break;
|
||||
}
|
||||
case kpidAttrib:
|
||||
{
|
||||
if (item.Attrib_Defined)
|
||||
prop = item.Attrib;
|
||||
break;
|
||||
}
|
||||
|
||||
case kpidMethod:
|
||||
if (_archive.IsSolid)
|
||||
prop = _methodString;
|
||||
else
|
||||
prop = GetMethod(_archive.UseFilter, item.IsCompressed ? _archive.Method :
|
||||
NMethodType::kCopy, item.DictionarySize);
|
||||
break;
|
||||
|
||||
case kpidSolid: prop = _archive.IsSolid; break;
|
||||
}
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
static bool UninstallerPatch(const Byte *p, size_t size, CByteBuffer &dest)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (size < 4)
|
||||
return false;
|
||||
UInt32 len = Get32(p);
|
||||
if (len == 0)
|
||||
return size == 4;
|
||||
if (size < 8)
|
||||
return false;
|
||||
UInt32 offs = Get32(p + 4);
|
||||
p += 8;
|
||||
size -= 8;
|
||||
if (size < len || offs > dest.Size() || len > dest.Size() - offs)
|
||||
return false;
|
||||
memcpy(dest + offs, p, len);
|
||||
p += len;
|
||||
size -= len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
||||
if (allFilesMode)
|
||||
GetNumberOfItems(&numItems);
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
|
||||
UInt64 totalSize = 0;
|
||||
UInt64 solidPosMax = 0;
|
||||
|
||||
UInt32 i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 index = (allFilesMode ? i : indices[i]);
|
||||
|
||||
#ifdef NSIS_SCRIPT
|
||||
if (index >= _archive.Items.Size())
|
||||
{
|
||||
if (index == _archive.Items.Size())
|
||||
totalSize += _archive.Script.Len();
|
||||
else
|
||||
totalSize += _archive.LicenseFiles[index - (_archive.Items.Size() + 1)].Size;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
UInt32 size;
|
||||
if (_archive.IsSolid)
|
||||
{
|
||||
GetUncompressedSize(index, size);
|
||||
UInt64 pos = (UInt64)_archive.GetPosOfSolidItem(index) + size;
|
||||
if (solidPosMax < pos)
|
||||
solidPosMax = pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetCompressedSize(index, size);
|
||||
totalSize += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extractCallback->SetTotal(totalSize + solidPosMax);
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
lps->Init(extractCallback, !_archive.IsSolid);
|
||||
|
||||
if (_archive.IsSolid)
|
||||
{
|
||||
RINOK(_archive.SeekTo_DataStreamOffset());
|
||||
RINOK(_archive.InitDecoder());
|
||||
_archive.Decoder.StreamPos = 0;
|
||||
}
|
||||
|
||||
/* We use tempBuf for solid archives, if there is duplicate item.
|
||||
We don't know uncompressed size for non-solid archives, so we can't
|
||||
allocate exact buffer.
|
||||
We use tempBuf also for first part (EXE stub) of unistall.exe
|
||||
and tempBuf2 is used for second part (NSIS script). */
|
||||
|
||||
CByteBuffer tempBuf;
|
||||
CByteBuffer tempBuf2;
|
||||
|
||||
/* tempPos is pos in uncompressed stream of previous item for solid archive, that
|
||||
was written to tempBuf */
|
||||
UInt64 tempPos = (UInt64)(Int64)-1;
|
||||
|
||||
/* prevPos is pos in uncompressed stream of previous item for solid archive.
|
||||
It's used for test mode (where we don't need to test same file second time */
|
||||
UInt64 prevPos = (UInt64)(Int64)-1;
|
||||
|
||||
// if there is error in solid archive, we show error for all subsequent files
|
||||
bool solidDataError = false;
|
||||
|
||||
UInt64 curTotalPacked = 0, curTotalUnpacked = 0;
|
||||
UInt32 curPacked = 0;
|
||||
UInt64 curUnpacked = 0;
|
||||
|
||||
for (i = 0; i < numItems; i++,
|
||||
curTotalPacked += curPacked,
|
||||
curTotalUnpacked += curUnpacked)
|
||||
{
|
||||
lps->InSize = curTotalPacked;
|
||||
lps->OutSize = curTotalUnpacked;
|
||||
if (_archive.IsSolid)
|
||||
lps->OutSize += _archive.Decoder.StreamPos;
|
||||
|
||||
curPacked = 0;
|
||||
curUnpacked = 0;
|
||||
RINOK(lps->SetCur());
|
||||
|
||||
// RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
Int32 askMode = testMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
UInt32 index = allFilesMode ? i : indices[i];
|
||||
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
|
||||
bool dataError = false;
|
||||
|
||||
#ifdef NSIS_SCRIPT
|
||||
if (index >= (UInt32)_archive.Items.Size())
|
||||
{
|
||||
const void *data;
|
||||
size_t size;
|
||||
if (index == (UInt32)_archive.Items.Size())
|
||||
{
|
||||
data = (const Byte *)_archive.Script;
|
||||
size = _archive.Script.Len();
|
||||
}
|
||||
else
|
||||
{
|
||||
CLicenseFile &lic = _archive.LicenseFiles[index - (_archive.Items.Size() + 1)];
|
||||
if (lic.Text.Size() != 0)
|
||||
data = lic.Text;
|
||||
else
|
||||
data = _archive._data + lic.Offset;
|
||||
size = lic.Size;
|
||||
}
|
||||
curUnpacked = size;
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
if (realOutStream)
|
||||
RINOK(WriteStream(realOutStream, data, size));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
const CItem &item = _archive.Items[index];
|
||||
|
||||
if (!_archive.IsSolid)
|
||||
GetCompressedSize(index, curPacked);
|
||||
|
||||
if (!testMode && !realOutStream)
|
||||
continue;
|
||||
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
|
||||
dataError = solidDataError;
|
||||
|
||||
bool needDecompress = !solidDataError;
|
||||
if (needDecompress)
|
||||
{
|
||||
if (testMode && _archive.IsSolid && _archive.GetPosOfSolidItem(index) == prevPos)
|
||||
needDecompress = false;
|
||||
}
|
||||
|
||||
if (needDecompress)
|
||||
{
|
||||
bool writeToTemp = false;
|
||||
bool readFromTemp = false;
|
||||
|
||||
if (!_archive.IsSolid)
|
||||
{
|
||||
RINOK(_archive.SeekToNonSolidItem(index));
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt64 pos = _archive.GetPosOfSolidItem(index);
|
||||
if (pos < _archive.Decoder.StreamPos)
|
||||
{
|
||||
if (pos != tempPos)
|
||||
solidDataError = dataError = true;
|
||||
readFromTemp = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
HRESULT res = _archive.Decoder.SetToPos(pos, progress);
|
||||
if (res != S_OK)
|
||||
{
|
||||
if (res != S_FALSE)
|
||||
return res;
|
||||
solidDataError = dataError = true;
|
||||
}
|
||||
else if (!testMode && i + 1 < numItems)
|
||||
{
|
||||
UInt32 next = allFilesMode ? i + 1 : indices[i + 1];
|
||||
if (next < _archive.Items.Size())
|
||||
{
|
||||
UInt64 nextPos = _archive.GetPosOfSolidItem(next);
|
||||
if (nextPos == pos)
|
||||
{
|
||||
writeToTemp = true;
|
||||
tempPos = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
prevPos = pos;
|
||||
}
|
||||
|
||||
if (!dataError)
|
||||
{
|
||||
// UInt32 unpackSize = 0;
|
||||
// bool unpackSize_Defined = false;
|
||||
bool writeToTemp1 = writeToTemp;
|
||||
if (item.IsUninstaller)
|
||||
{
|
||||
// unpackSize = item.PatchSize;
|
||||
// unpackSize_Defined = true;
|
||||
if (!readFromTemp)
|
||||
writeToTemp = true;
|
||||
writeToTemp1 = writeToTemp;
|
||||
if (_archive.ExeStub.Size() == 0)
|
||||
{
|
||||
if (writeToTemp1 && !readFromTemp)
|
||||
tempBuf.Free();
|
||||
writeToTemp1 = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (readFromTemp)
|
||||
{
|
||||
if (realOutStream && !item.IsUninstaller)
|
||||
RINOK(WriteStream(realOutStream, tempBuf, tempBuf.Size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 curUnpacked32 = 0;
|
||||
HRESULT res = _archive.Decoder.Decode(
|
||||
writeToTemp1 ? &tempBuf : NULL,
|
||||
item.IsUninstaller, item.PatchSize,
|
||||
item.IsUninstaller ? NULL : (ISequentialOutStream *)realOutStream,
|
||||
progress,
|
||||
curPacked, curUnpacked32);
|
||||
curUnpacked = curUnpacked32;
|
||||
if (_archive.IsSolid)
|
||||
curUnpacked = 0;
|
||||
if (res != S_OK)
|
||||
{
|
||||
if (res != S_FALSE)
|
||||
return res;
|
||||
dataError = true;
|
||||
if (_archive.IsSolid)
|
||||
solidDataError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!dataError && item.IsUninstaller)
|
||||
{
|
||||
if (_archive.ExeStub.Size() != 0)
|
||||
{
|
||||
CByteBuffer destBuf = _archive.ExeStub;
|
||||
dataError = !UninstallerPatch(tempBuf, tempBuf.Size(), destBuf);
|
||||
|
||||
if (realOutStream)
|
||||
RINOK(WriteStream(realOutStream, destBuf, destBuf.Size()));
|
||||
}
|
||||
|
||||
if (readFromTemp)
|
||||
{
|
||||
if (realOutStream)
|
||||
RINOK(WriteStream(realOutStream, tempBuf2, tempBuf2.Size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 curPacked2 = 0;
|
||||
UInt32 curUnpacked2 = 0;
|
||||
HRESULT res = _archive.Decoder.Decode(
|
||||
writeToTemp ? &tempBuf2 : NULL,
|
||||
false, 0,
|
||||
realOutStream,
|
||||
progress,
|
||||
curPacked2, curUnpacked2);
|
||||
curPacked += curPacked2;
|
||||
if (!_archive.IsSolid)
|
||||
curUnpacked += curUnpacked2;
|
||||
if (res != S_OK)
|
||||
{
|
||||
if (res != S_FALSE)
|
||||
return res;
|
||||
dataError = true;
|
||||
if (_archive.IsSolid)
|
||||
solidDataError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
realOutStream.Release();
|
||||
RINOK(extractCallback->SetOperationResult(dataError ?
|
||||
NExtract::NOperationResult::kDataError :
|
||||
NExtract::NOperationResult::kOK));
|
||||
}
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
}}
|
||||
36
CPP/7zip/Archive/Nsis/NsisHandler.h
Normal file
36
CPP/7zip/Archive/Nsis/NsisHandler.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// NSisHandler.h
|
||||
|
||||
#ifndef __NSIS_HANDLER_H
|
||||
#define __NSIS_HANDLER_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../Common/CreateCoder.h"
|
||||
|
||||
#include "../IArchive.h"
|
||||
|
||||
#include "NsisIn.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NNsis {
|
||||
|
||||
class CHandler:
|
||||
public IInArchive,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
CInArchive _archive;
|
||||
AString _methodString;
|
||||
|
||||
bool GetUncompressedSize(unsigned index, UInt32 &size) const;
|
||||
bool GetCompressedSize(unsigned index, UInt32 &size) const;
|
||||
|
||||
// AString GetMethod(NMethodType::EEnum method, bool useItemFilter, UInt32 dictionary) const;
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(IInArchive)
|
||||
|
||||
INTERFACE_IInArchive(;)
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
5898
CPP/7zip/Archive/Nsis/NsisIn.cpp
Normal file
5898
CPP/7zip/Archive/Nsis/NsisIn.cpp
Normal file
File diff suppressed because it is too large
Load Diff
445
CPP/7zip/Archive/Nsis/NsisIn.h
Normal file
445
CPP/7zip/Archive/Nsis/NsisIn.h
Normal file
@@ -0,0 +1,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
|
||||
20
CPP/7zip/Archive/Nsis/NsisRegister.cpp
Normal file
20
CPP/7zip/Archive/Nsis/NsisRegister.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// NsisRegister.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../Common/RegisterArc.h"
|
||||
|
||||
#include "NsisHandler.h"
|
||||
|
||||
namespace NArchive {
|
||||
namespace NNsis {
|
||||
|
||||
REGISTER_ARC_I(
|
||||
"Nsis", "nsis", 0, 0x9,
|
||||
kSignature,
|
||||
4,
|
||||
NArcInfoFlags::kFindSignature |
|
||||
NArcInfoFlags::kUseGlobalOffset,
|
||||
NULL)
|
||||
|
||||
}}
|
||||
8
CPP/7zip/Archive/Nsis/StdAfx.h
Normal file
8
CPP/7zip/Archive/Nsis/StdAfx.h
Normal file
@@ -0,0 +1,8 @@
|
||||
// StdAfx.h
|
||||
|
||||
#ifndef __STDAFX_H
|
||||
#define __STDAFX_H
|
||||
|
||||
#include "../../../Common/Common.h"
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user