4.58 beta

This commit is contained in:
Igor Pavlov
2008-05-05 00:00:00 +00:00
committed by Kornel Lesiński
parent bd1fa36322
commit 3901bf0ab8
326 changed files with 10643 additions and 14913 deletions

View File

@@ -133,9 +133,9 @@ HRESULT CDecoder::Init(
return S_OK;
}
HRESULT CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
HRESULT CDecoder::Read(void *data, size_t *processedSize)
{
return ReadStream(_decoderInStream, data, size, processedSize);;
return ReadStream(_decoderInStream, data, processedSize);;
}
}}

View File

@@ -39,7 +39,7 @@ public:
HRESULT Init(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream, NMethodType::EEnum method, bool thereIsFilterFlag, bool &useFilter);
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
HRESULT Read(void *data, size_t *processedSize);
};
}}

View File

@@ -12,6 +12,7 @@
#include "Windows/PropVariant.h"
#include "../Common/ItemNameUtils.h"
#include "../../Common/StreamUtils.h"
using namespace NWindows;
@@ -233,8 +234,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
const UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetReducedName(), CP_ACP));
prop = (const wchar_t *)s;
UString s;
if (_archive.IsUnicode)
s = item.GetReducedNameU();
else
s = MultiByteToUnicodeString(item.GetReducedNameA(), CP_ACP);
s = NItemName::WinNameToOSName(s);
if (!s.IsEmpty())
prop = (const wchar_t *)s;
break;
}
case kpidIsFolder:
@@ -348,7 +355,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
continue;
RINOK(extractCallback->PrepareOperation(askMode));
if (!testMode)
RINOK(realOutStream->Write((const char *)_archive.Script, (UInt32)_archive.Script.Length(), NULL));
RINOK(WriteStream(realOutStream, (const char *)_archive.Script, (UInt32)_archive.Script.Length()));
}
else
#endif
@@ -379,9 +386,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt64 pos = _archive.GetPosOfSolidItem(index);
while(streamPos < pos)
{
UInt32 curSize = (UInt32)MyMin(pos - streamPos, (UInt64)kBufferLength);
UInt32 processedSize;
HRESULT res = _archive.Decoder.Read(buffer, curSize, &processedSize);
size_t processedSize = (UInt32)MyMin(pos - streamPos, (UInt64)kBufferLength);
HRESULT res = _archive.Decoder.Read(buffer, &processedSize);
if (res != S_OK)
{
if (res != S_FALSE)
@@ -398,8 +404,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
}
if (streamPos == pos)
{
UInt32 processedSize;
RINOK(_archive.Decoder.Read(buffer, 4, &processedSize));
size_t processedSize = 4;
RINOK(_archive.Decoder.Read(buffer, &processedSize));
if (processedSize != 4)
return E_FAIL;
streamPos += processedSize;
@@ -433,8 +439,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt32 curSize = kBufferLength;
if (sizeIsKnown && curSize > fullSize)
curSize = fullSize;
UInt32 processedSize;
HRESULT res = _archive.Decoder.Read(buffer, curSize, &processedSize);
size_t processedSize = curSize;
HRESULT res = _archive.Decoder.Read(buffer, &processedSize);
if (res != S_OK)
{
if (res != S_FALSE)
@@ -449,7 +455,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
break;
}
fullSize -= processedSize;
fullSize -= (UInt32)processedSize;
streamPos += processedSize;
offset += processedSize;
@@ -460,7 +466,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
completed = currentTotalSize + offset;
RINOK(extractCallback->SetCompleted(&completed));
if (!testMode)
RINOK(realOutStream->Write(buffer, processedSize, NULL));
RINOK(WriteStream(realOutStream, buffer, processedSize));
}
}
else
@@ -478,7 +484,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
fullSize -= processedSize;
streamPos += processedSize;
if (!testMode)
RINOK(realOutStream->Write(buffer, processedSize, 0));
RINOK(WriteStream(realOutStream, buffer, processedSize));
}
}
}

View File

@@ -2,6 +2,8 @@
#include "StdAfx.h"
// #include <stdio.h>
#include "NsisIn.h"
#include "NsisDecode.h"
@@ -9,6 +11,7 @@
#include "../../Common/StreamUtils.h"
#include "Common/StringConvert.h"
#include "Common/IntToString.h"
namespace NArchive {
@@ -27,6 +30,14 @@ public:
static const char *kCrLf = "\x0D\x0A";
#endif
#define NS_UN_SKIP_CODE 0xE000
#define NS_UN_VAR_CODE 0xE001
#define NS_UN_SHELL_CODE 0xE002
#define NS_UN_LANG_CODE 0xE003
#define NS_UN_CODES_START NS_UN_SKIP_CODE
#define NS_UN_CODES_END NS_UN_LANG_CODE
UInt32 GetUInt32FromMemLE(const Byte *p)
{
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
@@ -60,12 +71,20 @@ static int CompareItems(void *const *p1, void *const *p2, void * /* param */)
const CItem &i1 = **(CItem **)p1;
const CItem &i2 = **(CItem **)p2;
RINOZ(MyCompare(i1.Pos, i2.Pos));
RINOZ(i1.Prefix.Compare(i2.Prefix));
RINOZ(i1.Name.Compare(i2.Name));
if (i1.IsUnicode)
{
RINOZ(i1.PrefixU.Compare(i2.PrefixU));
RINOZ(i1.NameU.Compare(i2.NameU));
}
else
{
RINOZ(i1.PrefixA.Compare(i2.PrefixA));
RINOZ(i1.NameA.Compare(i2.NameA));
}
return 0;
}
AString CInArchive::ReadString(UInt32 pos)
AString CInArchive::ReadStringA(UInt32 pos)
{
AString s;
UInt32 offset = GetOffset() + _stringsPos + pos;
@@ -81,6 +100,24 @@ AString CInArchive::ReadString(UInt32 pos)
return s;
}
UString CInArchive::ReadStringU(UInt32 pos)
{
UString s;
UInt32 offset = GetOffset() + _stringsPos + (pos * 2);
for (;;)
{
if (offset >= _size || offset + 1 >= _size)
throw 1;
char c0 = _data[offset++];
char c1 = _data[offset++];
wchar_t c = (c0 | ((wchar_t)c1 << 8));
if (c == 0)
break;
s += c;
}
return s;
}
/*
static AString ParsePrefix(const AString &prefix)
{
@@ -466,13 +503,27 @@ static AString GetVar(UInt32 index)
return res;
}
// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value.
#define NS_SKIP_CODE 252
#define NS_VAR_CODE 253
#define NS_SHELL_CODE 254
#define NS_LANG_CODE 255
#define NS_CODES_START NS_SKIP_CODE
static AString GetShellString(int index)
{
AString res = "$";
if (index < kNumShellStrings)
{
const char *sz = kShellStrings[index];
if (sz[0] != 0)
return res + sz;
}
res += "SHELL[";
res += UIntToString(index);
res += "]";
return res;
}
// Based on Dave Laundon's simplified process_string
AString GetNsisString(const AString &s)
{
@@ -487,26 +538,7 @@ AString GetNsisString(const AString &s)
nData |= (((int)(c1 & 0x7F)) << 7);
if (nVarIdx == NS_SHELL_CODE)
{
UInt32 index = c1;
bool needPrint = true;
res += "$";
if (index < kNumShellStrings)
{
const char *sz = kShellStrings[index];
if (sz[0] != 0)
{
res += sz;
needPrint = false;
}
}
if (needPrint)
{
res += "SHELL[";
res += UIntToString(index);
res += "]";
}
}
res += GetShellString(c1);
else if (nVarIdx == NS_VAR_CODE)
res += GetVar(nData);
else if (nVarIdx == NS_LANG_CODE)
@@ -523,9 +555,53 @@ AString GetNsisString(const AString &s)
return res;
}
UString GetNsisString(const UString &s)
{
UString res;
for (int i = 0; i < s.Length();)
{
wchar_t nVarIdx = s[i++];
if (nVarIdx > NS_UN_CODES_START && nVarIdx <= NS_UN_CODES_END)
{
if (i == s.Length())
break;
int nData = s[i++] & 0x7FFF;
if (nVarIdx == NS_UN_SHELL_CODE)
res += GetUnicodeString(GetShellString(nData >> 8));
else if (nVarIdx == NS_UN_VAR_CODE)
res += GetUnicodeString(GetVar(nData));
else if (nVarIdx == NS_UN_LANG_CODE)
res += L"NS_LANG_CODE";
}
else if (nVarIdx == NS_UN_SKIP_CODE)
{
if (i == s.Length())
break;
res += s[i++];
}
else // Normal char
res += (char)nVarIdx;
}
return res;
}
AString CInArchive::ReadString2A(UInt32 pos)
{
return GetNsisString(ReadStringA(pos));
}
UString CInArchive::ReadString2U(UInt32 pos)
{
return GetNsisString(ReadStringU(pos));
}
AString CInArchive::ReadString2(UInt32 pos)
{
return GetNsisString(ReadString(pos));
if (IsUnicode)
return UnicodeStringToMultiByte(ReadString2U(pos));
else
return ReadString2A(pos);
}
#define DEL_DIR 1
@@ -566,7 +642,8 @@ AString CEntry::GetParamsString(int numParams)
HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
{
_posInData = bh.Offset + GetOffset();
AString prefix;
AString prefixA;
UString prefixU;
for (UInt32 i = 0; i < bh.Num; i++)
{
CEntry e;
@@ -585,11 +662,22 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
{
case EW_CREATEDIR:
{
prefix.Empty();
prefix = ReadString2(e.Params[0]);
if (IsUnicode)
{
prefixU.Empty();
prefixU = ReadString2U(e.Params[0]);
}
else
{
prefixA.Empty();
prefixA = ReadString2A(e.Params[0]);
}
#ifdef NSIS_SCRIPT
Script += " ";
Script += prefix;
if (IsUnicode)
Script += UnicodeStringToMultiByte(prefixU);
else
Script += prefixA;
#endif
break;
}
@@ -597,9 +685,18 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
case EW_EXTRACTFILE:
{
CItem item;
item.Prefix = prefix;
item.IsUnicode = IsUnicode;
if (IsUnicode)
{
item.PrefixU = prefixU;
item.NameU = ReadString2U(e.Params[1]);
}
else
{
item.PrefixA = prefixA;
item.NameA = ReadString2A(e.Params[1]);
}
/* UInt32 overwriteFlag = e.Params[0]; */
item.Name = ReadString2(e.Params[1]);
item.Pos = e.Params[2];
item.DateTime.dwLowDateTime = e.Params[3];
item.DateTime.dwHighDateTime = e.Params[4];
@@ -614,7 +711,11 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
Items.Add(item);
#ifdef NSIS_SCRIPT
Script += " ";
Script += item.Name;
if (IsUnicode)
Script += UnicodeStringToMultiByte(item.NameU);
else
Script += item.NameA;
#endif
break;
}
@@ -908,7 +1009,10 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
// if (IsSolid)
for (i = 0; i + 1 < Items.Size();)
{
if (Items[i].Pos == Items[i + 1].Pos && (IsSolid || Items[i].Name == Items[i + 1].Name))
bool sameName = IsUnicode ?
(Items[i].NameU == Items[i + 1].NameU) :
(Items[i].NameA == Items[i + 1].NameA);
if (Items[i].Pos == Items[i + 1].Pos && (IsSolid || sameName))
Items.Delete(i + 1);
else
i++;
@@ -927,8 +1031,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
RINOK(_stream->Seek(GetPosOfNonSolidItem(i), STREAM_SEEK_SET, NULL));
const UInt32 kSigSize = 4 + 1 + 5;
BYTE sig[kSigSize];
UInt32 processedSize;
RINOK(ReadStream(_stream, sig, kSigSize, &processedSize));
size_t processedSize = kSigSize;
RINOK(ReadStream(_stream, sig, &processedSize));
if (processedSize < 4)
return S_FALSE;
UInt32 size = GetUInt32FromMemLE(sig);
@@ -977,7 +1081,37 @@ HRESULT CInArchive::Parse()
ReadBlockHeader(bhData);
_stringsPos = bhStrings.Offset;
UInt32 pos = GetOffset() + _stringsPos;
int numZeros0 = 0;
int numZeros1 = 0;
int i;
const kBlockSize = 256;
for (i = 0; i < kBlockSize; i++)
{
if (pos >= _size || pos + 1 >= _size)
break;
char c0 = _data[pos++];
char c1 = _data[pos++];
wchar_t c = (c0 | ((wchar_t)c1 << 8));
if (c >= NS_UN_CODES_START && c < NS_UN_CODES_END)
{
if (pos >= _size || pos + 1 >= _size)
break;
pos += 2;
numZeros1++;
}
else
{
if (c0 == 0 && c1 != 0)
numZeros0++;
if (c1 == 0)
numZeros1++;
}
// printf("\nnumZeros0 = %2x %2x", _data[pos + 0], _data[pos + 1]);
}
IsUnicode = (numZeros1 > numZeros0 * 3 + kBlockSize / 16);
// printf("\nnumZeros0 = %3d numZeros1 = %3d", numZeros0, numZeros1);
return ReadEntries(bhEntries);
}
@@ -1010,10 +1144,7 @@ HRESULT CInArchive::Open2(
const UInt32 kSigSize = 4 + 1 + 5 + 1; // size, flag, lzma props, lzma first byte
BYTE sig[kSigSize];
UInt32 processedSize;
RINOK(ReadStream(_stream, sig, kSigSize, &processedSize));
if (processedSize != kSigSize)
return S_FALSE;
RINOK(ReadStream_FALSE(_stream, sig, kSigSize));
UInt64 position;
RINOK(_stream->Seek(StreamOffset, STREAM_SEEK_SET, &position));
@@ -1065,11 +1196,11 @@ HRESULT CInArchive::Open2(
RINOK(Decoder.Init(
EXTERNAL_CODECS_LOC_VARS
_stream, Method, FilterFlag, UseFilter));
UInt32 processedSize;
RINOK(Decoder.Read(_data, unpackSize, &processedSize));
size_t processedSize = unpackSize;
RINOK(Decoder.Read(_data, &processedSize));
if (processedSize != unpackSize)
return S_FALSE;
_size = (size_t)processedSize;
_size = processedSize;
if (IsSolid)
{
UInt32 size2 = ReadUInt32();
@@ -1081,9 +1212,7 @@ HRESULT CInArchive::Open2(
{
_data.SetCapacity(unpackSize);
_size = (size_t)unpackSize;
RINOK(ReadStream(_stream, (Byte *)_data, unpackSize, &processedSize));
if (processedSize != unpackSize)
return S_FALSE;
RINOK(ReadStream_FALSE(_stream, (Byte *)_data, unpackSize));
}
return Parse();
}
@@ -1138,22 +1267,17 @@ HRESULT CInArchive::Open(
UInt64 headerPosition = 0;
while (position <= maxSize)
{
UInt32 processedSize;
RINOK(ReadStream(inStream, buffer, kStartHeaderSize, &processedSize));
if (processedSize != kStartHeaderSize)
return S_FALSE;
RINOK(ReadStream_FALSE(inStream, buffer, kStartHeaderSize));
headerPosition = position;
position += processedSize;
position += kStartHeaderSize;
if(memcmp(buffer + 4, kSignature, kSignatureSize) == 0)
{
found = true;
break;
}
const UInt32 kRem = kStep - kStartHeaderSize;
RINOK(ReadStream(inStream, buffer + kStartHeaderSize, kRem, &processedSize));
if (processedSize != kRem)
return S_FALSE;
position += processedSize;
RINOK(ReadStream_FALSE(inStream, buffer + kStartHeaderSize, kRem));
position += kRem;
}
if (!found)
return S_FALSE;

View File

@@ -56,41 +56,56 @@ struct CBlockHeader
struct CItem
{
AString Prefix;
AString Name;
UInt32 Pos;
AString PrefixA;
UString PrefixU;
AString NameA;
UString NameU;
FILETIME DateTime;
bool IsUnicode;
bool UseFilter;
bool IsCompressed;
bool SizeIsDefined;
bool CompressedSizeIsDefined;
bool EstimatedSizeIsDefined;
UInt32 Pos;
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) {}
CItem(): IsUnicode(false), UseFilter(false), IsCompressed(true), SizeIsDefined(false),
CompressedSizeIsDefined(false), EstimatedSizeIsDefined(false), Size(0) {}
bool IsINSTDIR() const
{
if (Prefix.Length() < 3)
return false;
return true;
return (PrefixA.Length() >= 3 || PrefixU.Length() >= 3);
}
AString GetReducedName() const
AString GetReducedNameA() const
{
AString prefix = Prefix;
AString prefix = PrefixA;
if (prefix.Length() > 0)
if (prefix[prefix.Length() - 1] != '\\')
prefix += '\\';
AString s2 = prefix + Name;
AString s2 = prefix + NameA;
const int len = 9;
if (s2.Left(len).CompareNoCase("$INSTDIR\\") == 0)
s2 = s2.Mid(len);
return s2;
}
UString GetReducedNameU() const
{
UString prefix = PrefixU;
if (prefix.Length() > 0)
if (prefix[prefix.Length() - 1] != L'\\')
prefix += L'\\';
UString s2 = prefix + NameU;
const int len = 9;
if (s2.Left(len).CompareNoCase(L"$INSTDIR\\") == 0)
s2 = s2.Mid(len);
return s2;
}
};
@@ -105,7 +120,10 @@ class CInArchive
DECL_EXTERNAL_CODECS_LOC_VARS2
);
void ReadBlockHeader(CBlockHeader &bh);
AString ReadString(UInt32 pos);
AString ReadStringA(UInt32 pos);
UString ReadStringU(UInt32 pos);
AString ReadString2A(UInt32 pos);
UString ReadString2U(UInt32 pos);
AString ReadString2(UInt32 pos);
HRESULT ReadEntries(const CBlockHeader &bh);
HRESULT Parse();
@@ -129,12 +147,13 @@ public:
UInt64 StreamOffset;
CDecoder Decoder;
CObjectVector<CItem> Items;
bool IsSolid;
CFirstHeader FirstHeader;
NMethodType::EEnum Method;
bool UseFilter;
UInt32 DictionarySize;
bool IsSolid;
bool UseFilter;
bool FilterFlag;
bool IsUnicode;
#ifdef NSIS_SCRIPT
AString Script;