summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2018-03-31 20:38:19 +0200
committerDidier Raboud <odyx@debian.org>2018-03-31 20:38:19 +0200
commitf05798f0619384fdb055f634ca4233378f2779dd (patch)
treeb1f9b212f77580c824cc765ac3778fc6c8f4d4d8 /Source
parent59c41c0897494001ced424157660d4ee59bb5426 (diff)
Import Upstream version 2.32
Diffstat (limited to 'Source')
-rwxr-xr-xSource/7zip/7zGuids.cpp62
-rwxr-xr-xSource/7zip/7zip/Common/InBuffer.cpp190
-rwxr-xr-xSource/7zip/7zip/Common/InBuffer.h182
-rwxr-xr-xSource/7zip/7zip/Common/OutBuffer.cpp262
-rwxr-xr-xSource/7zip/7zip/Common/OutBuffer.h158
-rwxr-xr-xSource/7zip/7zip/Common/StdAfx.h16
-rwxr-xr-xSource/7zip/7zip/Common/StreamUtils.cpp118
-rwxr-xr-xSource/7zip/7zip/Common/StreamUtils.h52
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/BinTree/BinTree.h138
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/BinTree/BinTree2.h54
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/BinTree/BinTree3.h62
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/BinTree/BinTree3Z.h62
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/BinTree/BinTree3ZMain.h62
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/BinTree/BinTree4.h66
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/BinTree/BinTree4b.h78
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/BinTree/BinTreeMF.h238
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/BinTree/BinTreeMFMain.h196
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/BinTree/BinTreeMain.h1092
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/IMatchFinder.h94
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/LZInWindow.cpp240
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/LZInWindow.h204
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/LZOutWindow.cpp64
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/LZOutWindow.h142
-rwxr-xr-xSource/7zip/7zip/Compress/LZ/StdAfx.h12
-rwxr-xr-xSource/7zip/7zip/Compress/LZMA/LZMA.h194
-rwxr-xr-xSource/7zip/7zip/Compress/LZMA/LZMAEncoder.cpp3160
-rwxr-xr-xSource/7zip/7zip/Compress/LZMA/LZMAEncoder.h852
-rwxr-xr-xSource/7zip/7zip/Compress/LZMA/StdAfx.h16
-rwxr-xr-xSource/7zip/7zip/Compress/RangeCoder/RangeCoder.h440
-rwxr-xr-xSource/7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp190
-rwxr-xr-xSource/7zip/7zip/Compress/RangeCoder/RangeCoderBit.h270
-rwxr-xr-xSource/7zip/7zip/Compress/RangeCoder/RangeCoderBitTree.h352
-rwxr-xr-xSource/7zip/7zip/Compress/RangeCoder/RangeCoderOpt.h92
-rwxr-xr-xSource/7zip/7zip/Compress/RangeCoder/StdAfx.h12
-rwxr-xr-xSource/7zip/7zip/ICoder.h356
-rwxr-xr-xSource/7zip/7zip/IStream.h154
-rwxr-xr-xSource/7zip/Common/Alloc.cpp266
-rwxr-xr-xSource/7zip/Common/Alloc.h88
-rwxr-xr-xSource/7zip/Common/CRC.cpp152
-rwxr-xr-xSource/7zip/Common/CRC.h102
-rwxr-xr-xSource/7zip/Common/Defs.h70
-rwxr-xr-xSource/7zip/Common/MyCom.h436
-rwxr-xr-xSource/7zip/Common/MyGuidDef.h138
-rwxr-xr-xSource/7zip/Common/MyUnknown.h78
-rwxr-xr-xSource/7zip/Common/MyWindows.h440
-rwxr-xr-xSource/7zip/Common/StdAfx.h46
-rwxr-xr-xSource/7zip/Common/Types.h144
-rwxr-xr-xSource/7zip/LZMADecode.c1092
-rwxr-xr-xSource/7zip/LZMADecode.h276
-rwxr-xr-xSource/7zip/sdk.diff334
-rwxr-xr-xSource/DialogTemplate.cpp1308
-rwxr-xr-xSource/DialogTemplate.h330
-rwxr-xr-xSource/Platform.h1750
-rwxr-xr-xSource/Plugins.cpp414
-rwxr-xr-xSource/Plugins.h86
-rwxr-xr-xSource/ResourceEditor.cpp2092
-rwxr-xr-xSource/ResourceEditor.h482
-rwxr-xr-xSource/ResourceVersionInfo.cpp636
-rwxr-xr-xSource/ResourceVersionInfo.h134
-rwxr-xr-xSource/SConscript187
-rwxr-xr-xSource/ShConstants.cpp170
-rwxr-xr-xSource/ShConstants.h94
-rwxr-xr-xSource/Tests/DialogTemplate.cpp94
-rwxr-xr-xSource/Tests/ResourceEditor.cpp1664
-rwxr-xr-xSource/Tests/SConscript322
-rwxr-xr-xSource/Tests/compression.cpp308
-rwxr-xr-xSource/Tests/decompress.cpp124
-rwxr-xr-xSource/Tests/decompress.h132
-rwxr-xr-xSource/Tests/endian.cpp112
-rwxr-xr-xSource/Tests/memcpy.c22
-rwxr-xr-xSource/Tests/mmap.cpp148
-rwxr-xr-xSource/Tests/preprocessor.nsi448
-rwxr-xr-xSource/Tests/root.txt12
-rwxr-xr-xSource/Tests/specmatch.cpp90
-rwxr-xr-xSource/Tests/textrunner.cpp44
-rwxr-xr-xSource/Tests/winchar.cpp258
-rwxr-xr-xSource/afxres.h42
-rwxr-xr-xSource/boost/checked_delete.hpp142
-rwxr-xr-xSource/boost/detail/workaround.hpp148
-rwxr-xr-xSource/boost/scoped_array.hpp244
-rwxr-xr-xSource/boost/scoped_ptr.hpp274
-rwxr-xr-xSource/build.cpp6962
-rwxr-xr-xSource/build.h833
-rwxr-xr-xSource/bzip2/blocksort.c2218
-rwxr-xr-xSource/bzip2/bzlib.c1242
-rwxr-xr-xSource/bzip2/bzlib.h888
-rwxr-xr-xSource/bzip2/compress.c1338
-rwxr-xr-xSource/bzip2/decompress.c1068
-rwxr-xr-xSource/bzip2/huffman.c488
-rwxr-xr-xSource/cbzip2.h198
-rwxr-xr-xSource/clzma.cpp928
-rwxr-xr-xSource/clzma.h206
-rwxr-xr-xSource/compressor.h92
-rwxr-xr-xSource/crc32.c94
-rwxr-xr-xSource/crc32.h58
-rwxr-xr-xSource/czlib.h182
-rwxr-xr-xSource/dirreader.cpp488
-rwxr-xr-xSource/dirreader.h112
-rwxr-xr-xSource/exehead/Main.c696
-rwxr-xr-xSource/exehead/SConscript202
-rwxr-xr-xSource/exehead/Ui.c3384
-rwxr-xr-xSource/exehead/afxres.h42
-rwxr-xr-xSource/exehead/bgbg.c198
-rwxr-xr-xSource/exehead/components.c328
-rwxr-xr-xSource/exehead/components.h56
-rwxr-xr-xSource/exehead/config.h322
-rwxr-xr-xSource/exehead/exec.c3252
-rwxr-xr-xSource/exehead/exec.h52
-rwxr-xr-xSource/exehead/fileform.c1140
-rwxr-xr-xSource/exehead/fileform.h1106
-rwxr-xr-xSource/exehead/lang.h170
-rwxr-xr-xSource/exehead/resource.h112
-rwxr-xr-xSource/exehead/resource.rc564
-rwxr-xr-xSource/exehead/state.h84
-rwxr-xr-xSource/exehead/ui.h120
-rwxr-xr-xSource/exehead/util.c1920
-rwxr-xr-xSource/exehead/util.h244
-rwxr-xr-xSource/fileform.cpp388
-rwxr-xr-xSource/fileform.h126
-rwxr-xr-xSource/growbuf.cpp176
-rwxr-xr-xSource/growbuf.h124
-rwxr-xr-xSource/icon.cpp379
-rwxr-xr-xSource/icon.h76
-rwxr-xr-xSource/lang.cpp2216
-rwxr-xr-xSource/lang.h398
-rwxr-xr-xSource/lineparse.cpp472
-rwxr-xr-xSource/lineparse.h94
-rwxr-xr-xSource/makenssi.cpp1108
-rwxr-xr-xSource/manifest.cpp134
-rwxr-xr-xSource/manifest.h82
-rwxr-xr-xSource/mmap.cpp1024
-rwxr-xr-xSource/mmap.h288
-rwxr-xr-xSource/script.cpp12347
-rwxr-xr-xSource/strlist.cpp408
-rwxr-xr-xSource/strlist.h516
-rwxr-xr-xSource/tokens.cpp794
-rwxr-xr-xSource/tokens.h548
-rwxr-xr-xSource/uservars.h206
-rwxr-xr-xSource/util.cpp1927
-rwxr-xr-xSource/util.h302
-rwxr-xr-xSource/winchar.cpp252
-rwxr-xr-xSource/winchar.h52
-rwxr-xr-xSource/writer.cpp178
-rwxr-xr-xSource/writer.h174
-rwxr-xr-xSource/zlib/DEFLATE.H502
-rwxr-xr-xSource/zlib/INFBLOCK.C1420
-rwxr-xr-xSource/zlib/ZCONF.H142
-rwxr-xr-xSource/zlib/ZLIB.H594
-rwxr-xr-xSource/zlib/ZUTIL.H170
-rwxr-xr-xSource/zlib/deflate.c1714
-rwxr-xr-xSource/zlib/trees.c1788
151 files changed, 44346 insertions, 44065 deletions
diff --git a/Source/7zip/7zGuids.cpp b/Source/7zip/7zGuids.cpp
index f076b0f..1ca1ac1 100755
--- a/Source/7zip/7zGuids.cpp
+++ b/Source/7zip/7zGuids.cpp
@@ -1,31 +1,31 @@
-/*
- * 7zGuids.cpp
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-// DLLExports.cpp
-
-// #include "StdAfx.h"
-
-#ifdef WIN32
-# include <objbase.h>
-# include <initguid.h>
-#endif
-
-#include "../Platform.h"
-
-#define INITGUID
-#include "7zip/ICoder.h"
-#include "7zip/Compress/LZ/IMatchFinder.h"
+/*
+ * 7zGuids.cpp
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+// DLLExports.cpp
+
+// #include "StdAfx.h"
+
+#ifdef WIN32
+# include <objbase.h>
+# include <initguid.h>
+#endif
+
+#include "../Platform.h"
+
+#define INITGUID
+#include "7zip/ICoder.h"
+#include "7zip/Compress/LZ/IMatchFinder.h"
diff --git a/Source/7zip/7zip/Common/InBuffer.cpp b/Source/7zip/7zip/Common/InBuffer.cpp
index 4d99f5c..e0dcb3d 100755
--- a/Source/7zip/7zip/Common/InBuffer.cpp
+++ b/Source/7zip/7zip/Common/InBuffer.cpp
@@ -1,95 +1,95 @@
-/*
- * InBuffer.cpp
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "StdAfx.h"
-
-#include "InBuffer.h"
-
-#include "../../Common/Alloc.h"
-
-CInBuffer::CInBuffer():
- _buffer(0),
- _bufferLimit(0),
- _bufferBase(0),
- _stream(0),
- _bufferSize(0)
-{}
-
-bool CInBuffer::Create(UInt32 bufferSize)
-{
- const UInt32 kMinBlockSize = 1;
- if (bufferSize < kMinBlockSize)
- bufferSize = kMinBlockSize;
- if (_bufferBase != 0 && _bufferSize == bufferSize)
- return true;
- Free();
- _bufferSize = bufferSize;
- _bufferBase = (Byte *)::MidAlloc(bufferSize);
- return (_bufferBase != 0);
-}
-
-void CInBuffer::Free()
-{
- ::MidFree(_bufferBase);
- _bufferBase = 0;
-}
-
-void CInBuffer::SetStream(ISequentialInStream *stream)
-{
- _stream = stream;
-}
-
-void CInBuffer::Init()
-{
- _processedSize = 0;
- _buffer = _bufferBase;
- _bufferLimit = _buffer;
- _wasFinished = false;
- #ifdef _NO_EXCEPTIONS
- ErrorCode = S_OK;
- #endif
-}
-
-bool CInBuffer::ReadBlock()
-{
- #ifdef _NO_EXCEPTIONS
- if (ErrorCode != S_OK)
- return false;
- #endif
- if (_wasFinished)
- return false;
- _processedSize += (_buffer - _bufferBase);
- UInt32 numProcessedBytes;
- HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
- #ifdef _NO_EXCEPTIONS
- ErrorCode = result;
- #else
- if (result != S_OK)
- throw CInBufferException(result);
- #endif
- _buffer = _bufferBase;
- _bufferLimit = _buffer + numProcessedBytes;
- _wasFinished = (numProcessedBytes == 0);
- return (!_wasFinished);
-}
-
-Byte CInBuffer::ReadBlock2()
-{
- if(!ReadBlock())
- return 0xFF;
- return *_buffer++;
-}
+/*
+ * InBuffer.cpp
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "StdAfx.h"
+
+#include "InBuffer.h"
+
+#include "../../Common/Alloc.h"
+
+CInBuffer::CInBuffer():
+ _buffer(0),
+ _bufferLimit(0),
+ _bufferBase(0),
+ _stream(0),
+ _bufferSize(0)
+{}
+
+bool CInBuffer::Create(UInt32 bufferSize)
+{
+ const UInt32 kMinBlockSize = 1;
+ if (bufferSize < kMinBlockSize)
+ bufferSize = kMinBlockSize;
+ if (_bufferBase != 0 && _bufferSize == bufferSize)
+ return true;
+ Free();
+ _bufferSize = bufferSize;
+ _bufferBase = (Byte *)::MidAlloc(bufferSize);
+ return (_bufferBase != 0);
+}
+
+void CInBuffer::Free()
+{
+ ::MidFree(_bufferBase);
+ _bufferBase = 0;
+}
+
+void CInBuffer::SetStream(ISequentialInStream *stream)
+{
+ _stream = stream;
+}
+
+void CInBuffer::Init()
+{
+ _processedSize = 0;
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer;
+ _wasFinished = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+bool CInBuffer::ReadBlock()
+{
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ return false;
+ #endif
+ if (_wasFinished)
+ return false;
+ _processedSize += (_buffer - _bufferBase);
+ UInt32 numProcessedBytes;
+ HRESULT result = _stream->Read(_bufferBase, _bufferSize, &numProcessedBytes);
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = result;
+ #else
+ if (result != S_OK)
+ throw CInBufferException(result);
+ #endif
+ _buffer = _bufferBase;
+ _bufferLimit = _buffer + numProcessedBytes;
+ _wasFinished = (numProcessedBytes == 0);
+ return (!_wasFinished);
+}
+
+Byte CInBuffer::ReadBlock2()
+{
+ if(!ReadBlock())
+ return 0xFF;
+ return *_buffer++;
+}
diff --git a/Source/7zip/7zip/Common/InBuffer.h b/Source/7zip/7zip/Common/InBuffer.h
index 797875f..d1a3556 100755
--- a/Source/7zip/7zip/Common/InBuffer.h
+++ b/Source/7zip/7zip/Common/InBuffer.h
@@ -1,91 +1,91 @@
-/*
- * InBuffer.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __INBUFFER_H
-#define __INBUFFER_H
-
-#include "../IStream.h"
-#include "../../Common/MyCom.h"
-
-#ifndef _NO_EXCEPTIONS
-class CInBufferException
-{
-public:
- HRESULT ErrorCode;
- CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
-};
-#endif
-
-class CInBuffer
-{
- Byte *_buffer;
- Byte *_bufferLimit;
- Byte *_bufferBase;
- CMyComPtr<ISequentialInStream> _stream;
- UInt64 _processedSize;
- UInt32 _bufferSize;
- bool _wasFinished;
-
- bool ReadBlock();
- Byte ReadBlock2();
-
-public:
- #ifdef _NO_EXCEPTIONS
- HRESULT ErrorCode;
- #endif
-
- CInBuffer();
- ~CInBuffer() { Free(); }
-
- bool Create(UInt32 bufferSize);
- void Free();
-
- void SetStream(ISequentialInStream *stream);
- void Init();
- void ReleaseStream() { _stream.Release(); }
-
- bool ReadByte(Byte &b)
- {
- if(_buffer >= _bufferLimit)
- if(!ReadBlock())
- return false;
- b = *_buffer++;
- return true;
- }
- Byte ReadByte()
- {
- if(_buffer >= _bufferLimit)
- return ReadBlock2();
- return *_buffer++;
- }
- void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
- {
- for(processedSize = 0; processedSize < size; processedSize++)
- if (!ReadByte(((Byte *)data)[processedSize]))
- return;
- }
- bool ReadBytes(void *data, UInt32 size)
- {
- UInt32 processedSize;
- ReadBytes(data, size, processedSize);
- return (processedSize == size);
- }
- UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
- bool WasFinished() const { return _wasFinished; }
-};
-
-#endif
+/*
+ * InBuffer.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __INBUFFER_H
+#define __INBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+#ifndef _NO_EXCEPTIONS
+class CInBufferException
+{
+public:
+ HRESULT ErrorCode;
+ CInBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+#endif
+
+class CInBuffer
+{
+ Byte *_buffer;
+ Byte *_bufferLimit;
+ Byte *_bufferBase;
+ CMyComPtr<ISequentialInStream> _stream;
+ UInt64 _processedSize;
+ UInt32 _bufferSize;
+ bool _wasFinished;
+
+ bool ReadBlock();
+ Byte ReadBlock2();
+
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ CInBuffer();
+ ~CInBuffer() { Free(); }
+
+ bool Create(UInt32 bufferSize);
+ void Free();
+
+ void SetStream(ISequentialInStream *stream);
+ void Init();
+ void ReleaseStream() { _stream.Release(); }
+
+ bool ReadByte(Byte &b)
+ {
+ if(_buffer >= _bufferLimit)
+ if(!ReadBlock())
+ return false;
+ b = *_buffer++;
+ return true;
+ }
+ Byte ReadByte()
+ {
+ if(_buffer >= _bufferLimit)
+ return ReadBlock2();
+ return *_buffer++;
+ }
+ void ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
+ {
+ for(processedSize = 0; processedSize < size; processedSize++)
+ if (!ReadByte(((Byte *)data)[processedSize]))
+ return;
+ }
+ bool ReadBytes(void *data, UInt32 size)
+ {
+ UInt32 processedSize;
+ ReadBytes(data, size, processedSize);
+ return (processedSize == size);
+ }
+ UInt64 GetProcessedSize() const { return _processedSize + (_buffer - _bufferBase); }
+ bool WasFinished() const { return _wasFinished; }
+};
+
+#endif
diff --git a/Source/7zip/7zip/Common/OutBuffer.cpp b/Source/7zip/7zip/Common/OutBuffer.cpp
index 09bed1b..2803a6a 100755
--- a/Source/7zip/7zip/Common/OutBuffer.cpp
+++ b/Source/7zip/7zip/Common/OutBuffer.cpp
@@ -1,131 +1,131 @@
-/*
- * OutBuffer.cpp
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "StdAfx.h"
-
-#include "OutBuffer.h"
-
-#include "../../Common/Alloc.h"
-
-bool COutBuffer::Create(UInt32 bufferSize)
-{
- const UInt32 kMinBlockSize = 1;
- if (bufferSize < kMinBlockSize)
- bufferSize = kMinBlockSize;
- if (_buffer != 0 && _bufferSize == bufferSize)
- return true;
- Free();
- _bufferSize = bufferSize;
- _buffer = (Byte *)::MidAlloc(bufferSize);
- return (_buffer != 0);
-}
-
-void COutBuffer::Free()
-{
- ::MidFree(_buffer);
- _buffer = 0;
-}
-
-void COutBuffer::SetStream(ISequentialOutStream *stream)
-{
- _stream = stream;
-}
-
-void COutBuffer::Init()
-{
- _streamPos = 0;
- _limitPos = _bufferSize;
- _pos = 0;
- _processedSize = 0;
- _overDict = false;
- #ifdef _NO_EXCEPTIONS
- ErrorCode = S_OK;
- #endif
-}
-
-UInt64 COutBuffer::GetProcessedSize() const
-{
- UInt64 res = _processedSize + _pos - _streamPos;
- if (_streamPos > _pos)
- res += _bufferSize;
- return res;
-}
-
-
-HRESULT COutBuffer::FlushPart()
-{
- // _streamPos < _bufferSize
- UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
- HRESULT result = S_OK;
- #ifdef _NO_EXCEPTIONS
- result = ErrorCode;
- #endif
- if (_buffer2 != 0)
- {
- memmove(_buffer2, _buffer + _streamPos, size);
- _buffer2 += size;
- }
-
- if (_stream != 0
- #ifdef _NO_EXCEPTIONS
- && (ErrorCode == S_OK)
- #endif
- )
- {
- UInt32 processedSize = 0;
- result = _stream->Write(_buffer + _streamPos, size, &processedSize);
- size = processedSize;
- }
- _streamPos += size;
- if (_streamPos == _bufferSize)
- _streamPos = 0;
- if (_pos == _bufferSize)
- {
- _overDict = true;
- _pos = 0;
- }
- _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
- _processedSize += size;
- return result;
-}
-
-HRESULT COutBuffer::Flush()
-{
- #ifdef _NO_EXCEPTIONS
- if (ErrorCode != S_OK)
- return ErrorCode;
- #endif
-
- while(_streamPos != _pos)
- {
- HRESULT result = FlushPart();
- if (result != S_OK)
- return result;
- }
- return S_OK;
-}
-
-void COutBuffer::FlushWithCheck()
-{
- HRESULT result = FlushPart();
- #ifdef _NO_EXCEPTIONS
- ErrorCode = result;
- #else
- if (result != S_OK)
- throw COutBufferException(result);
- #endif
-}
+/*
+ * OutBuffer.cpp
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "StdAfx.h"
+
+#include "OutBuffer.h"
+
+#include "../../Common/Alloc.h"
+
+bool COutBuffer::Create(UInt32 bufferSize)
+{
+ const UInt32 kMinBlockSize = 1;
+ if (bufferSize < kMinBlockSize)
+ bufferSize = kMinBlockSize;
+ if (_buffer != 0 && _bufferSize == bufferSize)
+ return true;
+ Free();
+ _bufferSize = bufferSize;
+ _buffer = (Byte *)::MidAlloc(bufferSize);
+ return (_buffer != 0);
+}
+
+void COutBuffer::Free()
+{
+ ::MidFree(_buffer);
+ _buffer = 0;
+}
+
+void COutBuffer::SetStream(ISequentialOutStream *stream)
+{
+ _stream = stream;
+}
+
+void COutBuffer::Init()
+{
+ _streamPos = 0;
+ _limitPos = _bufferSize;
+ _pos = 0;
+ _processedSize = 0;
+ _overDict = false;
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+UInt64 COutBuffer::GetProcessedSize() const
+{
+ UInt64 res = _processedSize + _pos - _streamPos;
+ if (_streamPos > _pos)
+ res += _bufferSize;
+ return res;
+}
+
+
+HRESULT COutBuffer::FlushPart()
+{
+ // _streamPos < _bufferSize
+ UInt32 size = (_streamPos >= _pos) ? (_bufferSize - _streamPos) : (_pos - _streamPos);
+ HRESULT result = S_OK;
+ #ifdef _NO_EXCEPTIONS
+ result = ErrorCode;
+ #endif
+ if (_buffer2 != 0)
+ {
+ memmove(_buffer2, _buffer + _streamPos, size);
+ _buffer2 += size;
+ }
+
+ if (_stream != 0
+ #ifdef _NO_EXCEPTIONS
+ && (ErrorCode == S_OK)
+ #endif
+ )
+ {
+ UInt32 processedSize = 0;
+ result = _stream->Write(_buffer + _streamPos, size, &processedSize);
+ size = processedSize;
+ }
+ _streamPos += size;
+ if (_streamPos == _bufferSize)
+ _streamPos = 0;
+ if (_pos == _bufferSize)
+ {
+ _overDict = true;
+ _pos = 0;
+ }
+ _limitPos = (_streamPos > _pos) ? _streamPos : _bufferSize;
+ _processedSize += size;
+ return result;
+}
+
+HRESULT COutBuffer::Flush()
+{
+ #ifdef _NO_EXCEPTIONS
+ if (ErrorCode != S_OK)
+ return ErrorCode;
+ #endif
+
+ while(_streamPos != _pos)
+ {
+ HRESULT result = FlushPart();
+ if (result != S_OK)
+ return result;
+ }
+ return S_OK;
+}
+
+void COutBuffer::FlushWithCheck()
+{
+ HRESULT result = FlushPart();
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = result;
+ #else
+ if (result != S_OK)
+ throw COutBufferException(result);
+ #endif
+}
diff --git a/Source/7zip/7zip/Common/OutBuffer.h b/Source/7zip/7zip/Common/OutBuffer.h
index 34915b7..851ef09 100755
--- a/Source/7zip/7zip/Common/OutBuffer.h
+++ b/Source/7zip/7zip/Common/OutBuffer.h
@@ -1,79 +1,79 @@
-/*
- * OutBuffer.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __OUTBUFFER_H
-#define __OUTBUFFER_H
-
-#include "../IStream.h"
-#include "../../Common/MyCom.h"
-
-#ifndef _NO_EXCEPTIONS
-struct COutBufferException
-{
- HRESULT ErrorCode;
- COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
-};
-#endif
-
-class COutBuffer
-{
-protected:
- Byte *_buffer;
- UInt32 _pos;
- UInt32 _limitPos;
- UInt32 _streamPos;
- UInt32 _bufferSize;
- CMyComPtr<ISequentialOutStream> _stream;
- UInt64 _processedSize;
- Byte *_buffer2;
- bool _overDict;
-
- HRESULT FlushPart();
- void FlushWithCheck();
-public:
- #ifdef _NO_EXCEPTIONS
- HRESULT ErrorCode;
- #endif
-
- COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
- ~COutBuffer() { Free(); }
-
- bool Create(UInt32 bufferSize);
- void Free();
-
- void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
- void SetStream(ISequentialOutStream *stream);
- void Init();
- HRESULT Flush();
- void ReleaseStream() { _stream.Release(); }
-
- void WriteByte(Byte b)
- {
- _buffer[_pos++] = b;
- if(_pos == _limitPos)
- FlushWithCheck();
- }
- void WriteBytes(const void *data, size_t size)
- {
- for (size_t i = 0; i < size; i++)
- WriteByte(((const Byte *)data)[i]);
- }
-
- UInt64 GetProcessedSize() const;
-};
-
-#endif
+/*
+ * OutBuffer.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __OUTBUFFER_H
+#define __OUTBUFFER_H
+
+#include "../IStream.h"
+#include "../../Common/MyCom.h"
+
+#ifndef _NO_EXCEPTIONS
+struct COutBufferException
+{
+ HRESULT ErrorCode;
+ COutBufferException(HRESULT errorCode): ErrorCode(errorCode) {}
+};
+#endif
+
+class COutBuffer
+{
+protected:
+ Byte *_buffer;
+ UInt32 _pos;
+ UInt32 _limitPos;
+ UInt32 _streamPos;
+ UInt32 _bufferSize;
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _processedSize;
+ Byte *_buffer2;
+ bool _overDict;
+
+ HRESULT FlushPart();
+ void FlushWithCheck();
+public:
+ #ifdef _NO_EXCEPTIONS
+ HRESULT ErrorCode;
+ #endif
+
+ COutBuffer(): _buffer(0), _pos(0), _stream(0), _buffer2(0) {}
+ ~COutBuffer() { Free(); }
+
+ bool Create(UInt32 bufferSize);
+ void Free();
+
+ void SetMemStream(Byte *buffer) { _buffer2 = buffer; }
+ void SetStream(ISequentialOutStream *stream);
+ void Init();
+ HRESULT Flush();
+ void ReleaseStream() { _stream.Release(); }
+
+ void WriteByte(Byte b)
+ {
+ _buffer[_pos++] = b;
+ if(_pos == _limitPos)
+ FlushWithCheck();
+ }
+ void WriteBytes(const void *data, size_t size)
+ {
+ for (size_t i = 0; i < size; i++)
+ WriteByte(((const Byte *)data)[i]);
+ }
+
+ UInt64 GetProcessedSize() const;
+};
+
+#endif
diff --git a/Source/7zip/7zip/Common/StdAfx.h b/Source/7zip/7zip/Common/StdAfx.h
index 8e1b1ea..2736abc 100755
--- a/Source/7zip/7zip/Common/StdAfx.h
+++ b/Source/7zip/7zip/Common/StdAfx.h
@@ -1,8 +1,8 @@
-// StdAfx.h
-
-#ifndef __STDAFX_H
-#define __STDAFX_H
-
-#include "../../Common/MyWindows.h"
-
-#endif
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../Common/MyWindows.h"
+
+#endif
diff --git a/Source/7zip/7zip/Common/StreamUtils.cpp b/Source/7zip/7zip/Common/StreamUtils.cpp
index ad77344..e072a67 100755
--- a/Source/7zip/7zip/Common/StreamUtils.cpp
+++ b/Source/7zip/7zip/Common/StreamUtils.cpp
@@ -1,59 +1,59 @@
-/*
- * StreamUtils.cpp
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "StdAfx.h"
-
-#include "../../Common/MyCom.h"
-#include "StreamUtils.h"
-
-HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize)
-{
- if (processedSize != 0)
- *processedSize = 0;
- while(size != 0)
- {
- UInt32 processedSizeLoc;
- HRESULT res = stream->Read(data, size, &processedSizeLoc);
- if (processedSize != 0)
- *processedSize += processedSizeLoc;
- data = (Byte *)((Byte *)data + processedSizeLoc);
- size -= processedSizeLoc;
- RINOK(res);
- if (processedSizeLoc == 0)
- return S_OK;
- }
- return S_OK;
-}
-
-HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize)
-{
- if (processedSize != 0)
- *processedSize = 0;
- while(size != 0)
- {
- UInt32 processedSizeLoc;
- HRESULT res = stream->Write(data, size, &processedSizeLoc);
- if (processedSize != 0)
- *processedSize += processedSizeLoc;
- data = (const void *)((const Byte *)data + processedSizeLoc);
- size -= processedSizeLoc;
- RINOK(res);
- if (processedSizeLoc == 0)
- break;
- }
- return S_OK;
-}
+/*
+ * StreamUtils.cpp
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "StdAfx.h"
+
+#include "../../Common/MyCom.h"
+#include "StreamUtils.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize != 0)
+ *processedSize = 0;
+ while(size != 0)
+ {
+ UInt32 processedSizeLoc;
+ HRESULT res = stream->Read(data, size, &processedSizeLoc);
+ if (processedSize != 0)
+ *processedSize += processedSizeLoc;
+ data = (Byte *)((Byte *)data + processedSizeLoc);
+ size -= processedSizeLoc;
+ RINOK(res);
+ if (processedSizeLoc == 0)
+ return S_OK;
+ }
+ return S_OK;
+}
+
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize)
+{
+ if (processedSize != 0)
+ *processedSize = 0;
+ while(size != 0)
+ {
+ UInt32 processedSizeLoc;
+ HRESULT res = stream->Write(data, size, &processedSizeLoc);
+ if (processedSize != 0)
+ *processedSize += processedSizeLoc;
+ data = (const void *)((const Byte *)data + processedSizeLoc);
+ size -= processedSizeLoc;
+ RINOK(res);
+ if (processedSizeLoc == 0)
+ break;
+ }
+ return S_OK;
+}
diff --git a/Source/7zip/7zip/Common/StreamUtils.h b/Source/7zip/7zip/Common/StreamUtils.h
index 58b8141..76cc8b2 100755
--- a/Source/7zip/7zip/Common/StreamUtils.h
+++ b/Source/7zip/7zip/Common/StreamUtils.h
@@ -1,26 +1,26 @@
-/*
- * StreamUtils.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __STREAMUTILS_H
-#define __STREAMUTILS_H
-
-#include "../IStream.h"
-
-HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize);
-HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize);
-
-#endif
+/*
+ * StreamUtils.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __STREAMUTILS_H
+#define __STREAMUTILS_H
+
+#include "../IStream.h"
+
+HRESULT ReadStream(ISequentialInStream *stream, void *data, UInt32 size, UInt32 *processedSize);
+HRESULT WriteStream(ISequentialOutStream *stream, const void *data, UInt32 size, UInt32 *processedSize);
+
+#endif
diff --git a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree.h b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree.h
index 186adab..c672b6b 100755
--- a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree.h
+++ b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree.h
@@ -1,69 +1,69 @@
-/*
- * BinTree.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "../LZInWindow.h"
-#include "../IMatchFinder.h"
-
-namespace BT_NAMESPACE {
-
-typedef UInt32 CIndex;
-const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1;
-
-class CMatchFinder:
- public IMatchFinder,
- public CLZInWindow,
- public CMyUnknownImp,
- public IMatchFinderSetNumPasses
-{
- UInt32 _cyclicBufferPos;
- UInt32 _cyclicBufferSize; // it must be historySize + 1
- UInt32 _matchMaxLen;
- CIndex *_hash;
- CIndex *_son;
- UInt32 _hashMask;
- UInt32 _cutValue;
- UInt32 _hashSizeSum;
-
- void Normalize();
- void FreeThisClassMemory();
- void FreeMemory();
-
- MY_UNKNOWN_IMP
-
- STDMETHOD(SetStream)(ISequentialInStream *inStream);
- STDMETHOD_(void, ReleaseStream)();
- STDMETHOD(Init)();
- HRESULT MovePos();
- STDMETHOD_(Byte, GetIndexByte)(Int32 index);
- STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit);
- STDMETHOD_(UInt32, GetNumAvailableBytes)();
- STDMETHOD_(const Byte *, GetPointerToCurrentPos)();
- STDMETHOD_(Int32, NeedChangeBufferPos)(UInt32 numCheckBytes);
- STDMETHOD_(void, ChangeBufferPos)();
-
- STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
- UInt32 matchMaxLen, UInt32 keepAddBufferAfter);
- STDMETHOD(GetMatches)(UInt32 *distances);
- STDMETHOD(Skip)(UInt32 num);
-
-public:
- CMatchFinder();
- virtual ~CMatchFinder();
- virtual void SetNumPasses(UInt32 numPasses) { _cutValue = numPasses; }
-};
-
-}
+/*
+ * BinTree.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "../LZInWindow.h"
+#include "../IMatchFinder.h"
+
+namespace BT_NAMESPACE {
+
+typedef UInt32 CIndex;
+const UInt32 kMaxValForNormalize = (UInt32(1) << 31) - 1;
+
+class CMatchFinder:
+ public IMatchFinder,
+ public CLZInWindow,
+ public CMyUnknownImp,
+ public IMatchFinderSetNumPasses
+{
+ UInt32 _cyclicBufferPos;
+ UInt32 _cyclicBufferSize; // it must be historySize + 1
+ UInt32 _matchMaxLen;
+ CIndex *_hash;
+ CIndex *_son;
+ UInt32 _hashMask;
+ UInt32 _cutValue;
+ UInt32 _hashSizeSum;
+
+ void Normalize();
+ void FreeThisClassMemory();
+ void FreeMemory();
+
+ MY_UNKNOWN_IMP
+
+ STDMETHOD(SetStream)(ISequentialInStream *inStream);
+ STDMETHOD_(void, ReleaseStream)();
+ STDMETHOD(Init)();
+ HRESULT MovePos();
+ STDMETHOD_(Byte, GetIndexByte)(Int32 index);
+ STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit);
+ STDMETHOD_(UInt32, GetNumAvailableBytes)();
+ STDMETHOD_(const Byte *, GetPointerToCurrentPos)();
+ STDMETHOD_(Int32, NeedChangeBufferPos)(UInt32 numCheckBytes);
+ STDMETHOD_(void, ChangeBufferPos)();
+
+ STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter);
+ STDMETHOD(GetMatches)(UInt32 *distances);
+ STDMETHOD(Skip)(UInt32 num);
+
+public:
+ CMatchFinder();
+ virtual ~CMatchFinder();
+ virtual void SetNumPasses(UInt32 numPasses) { _cutValue = numPasses; }
+};
+
+}
diff --git a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree2.h b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree2.h
index 2e2996a..0a7e559 100755
--- a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree2.h
+++ b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree2.h
@@ -1,27 +1,27 @@
-/*
- * BinTree2.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __BINTREE2_H
-#define __BINTREE2_H
-
-#define BT_NAMESPACE NBT2
-
-#include "BinTreeMain.h"
-
-#undef BT_NAMESPACE
-
-#endif
+/*
+ * BinTree2.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __BINTREE2_H
+#define __BINTREE2_H
+
+#define BT_NAMESPACE NBT2
+
+#include "BinTreeMain.h"
+
+#undef BT_NAMESPACE
+
+#endif
diff --git a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3.h b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3.h
index 6b5b116..9515b65 100755
--- a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3.h
+++ b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3.h
@@ -1,31 +1,31 @@
-/*
- * BinTree3.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __BINTREE3_H
-#define __BINTREE3_H
-
-#define BT_NAMESPACE NBT3
-
-#define HASH_ARRAY_2
-
-#include "BinTreeMain.h"
-
-#undef HASH_ARRAY_2
-
-#undef BT_NAMESPACE
-
-#endif
+/*
+ * BinTree3.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __BINTREE3_H
+#define __BINTREE3_H
+
+#define BT_NAMESPACE NBT3
+
+#define HASH_ARRAY_2
+
+#include "BinTreeMain.h"
+
+#undef HASH_ARRAY_2
+
+#undef BT_NAMESPACE
+
+#endif
diff --git a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3Z.h b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3Z.h
index f21cdbd..97d0175 100755
--- a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3Z.h
+++ b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3Z.h
@@ -1,31 +1,31 @@
-/*
- * BinTree3Z.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __BINTREE3Z_H
-#define __BINTREE3Z_H
-
-#define BT_NAMESPACE NBT3Z
-
-#define HASH_ZIP
-
-#include "BinTreeMain.h"
-
-#undef HASH_ZIP
-
-#undef BT_NAMESPACE
-
-#endif
+/*
+ * BinTree3Z.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __BINTREE3Z_H
+#define __BINTREE3Z_H
+
+#define BT_NAMESPACE NBT3Z
+
+#define HASH_ZIP
+
+#include "BinTreeMain.h"
+
+#undef HASH_ZIP
+
+#undef BT_NAMESPACE
+
+#endif
diff --git a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3ZMain.h b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3ZMain.h
index 15a786c..bb5425b 100755
--- a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3ZMain.h
+++ b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree3ZMain.h
@@ -1,31 +1,31 @@
-/*
- * BinTree3ZMain.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __BINTREE3ZMAIN__H
-#define __BINTREE3ZMAIN__H
-
-#undef BT_NAMESPACE
-#define BT_NAMESPACE NBT3Z
-
-#define HASH_ZIP
-
-#include "BinTreeMain.h"
-
-#undef HASH_ZIP
-
-#endif
-
+/*
+ * BinTree3ZMain.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __BINTREE3ZMAIN__H
+#define __BINTREE3ZMAIN__H
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT3Z
+
+#define HASH_ZIP
+
+#include "BinTreeMain.h"
+
+#undef HASH_ZIP
+
+#endif
+
diff --git a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree4.h b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree4.h
index 1b215a3..9339f1f 100755
--- a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree4.h
+++ b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree4.h
@@ -1,33 +1,33 @@
-/*
- * BinTree4.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __BINTREE4_H
-#define __BINTREE4_H
-
-#define BT_NAMESPACE NBT4
-
-#define HASH_ARRAY_2
-#define HASH_ARRAY_3
-
-#include "BinTreeMain.h"
-
-#undef HASH_ARRAY_2
-#undef HASH_ARRAY_3
-
-#undef BT_NAMESPACE
-
-#endif
+/*
+ * BinTree4.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __BINTREE4_H
+#define __BINTREE4_H
+
+#define BT_NAMESPACE NBT4
+
+#define HASH_ARRAY_2
+#define HASH_ARRAY_3
+
+#include "BinTreeMain.h"
+
+#undef HASH_ARRAY_2
+#undef HASH_ARRAY_3
+
+#undef BT_NAMESPACE
+
+#endif
diff --git a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree4b.h b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree4b.h
index e7c23ca..6dea0da 100755
--- a/Source/7zip/7zip/Compress/LZ/BinTree/BinTree4b.h
+++ b/Source/7zip/7zip/Compress/LZ/BinTree/BinTree4b.h
@@ -1,39 +1,39 @@
-/*
- * BinTreeb.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __BINTREE4B__H
-#define __BINTREE4B__H
-
-#undef BT_CLSID
-#define BT_CLSID CLSID_CMatchFinderBT4b
-
-#undef BT_NAMESPACE
-#define BT_NAMESPACE NBT4B
-
-#define HASH_ARRAY_2
-#define HASH_ARRAY_3
-#define HASH_BIG
-
-#include "BinTreeMF.h"
-#include "BinTreeMFMain.h"
-
-#undef HASH_ARRAY_2
-#undef HASH_ARRAY_3
-#undef HASH_BIG
-
-#endif
-
+/*
+ * BinTreeb.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __BINTREE4B__H
+#define __BINTREE4B__H
+
+#undef BT_CLSID
+#define BT_CLSID CLSID_CMatchFinderBT4b
+
+#undef BT_NAMESPACE
+#define BT_NAMESPACE NBT4B
+
+#define HASH_ARRAY_2
+#define HASH_ARRAY_3
+#define HASH_BIG
+
+#include "BinTreeMF.h"
+#include "BinTreeMFMain.h"
+
+#undef HASH_ARRAY_2
+#undef HASH_ARRAY_3
+#undef HASH_BIG
+
+#endif
+
diff --git a/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMF.h b/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMF.h
index 12b70f3..47e6099 100755
--- a/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMF.h
+++ b/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMF.h
@@ -1,119 +1,119 @@
-/*
- * BinTreeMF.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-// #ifndef __BINTREEMF_H
-// #define __BINTREEMF_H
-
-#include "../../../ICoder.h"
-#include "BinTree.h"
-
-namespace BT_NAMESPACE {
-
-#undef kIDByte
-#undef kIDString
-
-#ifdef HASH_ARRAY_2
- #ifdef HASH_ARRAY_3
- #ifdef HASH_BIG
- #define kIDByte 0x4
- #define kIDString TEXT("4b")
- #else
- #define kIDByte 0x3
- #define kIDString TEXT("4")
- #endif
- #else
- #define kIDByte 0x2
- #define kIDString TEXT("3")
- #endif
-#else
- #ifdef HASH_ZIP
- #define kIDByte 0x0
- #define kIDString TEXT("3Z")
- #else
- #define kIDByte 0x1
- #define kIDString TEXT("2")
- #endif
-#endif
-
-#undef kIDUse3BytesByte
-#undef kIDUse3BytesString
-
-#define kIDUse3BytesByte 0x00
-#define kIDUse3BytesString TEXT("")
-
-// #undef kIDStringFull
-
-// #define kIDStringFull TEXT("Compress.MatchFinderBT") kIDString kIDUse3BytesString
-
-// {23170F69-40C1-278C-02XX-0000000000}
-DEFINE_GUID(BT_CLSID,
-0x23170F69, 0x40C1, 0x278C, 0x02, kIDByte | kIDUse3BytesByte,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
-
-class CInTree2: public CInTree
-{
- CMyComPtr<IMatchFinderCallback> _callback;
- virtual void BeforeMoveBlock();
- virtual void AfterMoveBlock();
-public:
- void SetCallback(IMatchFinderCallback *callback)
- {
- _callback = callback;
- }
-};
-
-class CMatchFinderBinTree:
- public IMatchFinder,
- public IMatchFinderSetCallback,
- public CMyUnknownImp
-{
- MY_UNKNOWN_IMP1(IMatchFinderSetCallback)
-
- STDMETHOD(Init)(ISequentialInStream *stream);
- STDMETHOD_(void, ReleaseStream)();
- STDMETHOD(MovePos)();
- STDMETHOD_(Byte, GetIndexByte)(Int32 index);
- STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit);
- STDMETHOD_(UInt32, GetNumAvailableBytes)();
- STDMETHOD_(const Byte *, GetPointerToCurrentPos)();
- STDMETHOD(Create)(UInt32 sizeHistory,
- UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
- UInt32 keepAddBufferAfter);
- STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances);
- STDMETHOD_(void, DummyLongestMatch)();
-
- // IMatchFinderSetCallback
- STDMETHOD(SetCallback)(IMatchFinderCallback *callback);
-
-private:
- // UInt32 m_WindowReservSize;
- CInTree2 _matchFinder;
-public:
- // CMatchFinderBinTree(): m_WindowReservSize((1 << 19) + 256) {};
- void SetCutValue(UInt32 cutValue)
- { _matchFinder.SetCutValue(cutValue); }
- /*
- void SetWindowReservSize(UInt32 reservWindowSize)
- { m_WindowReservSize = reservWindowSize; }
- */
- virtual ~CMatchFinderBinTree() {}
-};
-
-}
-
-// #endif
-
+/*
+ * BinTreeMF.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+// #ifndef __BINTREEMF_H
+// #define __BINTREEMF_H
+
+#include "../../../ICoder.h"
+#include "BinTree.h"
+
+namespace BT_NAMESPACE {
+
+#undef kIDByte
+#undef kIDString
+
+#ifdef HASH_ARRAY_2
+ #ifdef HASH_ARRAY_3
+ #ifdef HASH_BIG
+ #define kIDByte 0x4
+ #define kIDString TEXT("4b")
+ #else
+ #define kIDByte 0x3
+ #define kIDString TEXT("4")
+ #endif
+ #else
+ #define kIDByte 0x2
+ #define kIDString TEXT("3")
+ #endif
+#else
+ #ifdef HASH_ZIP
+ #define kIDByte 0x0
+ #define kIDString TEXT("3Z")
+ #else
+ #define kIDByte 0x1
+ #define kIDString TEXT("2")
+ #endif
+#endif
+
+#undef kIDUse3BytesByte
+#undef kIDUse3BytesString
+
+#define kIDUse3BytesByte 0x00
+#define kIDUse3BytesString TEXT("")
+
+// #undef kIDStringFull
+
+// #define kIDStringFull TEXT("Compress.MatchFinderBT") kIDString kIDUse3BytesString
+
+// {23170F69-40C1-278C-02XX-0000000000}
+DEFINE_GUID(BT_CLSID,
+0x23170F69, 0x40C1, 0x278C, 0x02, kIDByte | kIDUse3BytesByte,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+
+class CInTree2: public CInTree
+{
+ CMyComPtr<IMatchFinderCallback> _callback;
+ virtual void BeforeMoveBlock();
+ virtual void AfterMoveBlock();
+public:
+ void SetCallback(IMatchFinderCallback *callback)
+ {
+ _callback = callback;
+ }
+};
+
+class CMatchFinderBinTree:
+ public IMatchFinder,
+ public IMatchFinderSetCallback,
+ public CMyUnknownImp
+{
+ MY_UNKNOWN_IMP1(IMatchFinderSetCallback)
+
+ STDMETHOD(Init)(ISequentialInStream *stream);
+ STDMETHOD_(void, ReleaseStream)();
+ STDMETHOD(MovePos)();
+ STDMETHOD_(Byte, GetIndexByte)(Int32 index);
+ STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 back, UInt32 limit);
+ STDMETHOD_(UInt32, GetNumAvailableBytes)();
+ STDMETHOD_(const Byte *, GetPointerToCurrentPos)();
+ STDMETHOD(Create)(UInt32 sizeHistory,
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
+ UInt32 keepAddBufferAfter);
+ STDMETHOD_(UInt32, GetLongestMatch)(UInt32 *distances);
+ STDMETHOD_(void, DummyLongestMatch)();
+
+ // IMatchFinderSetCallback
+ STDMETHOD(SetCallback)(IMatchFinderCallback *callback);
+
+private:
+ // UInt32 m_WindowReservSize;
+ CInTree2 _matchFinder;
+public:
+ // CMatchFinderBinTree(): m_WindowReservSize((1 << 19) + 256) {};
+ void SetCutValue(UInt32 cutValue)
+ { _matchFinder.SetCutValue(cutValue); }
+ /*
+ void SetWindowReservSize(UInt32 reservWindowSize)
+ { m_WindowReservSize = reservWindowSize; }
+ */
+ virtual ~CMatchFinderBinTree() {}
+};
+
+}
+
+// #endif
+
diff --git a/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMFMain.h b/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMFMain.h
index f72a89e..5b4d979 100755
--- a/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMFMain.h
+++ b/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMFMain.h
@@ -1,98 +1,98 @@
-/*
- * BinTreeMFMain.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-// #include "StdAfx.h"
-
-// #include "BinTreeMF.h"
-#include "BinTreeMain.h"
-
-namespace BT_NAMESPACE {
-
-void CInTree2::BeforeMoveBlock()
-{
- if (_callback)
- _callback->BeforeChangingBufferPos();
- CInTree::BeforeMoveBlock();
-}
-
-void CInTree2::AfterMoveBlock()
-{
- CInTree::AfterMoveBlock();
- if (_callback)
- _callback->AfterChangingBufferPos();
-}
-
-STDMETHODIMP CMatchFinderBinTree::Init(ISequentialInStream *stream)
- { return _matchFinder.Init(stream); }
-
-STDMETHODIMP_(void) CMatchFinderBinTree::ReleaseStream()
-{
- // _matchFinder.ReleaseStream();
-}
-
-STDMETHODIMP CMatchFinderBinTree::MovePos()
- { return _matchFinder.MovePos(); }
-
-STDMETHODIMP_(Byte) CMatchFinderBinTree::GetIndexByte(Int32 index)
- { return _matchFinder.GetIndexByte(index); }
-
-STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetMatchLen(Int32 index,
- UInt32 back, UInt32 limit)
- { return _matchFinder.GetMatchLen(index, back, limit); }
-
-STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetNumAvailableBytes()
- { return _matchFinder.GetNumAvailableBytes(); }
-
-STDMETHODIMP CMatchFinderBinTree::Create(UInt32 sizeHistory,
- UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
- UInt32 keepAddBufferAfter)
-{
- UInt32 windowReservSize = (sizeHistory + keepAddBufferBefore +
- matchMaxLen + keepAddBufferAfter) / 2 + 256;
- // try
- {
- return _matchFinder.Create(sizeHistory, keepAddBufferBefore,
- matchMaxLen, keepAddBufferAfter, windowReservSize);
- }
- /*
- catch(...)
- {
- return E_OUTOFMEMORY;
- }
- */
-}
-
-STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetLongestMatch(UInt32 *distances)
- { return _matchFinder.GetLongestMatch(distances); }
-
-STDMETHODIMP_(void) CMatchFinderBinTree::DummyLongestMatch()
- { _matchFinder.DummyLongestMatch(); }
-
-STDMETHODIMP_(const Byte *) CMatchFinderBinTree::GetPointerToCurrentPos()
-{
- return _matchFinder.GetPointerToCurrentPos();
-}
-
-// IMatchFinderSetCallback
-STDMETHODIMP CMatchFinderBinTree::SetCallback(IMatchFinderCallback *callback)
-{
- _matchFinder.SetCallback(callback);
- return S_OK;
-}
-
-
-}
+/*
+ * BinTreeMFMain.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+// #include "StdAfx.h"
+
+// #include "BinTreeMF.h"
+#include "BinTreeMain.h"
+
+namespace BT_NAMESPACE {
+
+void CInTree2::BeforeMoveBlock()
+{
+ if (_callback)
+ _callback->BeforeChangingBufferPos();
+ CInTree::BeforeMoveBlock();
+}
+
+void CInTree2::AfterMoveBlock()
+{
+ CInTree::AfterMoveBlock();
+ if (_callback)
+ _callback->AfterChangingBufferPos();
+}
+
+STDMETHODIMP CMatchFinderBinTree::Init(ISequentialInStream *stream)
+ { return _matchFinder.Init(stream); }
+
+STDMETHODIMP_(void) CMatchFinderBinTree::ReleaseStream()
+{
+ // _matchFinder.ReleaseStream();
+}
+
+STDMETHODIMP CMatchFinderBinTree::MovePos()
+ { return _matchFinder.MovePos(); }
+
+STDMETHODIMP_(Byte) CMatchFinderBinTree::GetIndexByte(Int32 index)
+ { return _matchFinder.GetIndexByte(index); }
+
+STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetMatchLen(Int32 index,
+ UInt32 back, UInt32 limit)
+ { return _matchFinder.GetMatchLen(index, back, limit); }
+
+STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetNumAvailableBytes()
+ { return _matchFinder.GetNumAvailableBytes(); }
+
+STDMETHODIMP CMatchFinderBinTree::Create(UInt32 sizeHistory,
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen,
+ UInt32 keepAddBufferAfter)
+{
+ UInt32 windowReservSize = (sizeHistory + keepAddBufferBefore +
+ matchMaxLen + keepAddBufferAfter) / 2 + 256;
+ // try
+ {
+ return _matchFinder.Create(sizeHistory, keepAddBufferBefore,
+ matchMaxLen, keepAddBufferAfter, windowReservSize);
+ }
+ /*
+ catch(...)
+ {
+ return E_OUTOFMEMORY;
+ }
+ */
+}
+
+STDMETHODIMP_(UInt32) CMatchFinderBinTree::GetLongestMatch(UInt32 *distances)
+ { return _matchFinder.GetLongestMatch(distances); }
+
+STDMETHODIMP_(void) CMatchFinderBinTree::DummyLongestMatch()
+ { _matchFinder.DummyLongestMatch(); }
+
+STDMETHODIMP_(const Byte *) CMatchFinderBinTree::GetPointerToCurrentPos()
+{
+ return _matchFinder.GetPointerToCurrentPos();
+}
+
+// IMatchFinderSetCallback
+STDMETHODIMP CMatchFinderBinTree::SetCallback(IMatchFinderCallback *callback)
+{
+ _matchFinder.SetCallback(callback);
+ return S_OK;
+}
+
+
+}
diff --git a/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMain.h b/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMain.h
index ed161c3..486165c 100755
--- a/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMain.h
+++ b/Source/7zip/7zip/Compress/LZ/BinTree/BinTreeMain.h
@@ -1,546 +1,546 @@
-/*
- * BinTreeMain.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "../../../../Common/Defs.h"
-#include "../../../../Common/CRC.h"
-#include "../../../../Common/Alloc.h"
-
-#include "BinTree.h"
-
-// #include <xmmintrin.h>
-// It's for prefetch
-// But prefetch doesn't give big gain in K8.
-
-namespace BT_NAMESPACE {
-
-#ifdef HASH_ARRAY_2
- static const UInt32 kHash2Size = 1 << 10;
- #define kNumHashDirectBytes 0
- #ifdef HASH_ARRAY_3
- static const UInt32 kNumHashBytes = 4;
- static const UInt32 kHash3Size = 1 << 16;
- #else
- static const UInt32 kNumHashBytes = 3;
- #endif
- static const UInt32 kHashSize = 0;
- static const UInt32 kMinMatchCheck = kNumHashBytes;
- static const UInt32 kStartMaxLen = 1;
-#else
- #ifdef HASH_ZIP
- #define kNumHashDirectBytes 0
- static const UInt32 kNumHashBytes = 3;
- static const UInt32 kHashSize = 1 << 16;
- static const UInt32 kMinMatchCheck = kNumHashBytes;
- static const UInt32 kStartMaxLen = 1;
- #else
- #define kNumHashDirectBytes 2
- static const UInt32 kNumHashBytes = 2;
- static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
- static const UInt32 kMinMatchCheck = kNumHashBytes + 1;
- static const UInt32 kStartMaxLen = 1;
- #endif
-#endif
-
-#ifdef HASH_ARRAY_2
-#ifdef HASH_ARRAY_3
-static const UInt32 kHash3Offset = kHash2Size;
-#endif
-#endif
-
-static const UInt32 kFixHashSize = 0
- #ifdef HASH_ARRAY_2
- + kHash2Size
- #ifdef HASH_ARRAY_3
- + kHash3Size
- #endif
- #endif
- ;
-
-CMatchFinder::CMatchFinder():
- _hash(0)
-{
-}
-
-void CMatchFinder::FreeThisClassMemory()
-{
- BigFree(_hash);
- _hash = 0;
-}
-
-void CMatchFinder::FreeMemory()
-{
- FreeThisClassMemory();
- CLZInWindow::Free();
-}
-
-CMatchFinder::~CMatchFinder()
-{
- FreeMemory();
-}
-
-STDMETHODIMP CMatchFinder::Create(UInt32 historySize, UInt32 keepAddBufferBefore,
- UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
-{
- if (historySize > kMaxValForNormalize - 256)
- {
- FreeMemory();
- return E_INVALIDARG;
- }
- _cutValue =
- #ifdef _HASH_CHAIN
- 8 + (matchMaxLen >> 2);
- #else
- 16 + (matchMaxLen >> 1);
- #endif
- UInt32 sizeReserv = (historySize + keepAddBufferBefore +
- matchMaxLen + keepAddBufferAfter) / 2 + 256;
- if (CLZInWindow::Create(historySize + keepAddBufferBefore,
- matchMaxLen + keepAddBufferAfter, sizeReserv))
- {
- _matchMaxLen = matchMaxLen;
- UInt32 newCyclicBufferSize = historySize + 1;
- if (_hash != 0 && newCyclicBufferSize == _cyclicBufferSize)
- return S_OK;
- FreeThisClassMemory();
- _cyclicBufferSize = newCyclicBufferSize; // don't change it
-
- UInt32 hs = kHashSize;
-
- #ifdef HASH_ARRAY_2
- hs = historySize - 1;
- hs |= (hs >> 1);
- hs |= (hs >> 2);
- hs |= (hs >> 4);
- hs |= (hs >> 8);
- hs >>= 1;
- hs |= 0xFFFF;
- if (hs > (1 << 24))
- {
- #ifdef HASH_ARRAY_3
- hs >>= 1;
- #else
- hs = (1 << 24) - 1;
- #endif
- }
- _hashMask = hs;
- hs++;
- #endif
- _hashSizeSum = hs + kFixHashSize;
- UInt32 numItems = _hashSizeSum + _cyclicBufferSize
- #ifndef _HASH_CHAIN
- * 2
- #endif
- ;
- size_t sizeInBytes = (size_t)numItems * sizeof(CIndex);
- if (sizeInBytes / sizeof(CIndex) != numItems)
- return E_OUTOFMEMORY;
- _hash = (CIndex *)BigAlloc(sizeInBytes);
- _son = _hash + _hashSizeSum;
- if (_hash != 0)
- return S_OK;
- }
- FreeMemory();
- return E_OUTOFMEMORY;
-}
-
-static const UInt32 kEmptyHashValue = 0;
-
-STDMETHODIMP CMatchFinder::SetStream(ISequentialInStream *stream)
-{
- CLZInWindow::SetStream(stream);
- return S_OK;
-}
-
-STDMETHODIMP CMatchFinder::Init()
-{
- RINOK(CLZInWindow::Init());
- for(UInt32 i = 0; i < _hashSizeSum; i++)
- _hash[i] = kEmptyHashValue;
- _cyclicBufferPos = 0;
- ReduceOffsets(-1);
- return S_OK;
-}
-
-STDMETHODIMP_(void) CMatchFinder::ReleaseStream()
-{
- // ReleaseStream();
-}
-
-#ifdef HASH_ARRAY_2
-#ifdef HASH_ARRAY_3
-
-#define HASH_CALC { \
- UInt32 temp = CCRC::Table[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hash3Value = (temp ^ (UInt32(cur[2]) << 8)) & (kHash3Size - 1); \
- hashValue = (temp ^ (UInt32(cur[2]) << 8) ^ (CCRC::Table[cur[3]] << 5)) & _hashMask; }
-
-#else // no HASH_ARRAY_3
-#define HASH_CALC { \
- UInt32 temp = CCRC::Table[cur[0]] ^ cur[1]; \
- hash2Value = temp & (kHash2Size - 1); \
- hashValue = (temp ^ (UInt32(cur[2]) << 8)) & _hashMask; }
-#endif // HASH_ARRAY_3
-#else // no HASH_ARRAY_2
-#ifdef HASH_ZIP
-inline UInt32 Hash(const Byte *pointer)
-{
- return ((UInt32(pointer[0]) << 8) ^ CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1);
-}
-#else // no HASH_ZIP
-inline UInt32 Hash(const Byte *pointer)
-{
- return pointer[0] ^ (UInt32(pointer[1]) << 8);
-}
-#endif // HASH_ZIP
-#endif // HASH_ARRAY_2
-
-STDMETHODIMP CMatchFinder::GetMatches(UInt32 *distances)
-{
- UInt32 lenLimit;
- if (_pos + _matchMaxLen <= _streamPos)
- lenLimit = _matchMaxLen;
- else
- {
- lenLimit = _streamPos - _pos;
- if(lenLimit < kMinMatchCheck)
- {
- distances[0] = 0;
- return MovePos();
- }
- }
-
- int offset = 1;
-
- UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
- const Byte *cur = _buffer + _pos;
-
- UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize;
-
- #ifdef HASH_ARRAY_2
- UInt32 hash2Value;
- #ifdef HASH_ARRAY_3
- UInt32 hash3Value;
- #endif
- UInt32 hashValue;
- HASH_CALC;
- #else
- UInt32 hashValue = Hash(cur);
- #endif
-
- UInt32 curMatch = _hash[kFixHashSize + hashValue];
- #ifdef HASH_ARRAY_2
- UInt32 curMatch2 = _hash[hash2Value];
- #ifdef HASH_ARRAY_3
- UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];
- #endif
- _hash[hash2Value] = _pos;
- if(curMatch2 > matchMinPos)
- if (_buffer[curMatch2] == cur[0])
- {
- distances[offset++] = maxLen = 2;
- distances[offset++] = _pos - curMatch2 - 1;
- }
-
- #ifdef HASH_ARRAY_3
- _hash[kHash3Offset + hash3Value] = _pos;
- if(curMatch3 > matchMinPos)
- if (_buffer[curMatch3] == cur[0])
- {
- if (curMatch3 == curMatch2)
- offset -= 2;
- distances[offset++] = maxLen = 3;
- distances[offset++] = _pos - curMatch3 - 1;
- curMatch2 = curMatch3;
- }
- #endif
- if (offset != 1 && curMatch2 == curMatch)
- {
- offset -= 2;
- maxLen = kStartMaxLen;
- }
- #endif
-
- _hash[kFixHashSize + hashValue] = _pos;
-
- CIndex *son = _son;
-
- #ifdef _HASH_CHAIN
- son[_cyclicBufferPos] = curMatch;
- #else
- CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1;
- CIndex *ptr1 = son + (_cyclicBufferPos << 1);
-
- UInt32 len0, len1;
- len0 = len1 = kNumHashDirectBytes;
- #endif
-
- #if kNumHashDirectBytes != 0
- if(curMatch > matchMinPos)
- {
- if (_buffer[curMatch + kNumHashDirectBytes] != cur[kNumHashDirectBytes])
- {
- distances[offset++] = maxLen = kNumHashDirectBytes;
- distances[offset++] = _pos - curMatch - 1;
- }
- }
- #endif
- UInt32 count = _cutValue;
- while(true)
- {
- if(curMatch <= matchMinPos || count-- == 0)
- {
- #ifndef _HASH_CHAIN
- *ptr0 = *ptr1 = kEmptyHashValue;
- #endif
- break;
- }
- UInt32 delta = _pos - curMatch;
- UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
- (_cyclicBufferPos - delta):
- (_cyclicBufferPos - delta + _cyclicBufferSize);
- CIndex *pair = son +
- #ifdef _HASH_CHAIN
- cyclicPos;
- #else
- (cyclicPos << 1);
- #endif
-
- // _mm_prefetch((const char *)pair, _MM_HINT_T0);
-
- const Byte *pb = _buffer + curMatch;
- UInt32 len =
- #ifdef _HASH_CHAIN
- kNumHashDirectBytes;
- if (pb[maxLen] == cur[maxLen])
- #else
- MyMin(len0, len1);
- #endif
- if (pb[len] == cur[len])
- {
- while(++len != lenLimit)
- if (pb[len] != cur[len])
- break;
- if (maxLen < len)
- {
- distances[offset++] = maxLen = len;
- distances[offset++] = delta - 1;
- if (len == lenLimit)
- {
- #ifndef _HASH_CHAIN
- *ptr1 = pair[0];
- *ptr0 = pair[1];
- #endif
- break;
- }
- }
- }
- #ifdef _HASH_CHAIN
- curMatch = *pair;
- #else
- if (pb[len] < cur[len])
- {
- *ptr1 = curMatch;
- ptr1 = pair + 1;
- curMatch = *ptr1;
- len1 = len;
- }
- else
- {
- *ptr0 = curMatch;
- ptr0 = pair;
- curMatch = *ptr0;
- len0 = len;
- }
- #endif
- }
- distances[0] = offset - 1;
- if (++_cyclicBufferPos == _cyclicBufferSize)
- _cyclicBufferPos = 0;
- RINOK(CLZInWindow::MovePos());
- if (_pos == kMaxValForNormalize)
- Normalize();
- return S_OK;
-}
-
-STDMETHODIMP CMatchFinder::Skip(UInt32 num)
-{
- do
- {
- #ifdef _HASH_CHAIN
- if (_streamPos - _pos < kNumHashBytes)
- {
- RINOK(MovePos());
- continue;
- }
- #else
- UInt32 lenLimit;
- if (_pos + _matchMaxLen <= _streamPos)
- lenLimit = _matchMaxLen;
- else
- {
- lenLimit = _streamPos - _pos;
- if(lenLimit < kMinMatchCheck)
- {
- RINOK(MovePos());
- continue;
- }
- }
- UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
- #endif
- const Byte *cur = _buffer + _pos;
-
- #ifdef HASH_ARRAY_2
- UInt32 hash2Value;
- #ifdef HASH_ARRAY_3
- UInt32 hash3Value;
- UInt32 hashValue;
- HASH_CALC;
- _hash[kHash3Offset + hash3Value] = _pos;
- #else
- UInt32 hashValue;
- HASH_CALC;
- #endif
- _hash[hash2Value] = _pos;
- #else
- UInt32 hashValue = Hash(cur);
- #endif
-
- UInt32 curMatch = _hash[kFixHashSize + hashValue];
- _hash[kFixHashSize + hashValue] = _pos;
-
- #ifdef _HASH_CHAIN
- _son[_cyclicBufferPos] = curMatch;
- #else
- CIndex *son = _son;
- CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1;
- CIndex *ptr1 = son + (_cyclicBufferPos << 1);
-
- UInt32 len0, len1;
- len0 = len1 = kNumHashDirectBytes;
- UInt32 count = _cutValue;
- while(true)
- {
- if(curMatch <= matchMinPos || count-- == 0)
- {
- *ptr0 = *ptr1 = kEmptyHashValue;
- break;
- }
-
- UInt32 delta = _pos - curMatch;
- UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
- (_cyclicBufferPos - delta):
- (_cyclicBufferPos - delta + _cyclicBufferSize);
- CIndex *pair = son + (cyclicPos << 1);
-
- // _mm_prefetch((const char *)pair, _MM_HINT_T0);
-
- const Byte *pb = _buffer + curMatch;
- UInt32 len = MyMin(len0, len1);
-
- if (pb[len] == cur[len])
- {
- while(++len != lenLimit)
- if (pb[len] != cur[len])
- break;
- if (len == lenLimit)
- {
- *ptr1 = pair[0];
- *ptr0 = pair[1];
- break;
- }
- }
- if (pb[len] < cur[len])
- {
- *ptr1 = curMatch;
- ptr1 = pair + 1;
- curMatch = *ptr1;
- len1 = len;
- }
- else
- {
- *ptr0 = curMatch;
- ptr0 = pair;
- curMatch = *ptr0;
- len0 = len;
- }
- }
- #endif
- if (++_cyclicBufferPos == _cyclicBufferSize)
- _cyclicBufferPos = 0;
- RINOK(CLZInWindow::MovePos());
- if (_pos == kMaxValForNormalize)
- Normalize();
- }
- while(--num != 0);
- return S_OK;
-}
-
-void CMatchFinder::Normalize()
-{
- UInt32 subValue = _pos - _cyclicBufferSize;
- CIndex *items = _hash;
- UInt32 numItems = (_hashSizeSum + _cyclicBufferSize
- #ifndef _HASH_CHAIN
- * 2
- #endif
- );
- for (UInt32 i = 0; i < numItems; i++)
- {
- UInt32 value = items[i];
- if (value <= subValue)
- value = kEmptyHashValue;
- else
- value -= subValue;
- items[i] = value;
- }
- ReduceOffsets(subValue);
-}
-
-HRESULT CMatchFinder::MovePos()
-{
- if (++_cyclicBufferPos == _cyclicBufferSize)
- _cyclicBufferPos = 0;
- RINOK(CLZInWindow::MovePos());
- if (_pos == kMaxValForNormalize)
- Normalize();
- return S_OK;
-}
-
-STDMETHODIMP_(Byte) CMatchFinder::GetIndexByte(Int32 index)
- { return CLZInWindow::GetIndexByte(index); }
-
-STDMETHODIMP_(UInt32) CMatchFinder::GetMatchLen(Int32 index,
- UInt32 back, UInt32 limit)
- { return CLZInWindow::GetMatchLen(index, back, limit); }
-
-STDMETHODIMP_(UInt32) CMatchFinder::GetNumAvailableBytes()
- { return CLZInWindow::GetNumAvailableBytes(); }
-
-STDMETHODIMP_(const Byte *) CMatchFinder::GetPointerToCurrentPos()
- { return CLZInWindow::GetPointerToCurrentPos(); }
-
-STDMETHODIMP_(Int32) CMatchFinder::NeedChangeBufferPos(UInt32 numCheckBytes)
- { return CLZInWindow::NeedMove(numCheckBytes) ? 1: 0; }
-
-STDMETHODIMP_(void) CMatchFinder::ChangeBufferPos()
- { CLZInWindow::MoveBlock();}
-
-#undef HASH_CALC
-#undef kNumHashDirectBytes
-
-}
+/*
+ * BinTreeMain.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "../../../../Common/Defs.h"
+#include "../../../../Common/CRC.h"
+#include "../../../../Common/Alloc.h"
+
+#include "BinTree.h"
+
+// #include <xmmintrin.h>
+// It's for prefetch
+// But prefetch doesn't give big gain in K8.
+
+namespace BT_NAMESPACE {
+
+#ifdef HASH_ARRAY_2
+ static const UInt32 kHash2Size = 1 << 10;
+ #define kNumHashDirectBytes 0
+ #ifdef HASH_ARRAY_3
+ static const UInt32 kNumHashBytes = 4;
+ static const UInt32 kHash3Size = 1 << 16;
+ #else
+ static const UInt32 kNumHashBytes = 3;
+ #endif
+ static const UInt32 kHashSize = 0;
+ static const UInt32 kMinMatchCheck = kNumHashBytes;
+ static const UInt32 kStartMaxLen = 1;
+#else
+ #ifdef HASH_ZIP
+ #define kNumHashDirectBytes 0
+ static const UInt32 kNumHashBytes = 3;
+ static const UInt32 kHashSize = 1 << 16;
+ static const UInt32 kMinMatchCheck = kNumHashBytes;
+ static const UInt32 kStartMaxLen = 1;
+ #else
+ #define kNumHashDirectBytes 2
+ static const UInt32 kNumHashBytes = 2;
+ static const UInt32 kHashSize = 1 << (8 * kNumHashBytes);
+ static const UInt32 kMinMatchCheck = kNumHashBytes + 1;
+ static const UInt32 kStartMaxLen = 1;
+ #endif
+#endif
+
+#ifdef HASH_ARRAY_2
+#ifdef HASH_ARRAY_3
+static const UInt32 kHash3Offset = kHash2Size;
+#endif
+#endif
+
+static const UInt32 kFixHashSize = 0
+ #ifdef HASH_ARRAY_2
+ + kHash2Size
+ #ifdef HASH_ARRAY_3
+ + kHash3Size
+ #endif
+ #endif
+ ;
+
+CMatchFinder::CMatchFinder():
+ _hash(0)
+{
+}
+
+void CMatchFinder::FreeThisClassMemory()
+{
+ BigFree(_hash);
+ _hash = 0;
+}
+
+void CMatchFinder::FreeMemory()
+{
+ FreeThisClassMemory();
+ CLZInWindow::Free();
+}
+
+CMatchFinder::~CMatchFinder()
+{
+ FreeMemory();
+}
+
+STDMETHODIMP CMatchFinder::Create(UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter)
+{
+ if (historySize > kMaxValForNormalize - 256)
+ {
+ FreeMemory();
+ return E_INVALIDARG;
+ }
+ _cutValue =
+ #ifdef _HASH_CHAIN
+ 8 + (matchMaxLen >> 2);
+ #else
+ 16 + (matchMaxLen >> 1);
+ #endif
+ UInt32 sizeReserv = (historySize + keepAddBufferBefore +
+ matchMaxLen + keepAddBufferAfter) / 2 + 256;
+ if (CLZInWindow::Create(historySize + keepAddBufferBefore,
+ matchMaxLen + keepAddBufferAfter, sizeReserv))
+ {
+ _matchMaxLen = matchMaxLen;
+ UInt32 newCyclicBufferSize = historySize + 1;
+ if (_hash != 0 && newCyclicBufferSize == _cyclicBufferSize)
+ return S_OK;
+ FreeThisClassMemory();
+ _cyclicBufferSize = newCyclicBufferSize; // don't change it
+
+ UInt32 hs = kHashSize;
+
+ #ifdef HASH_ARRAY_2
+ hs = historySize - 1;
+ hs |= (hs >> 1);
+ hs |= (hs >> 2);
+ hs |= (hs >> 4);
+ hs |= (hs >> 8);
+ hs >>= 1;
+ hs |= 0xFFFF;
+ if (hs > (1 << 24))
+ {
+ #ifdef HASH_ARRAY_3
+ hs >>= 1;
+ #else
+ hs = (1 << 24) - 1;
+ #endif
+ }
+ _hashMask = hs;
+ hs++;
+ #endif
+ _hashSizeSum = hs + kFixHashSize;
+ UInt32 numItems = _hashSizeSum + _cyclicBufferSize
+ #ifndef _HASH_CHAIN
+ * 2
+ #endif
+ ;
+ size_t sizeInBytes = (size_t)numItems * sizeof(CIndex);
+ if (sizeInBytes / sizeof(CIndex) != numItems)
+ return E_OUTOFMEMORY;
+ _hash = (CIndex *)BigAlloc(sizeInBytes);
+ _son = _hash + _hashSizeSum;
+ if (_hash != 0)
+ return S_OK;
+ }
+ FreeMemory();
+ return E_OUTOFMEMORY;
+}
+
+static const UInt32 kEmptyHashValue = 0;
+
+STDMETHODIMP CMatchFinder::SetStream(ISequentialInStream *stream)
+{
+ CLZInWindow::SetStream(stream);
+ return S_OK;
+}
+
+STDMETHODIMP CMatchFinder::Init()
+{
+ RINOK(CLZInWindow::Init());
+ for(UInt32 i = 0; i < _hashSizeSum; i++)
+ _hash[i] = kEmptyHashValue;
+ _cyclicBufferPos = 0;
+ ReduceOffsets(-1);
+ return S_OK;
+}
+
+STDMETHODIMP_(void) CMatchFinder::ReleaseStream()
+{
+ // ReleaseStream();
+}
+
+#ifdef HASH_ARRAY_2
+#ifdef HASH_ARRAY_3
+
+#define HASH_CALC { \
+ UInt32 temp = CCRC::Table[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ (UInt32(cur[2]) << 8)) & (kHash3Size - 1); \
+ hashValue = (temp ^ (UInt32(cur[2]) << 8) ^ (CCRC::Table[cur[3]] << 5)) & _hashMask; }
+
+#else // no HASH_ARRAY_3
+#define HASH_CALC { \
+ UInt32 temp = CCRC::Table[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hashValue = (temp ^ (UInt32(cur[2]) << 8)) & _hashMask; }
+#endif // HASH_ARRAY_3
+#else // no HASH_ARRAY_2
+#ifdef HASH_ZIP
+inline UInt32 Hash(const Byte *pointer)
+{
+ return ((UInt32(pointer[0]) << 8) ^ CCRC::Table[pointer[1]] ^ pointer[2]) & (kHashSize - 1);
+}
+#else // no HASH_ZIP
+inline UInt32 Hash(const Byte *pointer)
+{
+ return pointer[0] ^ (UInt32(pointer[1]) << 8);
+}
+#endif // HASH_ZIP
+#endif // HASH_ARRAY_2
+
+STDMETHODIMP CMatchFinder::GetMatches(UInt32 *distances)
+{
+ UInt32 lenLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ lenLimit = _matchMaxLen;
+ else
+ {
+ lenLimit = _streamPos - _pos;
+ if(lenLimit < kMinMatchCheck)
+ {
+ distances[0] = 0;
+ return MovePos();
+ }
+ }
+
+ int offset = 1;
+
+ UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+ const Byte *cur = _buffer + _pos;
+
+ UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize;
+
+ #ifdef HASH_ARRAY_2
+ UInt32 hash2Value;
+ #ifdef HASH_ARRAY_3
+ UInt32 hash3Value;
+ #endif
+ UInt32 hashValue;
+ HASH_CALC;
+ #else
+ UInt32 hashValue = Hash(cur);
+ #endif
+
+ UInt32 curMatch = _hash[kFixHashSize + hashValue];
+ #ifdef HASH_ARRAY_2
+ UInt32 curMatch2 = _hash[hash2Value];
+ #ifdef HASH_ARRAY_3
+ UInt32 curMatch3 = _hash[kHash3Offset + hash3Value];
+ #endif
+ _hash[hash2Value] = _pos;
+ if(curMatch2 > matchMinPos)
+ if (_buffer[curMatch2] == cur[0])
+ {
+ distances[offset++] = maxLen = 2;
+ distances[offset++] = _pos - curMatch2 - 1;
+ }
+
+ #ifdef HASH_ARRAY_3
+ _hash[kHash3Offset + hash3Value] = _pos;
+ if(curMatch3 > matchMinPos)
+ if (_buffer[curMatch3] == cur[0])
+ {
+ if (curMatch3 == curMatch2)
+ offset -= 2;
+ distances[offset++] = maxLen = 3;
+ distances[offset++] = _pos - curMatch3 - 1;
+ curMatch2 = curMatch3;
+ }
+ #endif
+ if (offset != 1 && curMatch2 == curMatch)
+ {
+ offset -= 2;
+ maxLen = kStartMaxLen;
+ }
+ #endif
+
+ _hash[kFixHashSize + hashValue] = _pos;
+
+ CIndex *son = _son;
+
+ #ifdef _HASH_CHAIN
+ son[_cyclicBufferPos] = curMatch;
+ #else
+ CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CIndex *ptr1 = son + (_cyclicBufferPos << 1);
+
+ UInt32 len0, len1;
+ len0 = len1 = kNumHashDirectBytes;
+ #endif
+
+ #if kNumHashDirectBytes != 0
+ if(curMatch > matchMinPos)
+ {
+ if (_buffer[curMatch + kNumHashDirectBytes] != cur[kNumHashDirectBytes])
+ {
+ distances[offset++] = maxLen = kNumHashDirectBytes;
+ distances[offset++] = _pos - curMatch - 1;
+ }
+ }
+ #endif
+ UInt32 count = _cutValue;
+ while(true)
+ {
+ if(curMatch <= matchMinPos || count-- == 0)
+ {
+ #ifndef _HASH_CHAIN
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ #endif
+ break;
+ }
+ UInt32 delta = _pos - curMatch;
+ UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - delta):
+ (_cyclicBufferPos - delta + _cyclicBufferSize);
+ CIndex *pair = son +
+ #ifdef _HASH_CHAIN
+ cyclicPos;
+ #else
+ (cyclicPos << 1);
+ #endif
+
+ // _mm_prefetch((const char *)pair, _MM_HINT_T0);
+
+ const Byte *pb = _buffer + curMatch;
+ UInt32 len =
+ #ifdef _HASH_CHAIN
+ kNumHashDirectBytes;
+ if (pb[maxLen] == cur[maxLen])
+ #else
+ MyMin(len0, len1);
+ #endif
+ if (pb[len] == cur[len])
+ {
+ while(++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ distances[offset++] = maxLen = len;
+ distances[offset++] = delta - 1;
+ if (len == lenLimit)
+ {
+ #ifndef _HASH_CHAIN
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ #endif
+ break;
+ }
+ }
+ }
+ #ifdef _HASH_CHAIN
+ curMatch = *pair;
+ #else
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ #endif
+ }
+ distances[0] = offset - 1;
+ if (++_cyclicBufferPos == _cyclicBufferSize)
+ _cyclicBufferPos = 0;
+ RINOK(CLZInWindow::MovePos());
+ if (_pos == kMaxValForNormalize)
+ Normalize();
+ return S_OK;
+}
+
+STDMETHODIMP CMatchFinder::Skip(UInt32 num)
+{
+ do
+ {
+ #ifdef _HASH_CHAIN
+ if (_streamPos - _pos < kNumHashBytes)
+ {
+ RINOK(MovePos());
+ continue;
+ }
+ #else
+ UInt32 lenLimit;
+ if (_pos + _matchMaxLen <= _streamPos)
+ lenLimit = _matchMaxLen;
+ else
+ {
+ lenLimit = _streamPos - _pos;
+ if(lenLimit < kMinMatchCheck)
+ {
+ RINOK(MovePos());
+ continue;
+ }
+ }
+ UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0;
+ #endif
+ const Byte *cur = _buffer + _pos;
+
+ #ifdef HASH_ARRAY_2
+ UInt32 hash2Value;
+ #ifdef HASH_ARRAY_3
+ UInt32 hash3Value;
+ UInt32 hashValue;
+ HASH_CALC;
+ _hash[kHash3Offset + hash3Value] = _pos;
+ #else
+ UInt32 hashValue;
+ HASH_CALC;
+ #endif
+ _hash[hash2Value] = _pos;
+ #else
+ UInt32 hashValue = Hash(cur);
+ #endif
+
+ UInt32 curMatch = _hash[kFixHashSize + hashValue];
+ _hash[kFixHashSize + hashValue] = _pos;
+
+ #ifdef _HASH_CHAIN
+ _son[_cyclicBufferPos] = curMatch;
+ #else
+ CIndex *son = _son;
+ CIndex *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CIndex *ptr1 = son + (_cyclicBufferPos << 1);
+
+ UInt32 len0, len1;
+ len0 = len1 = kNumHashDirectBytes;
+ UInt32 count = _cutValue;
+ while(true)
+ {
+ if(curMatch <= matchMinPos || count-- == 0)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ break;
+ }
+
+ UInt32 delta = _pos - curMatch;
+ UInt32 cyclicPos = (delta <= _cyclicBufferPos) ?
+ (_cyclicBufferPos - delta):
+ (_cyclicBufferPos - delta + _cyclicBufferSize);
+ CIndex *pair = son + (cyclicPos << 1);
+
+ // _mm_prefetch((const char *)pair, _MM_HINT_T0);
+
+ const Byte *pb = _buffer + curMatch;
+ UInt32 len = MyMin(len0, len1);
+
+ if (pb[len] == cur[len])
+ {
+ while(++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (len == lenLimit)
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ break;
+ }
+ }
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ #endif
+ if (++_cyclicBufferPos == _cyclicBufferSize)
+ _cyclicBufferPos = 0;
+ RINOK(CLZInWindow::MovePos());
+ if (_pos == kMaxValForNormalize)
+ Normalize();
+ }
+ while(--num != 0);
+ return S_OK;
+}
+
+void CMatchFinder::Normalize()
+{
+ UInt32 subValue = _pos - _cyclicBufferSize;
+ CIndex *items = _hash;
+ UInt32 numItems = (_hashSizeSum + _cyclicBufferSize
+ #ifndef _HASH_CHAIN
+ * 2
+ #endif
+ );
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ UInt32 value = items[i];
+ if (value <= subValue)
+ value = kEmptyHashValue;
+ else
+ value -= subValue;
+ items[i] = value;
+ }
+ ReduceOffsets(subValue);
+}
+
+HRESULT CMatchFinder::MovePos()
+{
+ if (++_cyclicBufferPos == _cyclicBufferSize)
+ _cyclicBufferPos = 0;
+ RINOK(CLZInWindow::MovePos());
+ if (_pos == kMaxValForNormalize)
+ Normalize();
+ return S_OK;
+}
+
+STDMETHODIMP_(Byte) CMatchFinder::GetIndexByte(Int32 index)
+ { return CLZInWindow::GetIndexByte(index); }
+
+STDMETHODIMP_(UInt32) CMatchFinder::GetMatchLen(Int32 index,
+ UInt32 back, UInt32 limit)
+ { return CLZInWindow::GetMatchLen(index, back, limit); }
+
+STDMETHODIMP_(UInt32) CMatchFinder::GetNumAvailableBytes()
+ { return CLZInWindow::GetNumAvailableBytes(); }
+
+STDMETHODIMP_(const Byte *) CMatchFinder::GetPointerToCurrentPos()
+ { return CLZInWindow::GetPointerToCurrentPos(); }
+
+STDMETHODIMP_(Int32) CMatchFinder::NeedChangeBufferPos(UInt32 numCheckBytes)
+ { return CLZInWindow::NeedMove(numCheckBytes) ? 1: 0; }
+
+STDMETHODIMP_(void) CMatchFinder::ChangeBufferPos()
+ { CLZInWindow::MoveBlock();}
+
+#undef HASH_CALC
+#undef kNumHashDirectBytes
+
+}
diff --git a/Source/7zip/7zip/Compress/LZ/IMatchFinder.h b/Source/7zip/7zip/Compress/LZ/IMatchFinder.h
index 2979eaa..007b1e2 100755
--- a/Source/7zip/7zip/Compress/LZ/IMatchFinder.h
+++ b/Source/7zip/7zip/Compress/LZ/IMatchFinder.h
@@ -1,47 +1,47 @@
-/*
- * IMatchFinder.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __IMATCHFINDER_H
-#define __IMATCHFINDER_H
-
-struct IInWindowStream: public IUnknown
-{
- STDMETHOD(SetStream)(ISequentialInStream *inStream) PURE;
- STDMETHOD_(void, ReleaseStream)() PURE;
- STDMETHOD(Init)() PURE;
- STDMETHOD_(Byte, GetIndexByte)(Int32 index) PURE;
- STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 distance, UInt32 limit) PURE;
- STDMETHOD_(UInt32, GetNumAvailableBytes)() PURE;
- STDMETHOD_(const Byte *, GetPointerToCurrentPos)() PURE;
- STDMETHOD_(Int32, NeedChangeBufferPos)(UInt32 numCheckBytes) PURE;
- STDMETHOD_(void, ChangeBufferPos)() PURE;
-};
-
-struct IMatchFinder: public IInWindowStream
-{
- STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
- UInt32 matchMaxLen, UInt32 keepAddBufferAfter) PURE;
- STDMETHOD(GetMatches)(UInt32 *distances) PURE;
- STDMETHOD(Skip)(UInt32 num) PURE;
-};
-
-struct IMatchFinderSetNumPasses
-{
- virtual void SetNumPasses(UInt32 numPasses) PURE;
-};
-
-#endif
+/*
+ * IMatchFinder.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __IMATCHFINDER_H
+#define __IMATCHFINDER_H
+
+struct IInWindowStream: public IUnknown
+{
+ STDMETHOD(SetStream)(ISequentialInStream *inStream) PURE;
+ STDMETHOD_(void, ReleaseStream)() PURE;
+ STDMETHOD(Init)() PURE;
+ STDMETHOD_(Byte, GetIndexByte)(Int32 index) PURE;
+ STDMETHOD_(UInt32, GetMatchLen)(Int32 index, UInt32 distance, UInt32 limit) PURE;
+ STDMETHOD_(UInt32, GetNumAvailableBytes)() PURE;
+ STDMETHOD_(const Byte *, GetPointerToCurrentPos)() PURE;
+ STDMETHOD_(Int32, NeedChangeBufferPos)(UInt32 numCheckBytes) PURE;
+ STDMETHOD_(void, ChangeBufferPos)() PURE;
+};
+
+struct IMatchFinder: public IInWindowStream
+{
+ STDMETHOD(Create)(UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter) PURE;
+ STDMETHOD(GetMatches)(UInt32 *distances) PURE;
+ STDMETHOD(Skip)(UInt32 num) PURE;
+};
+
+struct IMatchFinderSetNumPasses
+{
+ virtual void SetNumPasses(UInt32 numPasses) PURE;
+};
+
+#endif
diff --git a/Source/7zip/7zip/Compress/LZ/LZInWindow.cpp b/Source/7zip/7zip/Compress/LZ/LZInWindow.cpp
index c5e1720..0af3b01 100755
--- a/Source/7zip/7zip/Compress/LZ/LZInWindow.cpp
+++ b/Source/7zip/7zip/Compress/LZ/LZInWindow.cpp
@@ -1,120 +1,120 @@
-/*
- * LZInWindow.cpp
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "StdAfx.h"
-
-#include "LZInWindow.h"
-#include "../../../Common/MyCom.h"
-#include "../../../Common/Alloc.h"
-
-void CLZInWindow::Free()
-{
- ::BigFree(_bufferBase);
- _bufferBase = 0;
-}
-
-bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
-{
- _keepSizeBefore = keepSizeBefore;
- _keepSizeAfter = keepSizeAfter;
- UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
- if (_bufferBase == 0 || _blockSize != blockSize)
- {
- Free();
- _blockSize = blockSize;
- if (_blockSize != 0)
- _bufferBase = (Byte *)::BigAlloc(_blockSize);
- }
- _pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter;
- if (_blockSize == 0)
- return true;
- return (_bufferBase != 0);
-}
-
-void CLZInWindow::SetStream(ISequentialInStream *stream)
-{
- _stream = stream;
-}
-
-HRESULT CLZInWindow::Init()
-{
- _buffer = _bufferBase;
- _pos = 0;
- _streamPos = 0;
- _streamEndWasReached = false;
- return ReadBlock();
-}
-
-/*
-void CLZInWindow::ReleaseStream()
-{
- _stream.Release();
-}
-*/
-
-///////////////////////////////////////////
-// ReadBlock
-
-// In State:
-// (_buffer + _streamPos) <= (_bufferBase + _blockSize)
-// Out State:
-// _posLimit <= _blockSize - _keepSizeAfter;
-// if(_streamEndWasReached == false):
-// _streamPos >= _pos + _keepSizeAfter
-// _posLimit = _streamPos - _keepSizeAfter;
-// else
-//
-
-HRESULT CLZInWindow::ReadBlock()
-{
- if(_streamEndWasReached)
- return S_OK;
- while(true)
- {
- UInt32 size = (UInt32)(_bufferBase - _buffer) + _blockSize - _streamPos;
- if(size == 0)
- return S_OK;
- UInt32 numReadBytes;
- RINOK(_stream->Read(_buffer + _streamPos, size, &numReadBytes));
- if(numReadBytes == 0)
- {
- _posLimit = _streamPos;
- const Byte *pointerToPostion = _buffer + _posLimit;
- if(pointerToPostion > _pointerToLastSafePosition)
- _posLimit = (UInt32)(_pointerToLastSafePosition - _buffer);
- _streamEndWasReached = true;
- return S_OK;
- }
- _streamPos += numReadBytes;
- if(_streamPos >= _pos + _keepSizeAfter)
- {
- _posLimit = _streamPos - _keepSizeAfter;
- return S_OK;
- }
- }
-}
-
-void CLZInWindow::MoveBlock()
-{
- UInt32 offset = (UInt32)(_buffer - _bufferBase) + _pos - _keepSizeBefore;
- // we need one additional byte, since MovePos moves on 1 byte.
- if (offset > 0)
- offset--;
- UInt32 numBytes = (UInt32)(_buffer - _bufferBase) + _streamPos - offset;
- memmove(_bufferBase, _bufferBase + offset, numBytes);
- _buffer -= offset;
-}
+/*
+ * LZInWindow.cpp
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "StdAfx.h"
+
+#include "LZInWindow.h"
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Alloc.h"
+
+void CLZInWindow::Free()
+{
+ ::BigFree(_bufferBase);
+ _bufferBase = 0;
+}
+
+bool CLZInWindow::Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv)
+{
+ _keepSizeBefore = keepSizeBefore;
+ _keepSizeAfter = keepSizeAfter;
+ UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
+ if (_bufferBase == 0 || _blockSize != blockSize)
+ {
+ Free();
+ _blockSize = blockSize;
+ if (_blockSize != 0)
+ _bufferBase = (Byte *)::BigAlloc(_blockSize);
+ }
+ _pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter;
+ if (_blockSize == 0)
+ return true;
+ return (_bufferBase != 0);
+}
+
+void CLZInWindow::SetStream(ISequentialInStream *stream)
+{
+ _stream = stream;
+}
+
+HRESULT CLZInWindow::Init()
+{
+ _buffer = _bufferBase;
+ _pos = 0;
+ _streamPos = 0;
+ _streamEndWasReached = false;
+ return ReadBlock();
+}
+
+/*
+void CLZInWindow::ReleaseStream()
+{
+ _stream.Release();
+}
+*/
+
+///////////////////////////////////////////
+// ReadBlock
+
+// In State:
+// (_buffer + _streamPos) <= (_bufferBase + _blockSize)
+// Out State:
+// _posLimit <= _blockSize - _keepSizeAfter;
+// if(_streamEndWasReached == false):
+// _streamPos >= _pos + _keepSizeAfter
+// _posLimit = _streamPos - _keepSizeAfter;
+// else
+//
+
+HRESULT CLZInWindow::ReadBlock()
+{
+ if(_streamEndWasReached)
+ return S_OK;
+ while(true)
+ {
+ UInt32 size = (UInt32)(_bufferBase - _buffer) + _blockSize - _streamPos;
+ if(size == 0)
+ return S_OK;
+ UInt32 numReadBytes;
+ RINOK(_stream->Read(_buffer + _streamPos, size, &numReadBytes));
+ if(numReadBytes == 0)
+ {
+ _posLimit = _streamPos;
+ const Byte *pointerToPostion = _buffer + _posLimit;
+ if(pointerToPostion > _pointerToLastSafePosition)
+ _posLimit = (UInt32)(_pointerToLastSafePosition - _buffer);
+ _streamEndWasReached = true;
+ return S_OK;
+ }
+ _streamPos += numReadBytes;
+ if(_streamPos >= _pos + _keepSizeAfter)
+ {
+ _posLimit = _streamPos - _keepSizeAfter;
+ return S_OK;
+ }
+ }
+}
+
+void CLZInWindow::MoveBlock()
+{
+ UInt32 offset = (UInt32)(_buffer - _bufferBase) + _pos - _keepSizeBefore;
+ // we need one additional byte, since MovePos moves on 1 byte.
+ if (offset > 0)
+ offset--;
+ UInt32 numBytes = (UInt32)(_buffer - _bufferBase) + _streamPos - offset;
+ memmove(_bufferBase, _bufferBase + offset, numBytes);
+ _buffer -= offset;
+}
diff --git a/Source/7zip/7zip/Compress/LZ/LZInWindow.h b/Source/7zip/7zip/Compress/LZ/LZInWindow.h
index 1bafd1a..4d6c5fe 100755
--- a/Source/7zip/7zip/Compress/LZ/LZInWindow.h
+++ b/Source/7zip/7zip/Compress/LZ/LZInWindow.h
@@ -1,102 +1,102 @@
-/*
- * LZInWindow.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __LZ_IN_WINDOW_H
-#define __LZ_IN_WINDOW_H
-
-#include "../../IStream.h"
-
-class CLZInWindow
-{
- Byte *_bufferBase; // pointer to buffer with data
- ISequentialInStream *_stream;
- UInt32 _posLimit; // offset (from _buffer) when new block reading must be done
- bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
- const Byte *_pointerToLastSafePosition;
-protected:
- Byte *_buffer; // Pointer to virtual Buffer begin
- UInt32 _blockSize; // Size of Allocated memory block
- UInt32 _pos; // offset (from _buffer) of curent byte
- UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
- UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
- UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
-
- void MoveBlock();
- HRESULT ReadBlock();
- void Free();
-public:
- CLZInWindow(): _bufferBase(0) {}
- virtual ~CLZInWindow() { Free(); }
-
- // keepSizeBefore + keepSizeAfter + keepSizeReserv < 4G)
- bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv = (1<<17));
-
- void SetStream(ISequentialInStream *stream);
- HRESULT Init();
- // void ReleaseStream();
-
- Byte *GetBuffer() const { return _buffer; }
-
- const Byte *GetPointerToCurrentPos() const { return _buffer + _pos; }
-
- HRESULT MovePos()
- {
- _pos++;
- if (_pos > _posLimit)
- {
- const Byte *pointerToPostion = _buffer + _pos;
- if(pointerToPostion > _pointerToLastSafePosition)
- MoveBlock();
- return ReadBlock();
- }
- else
- return S_OK;
- }
- Byte GetIndexByte(Int32 index) const { return _buffer[(size_t)_pos + index]; }
-
- // index + limit have not to exceed _keepSizeAfter;
- // -2G <= index < 2G
- UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) const
- {
- if(_streamEndWasReached)
- if ((_pos + index) + limit > _streamPos)
- limit = _streamPos - (_pos + index);
- distance++;
- const Byte *pby = _buffer + (size_t)_pos + index;
- UInt32 i;
- for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++);
- return i;
- }
-
- UInt32 GetNumAvailableBytes() const { return _streamPos - _pos; }
-
- void ReduceOffsets(Int32 subValue)
- {
- _buffer += subValue;
- _posLimit -= subValue;
- _pos -= subValue;
- _streamPos -= subValue;
- }
-
- bool NeedMove(UInt32 numCheckBytes)
- {
- UInt32 reserv = _pointerToLastSafePosition - (_buffer + _pos);
- return (reserv <= numCheckBytes);
- }
-};
-
-#endif
+/*
+ * LZInWindow.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __LZ_IN_WINDOW_H
+#define __LZ_IN_WINDOW_H
+
+#include "../../IStream.h"
+
+class CLZInWindow
+{
+ Byte *_bufferBase; // pointer to buffer with data
+ ISequentialInStream *_stream;
+ UInt32 _posLimit; // offset (from _buffer) when new block reading must be done
+ bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream
+ const Byte *_pointerToLastSafePosition;
+protected:
+ Byte *_buffer; // Pointer to virtual Buffer begin
+ UInt32 _blockSize; // Size of Allocated memory block
+ UInt32 _pos; // offset (from _buffer) of curent byte
+ UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
+ UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
+ UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream
+
+ void MoveBlock();
+ HRESULT ReadBlock();
+ void Free();
+public:
+ CLZInWindow(): _bufferBase(0) {}
+ virtual ~CLZInWindow() { Free(); }
+
+ // keepSizeBefore + keepSizeAfter + keepSizeReserv < 4G)
+ bool Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv = (1<<17));
+
+ void SetStream(ISequentialInStream *stream);
+ HRESULT Init();
+ // void ReleaseStream();
+
+ Byte *GetBuffer() const { return _buffer; }
+
+ const Byte *GetPointerToCurrentPos() const { return _buffer + _pos; }
+
+ HRESULT MovePos()
+ {
+ _pos++;
+ if (_pos > _posLimit)
+ {
+ const Byte *pointerToPostion = _buffer + _pos;
+ if(pointerToPostion > _pointerToLastSafePosition)
+ MoveBlock();
+ return ReadBlock();
+ }
+ else
+ return S_OK;
+ }
+ Byte GetIndexByte(Int32 index) const { return _buffer[(size_t)_pos + index]; }
+
+ // index + limit have not to exceed _keepSizeAfter;
+ // -2G <= index < 2G
+ UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) const
+ {
+ if(_streamEndWasReached)
+ if ((_pos + index) + limit > _streamPos)
+ limit = _streamPos - (_pos + index);
+ distance++;
+ const Byte *pby = _buffer + (size_t)_pos + index;
+ UInt32 i;
+ for(i = 0; i < limit && pby[i] == pby[(size_t)i - distance]; i++);
+ return i;
+ }
+
+ UInt32 GetNumAvailableBytes() const { return _streamPos - _pos; }
+
+ void ReduceOffsets(Int32 subValue)
+ {
+ _buffer += subValue;
+ _posLimit -= subValue;
+ _pos -= subValue;
+ _streamPos -= subValue;
+ }
+
+ bool NeedMove(UInt32 numCheckBytes)
+ {
+ UInt32 reserv = _pointerToLastSafePosition - (_buffer + _pos);
+ return (reserv <= numCheckBytes);
+ }
+};
+
+#endif
diff --git a/Source/7zip/7zip/Compress/LZ/LZOutWindow.cpp b/Source/7zip/7zip/Compress/LZ/LZOutWindow.cpp
index 5370eff..cf05633 100755
--- a/Source/7zip/7zip/Compress/LZ/LZOutWindow.cpp
+++ b/Source/7zip/7zip/Compress/LZ/LZOutWindow.cpp
@@ -1,32 +1,32 @@
-/*
- * LZOutWindow.cpp
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "StdAfx.h"
-
-#include "../../../Common/Alloc.h"
-#include "LZOutWindow.h"
-
-void CLZOutWindow::Init(bool solid)
-{
- if(!solid)
- COutBuffer::Init();
- #ifdef _NO_EXCEPTIONS
- ErrorCode = S_OK;
- #endif
-}
-
-
+/*
+ * LZOutWindow.cpp
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "StdAfx.h"
+
+#include "../../../Common/Alloc.h"
+#include "LZOutWindow.h"
+
+void CLZOutWindow::Init(bool solid)
+{
+ if(!solid)
+ COutBuffer::Init();
+ #ifdef _NO_EXCEPTIONS
+ ErrorCode = S_OK;
+ #endif
+}
+
+
diff --git a/Source/7zip/7zip/Compress/LZ/LZOutWindow.h b/Source/7zip/7zip/Compress/LZ/LZOutWindow.h
index e0ee36e..32648a0 100755
--- a/Source/7zip/7zip/Compress/LZ/LZOutWindow.h
+++ b/Source/7zip/7zip/Compress/LZ/LZOutWindow.h
@@ -1,71 +1,71 @@
-/*
- * LZOutWindow.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __LZ_OUT_WINDOW_H
-#define __LZ_OUT_WINDOW_H
-
-#include "../../IStream.h"
-#include "../../Common/OutBuffer.h"
-
-#ifndef _NO_EXCEPTIONS
-typedef COutBufferException CLZOutWindowException;
-#endif
-
-class CLZOutWindow: public COutBuffer
-{
-public:
- void Init(bool solid = false);
-
- // distance >= 0, len > 0,
- bool CopyBlock(UInt32 distance, UInt32 len)
- {
- UInt32 pos = _pos - distance - 1;
- if (distance >= _pos)
- {
- if (!_overDict || distance >= _bufferSize)
- return false;
- pos += _bufferSize;
- }
- do
- {
- if (pos == _bufferSize)
- pos = 0;
- _buffer[_pos++] = _buffer[pos++];
- if (_pos == _limitPos)
- FlushWithCheck();
- }
- while(--len != 0);
- return true;
- }
-
- void PutByte(Byte b)
- {
- _buffer[_pos++] = b;
- if (_pos == _limitPos)
- FlushWithCheck();
- }
-
- Byte GetByte(UInt32 distance) const
- {
- UInt32 pos = _pos - distance - 1;
- if (pos >= _bufferSize)
- pos += _bufferSize;
- return _buffer[pos];
- }
-};
-
-#endif
+/*
+ * LZOutWindow.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __LZ_OUT_WINDOW_H
+#define __LZ_OUT_WINDOW_H
+
+#include "../../IStream.h"
+#include "../../Common/OutBuffer.h"
+
+#ifndef _NO_EXCEPTIONS
+typedef COutBufferException CLZOutWindowException;
+#endif
+
+class CLZOutWindow: public COutBuffer
+{
+public:
+ void Init(bool solid = false);
+
+ // distance >= 0, len > 0,
+ bool CopyBlock(UInt32 distance, UInt32 len)
+ {
+ UInt32 pos = _pos - distance - 1;
+ if (distance >= _pos)
+ {
+ if (!_overDict || distance >= _bufferSize)
+ return false;
+ pos += _bufferSize;
+ }
+ do
+ {
+ if (pos == _bufferSize)
+ pos = 0;
+ _buffer[_pos++] = _buffer[pos++];
+ if (_pos == _limitPos)
+ FlushWithCheck();
+ }
+ while(--len != 0);
+ return true;
+ }
+
+ void PutByte(Byte b)
+ {
+ _buffer[_pos++] = b;
+ if (_pos == _limitPos)
+ FlushWithCheck();
+ }
+
+ Byte GetByte(UInt32 distance) const
+ {
+ UInt32 pos = _pos - distance - 1;
+ if (pos >= _bufferSize)
+ pos += _bufferSize;
+ return _buffer[pos];
+ }
+};
+
+#endif
diff --git a/Source/7zip/7zip/Compress/LZ/StdAfx.h b/Source/7zip/7zip/Compress/LZ/StdAfx.h
index 3de038a..3ff6d8a 100755
--- a/Source/7zip/7zip/Compress/LZ/StdAfx.h
+++ b/Source/7zip/7zip/Compress/LZ/StdAfx.h
@@ -1,6 +1,6 @@
-// StdAfx.h
-
-#ifndef __STDAFX_H
-#define __STDAFX_H
-
-#endif
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
diff --git a/Source/7zip/7zip/Compress/LZMA/LZMA.h b/Source/7zip/7zip/Compress/LZMA/LZMA.h
index 13e94e0..dbab974 100755
--- a/Source/7zip/7zip/Compress/LZMA/LZMA.h
+++ b/Source/7zip/7zip/Compress/LZMA/LZMA.h
@@ -1,97 +1,97 @@
-/*
- * LZMA.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __LZMA_H
-#define __LZMA_H
-
-namespace NCompress {
-namespace NLZMA {
-
-const UInt32 kNumRepDistances = 4;
-
-const int kNumStates = 12;
-
-const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
-const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
-const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
-const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
-
-class CState
-{
-public:
- Byte Index;
- void Init() { Index = 0; }
- void UpdateChar() { Index = kLiteralNextStates[Index]; }
- void UpdateMatch() { Index = kMatchNextStates[Index]; }
- void UpdateRep() { Index = kRepNextStates[Index]; }
- void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
- bool IsCharState() const { return Index < 7; }
-};
-
-const int kNumPosSlotBits = 6;
-const int kDicLogSizeMin = 0;
-const int kDicLogSizeMax = 32;
-const int kDistTableSizeMax = kDicLogSizeMax * 2;
-
-const UInt32 kNumLenToPosStates = 4;
-
-inline UInt32 GetLenToPosState(UInt32 len)
-{
- len -= 2;
- if (len < kNumLenToPosStates)
- return len;
- return kNumLenToPosStates - 1;
-}
-
-namespace NLength {
-
-const int kNumPosStatesBitsMax = 4;
-const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
-
-const int kNumPosStatesBitsEncodingMax = 4;
-const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
-
-const int kNumLowBits = 3;
-const int kNumMidBits = 3;
-const int kNumHighBits = 8;
-const UInt32 kNumLowSymbols = 1 << kNumLowBits;
-const UInt32 kNumMidSymbols = 1 << kNumMidBits;
-const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
-
-}
-
-const UInt32 kMatchMinLen = 2;
-const UInt32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
-
-const int kNumAlignBits = 4;
-const UInt32 kAlignTableSize = 1 << kNumAlignBits;
-const UInt32 kAlignMask = (kAlignTableSize - 1);
-
-const UInt32 kStartPosModelIndex = 4;
-const UInt32 kEndPosModelIndex = 14;
-const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
-
-const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
-
-const int kNumLitPosStatesBitsEncodingMax = 4;
-const int kNumLitContextBitsMax = 8;
-
-const int kNumMoveBits = 5;
-
-}}
-
-#endif
+/*
+ * LZMA.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __LZMA_H
+#define __LZMA_H
+
+namespace NCompress {
+namespace NLZMA {
+
+const UInt32 kNumRepDistances = 4;
+
+const int kNumStates = 12;
+
+const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
+const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+class CState
+{
+public:
+ Byte Index;
+ void Init() { Index = 0; }
+ void UpdateChar() { Index = kLiteralNextStates[Index]; }
+ void UpdateMatch() { Index = kMatchNextStates[Index]; }
+ void UpdateRep() { Index = kRepNextStates[Index]; }
+ void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
+ bool IsCharState() const { return Index < 7; }
+};
+
+const int kNumPosSlotBits = 6;
+const int kDicLogSizeMin = 0;
+const int kDicLogSizeMax = 32;
+const int kDistTableSizeMax = kDicLogSizeMax * 2;
+
+const UInt32 kNumLenToPosStates = 4;
+
+inline UInt32 GetLenToPosState(UInt32 len)
+{
+ len -= 2;
+ if (len < kNumLenToPosStates)
+ return len;
+ return kNumLenToPosStates - 1;
+}
+
+namespace NLength {
+
+const int kNumPosStatesBitsMax = 4;
+const UInt32 kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
+
+const int kNumPosStatesBitsEncodingMax = 4;
+const UInt32 kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
+
+const int kNumLowBits = 3;
+const int kNumMidBits = 3;
+const int kNumHighBits = 8;
+const UInt32 kNumLowSymbols = 1 << kNumLowBits;
+const UInt32 kNumMidSymbols = 1 << kNumMidBits;
+const UInt32 kNumSymbolsTotal = kNumLowSymbols + kNumMidSymbols + (1 << kNumHighBits);
+
+}
+
+const UInt32 kMatchMinLen = 2;
+const UInt32 kMatchMaxLen = kMatchMinLen + NLength::kNumSymbolsTotal - 1;
+
+const int kNumAlignBits = 4;
+const UInt32 kAlignTableSize = 1 << kNumAlignBits;
+const UInt32 kAlignMask = (kAlignTableSize - 1);
+
+const UInt32 kStartPosModelIndex = 4;
+const UInt32 kEndPosModelIndex = 14;
+const UInt32 kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
+
+const UInt32 kNumFullDistances = 1 << (kEndPosModelIndex / 2);
+
+const int kNumLitPosStatesBitsEncodingMax = 4;
+const int kNumLitContextBitsMax = 8;
+
+const int kNumMoveBits = 5;
+
+}}
+
+#endif
diff --git a/Source/7zip/7zip/Compress/LZMA/LZMAEncoder.cpp b/Source/7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
index 5eae213..171ff7f 100755
--- a/Source/7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
+++ b/Source/7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
@@ -1,1580 +1,1580 @@
-/*
- * LZMAEncoder.cpp
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "StdAfx.h"
-
-#include "../../../Common/Defs.h"
-#include "../../Common/StreamUtils.h"
-
-#include "LZMAEncoder.h"
-
-// for minimal compressing code size define these:
-// #define COMPRESS_MF_BT
-// #define COMPRESS_MF_BT4
-
-#if !defined(COMPRESS_MF_BT) && !defined(COMPRESS_MF_HC)
-#define COMPRESS_MF_BT
-#define COMPRESS_MF_HC
-#endif
-
-#ifdef COMPRESS_MF_BT
-#if !defined(COMPRESS_MF_BT2) && !defined(COMPRESS_MF_BT3) && !defined(COMPRESS_MF_BT4)
-#define COMPRESS_MF_BT2
-#define COMPRESS_MF_BT3
-#define COMPRESS_MF_BT4
-#endif
-#ifdef COMPRESS_MF_BT2
-#include "../LZ/BinTree/BinTree2.h"
-#endif
-#ifdef COMPRESS_MF_BT3
-#include "../LZ/BinTree/BinTree3.h"
-#endif
-#ifdef COMPRESS_MF_BT4
-#include "../LZ/BinTree/BinTree4.h"
-#endif
-#endif
-
-#ifdef COMPRESS_MF_HC
-#include "../LZ/HashChain/HC4.h"
-#endif
-
-#ifdef COMPRESS_MF_MT
-#include "../LZ/MT/MT.h"
-#endif
-
-namespace NCompress {
-namespace NLZMA {
-
-const int kDefaultDictionaryLogSize = 22;
-const UInt32 kNumFastBytesDefault = 0x20;
-
-enum
-{
- kBT2,
- kBT3,
- kBT4,
- kHC4
-};
-
-/*static const wchar_t *kMatchFinderIDs[] =
-{
- L"BT2",
- L"BT3",
- L"BT4",
- L"HC4"
-};*/
-
-Byte g_FastPos[1 << 11];
-
-class CFastPosInit
-{
-public:
- CFastPosInit() { Init(); }
- void Init()
- {
- const Byte kFastSlots = 22;
- int c = 2;
- g_FastPos[0] = 0;
- g_FastPos[1] = 1;
-
- for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++)
- {
- UInt32 k = (1 << ((slotFast >> 1) - 1));
- for (UInt32 j = 0; j < k; j++, c++)
- g_FastPos[c] = slotFast;
- }
- }
-} g_FastPosInit;
-
-
-void CLiteralEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol)
-{
- UInt32 context = 1;
- int i = 8;
- do
- {
- i--;
- UInt32 bit = (symbol >> i) & 1;
- _encoders[context].Encode(rangeEncoder, bit);
- context = (context << 1) | bit;
- }
- while(i != 0);
-}
-
-void CLiteralEncoder2::EncodeMatched(NRangeCoder::CEncoder *rangeEncoder,
- Byte matchByte, Byte symbol)
-{
- UInt32 context = 1;
- int i = 8;
- do
- {
- i--;
- UInt32 bit = (symbol >> i) & 1;
- UInt32 matchBit = (matchByte >> i) & 1;
- _encoders[0x100 + (matchBit << 8) + context].Encode(rangeEncoder, bit);
- context = (context << 1) | bit;
- if (matchBit != bit)
- {
- while(i != 0)
- {
- i--;
- UInt32 bit = (symbol >> i) & 1;
- _encoders[context].Encode(rangeEncoder, bit);
- context = (context << 1) | bit;
- }
- break;
- }
- }
- while(i != 0);
-}
-
-UInt32 CLiteralEncoder2::GetPrice(bool matchMode, Byte matchByte, Byte symbol) const
-{
- UInt32 price = 0;
- UInt32 context = 1;
- int i = 8;
- if (matchMode)
- {
- do
- {
- i--;
- UInt32 matchBit = (matchByte >> i) & 1;
- UInt32 bit = (symbol >> i) & 1;
- price += _encoders[0x100 + (matchBit << 8) + context].GetPrice(bit);
- context = (context << 1) | bit;
- if (matchBit != bit)
- break;
- }
- while (i != 0);
- }
- while(i != 0)
- {
- i--;
- UInt32 bit = (symbol >> i) & 1;
- price += _encoders[context].GetPrice(bit);
- context = (context << 1) | bit;
- }
- return price;
-};
-
-
-namespace NLength {
-
-void CEncoder::Init(UInt32 numPosStates)
-{
- _choice.Init();
- _choice2.Init();
- for (UInt32 posState = 0; posState < numPosStates; posState++)
- {
- _lowCoder[posState].Init();
- _midCoder[posState].Init();
- }
- _highCoder.Init();
-}
-
-void CEncoder::Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState)
-{
- if(symbol < kNumLowSymbols)
- {
- _choice.Encode(rangeEncoder, 0);
- _lowCoder[posState].Encode(rangeEncoder, symbol);
- }
- else
- {
- _choice.Encode(rangeEncoder, 1);
- if(symbol < kNumLowSymbols + kNumMidSymbols)
- {
- _choice2.Encode(rangeEncoder, 0);
- _midCoder[posState].Encode(rangeEncoder, symbol - kNumLowSymbols);
- }
- else
- {
- _choice2.Encode(rangeEncoder, 1);
- _highCoder.Encode(rangeEncoder, symbol - kNumLowSymbols - kNumMidSymbols);
- }
- }
-}
-
-void CEncoder::SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const
-{
- UInt32 a0 = _choice.GetPrice0();
- UInt32 a1 = _choice.GetPrice1();
- UInt32 b0 = a1 + _choice2.GetPrice0();
- UInt32 b1 = a1 + _choice2.GetPrice1();
- UInt32 i = 0;
- for (i = 0; i < kNumLowSymbols; i++)
- {
- if (i >= numSymbols)
- return;
- prices[i] = a0 + _lowCoder[posState].GetPrice(i);
- }
- for (; i < kNumLowSymbols + kNumMidSymbols; i++)
- {
- if (i >= numSymbols)
- return;
- prices[i] = b0 + _midCoder[posState].GetPrice(i - kNumLowSymbols);
- }
- for (; i < numSymbols; i++)
- prices[i] = b1 + _highCoder.GetPrice(i - kNumLowSymbols - kNumMidSymbols);
-}
-
-}
-CEncoder::CEncoder():
- _numFastBytes(kNumFastBytesDefault),
- _distTableSize(kDefaultDictionaryLogSize * 2),
- _posStateBits(2),
- _posStateMask(4 - 1),
- _numLiteralPosStateBits(0),
- _numLiteralContextBits(3),
- _dictionarySize(1 << kDefaultDictionaryLogSize),
- _dictionarySizePrev(UInt32(-1)),
- _numFastBytesPrev(UInt32(-1)),
- _matchFinderCycles(0),
- _matchFinderIndex(kBT4),
- #ifdef COMPRESS_MF_MT
- _multiThread(false),
- #endif
- _writeEndMark(false),
- setMfPasses(0)
-{
- // _maxMode = false;
- _fastMode = false;
-}
-
-HRESULT CEncoder::Create()
-{
- if (!_rangeEncoder.Create(1 << 20))
- return E_OUTOFMEMORY;
- if (!_matchFinder)
- {
- switch(_matchFinderIndex)
- {
- #ifdef COMPRESS_MF_BT
- #ifdef COMPRESS_MF_BT2
- case kBT2:
- {
- NBT2::CMatchFinder *mfSpec = new NBT2::CMatchFinder;
- setMfPasses = mfSpec;
- _matchFinder = mfSpec;
- break;
- }
- #endif
- #ifdef COMPRESS_MF_BT3
- case kBT3:
- {
- NBT3::CMatchFinder *mfSpec = new NBT3::CMatchFinder;
- setMfPasses = mfSpec;
- _matchFinder = mfSpec;
- break;
- }
- #endif
- #ifdef COMPRESS_MF_BT4
- case kBT4:
- {
- NBT4::CMatchFinder *mfSpec = new NBT4::CMatchFinder;
- setMfPasses = mfSpec;
- _matchFinder = mfSpec;
- break;
- }
- #endif
- #endif
-
- #ifdef COMPRESS_MF_HC
- case kHC4:
- {
- NHC4::CMatchFinder *mfSpec = new NHC4::CMatchFinder;
- setMfPasses = mfSpec;
- _matchFinder = mfSpec;
- break;
- }
- #endif
- }
- if (_matchFinder == 0)
- return E_OUTOFMEMORY;
-
- #ifdef COMPRESS_MF_MT
- if (_multiThread && !(_fastMode && (_matchFinderIndex == kHC4)))
- {
- CMatchFinderMT *mfSpec = new CMatchFinderMT;
- if (mfSpec == 0)
- return E_OUTOFMEMORY;
- CMyComPtr<IMatchFinder> mf = mfSpec;
- RINOK(mfSpec->SetMatchFinder(_matchFinder));
- _matchFinder.Release();
- _matchFinder = mf;
- }
- #endif
- }
-
- if (!_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits))
- return E_OUTOFMEMORY;
-
- if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
- return S_OK;
- RINOK(_matchFinder->Create(_dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen + 1)); // actually it's + _numFastBytes - _numFastBytes
- if (_matchFinderCycles != 0 && setMfPasses != 0)
- setMfPasses->SetNumPasses(_matchFinderCycles);
- _dictionarySizePrev = _dictionarySize;
- _numFastBytesPrev = _numFastBytes;
- return S_OK;
-}
-
-/*static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString)
-{
- while (true)
- {
- wchar_t c = *testString;
- if (c >= 'a' && c <= 'z')
- c -= 0x20;
- if (*base != c)
- return false;
- if (c == 0)
- return true;
- base++;
- testString++;
- }
-}
-
-static int FindMatchFinder(const wchar_t *s)
-{
- for (int m = 0; m < (int)(sizeof(kMatchFinderIDs) / sizeof(kMatchFinderIDs[0])); m++)
- if (AreStringsEqual(kMatchFinderIDs[m], s))
- return m;
- return -1;
-}*/
-
-STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
- const PROPVARIANT *properties, UInt32 numProperties)
-{
- for (UInt32 i = 0; i < numProperties; i++)
- {
- const PROPVARIANT &prop = properties[i];
- switch(propIDs[i])
- {
- case NCoderPropID::kNumFastBytes:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 numFastBytes = prop.ulVal;
- if(numFastBytes < 5 || numFastBytes > kMatchMaxLen)
- return E_INVALIDARG;
- _numFastBytes = numFastBytes;
- break;
- }
- case NCoderPropID::kMatchFinderCycles:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- _matchFinderCycles = prop.ulVal;
- break;
- }
- case NCoderPropID::kAlgorithm:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 maximize = prop.ulVal;
- _fastMode = (maximize == 0);
- // _maxMode = (maximize >= 2);
- break;
- }
- case NCoderPropID::kMatchFinder:
- {
- return E_NOTIMPL;
- /*if (prop.vt != VT_BSTR)
- return E_INVALIDARG;
- int matchFinderIndexPrev = _matchFinderIndex;
- int m = FindMatchFinder(prop.bstrVal);
- if (m < 0)
- return E_INVALIDARG;
- _matchFinderIndex = m;
- if (_matchFinder && matchFinderIndexPrev != _matchFinderIndex)
- {
- _dictionarySizePrev = (UInt32)-1;
- ReleaseMatchFinder();
- }
- break;*/
- }
- #ifdef COMPRESS_MF_MT
- case NCoderPropID::kMultiThread:
- {
- if (prop.vt != VT_BOOL)
- return E_INVALIDARG;
- bool newMultiThread = (prop.boolVal == VARIANT_TRUE);
- if (newMultiThread != _multiThread)
- {
- _dictionarySizePrev = (UInt32)-1;
- ReleaseMatchFinder();
- _multiThread = newMultiThread;
- }
- break;
- }
- case NCoderPropID::kNumThreads:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- bool newMultiThread = (prop.ulVal > 1);
- if (newMultiThread != _multiThread)
- {
- _dictionarySizePrev = (UInt32)-1;
- ReleaseMatchFinder();
- _multiThread = newMultiThread;
- }
- break;
- }
- #endif
- case NCoderPropID::kDictionarySize:
- {
- const int kDicLogSizeMaxCompress = 30;
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 dictionarySize = prop.ulVal;
- if (dictionarySize < UInt32(1 << kDicLogSizeMin) ||
- dictionarySize > UInt32(1 << kDicLogSizeMaxCompress))
- return E_INVALIDARG;
- _dictionarySize = dictionarySize;
- UInt32 dicLogSize;
- for(dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)
- if (dictionarySize <= (UInt32(1) << dicLogSize))
- break;
- _distTableSize = dicLogSize * 2;
- break;
- }
- case NCoderPropID::kPosStateBits:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 value = prop.ulVal;
- if (value > (UInt32)NLength::kNumPosStatesBitsEncodingMax)
- return E_INVALIDARG;
- _posStateBits = value;
- _posStateMask = (1 << _posStateBits) - 1;
- break;
- }
- case NCoderPropID::kLitPosBits:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 value = prop.ulVal;
- if (value > (UInt32)kNumLitPosStatesBitsEncodingMax)
- return E_INVALIDARG;
- _numLiteralPosStateBits = value;
- break;
- }
- case NCoderPropID::kLitContextBits:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 value = prop.ulVal;
- if (value > (UInt32)kNumLitContextBitsMax)
- return E_INVALIDARG;
- _numLiteralContextBits = value;
- break;
- }
- case NCoderPropID::kEndMarker:
- {
- if (prop.vt != VT_BOOL)
- return E_INVALIDARG;
- SetWriteEndMarkerMode(prop.boolVal == VARIANT_TRUE);
- break;
- }
- default:
- return E_INVALIDARG;
- }
- }
- return S_OK;
-}
-
-STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
-{
- const UInt32 kPropSize = 5;
- Byte properties[kPropSize];
- properties[0] = (_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits;
- for (int i = 0; i < 4; i++)
- properties[1 + i] = Byte(_dictionarySize >> (8 * i));
- return WriteStream(outStream, properties, kPropSize, NULL);
-}
-
-STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream)
-{
- _rangeEncoder.SetStream(outStream);
- return S_OK;
-}
-
-STDMETHODIMP CEncoder::ReleaseOutStream()
-{
- _rangeEncoder.ReleaseStream();
- return S_OK;
-}
-
-HRESULT CEncoder::Init()
-{
- CBaseState::Init();
-
- // RINOK(_matchFinder->Init(inStream));
- _rangeEncoder.Init();
-
- for(int i = 0; i < kNumStates; i++)
- {
- for (UInt32 j = 0; j <= _posStateMask; j++)
- {
- _isMatch[i][j].Init();
- _isRep0Long[i][j].Init();
- }
- _isRep[i].Init();
- _isRepG0[i].Init();
- _isRepG1[i].Init();
- _isRepG2[i].Init();
- }
-
- _literalEncoder.Init();
-
- {
- for(UInt32 i = 0; i < kNumLenToPosStates; i++)
- _posSlotEncoder[i].Init();
- }
- {
- for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
- _posEncoders[i].Init();
- }
-
- _lenEncoder.Init(1 << _posStateBits);
- _repMatchLenEncoder.Init(1 << _posStateBits);
-
- _posAlignEncoder.Init();
-
- _longestMatchWasFound = false;
- _optimumEndIndex = 0;
- _optimumCurrentIndex = 0;
- _additionalOffset = 0;
-
- return S_OK;
-}
-
-HRESULT CEncoder::MovePos(UInt32 num)
-{
- if (num == 0)
- return S_OK;
- _additionalOffset += num;
- return _matchFinder->Skip(num);
-}
-
-UInt32 CEncoder::Backward(UInt32 &backRes, UInt32 cur)
-{
- _optimumEndIndex = cur;
- UInt32 posMem = _optimum[cur].PosPrev;
- UInt32 backMem = _optimum[cur].BackPrev;
- do
- {
- if (_optimum[cur].Prev1IsChar)
- {
- _optimum[posMem].MakeAsChar();
- _optimum[posMem].PosPrev = posMem - 1;
- if (_optimum[cur].Prev2)
- {
- _optimum[posMem - 1].Prev1IsChar = false;
- _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
- _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
- }
- }
- UInt32 posPrev = posMem;
- UInt32 backCur = backMem;
-
- backMem = _optimum[posPrev].BackPrev;
- posMem = _optimum[posPrev].PosPrev;
-
- _optimum[posPrev].BackPrev = backCur;
- _optimum[posPrev].PosPrev = cur;
- cur = posPrev;
- }
- while(cur != 0);
- backRes = _optimum[0].BackPrev;
- _optimumCurrentIndex = _optimum[0].PosPrev;
- return _optimumCurrentIndex;
-}
-
-/*
-Out:
- (lenRes == 1) && (backRes == 0xFFFFFFFF) means Literal
-*/
-
-HRESULT CEncoder::GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes)
-{
- if(_optimumEndIndex != _optimumCurrentIndex)
- {
- const COptimal &optimum = _optimum[_optimumCurrentIndex];
- lenRes = optimum.PosPrev - _optimumCurrentIndex;
- backRes = optimum.BackPrev;
- _optimumCurrentIndex = optimum.PosPrev;
- return S_OK;
- }
- _optimumCurrentIndex = _optimumEndIndex = 0;
-
- UInt32 lenMain, numDistancePairs;
- if (!_longestMatchWasFound)
- {
- RINOK(ReadMatchDistances(lenMain, numDistancePairs));
- }
- else
- {
- lenMain = _longestMatchLength;
- numDistancePairs = _numDistancePairs;
- _longestMatchWasFound = false;
- }
-
- const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1;
- UInt32 numAvailableBytes = _matchFinder->GetNumAvailableBytes() + 1;
- if (numAvailableBytes < 2)
- {
- backRes = (UInt32)(-1);
- lenRes = 1;
- return S_OK;
- }
- if (numAvailableBytes > kMatchMaxLen)
- numAvailableBytes = kMatchMaxLen;
-
- UInt32 reps[kNumRepDistances];
- UInt32 repLens[kNumRepDistances];
- UInt32 repMaxIndex = 0;
- UInt32 i;
- for(i = 0; i < kNumRepDistances; i++)
- {
- reps[i] = _repDistances[i];
- UInt32 backOffset = reps[i] + 1;
- if (data[0] != data[(size_t)0 - backOffset] || data[1] != data[(size_t)1 - backOffset])
- {
- repLens[i] = 0;
- continue;
- }
- UInt32 lenTest;
- for (lenTest = 2; lenTest < numAvailableBytes &&
- data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++);
- repLens[i] = lenTest;
- if (lenTest > repLens[repMaxIndex])
- repMaxIndex = i;
- }
- if(repLens[repMaxIndex] >= _numFastBytes)
- {
- backRes = repMaxIndex;
- lenRes = repLens[repMaxIndex];
- return MovePos(lenRes - 1);
- }
-
- UInt32 *matchDistances = _matchDistances + 1;
- if(lenMain >= _numFastBytes)
- {
- backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances;
- lenRes = lenMain;
- return MovePos(lenMain - 1);
- }
- Byte currentByte = *data;
- Byte matchByte = data[(size_t)0 - reps[0] - 1];
-
- if(lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
- {
- backRes = (UInt32)-1;
- lenRes = 1;
- return S_OK;
- }
-
- _optimum[0].State = _state;
-
- UInt32 posState = (position & _posStateMask);
-
- _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice0() +
- _literalEncoder.GetSubCoder(position, _previousByte)->GetPrice(!_state.IsCharState(), matchByte, currentByte);
- _optimum[1].MakeAsChar();
-
- UInt32 matchPrice = _isMatch[_state.Index][posState].GetPrice1();
- UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1();
-
- if(matchByte == currentByte)
- {
- UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
- if(shortRepPrice < _optimum[1].Price)
- {
- _optimum[1].Price = shortRepPrice;
- _optimum[1].MakeAsShortRep();
- }
- }
- UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
-
- if(lenEnd < 2)
- {
- backRes = _optimum[1].BackPrev;
- lenRes = 1;
- return S_OK;
- }
-
- _optimum[1].PosPrev = 0;
- for (i = 0; i < kNumRepDistances; i++)
- _optimum[0].Backs[i] = reps[i];
-
- UInt32 len = lenEnd;
- do
- _optimum[len--].Price = kIfinityPrice;
- while (len >= 2);
-
- for(i = 0; i < kNumRepDistances; i++)
- {
- UInt32 repLen = repLens[i];
- if (repLen < 2)
- continue;
- UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState);
- do
- {
- UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
- COptimal &optimum = _optimum[repLen];
- if (curAndLenPrice < optimum.Price)
- {
- optimum.Price = curAndLenPrice;
- optimum.PosPrev = 0;
- optimum.BackPrev = i;
- optimum.Prev1IsChar = false;
- }
- }
- while(--repLen >= 2);
- }
-
- UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0();
-
- len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
- if (len <= lenMain)
- {
- UInt32 offs = 0;
- while (len > matchDistances[offs])
- offs += 2;
- for(; ; len++)
- {
- UInt32 distance = matchDistances[offs + 1];
- UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
- COptimal &optimum = _optimum[len];
- if (curAndLenPrice < optimum.Price)
- {
- optimum.Price = curAndLenPrice;
- optimum.PosPrev = 0;
- optimum.BackPrev = distance + kNumRepDistances;
- optimum.Prev1IsChar = false;
- }
- if (len == matchDistances[offs])
- {
- offs += 2;
- if (offs == numDistancePairs)
- break;
- }
- }
- }
-
- UInt32 cur = 0;
-
- while(true)
- {
- cur++;
- if(cur == lenEnd)
- {
- lenRes = Backward(backRes, cur);
- return S_OK;
- }
- UInt32 newLen, numDistancePairs;
- RINOK(ReadMatchDistances(newLen, numDistancePairs));
- if(newLen >= _numFastBytes)
- {
- _numDistancePairs = numDistancePairs;
- _longestMatchLength = newLen;
- _longestMatchWasFound = true;
- lenRes = Backward(backRes, cur);
- return S_OK;
- }
- position++;
- COptimal &curOptimum = _optimum[cur];
- UInt32 posPrev = curOptimum.PosPrev;
- CState state;
- if (curOptimum.Prev1IsChar)
- {
- posPrev--;
- if (curOptimum.Prev2)
- {
- state = _optimum[curOptimum.PosPrev2].State;
- if (curOptimum.BackPrev2 < kNumRepDistances)
- state.UpdateRep();
- else
- state.UpdateMatch();
- }
- else
- state = _optimum[posPrev].State;
- state.UpdateChar();
- }
- else
- state = _optimum[posPrev].State;
- if (posPrev == cur - 1)
- {
- if (curOptimum.IsShortRep())
- state.UpdateShortRep();
- else
- state.UpdateChar();
- }
- else
- {
- UInt32 pos;
- if (curOptimum.Prev1IsChar && curOptimum.Prev2)
- {
- posPrev = curOptimum.PosPrev2;
- pos = curOptimum.BackPrev2;
- state.UpdateRep();
- }
- else
- {
- pos = curOptimum.BackPrev;
- if (pos < kNumRepDistances)
- state.UpdateRep();
- else
- state.UpdateMatch();
- }
- const COptimal &prevOptimum = _optimum[posPrev];
- if (pos < kNumRepDistances)
- {
- reps[0] = prevOptimum.Backs[pos];
- UInt32 i;
- for(i = 1; i <= pos; i++)
- reps[i] = prevOptimum.Backs[i - 1];
- for(; i < kNumRepDistances; i++)
- reps[i] = prevOptimum.Backs[i];
- }
- else
- {
- reps[0] = (pos - kNumRepDistances);
- for(UInt32 i = 1; i < kNumRepDistances; i++)
- reps[i] = prevOptimum.Backs[i - 1];
- }
- }
- curOptimum.State = state;
- for(UInt32 i = 0; i < kNumRepDistances; i++)
- curOptimum.Backs[i] = reps[i];
- UInt32 curPrice = curOptimum.Price;
- const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1;
- const Byte currentByte = *data;
- const Byte matchByte = data[(size_t)0 - reps[0] - 1];
-
- UInt32 posState = (position & _posStateMask);
-
- UInt32 curAnd1Price = curPrice +
- _isMatch[state.Index][posState].GetPrice0() +
- _literalEncoder.GetSubCoder(position, data[(size_t)0 - 1])->GetPrice(!state.IsCharState(), matchByte, currentByte);
-
- COptimal &nextOptimum = _optimum[cur + 1];
-
- bool nextIsChar = false;
- if (curAnd1Price < nextOptimum.Price)
- {
- nextOptimum.Price = curAnd1Price;
- nextOptimum.PosPrev = cur;
- nextOptimum.MakeAsChar();
- nextIsChar = true;
- }
-
- UInt32 matchPrice = curPrice + _isMatch[state.Index][posState].GetPrice1();
- UInt32 repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1();
-
- if(matchByte == currentByte &&
- !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
- {
- UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
- if(shortRepPrice <= nextOptimum.Price)
- {
- nextOptimum.Price = shortRepPrice;
- nextOptimum.PosPrev = cur;
- nextOptimum.MakeAsShortRep();
- nextIsChar = true;
- }
- }
- /*
- if(newLen == 2 && matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ?
- continue;
- */
-
- UInt32 numAvailableBytesFull = _matchFinder->GetNumAvailableBytes() + 1;
- numAvailableBytesFull = MyMin(kNumOpts - 1 - cur, numAvailableBytesFull);
- UInt32 numAvailableBytes = numAvailableBytesFull;
-
- if (numAvailableBytes < 2)
- continue;
- if (numAvailableBytes > _numFastBytes)
- numAvailableBytes = _numFastBytes;
- if (!nextIsChar && matchByte != currentByte) // speed optimization
- {
- // try Literal + rep0
- UInt32 backOffset = reps[0] + 1;
- UInt32 limit = MyMin(numAvailableBytesFull, _numFastBytes + 1);
- UInt32 temp;
- for (temp = 1; temp < limit &&
- data[temp] == data[(size_t)temp - backOffset]; temp++);
- UInt32 lenTest2 = temp - 1;
- if (lenTest2 >= 2)
- {
- CState state2 = state;
- state2.UpdateChar();
- UInt32 posStateNext = (position + 1) & _posStateMask;
- UInt32 nextRepMatchPrice = curAnd1Price +
- _isMatch[state2.Index][posStateNext].GetPrice1() +
- _isRep[state2.Index].GetPrice1();
- // for (; lenTest2 >= 2; lenTest2--)
- {
- UInt32 offset = cur + 1 + lenTest2;
- while(lenEnd < offset)
- _optimum[++lenEnd].Price = kIfinityPrice;
- UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
- 0, lenTest2, state2, posStateNext);
- COptimal &optimum = _optimum[offset];
- if (curAndLenPrice < optimum.Price)
- {
- optimum.Price = curAndLenPrice;
- optimum.PosPrev = cur + 1;
- optimum.BackPrev = 0;
- optimum.Prev1IsChar = true;
- optimum.Prev2 = false;
- }
- }
- }
- }
-
- UInt32 startLen = 2; // speed optimization
- for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++)
- {
- // UInt32 repLen = _matchFinder->GetMatchLen(0 - 1, reps[repIndex], newLen); // test it;
- UInt32 backOffset = reps[repIndex] + 1;
- if (data[0] != data[(size_t)0 - backOffset] ||
- data[1] != data[(size_t)1 - backOffset])
- continue;
- UInt32 lenTest;
- for (lenTest = 2; lenTest < numAvailableBytes &&
- data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++);
- while(lenEnd < cur + lenTest)
- _optimum[++lenEnd].Price = kIfinityPrice;
- UInt32 lenTestTemp = lenTest;
- UInt32 price = repMatchPrice + GetPureRepPrice(repIndex, state, posState);
- do
- {
- UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState);
- COptimal &optimum = _optimum[cur + lenTest];
- if (curAndLenPrice < optimum.Price)
- {
- optimum.Price = curAndLenPrice;
- optimum.PosPrev = cur;
- optimum.BackPrev = repIndex;
- optimum.Prev1IsChar = false;
- }
- }
- while(--lenTest >= 2);
- lenTest = lenTestTemp;
-
- if (repIndex == 0)
- startLen = lenTest + 1;
-
- // if (_maxMode)
- {
- UInt32 lenTest2 = lenTest + 1;
- UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
- for (; lenTest2 < limit &&
- data[lenTest2] == data[(size_t)lenTest2 - backOffset]; lenTest2++);
- lenTest2 -= lenTest + 1;
- if (lenTest2 >= 2)
- {
- CState state2 = state;
- state2.UpdateRep();
- UInt32 posStateNext = (position + lenTest) & _posStateMask;
- UInt32 curAndLenCharPrice =
- price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState) +
- _isMatch[state2.Index][posStateNext].GetPrice0() +
- _literalEncoder.GetSubCoder(position + lenTest, data[(size_t)lenTest - 1])->GetPrice(
- true, data[(size_t)lenTest - backOffset], data[lenTest]);
- state2.UpdateChar();
- posStateNext = (position + lenTest + 1) & _posStateMask;
- UInt32 nextRepMatchPrice = curAndLenCharPrice +
- _isMatch[state2.Index][posStateNext].GetPrice1() +
- _isRep[state2.Index].GetPrice1();
-
- // for(; lenTest2 >= 2; lenTest2--)
- {
- UInt32 offset = cur + lenTest + 1 + lenTest2;
- while(lenEnd < offset)
- _optimum[++lenEnd].Price = kIfinityPrice;
- UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
- 0, lenTest2, state2, posStateNext);
- COptimal &optimum = _optimum[offset];
- if (curAndLenPrice < optimum.Price)
- {
- optimum.Price = curAndLenPrice;
- optimum.PosPrev = cur + lenTest + 1;
- optimum.BackPrev = 0;
- optimum.Prev1IsChar = true;
- optimum.Prev2 = true;
- optimum.PosPrev2 = cur;
- optimum.BackPrev2 = repIndex;
- }
- }
- }
- }
- }
-
- // for(UInt32 lenTest = 2; lenTest <= newLen; lenTest++)
- if (newLen > numAvailableBytes)
- {
- newLen = numAvailableBytes;
- for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2);
- matchDistances[numDistancePairs] = newLen;
- numDistancePairs += 2;
- }
- if (newLen >= startLen)
- {
- UInt32 normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0();
- while(lenEnd < cur + newLen)
- _optimum[++lenEnd].Price = kIfinityPrice;
-
- UInt32 offs = 0;
- while(startLen > matchDistances[offs])
- offs += 2;
- UInt32 curBack = matchDistances[offs + 1];
- UInt32 posSlot = GetPosSlot2(curBack);
- for(UInt32 lenTest = /*2*/ startLen; ; lenTest++)
- {
- UInt32 curAndLenPrice = normalMatchPrice;
- UInt32 lenToPosState = GetLenToPosState(lenTest);
- if (curBack < kNumFullDistances)
- curAndLenPrice += _distancesPrices[lenToPosState][curBack];
- else
- curAndLenPrice += _posSlotPrices[lenToPosState][posSlot] + _alignPrices[curBack & kAlignMask];
-
- curAndLenPrice += _lenEncoder.GetPrice(lenTest - kMatchMinLen, posState);
-
- COptimal &optimum = _optimum[cur + lenTest];
- if (curAndLenPrice < optimum.Price)
- {
- optimum.Price = curAndLenPrice;
- optimum.PosPrev = cur;
- optimum.BackPrev = curBack + kNumRepDistances;
- optimum.Prev1IsChar = false;
- }
-
- if (/*_maxMode && */lenTest == matchDistances[offs])
- {
- // Try Match + Literal + Rep0
- UInt32 backOffset = curBack + 1;
- UInt32 lenTest2 = lenTest + 1;
- UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
- for (; lenTest2 < limit &&
- data[lenTest2] == data[(size_t)lenTest2 - backOffset]; lenTest2++);
- lenTest2 -= lenTest + 1;
- if (lenTest2 >= 2)
- {
- CState state2 = state;
- state2.UpdateMatch();
- UInt32 posStateNext = (position + lenTest) & _posStateMask;
- UInt32 curAndLenCharPrice = curAndLenPrice +
- _isMatch[state2.Index][posStateNext].GetPrice0() +
- _literalEncoder.GetSubCoder(position + lenTest, data[(size_t)lenTest - 1])->GetPrice(
- true, data[(size_t)lenTest - backOffset], data[lenTest]);
- state2.UpdateChar();
- posStateNext = (posStateNext + 1) & _posStateMask;
- UInt32 nextRepMatchPrice = curAndLenCharPrice +
- _isMatch[state2.Index][posStateNext].GetPrice1() +
- _isRep[state2.Index].GetPrice1();
-
- // for(; lenTest2 >= 2; lenTest2--)
- {
- UInt32 offset = cur + lenTest + 1 + lenTest2;
- while(lenEnd < offset)
- _optimum[++lenEnd].Price = kIfinityPrice;
- UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
- COptimal &optimum = _optimum[offset];
- if (curAndLenPrice < optimum.Price)
- {
- optimum.Price = curAndLenPrice;
- optimum.PosPrev = cur + lenTest + 1;
- optimum.BackPrev = 0;
- optimum.Prev1IsChar = true;
- optimum.Prev2 = true;
- optimum.PosPrev2 = cur;
- optimum.BackPrev2 = curBack + kNumRepDistances;
- }
- }
- }
- offs += 2;
- if (offs == numDistancePairs)
- break;
- curBack = matchDistances[offs + 1];
- if (curBack >= kNumFullDistances)
- posSlot = GetPosSlot2(curBack);
- }
- }
- }
- }
-}
-
-static inline bool ChangePair(UInt32 smallDist, UInt32 bigDist)
-{
- return ((bigDist >> 7) > smallDist);
-}
-
-
-HRESULT CEncoder::ReadMatchDistances(UInt32 &lenRes, UInt32 &numDistancePairs)
-{
- lenRes = 0;
- RINOK(_matchFinder->GetMatches(_matchDistances));
- numDistancePairs = _matchDistances[0];
- if (numDistancePairs > 0)
- {
- lenRes = _matchDistances[1 + numDistancePairs - 2];
- if (lenRes == _numFastBytes)
- lenRes += _matchFinder->GetMatchLen(lenRes - 1, _matchDistances[1 + numDistancePairs - 1],
- kMatchMaxLen - lenRes);
- }
- _additionalOffset++;
- return S_OK;
-}
-
-HRESULT CEncoder::GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes)
-{
- UInt32 lenMain, numDistancePairs;
- if (!_longestMatchWasFound)
- {
- RINOK(ReadMatchDistances(lenMain, numDistancePairs));
- }
- else
- {
- lenMain = _longestMatchLength;
- numDistancePairs = _numDistancePairs;
- _longestMatchWasFound = false;
- }
-
- const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1;
- UInt32 numAvailableBytes = _matchFinder->GetNumAvailableBytes() + 1;
- if (numAvailableBytes > kMatchMaxLen)
- numAvailableBytes = kMatchMaxLen;
- if (numAvailableBytes < 2)
- {
- backRes = (UInt32)(-1);
- lenRes = 1;
- return S_OK;
- }
-
- UInt32 repLens[kNumRepDistances];
- UInt32 repMaxIndex = 0;
-
- for(UInt32 i = 0; i < kNumRepDistances; i++)
- {
- UInt32 backOffset = _repDistances[i] + 1;
- if (data[0] != data[(size_t)0 - backOffset] || data[1] != data[(size_t)1 - backOffset])
- {
- repLens[i] = 0;
- continue;
- }
- UInt32 len;
- for (len = 2; len < numAvailableBytes && data[len] == data[(size_t)len - backOffset]; len++);
- if(len >= _numFastBytes)
- {
- backRes = i;
- lenRes = len;
- return MovePos(lenRes - 1);
- }
- repLens[i] = len;
- if (len > repLens[repMaxIndex])
- repMaxIndex = i;
- }
- UInt32 *matchDistances = _matchDistances + 1;
- if(lenMain >= _numFastBytes)
- {
- backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances;
- lenRes = lenMain;
- return MovePos(lenMain - 1);
- }
-
- UInt32 backMain = 0; // for GCC
- if (lenMain >= 2)
- {
- backMain = matchDistances[numDistancePairs - 1];
- while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1)
- {
- if (!ChangePair(matchDistances[numDistancePairs - 3], backMain))
- break;
- numDistancePairs -= 2;
- lenMain = matchDistances[numDistancePairs - 2];
- backMain = matchDistances[numDistancePairs - 1];
- }
- if (lenMain == 2 && backMain >= 0x80)
- lenMain = 1;
- }
-
- if (repLens[repMaxIndex] >= 2)
- {
- if (repLens[repMaxIndex] + 1 >= lenMain ||
- repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9)) ||
- repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15)))
- {
- backRes = repMaxIndex;
- lenRes = repLens[repMaxIndex];
- return MovePos(lenRes - 1);
- }
- }
-
- if (lenMain >= 2 && numAvailableBytes > 2)
- {
- RINOK(ReadMatchDistances(_longestMatchLength, _numDistancePairs));
- if (_longestMatchLength >= 2)
- {
- UInt32 newDistance = matchDistances[_numDistancePairs - 1];
- if (_longestMatchLength >= lenMain && newDistance < backMain ||
- _longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance) ||
- _longestMatchLength > lenMain + 1 ||
- _longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain))
- {
- _longestMatchWasFound = true;
- backRes = UInt32(-1);
- lenRes = 1;
- return S_OK;
- }
- }
- data++;
- numAvailableBytes--;
- for(UInt32 i = 0; i < kNumRepDistances; i++)
- {
- UInt32 backOffset = _repDistances[i] + 1;
- if (data[1] != data[(size_t)1 - backOffset] || data[2] != data[(size_t)2 - backOffset])
- {
- repLens[i] = 0;
- continue;
- }
- UInt32 len;
- for (len = 2; len < numAvailableBytes && data[len] == data[(size_t)len - backOffset]; len++);
- if (len + 1 >= lenMain)
- {
- _longestMatchWasFound = true;
- backRes = UInt32(-1);
- lenRes = 1;
- return S_OK;
- }
- }
- backRes = backMain + kNumRepDistances;
- lenRes = lenMain;
- return MovePos(lenMain - 2);
- }
- backRes = UInt32(-1);
- lenRes = 1;
- return S_OK;
-}
-
-HRESULT CEncoder::Flush(UInt32 nowPos)
-{
- ReleaseMFStream();
- WriteEndMarker(nowPos & _posStateMask);
- _rangeEncoder.FlushData();
- return _rangeEncoder.FlushStream();
-}
-
-void CEncoder::WriteEndMarker(UInt32 posState)
-{
- // This function for writing End Mark for stream version of LZMA.
- // In current version this feature is not used.
- if (!_writeEndMark)
- return;
-
- _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
- _isRep[_state.Index].Encode(&_rangeEncoder, 0);
- _state.UpdateMatch();
- UInt32 len = kMatchMinLen; // kMatchMaxLen;
- _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
- UInt32 posSlot = (1 << kNumPosSlotBits) - 1;
- UInt32 lenToPosState = GetLenToPosState(len);
- _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot);
- UInt32 footerBits = 30;
- UInt32 posReduced = (UInt32(1) << footerBits) - 1;
- _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
- _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
-}
-
-HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
- ISequentialOutStream *outStream,
- const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress)
-{
- _needReleaseMFStream = false;
- CCoderReleaser coderReleaser(this);
- RINOK(SetStreams(inStream, outStream, inSize, outSize));
- while(true)
- {
- UInt64 processedInSize;
- UInt64 processedOutSize;
- Int32 finished;
- RINOK(CodeOneBlock(&processedInSize, &processedOutSize, &finished));
- if (finished != 0)
- return S_OK;
- if (progress != 0)
- {
- RINOK(progress->SetRatioInfo(&processedInSize, &processedOutSize));
- }
- }
-}
-
-HRESULT CEncoder::SetStreams(ISequentialInStream *inStream,
- ISequentialOutStream *outStream,
- const UInt64 *inSize, const UInt64 *outSize)
-{
- _inStream = inStream;
- _finished = false;
- RINOK(Create());
- RINOK(SetOutStream(outStream));
- RINOK(Init());
-
- // CCoderReleaser releaser(this);
-
- /*
- if (_matchFinder->GetNumAvailableBytes() == 0)
- return Flush();
- */
-
- if (!_fastMode)
- {
- FillDistancesPrices();
- FillAlignPrices();
- }
-
- _lenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
- _lenEncoder.UpdateTables(1 << _posStateBits);
- _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
- _repMatchLenEncoder.UpdateTables(1 << _posStateBits);
-
- nowPos64 = 0;
- return S_OK;
-}
-
-HRESULT CEncoder::CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished)
-{
- if (_inStream != 0)
- {
- RINOK(_matchFinder->SetStream(_inStream));
- RINOK(_matchFinder->Init());
- _needReleaseMFStream = true;
- _inStream = 0;
- }
-
-
- *finished = 1;
- if (_finished)
- return S_OK;
- _finished = true;
-
- if (nowPos64 == 0)
- {
- if (_matchFinder->GetNumAvailableBytes() == 0)
- return Flush(UInt32(nowPos64));
- UInt32 len, numDistancePairs;
- RINOK(ReadMatchDistances(len, numDistancePairs));
- UInt32 posState = UInt32(nowPos64) & _posStateMask;
- _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
- _state.UpdateChar();
- Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset);
- _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte)->Encode(&_rangeEncoder, curByte);
- _previousByte = curByte;
- _additionalOffset--;
- nowPos64++;
- }
-
- UInt32 nowPos32 = (UInt32)nowPos64;
- UInt32 progressPosValuePrev = nowPos32;
-
- if (_matchFinder->GetNumAvailableBytes() == 0)
- return Flush(nowPos32);
-
- while(true)
- {
- #ifdef _NO_EXCEPTIONS
- if (_rangeEncoder.Stream.ErrorCode != S_OK)
- return _rangeEncoder.Stream.ErrorCode;
- #endif
- UInt32 pos, len;
- HRESULT result;
- if (_fastMode)
- result = GetOptimumFast(nowPos32, pos, len);
- else
- result = GetOptimum(nowPos32, pos, len);
- RINOK(result);
-
- UInt32 posState = nowPos32 & _posStateMask;
- if(len == 1 && pos == 0xFFFFFFFF)
- {
- _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
- Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset);
- CLiteralEncoder2 *subCoder = _literalEncoder.GetSubCoder(nowPos32, _previousByte);
- if(_state.IsCharState())
- subCoder->Encode(&_rangeEncoder, curByte);
- else
- {
- Byte matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - _additionalOffset);
- subCoder->EncodeMatched(&_rangeEncoder, matchByte, curByte);
- }
- _state.UpdateChar();
- _previousByte = curByte;
- }
- else
- {
- _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
- if(pos < kNumRepDistances)
- {
- _isRep[_state.Index].Encode(&_rangeEncoder, 1);
- if(pos == 0)
- {
- _isRepG0[_state.Index].Encode(&_rangeEncoder, 0);
- _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, ((len == 1) ? 0 : 1));
- }
- else
- {
- UInt32 distance = _repDistances[pos];
- _isRepG0[_state.Index].Encode(&_rangeEncoder, 1);
- if (pos == 1)
- _isRepG1[_state.Index].Encode(&_rangeEncoder, 0);
- else
- {
- _isRepG1[_state.Index].Encode(&_rangeEncoder, 1);
- _isRepG2[_state.Index].Encode(&_rangeEncoder, pos - 2);
- if (pos == 3)
- _repDistances[3] = _repDistances[2];
- _repDistances[2] = _repDistances[1];
- }
- _repDistances[1] = _repDistances[0];
- _repDistances[0] = distance;
- }
- if (len == 1)
- _state.UpdateShortRep();
- else
- {
- _repMatchLenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
- _state.UpdateRep();
- }
- }
- else
- {
- _isRep[_state.Index].Encode(&_rangeEncoder, 0);
- _state.UpdateMatch();
- _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
- pos -= kNumRepDistances;
- UInt32 posSlot = GetPosSlot(pos);
- _posSlotEncoder[GetLenToPosState(len)].Encode(&_rangeEncoder, posSlot);
-
- if (posSlot >= kStartPosModelIndex)
- {
- UInt32 footerBits = ((posSlot >> 1) - 1);
- UInt32 base = ((2 | (posSlot & 1)) << footerBits);
- UInt32 posReduced = pos - base;
-
- if (posSlot < kEndPosModelIndex)
- NRangeCoder::ReverseBitTreeEncode(_posEncoders + base - posSlot - 1,
- &_rangeEncoder, footerBits, posReduced);
- else
- {
- _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
- _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
- _alignPriceCount++;
- }
- }
- _repDistances[3] = _repDistances[2];
- _repDistances[2] = _repDistances[1];
- _repDistances[1] = _repDistances[0];
- _repDistances[0] = pos;
- _matchPriceCount++;
- }
- _previousByte = _matchFinder->GetIndexByte(len - 1 - _additionalOffset);
- }
- _additionalOffset -= len;
- nowPos32 += len;
- if (_additionalOffset == 0)
- {
- if (!_fastMode)
- {
- if (_matchPriceCount >= (1 << 7))
- FillDistancesPrices();
- if (_alignPriceCount >= kAlignTableSize)
- FillAlignPrices();
- }
- if (_matchFinder->GetNumAvailableBytes() == 0)
- return Flush(nowPos32);
- if (nowPos32 - progressPosValuePrev >= (1 << 14))
- {
- nowPos64 += nowPos32 - progressPosValuePrev;
- *inSize = nowPos64;
- *outSize = _rangeEncoder.GetProcessedSize();
- _finished = false;
- *finished = 0;
- return S_OK;
- }
- }
- }
-}
-
-STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
- ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress)
-{
- #ifndef _NO_EXCEPTIONS
- try
- {
- #endif
- return CodeReal(inStream, outStream, inSize, outSize, progress);
- #ifndef _NO_EXCEPTIONS
- }
- catch(const COutBufferException &e) { return e.ErrorCode; }
- catch(...) { return E_FAIL; }
- #endif
-}
-
-void CEncoder::FillDistancesPrices()
-{
- UInt32 tempPrices[kNumFullDistances];
- for (UInt32 i = kStartPosModelIndex; i < kNumFullDistances; i++)
- {
- UInt32 posSlot = GetPosSlot(i);
- UInt32 footerBits = ((posSlot >> 1) - 1);
- UInt32 base = ((2 | (posSlot & 1)) << footerBits);
- tempPrices[i] = NRangeCoder::ReverseBitTreeGetPrice(_posEncoders +
- base - posSlot - 1, footerBits, i - base);
- }
-
- for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
- {
- UInt32 posSlot;
- NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> &encoder = _posSlotEncoder[lenToPosState];
- UInt32 *posSlotPrices = _posSlotPrices[lenToPosState];
- for (posSlot = 0; posSlot < _distTableSize; posSlot++)
- posSlotPrices[posSlot] = encoder.GetPrice(posSlot);
- for (posSlot = kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
- posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << NRangeCoder::kNumBitPriceShiftBits);
-
- UInt32 *distancesPrices = _distancesPrices[lenToPosState];
- UInt32 i;
- for (i = 0; i < kStartPosModelIndex; i++)
- distancesPrices[i] = posSlotPrices[i];
- for (; i < kNumFullDistances; i++)
- distancesPrices[i] = posSlotPrices[GetPosSlot(i)] + tempPrices[i];
- }
- _matchPriceCount = 0;
-}
-
-void CEncoder::FillAlignPrices()
-{
- for (UInt32 i = 0; i < kAlignTableSize; i++)
- _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
- _alignPriceCount = 0;
-}
-
-}}
+/*
+ * LZMAEncoder.cpp
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "StdAfx.h"
+
+#include "../../../Common/Defs.h"
+#include "../../Common/StreamUtils.h"
+
+#include "LZMAEncoder.h"
+
+// for minimal compressing code size define these:
+// #define COMPRESS_MF_BT
+// #define COMPRESS_MF_BT4
+
+#if !defined(COMPRESS_MF_BT) && !defined(COMPRESS_MF_HC)
+#define COMPRESS_MF_BT
+#define COMPRESS_MF_HC
+#endif
+
+#ifdef COMPRESS_MF_BT
+#if !defined(COMPRESS_MF_BT2) && !defined(COMPRESS_MF_BT3) && !defined(COMPRESS_MF_BT4)
+#define COMPRESS_MF_BT2
+#define COMPRESS_MF_BT3
+#define COMPRESS_MF_BT4
+#endif
+#ifdef COMPRESS_MF_BT2
+#include "../LZ/BinTree/BinTree2.h"
+#endif
+#ifdef COMPRESS_MF_BT3
+#include "../LZ/BinTree/BinTree3.h"
+#endif
+#ifdef COMPRESS_MF_BT4
+#include "../LZ/BinTree/BinTree4.h"
+#endif
+#endif
+
+#ifdef COMPRESS_MF_HC
+#include "../LZ/HashChain/HC4.h"
+#endif
+
+#ifdef COMPRESS_MF_MT
+#include "../LZ/MT/MT.h"
+#endif
+
+namespace NCompress {
+namespace NLZMA {
+
+const int kDefaultDictionaryLogSize = 22;
+const UInt32 kNumFastBytesDefault = 0x20;
+
+enum
+{
+ kBT2,
+ kBT3,
+ kBT4,
+ kHC4
+};
+
+/*static const wchar_t *kMatchFinderIDs[] =
+{
+ L"BT2",
+ L"BT3",
+ L"BT4",
+ L"HC4"
+};*/
+
+Byte g_FastPos[1 << 11];
+
+class CFastPosInit
+{
+public:
+ CFastPosInit() { Init(); }
+ void Init()
+ {
+ const Byte kFastSlots = 22;
+ int c = 2;
+ g_FastPos[0] = 0;
+ g_FastPos[1] = 1;
+
+ for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++)
+ {
+ UInt32 k = (1 << ((slotFast >> 1) - 1));
+ for (UInt32 j = 0; j < k; j++, c++)
+ g_FastPos[c] = slotFast;
+ }
+ }
+} g_FastPosInit;
+
+
+void CLiteralEncoder2::Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol)
+{
+ UInt32 context = 1;
+ int i = 8;
+ do
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ _encoders[context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ }
+ while(i != 0);
+}
+
+void CLiteralEncoder2::EncodeMatched(NRangeCoder::CEncoder *rangeEncoder,
+ Byte matchByte, Byte symbol)
+{
+ UInt32 context = 1;
+ int i = 8;
+ do
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ UInt32 matchBit = (matchByte >> i) & 1;
+ _encoders[0x100 + (matchBit << 8) + context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ if (matchBit != bit)
+ {
+ while(i != 0)
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ _encoders[context].Encode(rangeEncoder, bit);
+ context = (context << 1) | bit;
+ }
+ break;
+ }
+ }
+ while(i != 0);
+}
+
+UInt32 CLiteralEncoder2::GetPrice(bool matchMode, Byte matchByte, Byte symbol) const
+{
+ UInt32 price = 0;
+ UInt32 context = 1;
+ int i = 8;
+ if (matchMode)
+ {
+ do
+ {
+ i--;
+ UInt32 matchBit = (matchByte >> i) & 1;
+ UInt32 bit = (symbol >> i) & 1;
+ price += _encoders[0x100 + (matchBit << 8) + context].GetPrice(bit);
+ context = (context << 1) | bit;
+ if (matchBit != bit)
+ break;
+ }
+ while (i != 0);
+ }
+ while(i != 0)
+ {
+ i--;
+ UInt32 bit = (symbol >> i) & 1;
+ price += _encoders[context].GetPrice(bit);
+ context = (context << 1) | bit;
+ }
+ return price;
+};
+
+
+namespace NLength {
+
+void CEncoder::Init(UInt32 numPosStates)
+{
+ _choice.Init();
+ _choice2.Init();
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ {
+ _lowCoder[posState].Init();
+ _midCoder[posState].Init();
+ }
+ _highCoder.Init();
+}
+
+void CEncoder::Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState)
+{
+ if(symbol < kNumLowSymbols)
+ {
+ _choice.Encode(rangeEncoder, 0);
+ _lowCoder[posState].Encode(rangeEncoder, symbol);
+ }
+ else
+ {
+ _choice.Encode(rangeEncoder, 1);
+ if(symbol < kNumLowSymbols + kNumMidSymbols)
+ {
+ _choice2.Encode(rangeEncoder, 0);
+ _midCoder[posState].Encode(rangeEncoder, symbol - kNumLowSymbols);
+ }
+ else
+ {
+ _choice2.Encode(rangeEncoder, 1);
+ _highCoder.Encode(rangeEncoder, symbol - kNumLowSymbols - kNumMidSymbols);
+ }
+ }
+}
+
+void CEncoder::SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const
+{
+ UInt32 a0 = _choice.GetPrice0();
+ UInt32 a1 = _choice.GetPrice1();
+ UInt32 b0 = a1 + _choice2.GetPrice0();
+ UInt32 b1 = a1 + _choice2.GetPrice1();
+ UInt32 i = 0;
+ for (i = 0; i < kNumLowSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = a0 + _lowCoder[posState].GetPrice(i);
+ }
+ for (; i < kNumLowSymbols + kNumMidSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = b0 + _midCoder[posState].GetPrice(i - kNumLowSymbols);
+ }
+ for (; i < numSymbols; i++)
+ prices[i] = b1 + _highCoder.GetPrice(i - kNumLowSymbols - kNumMidSymbols);
+}
+
+}
+CEncoder::CEncoder():
+ _numFastBytes(kNumFastBytesDefault),
+ _distTableSize(kDefaultDictionaryLogSize * 2),
+ _posStateBits(2),
+ _posStateMask(4 - 1),
+ _numLiteralPosStateBits(0),
+ _numLiteralContextBits(3),
+ _dictionarySize(1 << kDefaultDictionaryLogSize),
+ _dictionarySizePrev(UInt32(-1)),
+ _numFastBytesPrev(UInt32(-1)),
+ _matchFinderCycles(0),
+ _matchFinderIndex(kBT4),
+ #ifdef COMPRESS_MF_MT
+ _multiThread(false),
+ #endif
+ _writeEndMark(false),
+ setMfPasses(0)
+{
+ // _maxMode = false;
+ _fastMode = false;
+}
+
+HRESULT CEncoder::Create()
+{
+ if (!_rangeEncoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
+ if (!_matchFinder)
+ {
+ switch(_matchFinderIndex)
+ {
+ #ifdef COMPRESS_MF_BT
+ #ifdef COMPRESS_MF_BT2
+ case kBT2:
+ {
+ NBT2::CMatchFinder *mfSpec = new NBT2::CMatchFinder;
+ setMfPasses = mfSpec;
+ _matchFinder = mfSpec;
+ break;
+ }
+ #endif
+ #ifdef COMPRESS_MF_BT3
+ case kBT3:
+ {
+ NBT3::CMatchFinder *mfSpec = new NBT3::CMatchFinder;
+ setMfPasses = mfSpec;
+ _matchFinder = mfSpec;
+ break;
+ }
+ #endif
+ #ifdef COMPRESS_MF_BT4
+ case kBT4:
+ {
+ NBT4::CMatchFinder *mfSpec = new NBT4::CMatchFinder;
+ setMfPasses = mfSpec;
+ _matchFinder = mfSpec;
+ break;
+ }
+ #endif
+ #endif
+
+ #ifdef COMPRESS_MF_HC
+ case kHC4:
+ {
+ NHC4::CMatchFinder *mfSpec = new NHC4::CMatchFinder;
+ setMfPasses = mfSpec;
+ _matchFinder = mfSpec;
+ break;
+ }
+ #endif
+ }
+ if (_matchFinder == 0)
+ return E_OUTOFMEMORY;
+
+ #ifdef COMPRESS_MF_MT
+ if (_multiThread && !(_fastMode && (_matchFinderIndex == kHC4)))
+ {
+ CMatchFinderMT *mfSpec = new CMatchFinderMT;
+ if (mfSpec == 0)
+ return E_OUTOFMEMORY;
+ CMyComPtr<IMatchFinder> mf = mfSpec;
+ RINOK(mfSpec->SetMatchFinder(_matchFinder));
+ _matchFinder.Release();
+ _matchFinder = mf;
+ }
+ #endif
+ }
+
+ if (!_literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits))
+ return E_OUTOFMEMORY;
+
+ if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes)
+ return S_OK;
+ RINOK(_matchFinder->Create(_dictionarySize, kNumOpts, _numFastBytes, kMatchMaxLen + 1)); // actually it's + _numFastBytes - _numFastBytes
+ if (_matchFinderCycles != 0 && setMfPasses != 0)
+ setMfPasses->SetNumPasses(_matchFinderCycles);
+ _dictionarySizePrev = _dictionarySize;
+ _numFastBytesPrev = _numFastBytes;
+ return S_OK;
+}
+
+/*static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString)
+{
+ while (true)
+ {
+ wchar_t c = *testString;
+ if (c >= 'a' && c <= 'z')
+ c -= 0x20;
+ if (*base != c)
+ return false;
+ if (c == 0)
+ return true;
+ base++;
+ testString++;
+ }
+}
+
+static int FindMatchFinder(const wchar_t *s)
+{
+ for (int m = 0; m < (int)(sizeof(kMatchFinderIDs) / sizeof(kMatchFinderIDs[0])); m++)
+ if (AreStringsEqual(kMatchFinderIDs[m], s))
+ return m;
+ return -1;
+}*/
+
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties)
+{
+ for (UInt32 i = 0; i < numProperties; i++)
+ {
+ const PROPVARIANT &prop = properties[i];
+ switch(propIDs[i])
+ {
+ case NCoderPropID::kNumFastBytes:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 numFastBytes = prop.ulVal;
+ if(numFastBytes < 5 || numFastBytes > kMatchMaxLen)
+ return E_INVALIDARG;
+ _numFastBytes = numFastBytes;
+ break;
+ }
+ case NCoderPropID::kMatchFinderCycles:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ _matchFinderCycles = prop.ulVal;
+ break;
+ }
+ case NCoderPropID::kAlgorithm:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 maximize = prop.ulVal;
+ _fastMode = (maximize == 0);
+ // _maxMode = (maximize >= 2);
+ break;
+ }
+ case NCoderPropID::kMatchFinder:
+ {
+ return E_NOTIMPL;
+ /*if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
+ int matchFinderIndexPrev = _matchFinderIndex;
+ int m = FindMatchFinder(prop.bstrVal);
+ if (m < 0)
+ return E_INVALIDARG;
+ _matchFinderIndex = m;
+ if (_matchFinder && matchFinderIndexPrev != _matchFinderIndex)
+ {
+ _dictionarySizePrev = (UInt32)-1;
+ ReleaseMatchFinder();
+ }
+ break;*/
+ }
+ #ifdef COMPRESS_MF_MT
+ case NCoderPropID::kMultiThread:
+ {
+ if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ bool newMultiThread = (prop.boolVal == VARIANT_TRUE);
+ if (newMultiThread != _multiThread)
+ {
+ _dictionarySizePrev = (UInt32)-1;
+ ReleaseMatchFinder();
+ _multiThread = newMultiThread;
+ }
+ break;
+ }
+ case NCoderPropID::kNumThreads:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ bool newMultiThread = (prop.ulVal > 1);
+ if (newMultiThread != _multiThread)
+ {
+ _dictionarySizePrev = (UInt32)-1;
+ ReleaseMatchFinder();
+ _multiThread = newMultiThread;
+ }
+ break;
+ }
+ #endif
+ case NCoderPropID::kDictionarySize:
+ {
+ const int kDicLogSizeMaxCompress = 30;
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 dictionarySize = prop.ulVal;
+ if (dictionarySize < UInt32(1 << kDicLogSizeMin) ||
+ dictionarySize > UInt32(1 << kDicLogSizeMaxCompress))
+ return E_INVALIDARG;
+ _dictionarySize = dictionarySize;
+ UInt32 dicLogSize;
+ for(dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++)
+ if (dictionarySize <= (UInt32(1) << dicLogSize))
+ break;
+ _distTableSize = dicLogSize * 2;
+ break;
+ }
+ case NCoderPropID::kPosStateBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)NLength::kNumPosStatesBitsEncodingMax)
+ return E_INVALIDARG;
+ _posStateBits = value;
+ _posStateMask = (1 << _posStateBits) - 1;
+ break;
+ }
+ case NCoderPropID::kLitPosBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)kNumLitPosStatesBitsEncodingMax)
+ return E_INVALIDARG;
+ _numLiteralPosStateBits = value;
+ break;
+ }
+ case NCoderPropID::kLitContextBits:
+ {
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 value = prop.ulVal;
+ if (value > (UInt32)kNumLitContextBitsMax)
+ return E_INVALIDARG;
+ _numLiteralContextBits = value;
+ break;
+ }
+ case NCoderPropID::kEndMarker:
+ {
+ if (prop.vt != VT_BOOL)
+ return E_INVALIDARG;
+ SetWriteEndMarkerMode(prop.boolVal == VARIANT_TRUE);
+ break;
+ }
+ default:
+ return E_INVALIDARG;
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
+{
+ const UInt32 kPropSize = 5;
+ Byte properties[kPropSize];
+ properties[0] = (_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits;
+ for (int i = 0; i < 4; i++)
+ properties[1 + i] = Byte(_dictionarySize >> (8 * i));
+ return WriteStream(outStream, properties, kPropSize, NULL);
+}
+
+STDMETHODIMP CEncoder::SetOutStream(ISequentialOutStream *outStream)
+{
+ _rangeEncoder.SetStream(outStream);
+ return S_OK;
+}
+
+STDMETHODIMP CEncoder::ReleaseOutStream()
+{
+ _rangeEncoder.ReleaseStream();
+ return S_OK;
+}
+
+HRESULT CEncoder::Init()
+{
+ CBaseState::Init();
+
+ // RINOK(_matchFinder->Init(inStream));
+ _rangeEncoder.Init();
+
+ for(int i = 0; i < kNumStates; i++)
+ {
+ for (UInt32 j = 0; j <= _posStateMask; j++)
+ {
+ _isMatch[i][j].Init();
+ _isRep0Long[i][j].Init();
+ }
+ _isRep[i].Init();
+ _isRepG0[i].Init();
+ _isRepG1[i].Init();
+ _isRepG2[i].Init();
+ }
+
+ _literalEncoder.Init();
+
+ {
+ for(UInt32 i = 0; i < kNumLenToPosStates; i++)
+ _posSlotEncoder[i].Init();
+ }
+ {
+ for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ _posEncoders[i].Init();
+ }
+
+ _lenEncoder.Init(1 << _posStateBits);
+ _repMatchLenEncoder.Init(1 << _posStateBits);
+
+ _posAlignEncoder.Init();
+
+ _longestMatchWasFound = false;
+ _optimumEndIndex = 0;
+ _optimumCurrentIndex = 0;
+ _additionalOffset = 0;
+
+ return S_OK;
+}
+
+HRESULT CEncoder::MovePos(UInt32 num)
+{
+ if (num == 0)
+ return S_OK;
+ _additionalOffset += num;
+ return _matchFinder->Skip(num);
+}
+
+UInt32 CEncoder::Backward(UInt32 &backRes, UInt32 cur)
+{
+ _optimumEndIndex = cur;
+ UInt32 posMem = _optimum[cur].PosPrev;
+ UInt32 backMem = _optimum[cur].BackPrev;
+ do
+ {
+ if (_optimum[cur].Prev1IsChar)
+ {
+ _optimum[posMem].MakeAsChar();
+ _optimum[posMem].PosPrev = posMem - 1;
+ if (_optimum[cur].Prev2)
+ {
+ _optimum[posMem - 1].Prev1IsChar = false;
+ _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2;
+ _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2;
+ }
+ }
+ UInt32 posPrev = posMem;
+ UInt32 backCur = backMem;
+
+ backMem = _optimum[posPrev].BackPrev;
+ posMem = _optimum[posPrev].PosPrev;
+
+ _optimum[posPrev].BackPrev = backCur;
+ _optimum[posPrev].PosPrev = cur;
+ cur = posPrev;
+ }
+ while(cur != 0);
+ backRes = _optimum[0].BackPrev;
+ _optimumCurrentIndex = _optimum[0].PosPrev;
+ return _optimumCurrentIndex;
+}
+
+/*
+Out:
+ (lenRes == 1) && (backRes == 0xFFFFFFFF) means Literal
+*/
+
+HRESULT CEncoder::GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes)
+{
+ if(_optimumEndIndex != _optimumCurrentIndex)
+ {
+ const COptimal &optimum = _optimum[_optimumCurrentIndex];
+ lenRes = optimum.PosPrev - _optimumCurrentIndex;
+ backRes = optimum.BackPrev;
+ _optimumCurrentIndex = optimum.PosPrev;
+ return S_OK;
+ }
+ _optimumCurrentIndex = _optimumEndIndex = 0;
+
+ UInt32 lenMain, numDistancePairs;
+ if (!_longestMatchWasFound)
+ {
+ RINOK(ReadMatchDistances(lenMain, numDistancePairs));
+ }
+ else
+ {
+ lenMain = _longestMatchLength;
+ numDistancePairs = _numDistancePairs;
+ _longestMatchWasFound = false;
+ }
+
+ const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1;
+ UInt32 numAvailableBytes = _matchFinder->GetNumAvailableBytes() + 1;
+ if (numAvailableBytes < 2)
+ {
+ backRes = (UInt32)(-1);
+ lenRes = 1;
+ return S_OK;
+ }
+ if (numAvailableBytes > kMatchMaxLen)
+ numAvailableBytes = kMatchMaxLen;
+
+ UInt32 reps[kNumRepDistances];
+ UInt32 repLens[kNumRepDistances];
+ UInt32 repMaxIndex = 0;
+ UInt32 i;
+ for(i = 0; i < kNumRepDistances; i++)
+ {
+ reps[i] = _repDistances[i];
+ UInt32 backOffset = reps[i] + 1;
+ if (data[0] != data[(size_t)0 - backOffset] || data[1] != data[(size_t)1 - backOffset])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ UInt32 lenTest;
+ for (lenTest = 2; lenTest < numAvailableBytes &&
+ data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++);
+ repLens[i] = lenTest;
+ if (lenTest > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if(repLens[repMaxIndex] >= _numFastBytes)
+ {
+ backRes = repMaxIndex;
+ lenRes = repLens[repMaxIndex];
+ return MovePos(lenRes - 1);
+ }
+
+ UInt32 *matchDistances = _matchDistances + 1;
+ if(lenMain >= _numFastBytes)
+ {
+ backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances;
+ lenRes = lenMain;
+ return MovePos(lenMain - 1);
+ }
+ Byte currentByte = *data;
+ Byte matchByte = data[(size_t)0 - reps[0] - 1];
+
+ if(lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
+ {
+ backRes = (UInt32)-1;
+ lenRes = 1;
+ return S_OK;
+ }
+
+ _optimum[0].State = _state;
+
+ UInt32 posState = (position & _posStateMask);
+
+ _optimum[1].Price = _isMatch[_state.Index][posState].GetPrice0() +
+ _literalEncoder.GetSubCoder(position, _previousByte)->GetPrice(!_state.IsCharState(), matchByte, currentByte);
+ _optimum[1].MakeAsChar();
+
+ UInt32 matchPrice = _isMatch[_state.Index][posState].GetPrice1();
+ UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1();
+
+ if(matchByte == currentByte)
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState);
+ if(shortRepPrice < _optimum[1].Price)
+ {
+ _optimum[1].Price = shortRepPrice;
+ _optimum[1].MakeAsShortRep();
+ }
+ }
+ UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
+
+ if(lenEnd < 2)
+ {
+ backRes = _optimum[1].BackPrev;
+ lenRes = 1;
+ return S_OK;
+ }
+
+ _optimum[1].PosPrev = 0;
+ for (i = 0; i < kNumRepDistances; i++)
+ _optimum[0].Backs[i] = reps[i];
+
+ UInt32 len = lenEnd;
+ do
+ _optimum[len--].Price = kIfinityPrice;
+ while (len >= 2);
+
+ for(i = 0; i < kNumRepDistances; i++)
+ {
+ UInt32 repLen = repLens[i];
+ if (repLen < 2)
+ continue;
+ UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState);
+ COptimal &optimum = _optimum[repLen];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = i;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ while(--repLen >= 2);
+ }
+
+ UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0();
+
+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+ if (len <= lenMain)
+ {
+ UInt32 offs = 0;
+ while (len > matchDistances[offs])
+ offs += 2;
+ for(; ; len++)
+ {
+ UInt32 distance = matchDistances[offs + 1];
+ UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState);
+ COptimal &optimum = _optimum[len];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = 0;
+ optimum.BackPrev = distance + kNumRepDistances;
+ optimum.Prev1IsChar = false;
+ }
+ if (len == matchDistances[offs])
+ {
+ offs += 2;
+ if (offs == numDistancePairs)
+ break;
+ }
+ }
+ }
+
+ UInt32 cur = 0;
+
+ while(true)
+ {
+ cur++;
+ if(cur == lenEnd)
+ {
+ lenRes = Backward(backRes, cur);
+ return S_OK;
+ }
+ UInt32 newLen, numDistancePairs;
+ RINOK(ReadMatchDistances(newLen, numDistancePairs));
+ if(newLen >= _numFastBytes)
+ {
+ _numDistancePairs = numDistancePairs;
+ _longestMatchLength = newLen;
+ _longestMatchWasFound = true;
+ lenRes = Backward(backRes, cur);
+ return S_OK;
+ }
+ position++;
+ COptimal &curOptimum = _optimum[cur];
+ UInt32 posPrev = curOptimum.PosPrev;
+ CState state;
+ if (curOptimum.Prev1IsChar)
+ {
+ posPrev--;
+ if (curOptimum.Prev2)
+ {
+ state = _optimum[curOptimum.PosPrev2].State;
+ if (curOptimum.BackPrev2 < kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ else
+ state = _optimum[posPrev].State;
+ state.UpdateChar();
+ }
+ else
+ state = _optimum[posPrev].State;
+ if (posPrev == cur - 1)
+ {
+ if (curOptimum.IsShortRep())
+ state.UpdateShortRep();
+ else
+ state.UpdateChar();
+ }
+ else
+ {
+ UInt32 pos;
+ if (curOptimum.Prev1IsChar && curOptimum.Prev2)
+ {
+ posPrev = curOptimum.PosPrev2;
+ pos = curOptimum.BackPrev2;
+ state.UpdateRep();
+ }
+ else
+ {
+ pos = curOptimum.BackPrev;
+ if (pos < kNumRepDistances)
+ state.UpdateRep();
+ else
+ state.UpdateMatch();
+ }
+ const COptimal &prevOptimum = _optimum[posPrev];
+ if (pos < kNumRepDistances)
+ {
+ reps[0] = prevOptimum.Backs[pos];
+ UInt32 i;
+ for(i = 1; i <= pos; i++)
+ reps[i] = prevOptimum.Backs[i - 1];
+ for(; i < kNumRepDistances; i++)
+ reps[i] = prevOptimum.Backs[i];
+ }
+ else
+ {
+ reps[0] = (pos - kNumRepDistances);
+ for(UInt32 i = 1; i < kNumRepDistances; i++)
+ reps[i] = prevOptimum.Backs[i - 1];
+ }
+ }
+ curOptimum.State = state;
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ curOptimum.Backs[i] = reps[i];
+ UInt32 curPrice = curOptimum.Price;
+ const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1;
+ const Byte currentByte = *data;
+ const Byte matchByte = data[(size_t)0 - reps[0] - 1];
+
+ UInt32 posState = (position & _posStateMask);
+
+ UInt32 curAnd1Price = curPrice +
+ _isMatch[state.Index][posState].GetPrice0() +
+ _literalEncoder.GetSubCoder(position, data[(size_t)0 - 1])->GetPrice(!state.IsCharState(), matchByte, currentByte);
+
+ COptimal &nextOptimum = _optimum[cur + 1];
+
+ bool nextIsChar = false;
+ if (curAnd1Price < nextOptimum.Price)
+ {
+ nextOptimum.Price = curAnd1Price;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsChar();
+ nextIsChar = true;
+ }
+
+ UInt32 matchPrice = curPrice + _isMatch[state.Index][posState].GetPrice1();
+ UInt32 repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1();
+
+ if(matchByte == currentByte &&
+ !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0))
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState);
+ if(shortRepPrice <= nextOptimum.Price)
+ {
+ nextOptimum.Price = shortRepPrice;
+ nextOptimum.PosPrev = cur;
+ nextOptimum.MakeAsShortRep();
+ nextIsChar = true;
+ }
+ }
+ /*
+ if(newLen == 2 && matchDistances[2] >= kDistLimit2) // test it maybe set 2000 ?
+ continue;
+ */
+
+ UInt32 numAvailableBytesFull = _matchFinder->GetNumAvailableBytes() + 1;
+ numAvailableBytesFull = MyMin(kNumOpts - 1 - cur, numAvailableBytesFull);
+ UInt32 numAvailableBytes = numAvailableBytesFull;
+
+ if (numAvailableBytes < 2)
+ continue;
+ if (numAvailableBytes > _numFastBytes)
+ numAvailableBytes = _numFastBytes;
+ if (!nextIsChar && matchByte != currentByte) // speed optimization
+ {
+ // try Literal + rep0
+ UInt32 backOffset = reps[0] + 1;
+ UInt32 limit = MyMin(numAvailableBytesFull, _numFastBytes + 1);
+ UInt32 temp;
+ for (temp = 1; temp < limit &&
+ data[temp] == data[(size_t)temp - backOffset]; temp++);
+ UInt32 lenTest2 = temp - 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateChar();
+ UInt32 posStateNext = (position + 1) & _posStateMask;
+ UInt32 nextRepMatchPrice = curAnd1Price +
+ _isMatch[state2.Index][posStateNext].GetPrice1() +
+ _isRep[state2.Index].GetPrice1();
+ // for (; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = cur + 1 + lenTest2;
+ while(lenEnd < offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = false;
+ }
+ }
+ }
+ }
+
+ UInt32 startLen = 2; // speed optimization
+ for(UInt32 repIndex = 0; repIndex < kNumRepDistances; repIndex++)
+ {
+ // UInt32 repLen = _matchFinder->GetMatchLen(0 - 1, reps[repIndex], newLen); // test it;
+ UInt32 backOffset = reps[repIndex] + 1;
+ if (data[0] != data[(size_t)0 - backOffset] ||
+ data[1] != data[(size_t)1 - backOffset])
+ continue;
+ UInt32 lenTest;
+ for (lenTest = 2; lenTest < numAvailableBytes &&
+ data[lenTest] == data[(size_t)lenTest - backOffset]; lenTest++);
+ while(lenEnd < cur + lenTest)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 lenTestTemp = lenTest;
+ UInt32 price = repMatchPrice + GetPureRepPrice(repIndex, state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState);
+ COptimal &optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = repIndex;
+ optimum.Prev1IsChar = false;
+ }
+ }
+ while(--lenTest >= 2);
+ lenTest = lenTestTemp;
+
+ if (repIndex == 0)
+ startLen = lenTest + 1;
+
+ // if (_maxMode)
+ {
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
+ for (; lenTest2 < limit &&
+ data[lenTest2] == data[(size_t)lenTest2 - backOffset]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateRep();
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
+ UInt32 curAndLenCharPrice =
+ price + _repMatchLenEncoder.GetPrice(lenTest - 2, posState) +
+ _isMatch[state2.Index][posStateNext].GetPrice0() +
+ _literalEncoder.GetSubCoder(position + lenTest, data[(size_t)lenTest - 1])->GetPrice(
+ true, data[(size_t)lenTest - backOffset], data[lenTest]);
+ state2.UpdateChar();
+ posStateNext = (position + lenTest + 1) & _posStateMask;
+ UInt32 nextRepMatchPrice = curAndLenCharPrice +
+ _isMatch[state2.Index][posStateNext].GetPrice1() +
+ _isRep[state2.Index].GetPrice1();
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ while(lenEnd < offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(
+ 0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = repIndex;
+ }
+ }
+ }
+ }
+ }
+
+ // for(UInt32 lenTest = 2; lenTest <= newLen; lenTest++)
+ if (newLen > numAvailableBytes)
+ {
+ newLen = numAvailableBytes;
+ for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2);
+ matchDistances[numDistancePairs] = newLen;
+ numDistancePairs += 2;
+ }
+ if (newLen >= startLen)
+ {
+ UInt32 normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0();
+ while(lenEnd < cur + newLen)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+
+ UInt32 offs = 0;
+ while(startLen > matchDistances[offs])
+ offs += 2;
+ UInt32 curBack = matchDistances[offs + 1];
+ UInt32 posSlot = GetPosSlot2(curBack);
+ for(UInt32 lenTest = /*2*/ startLen; ; lenTest++)
+ {
+ UInt32 curAndLenPrice = normalMatchPrice;
+ UInt32 lenToPosState = GetLenToPosState(lenTest);
+ if (curBack < kNumFullDistances)
+ curAndLenPrice += _distancesPrices[lenToPosState][curBack];
+ else
+ curAndLenPrice += _posSlotPrices[lenToPosState][posSlot] + _alignPrices[curBack & kAlignMask];
+
+ curAndLenPrice += _lenEncoder.GetPrice(lenTest - kMatchMinLen, posState);
+
+ COptimal &optimum = _optimum[cur + lenTest];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur;
+ optimum.BackPrev = curBack + kNumRepDistances;
+ optimum.Prev1IsChar = false;
+ }
+
+ if (/*_maxMode && */lenTest == matchDistances[offs])
+ {
+ // Try Match + Literal + Rep0
+ UInt32 backOffset = curBack + 1;
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = MyMin(numAvailableBytesFull, lenTest2 + _numFastBytes);
+ for (; lenTest2 < limit &&
+ data[lenTest2] == data[(size_t)lenTest2 - backOffset]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ CState state2 = state;
+ state2.UpdateMatch();
+ UInt32 posStateNext = (position + lenTest) & _posStateMask;
+ UInt32 curAndLenCharPrice = curAndLenPrice +
+ _isMatch[state2.Index][posStateNext].GetPrice0() +
+ _literalEncoder.GetSubCoder(position + lenTest, data[(size_t)lenTest - 1])->GetPrice(
+ true, data[(size_t)lenTest - backOffset], data[lenTest]);
+ state2.UpdateChar();
+ posStateNext = (posStateNext + 1) & _posStateMask;
+ UInt32 nextRepMatchPrice = curAndLenCharPrice +
+ _isMatch[state2.Index][posStateNext].GetPrice1() +
+ _isRep[state2.Index].GetPrice1();
+
+ // for(; lenTest2 >= 2; lenTest2--)
+ {
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ while(lenEnd < offset)
+ _optimum[++lenEnd].Price = kIfinityPrice;
+ UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext);
+ COptimal &optimum = _optimum[offset];
+ if (curAndLenPrice < optimum.Price)
+ {
+ optimum.Price = curAndLenPrice;
+ optimum.PosPrev = cur + lenTest + 1;
+ optimum.BackPrev = 0;
+ optimum.Prev1IsChar = true;
+ optimum.Prev2 = true;
+ optimum.PosPrev2 = cur;
+ optimum.BackPrev2 = curBack + kNumRepDistances;
+ }
+ }
+ }
+ offs += 2;
+ if (offs == numDistancePairs)
+ break;
+ curBack = matchDistances[offs + 1];
+ if (curBack >= kNumFullDistances)
+ posSlot = GetPosSlot2(curBack);
+ }
+ }
+ }
+ }
+}
+
+static inline bool ChangePair(UInt32 smallDist, UInt32 bigDist)
+{
+ return ((bigDist >> 7) > smallDist);
+}
+
+
+HRESULT CEncoder::ReadMatchDistances(UInt32 &lenRes, UInt32 &numDistancePairs)
+{
+ lenRes = 0;
+ RINOK(_matchFinder->GetMatches(_matchDistances));
+ numDistancePairs = _matchDistances[0];
+ if (numDistancePairs > 0)
+ {
+ lenRes = _matchDistances[1 + numDistancePairs - 2];
+ if (lenRes == _numFastBytes)
+ lenRes += _matchFinder->GetMatchLen(lenRes - 1, _matchDistances[1 + numDistancePairs - 1],
+ kMatchMaxLen - lenRes);
+ }
+ _additionalOffset++;
+ return S_OK;
+}
+
+HRESULT CEncoder::GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes)
+{
+ UInt32 lenMain, numDistancePairs;
+ if (!_longestMatchWasFound)
+ {
+ RINOK(ReadMatchDistances(lenMain, numDistancePairs));
+ }
+ else
+ {
+ lenMain = _longestMatchLength;
+ numDistancePairs = _numDistancePairs;
+ _longestMatchWasFound = false;
+ }
+
+ const Byte *data = _matchFinder->GetPointerToCurrentPos() - 1;
+ UInt32 numAvailableBytes = _matchFinder->GetNumAvailableBytes() + 1;
+ if (numAvailableBytes > kMatchMaxLen)
+ numAvailableBytes = kMatchMaxLen;
+ if (numAvailableBytes < 2)
+ {
+ backRes = (UInt32)(-1);
+ lenRes = 1;
+ return S_OK;
+ }
+
+ UInt32 repLens[kNumRepDistances];
+ UInt32 repMaxIndex = 0;
+
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ {
+ UInt32 backOffset = _repDistances[i] + 1;
+ if (data[0] != data[(size_t)0 - backOffset] || data[1] != data[(size_t)1 - backOffset])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ UInt32 len;
+ for (len = 2; len < numAvailableBytes && data[len] == data[(size_t)len - backOffset]; len++);
+ if(len >= _numFastBytes)
+ {
+ backRes = i;
+ lenRes = len;
+ return MovePos(lenRes - 1);
+ }
+ repLens[i] = len;
+ if (len > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ UInt32 *matchDistances = _matchDistances + 1;
+ if(lenMain >= _numFastBytes)
+ {
+ backRes = matchDistances[numDistancePairs - 1] + kNumRepDistances;
+ lenRes = lenMain;
+ return MovePos(lenMain - 1);
+ }
+
+ UInt32 backMain = 0; // for GCC
+ if (lenMain >= 2)
+ {
+ backMain = matchDistances[numDistancePairs - 1];
+ while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1)
+ {
+ if (!ChangePair(matchDistances[numDistancePairs - 3], backMain))
+ break;
+ numDistancePairs -= 2;
+ lenMain = matchDistances[numDistancePairs - 2];
+ backMain = matchDistances[numDistancePairs - 1];
+ }
+ if (lenMain == 2 && backMain >= 0x80)
+ lenMain = 1;
+ }
+
+ if (repLens[repMaxIndex] >= 2)
+ {
+ if (repLens[repMaxIndex] + 1 >= lenMain ||
+ repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9)) ||
+ repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15)))
+ {
+ backRes = repMaxIndex;
+ lenRes = repLens[repMaxIndex];
+ return MovePos(lenRes - 1);
+ }
+ }
+
+ if (lenMain >= 2 && numAvailableBytes > 2)
+ {
+ RINOK(ReadMatchDistances(_longestMatchLength, _numDistancePairs));
+ if (_longestMatchLength >= 2)
+ {
+ UInt32 newDistance = matchDistances[_numDistancePairs - 1];
+ if (_longestMatchLength >= lenMain && newDistance < backMain ||
+ _longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance) ||
+ _longestMatchLength > lenMain + 1 ||
+ _longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain))
+ {
+ _longestMatchWasFound = true;
+ backRes = UInt32(-1);
+ lenRes = 1;
+ return S_OK;
+ }
+ }
+ data++;
+ numAvailableBytes--;
+ for(UInt32 i = 0; i < kNumRepDistances; i++)
+ {
+ UInt32 backOffset = _repDistances[i] + 1;
+ if (data[1] != data[(size_t)1 - backOffset] || data[2] != data[(size_t)2 - backOffset])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ UInt32 len;
+ for (len = 2; len < numAvailableBytes && data[len] == data[(size_t)len - backOffset]; len++);
+ if (len + 1 >= lenMain)
+ {
+ _longestMatchWasFound = true;
+ backRes = UInt32(-1);
+ lenRes = 1;
+ return S_OK;
+ }
+ }
+ backRes = backMain + kNumRepDistances;
+ lenRes = lenMain;
+ return MovePos(lenMain - 2);
+ }
+ backRes = UInt32(-1);
+ lenRes = 1;
+ return S_OK;
+}
+
+HRESULT CEncoder::Flush(UInt32 nowPos)
+{
+ ReleaseMFStream();
+ WriteEndMarker(nowPos & _posStateMask);
+ _rangeEncoder.FlushData();
+ return _rangeEncoder.FlushStream();
+}
+
+void CEncoder::WriteEndMarker(UInt32 posState)
+{
+ // This function for writing End Mark for stream version of LZMA.
+ // In current version this feature is not used.
+ if (!_writeEndMark)
+ return;
+
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
+ _isRep[_state.Index].Encode(&_rangeEncoder, 0);
+ _state.UpdateMatch();
+ UInt32 len = kMatchMinLen; // kMatchMaxLen;
+ _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+ UInt32 posSlot = (1 << kNumPosSlotBits) - 1;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ _posSlotEncoder[lenToPosState].Encode(&_rangeEncoder, posSlot);
+ UInt32 footerBits = 30;
+ UInt32 posReduced = (UInt32(1) << footerBits) - 1;
+ _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
+}
+
+HRESULT CEncoder::CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ _needReleaseMFStream = false;
+ CCoderReleaser coderReleaser(this);
+ RINOK(SetStreams(inStream, outStream, inSize, outSize));
+ while(true)
+ {
+ UInt64 processedInSize;
+ UInt64 processedOutSize;
+ Int32 finished;
+ RINOK(CodeOneBlock(&processedInSize, &processedOutSize, &finished));
+ if (finished != 0)
+ return S_OK;
+ if (progress != 0)
+ {
+ RINOK(progress->SetRatioInfo(&processedInSize, &processedOutSize));
+ }
+ }
+}
+
+HRESULT CEncoder::SetStreams(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize)
+{
+ _inStream = inStream;
+ _finished = false;
+ RINOK(Create());
+ RINOK(SetOutStream(outStream));
+ RINOK(Init());
+
+ // CCoderReleaser releaser(this);
+
+ /*
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ return Flush();
+ */
+
+ if (!_fastMode)
+ {
+ FillDistancesPrices();
+ FillAlignPrices();
+ }
+
+ _lenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
+ _lenEncoder.UpdateTables(1 << _posStateBits);
+ _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - kMatchMinLen);
+ _repMatchLenEncoder.UpdateTables(1 << _posStateBits);
+
+ nowPos64 = 0;
+ return S_OK;
+}
+
+HRESULT CEncoder::CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished)
+{
+ if (_inStream != 0)
+ {
+ RINOK(_matchFinder->SetStream(_inStream));
+ RINOK(_matchFinder->Init());
+ _needReleaseMFStream = true;
+ _inStream = 0;
+ }
+
+
+ *finished = 1;
+ if (_finished)
+ return S_OK;
+ _finished = true;
+
+ if (nowPos64 == 0)
+ {
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ return Flush(UInt32(nowPos64));
+ UInt32 len, numDistancePairs;
+ RINOK(ReadMatchDistances(len, numDistancePairs));
+ UInt32 posState = UInt32(nowPos64) & _posStateMask;
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
+ _state.UpdateChar();
+ Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset);
+ _literalEncoder.GetSubCoder(UInt32(nowPos64), _previousByte)->Encode(&_rangeEncoder, curByte);
+ _previousByte = curByte;
+ _additionalOffset--;
+ nowPos64++;
+ }
+
+ UInt32 nowPos32 = (UInt32)nowPos64;
+ UInt32 progressPosValuePrev = nowPos32;
+
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ return Flush(nowPos32);
+
+ while(true)
+ {
+ #ifdef _NO_EXCEPTIONS
+ if (_rangeEncoder.Stream.ErrorCode != S_OK)
+ return _rangeEncoder.Stream.ErrorCode;
+ #endif
+ UInt32 pos, len;
+ HRESULT result;
+ if (_fastMode)
+ result = GetOptimumFast(nowPos32, pos, len);
+ else
+ result = GetOptimum(nowPos32, pos, len);
+ RINOK(result);
+
+ UInt32 posState = nowPos32 & _posStateMask;
+ if(len == 1 && pos == 0xFFFFFFFF)
+ {
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 0);
+ Byte curByte = _matchFinder->GetIndexByte(0 - _additionalOffset);
+ CLiteralEncoder2 *subCoder = _literalEncoder.GetSubCoder(nowPos32, _previousByte);
+ if(_state.IsCharState())
+ subCoder->Encode(&_rangeEncoder, curByte);
+ else
+ {
+ Byte matchByte = _matchFinder->GetIndexByte(0 - _repDistances[0] - 1 - _additionalOffset);
+ subCoder->EncodeMatched(&_rangeEncoder, matchByte, curByte);
+ }
+ _state.UpdateChar();
+ _previousByte = curByte;
+ }
+ else
+ {
+ _isMatch[_state.Index][posState].Encode(&_rangeEncoder, 1);
+ if(pos < kNumRepDistances)
+ {
+ _isRep[_state.Index].Encode(&_rangeEncoder, 1);
+ if(pos == 0)
+ {
+ _isRepG0[_state.Index].Encode(&_rangeEncoder, 0);
+ _isRep0Long[_state.Index][posState].Encode(&_rangeEncoder, ((len == 1) ? 0 : 1));
+ }
+ else
+ {
+ UInt32 distance = _repDistances[pos];
+ _isRepG0[_state.Index].Encode(&_rangeEncoder, 1);
+ if (pos == 1)
+ _isRepG1[_state.Index].Encode(&_rangeEncoder, 0);
+ else
+ {
+ _isRepG1[_state.Index].Encode(&_rangeEncoder, 1);
+ _isRepG2[_state.Index].Encode(&_rangeEncoder, pos - 2);
+ if (pos == 3)
+ _repDistances[3] = _repDistances[2];
+ _repDistances[2] = _repDistances[1];
+ }
+ _repDistances[1] = _repDistances[0];
+ _repDistances[0] = distance;
+ }
+ if (len == 1)
+ _state.UpdateShortRep();
+ else
+ {
+ _repMatchLenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+ _state.UpdateRep();
+ }
+ }
+ else
+ {
+ _isRep[_state.Index].Encode(&_rangeEncoder, 0);
+ _state.UpdateMatch();
+ _lenEncoder.Encode(&_rangeEncoder, len - kMatchMinLen, posState, !_fastMode);
+ pos -= kNumRepDistances;
+ UInt32 posSlot = GetPosSlot(pos);
+ _posSlotEncoder[GetLenToPosState(len)].Encode(&_rangeEncoder, posSlot);
+
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ UInt32 posReduced = pos - base;
+
+ if (posSlot < kEndPosModelIndex)
+ NRangeCoder::ReverseBitTreeEncode(_posEncoders + base - posSlot - 1,
+ &_rangeEncoder, footerBits, posReduced);
+ else
+ {
+ _rangeEncoder.EncodeDirectBits(posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
+ _posAlignEncoder.ReverseEncode(&_rangeEncoder, posReduced & kAlignMask);
+ _alignPriceCount++;
+ }
+ }
+ _repDistances[3] = _repDistances[2];
+ _repDistances[2] = _repDistances[1];
+ _repDistances[1] = _repDistances[0];
+ _repDistances[0] = pos;
+ _matchPriceCount++;
+ }
+ _previousByte = _matchFinder->GetIndexByte(len - 1 - _additionalOffset);
+ }
+ _additionalOffset -= len;
+ nowPos32 += len;
+ if (_additionalOffset == 0)
+ {
+ if (!_fastMode)
+ {
+ if (_matchPriceCount >= (1 << 7))
+ FillDistancesPrices();
+ if (_alignPriceCount >= kAlignTableSize)
+ FillAlignPrices();
+ }
+ if (_matchFinder->GetNumAvailableBytes() == 0)
+ return Flush(nowPos32);
+ if (nowPos32 - progressPosValuePrev >= (1 << 14))
+ {
+ nowPos64 += nowPos32 - progressPosValuePrev;
+ *inSize = nowPos64;
+ *outSize = _rangeEncoder.GetProcessedSize();
+ _finished = false;
+ *finished = 0;
+ return S_OK;
+ }
+ }
+ }
+}
+
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress)
+{
+ #ifndef _NO_EXCEPTIONS
+ try
+ {
+ #endif
+ return CodeReal(inStream, outStream, inSize, outSize, progress);
+ #ifndef _NO_EXCEPTIONS
+ }
+ catch(const COutBufferException &e) { return e.ErrorCode; }
+ catch(...) { return E_FAIL; }
+ #endif
+}
+
+void CEncoder::FillDistancesPrices()
+{
+ UInt32 tempPrices[kNumFullDistances];
+ for (UInt32 i = kStartPosModelIndex; i < kNumFullDistances; i++)
+ {
+ UInt32 posSlot = GetPosSlot(i);
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ tempPrices[i] = NRangeCoder::ReverseBitTreeGetPrice(_posEncoders +
+ base - posSlot - 1, footerBits, i - base);
+ }
+
+ for (UInt32 lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+ {
+ UInt32 posSlot;
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> &encoder = _posSlotEncoder[lenToPosState];
+ UInt32 *posSlotPrices = _posSlotPrices[lenToPosState];
+ for (posSlot = 0; posSlot < _distTableSize; posSlot++)
+ posSlotPrices[posSlot] = encoder.GetPrice(posSlot);
+ for (posSlot = kEndPosModelIndex; posSlot < _distTableSize; posSlot++)
+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << NRangeCoder::kNumBitPriceShiftBits);
+
+ UInt32 *distancesPrices = _distancesPrices[lenToPosState];
+ UInt32 i;
+ for (i = 0; i < kStartPosModelIndex; i++)
+ distancesPrices[i] = posSlotPrices[i];
+ for (; i < kNumFullDistances; i++)
+ distancesPrices[i] = posSlotPrices[GetPosSlot(i)] + tempPrices[i];
+ }
+ _matchPriceCount = 0;
+}
+
+void CEncoder::FillAlignPrices()
+{
+ for (UInt32 i = 0; i < kAlignTableSize; i++)
+ _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i);
+ _alignPriceCount = 0;
+}
+
+}}
diff --git a/Source/7zip/7zip/Compress/LZMA/LZMAEncoder.h b/Source/7zip/7zip/Compress/LZMA/LZMAEncoder.h
index 5fe8d4c..41c7118 100755
--- a/Source/7zip/7zip/Compress/LZMA/LZMAEncoder.h
+++ b/Source/7zip/7zip/Compress/LZMA/LZMAEncoder.h
@@ -1,426 +1,426 @@
-/*
- * LZMAEncoder.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __LZMA_ENCODER_H
-#define __LZMA_ENCODER_H
-
-#include "../../../Common/MyCom.h"
-#include "../../../Common/Alloc.h"
-#include "../../ICoder.h"
-#include "../LZ/IMatchFinder.h"
-#include "../RangeCoder/RangeCoderBitTree.h"
-
-#include "LZMA.h"
-
-namespace NCompress {
-namespace NLZMA {
-
-typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
-
-class CBaseState
-{
-protected:
- CState _state;
- Byte _previousByte;
- UInt32 _repDistances[kNumRepDistances];
- void Init()
- {
- _state.Init();
- _previousByte = 0;
- for(UInt32 i = 0 ; i < kNumRepDistances; i++)
- _repDistances[i] = 0;
- }
-};
-
-struct COptimal
-{
- CState State;
-
- bool Prev1IsChar;
- bool Prev2;
-
- UInt32 PosPrev2;
- UInt32 BackPrev2;
-
- UInt32 Price;
- UInt32 PosPrev; // posNext;
- UInt32 BackPrev;
- UInt32 Backs[kNumRepDistances];
- void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; }
- void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
- bool IsShortRep() { return (BackPrev == 0); }
-};
-
-
-extern Byte g_FastPos[1 << 11];
-inline UInt32 GetPosSlot(UInt32 pos)
-{
- if (pos < (1 << 11))
- return g_FastPos[pos];
- if (pos < (1 << 21))
- return g_FastPos[pos >> 10] + 20;
- return g_FastPos[pos >> 20] + 40;
-}
-
-inline UInt32 GetPosSlot2(UInt32 pos)
-{
- if (pos < (1 << 17))
- return g_FastPos[pos >> 6] + 12;
- if (pos < (1 << 27))
- return g_FastPos[pos >> 16] + 32;
- return g_FastPos[pos >> 26] + 52;
-}
-
-const UInt32 kIfinityPrice = 0xFFFFFFF;
-
-const UInt32 kNumOpts = 1 << 12;
-
-
-class CLiteralEncoder2
-{
- CMyBitEncoder _encoders[0x300];
-public:
- void Init()
- {
- for (int i = 0; i < 0x300; i++)
- _encoders[i].Init();
- }
- void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol);
- void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol);
- UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const;
-};
-
-class CLiteralEncoder
-{
- CLiteralEncoder2 *_coders;
- int _numPrevBits;
- int _numPosBits;
- UInt32 _posMask;
-public:
- CLiteralEncoder(): _coders(0) {}
- ~CLiteralEncoder() { Free(); }
- void Free()
- {
- MyFree(_coders);
- _coders = 0;
- }
- bool Create(int numPosBits, int numPrevBits)
- {
- if (_coders == 0 || (numPosBits + numPrevBits) != (_numPrevBits + _numPosBits))
- {
- Free();
- UInt32 numStates = 1 << (numPosBits + numPrevBits);
- _coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2));
- }
- _numPosBits = numPosBits;
- _posMask = (1 << numPosBits) - 1;
- _numPrevBits = numPrevBits;
- return (_coders != 0);
- }
- void Init()
- {
- UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
- for (UInt32 i = 0; i < numStates; i++)
- _coders[i].Init();
- }
- CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte)
- { return &_coders[((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits))]; }
-};
-
-namespace NLength {
-
-class CEncoder
-{
- CMyBitEncoder _choice;
- CMyBitEncoder _choice2;
- NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesEncodingMax];
- NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax];
- NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder;
-public:
- void Init(UInt32 numPosStates);
- void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState);
- void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const;
-};
-
-const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
-
-class CPriceTableEncoder: public CEncoder
-{
- UInt32 _prices[kNumPosStatesEncodingMax][kNumSymbolsTotal];
- UInt32 _tableSize;
- UInt32 _counters[kNumPosStatesEncodingMax];
-public:
- void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }
- UInt32 GetPrice(UInt32 symbol, UInt32 posState) const { return _prices[posState][symbol]; }
- void UpdateTable(UInt32 posState)
- {
- SetPrices(posState, _tableSize, _prices[posState]);
- _counters[posState] = _tableSize;
- }
- void UpdateTables(UInt32 numPosStates)
- {
- for (UInt32 posState = 0; posState < numPosStates; posState++)
- UpdateTable(posState);
- }
- void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState, bool updatePrice)
- {
- CEncoder::Encode(rangeEncoder, symbol, posState);
- if (updatePrice)
- if (--_counters[posState] == 0)
- UpdateTable(posState);
- }
-};
-
-}
-
-class CEncoder :
- public ICompressCoder,
- public ICompressSetOutStream,
- public ICompressSetCoderProperties,
- public ICompressWriteCoderProperties,
- public CBaseState,
- public CMyUnknownImp
-{
- COptimal _optimum[kNumOpts];
- CMyComPtr<IMatchFinder> _matchFinder; // test it
- NRangeCoder::CEncoder _rangeEncoder;
-
- CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];
- CMyBitEncoder _isRep[kNumStates];
- CMyBitEncoder _isRepG0[kNumStates];
- CMyBitEncoder _isRepG1[kNumStates];
- CMyBitEncoder _isRepG2[kNumStates];
- CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax];
-
- NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
-
- CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];
- NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder;
-
- NLength::CPriceTableEncoder _lenEncoder;
- NLength::CPriceTableEncoder _repMatchLenEncoder;
-
- CLiteralEncoder _literalEncoder;
-
- UInt32 _matchDistances[kMatchMaxLen * 2 + 2 + 1];
-
- bool _fastMode;
- // bool _maxMode;
- UInt32 _numFastBytes;
- UInt32 _longestMatchLength;
- UInt32 _numDistancePairs;
-
- UInt32 _additionalOffset;
-
- UInt32 _optimumEndIndex;
- UInt32 _optimumCurrentIndex;
-
- bool _longestMatchWasFound;
-
- UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
-
- UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
-
- UInt32 _alignPrices[kAlignTableSize];
- UInt32 _alignPriceCount;
-
- UInt32 _distTableSize;
-
- UInt32 _posStateBits;
- UInt32 _posStateMask;
- UInt32 _numLiteralPosStateBits;
- UInt32 _numLiteralContextBits;
-
- UInt32 _dictionarySize;
-
- UInt32 _dictionarySizePrev;
- UInt32 _numFastBytesPrev;
-
- UInt32 _matchPriceCount;
- UInt64 nowPos64;
- bool _finished;
- ISequentialInStream *_inStream;
-
- UInt32 _matchFinderCycles;
- int _matchFinderIndex;
- #ifdef COMPRESS_MF_MT
- bool _multiThread;
- #endif
-
- bool _writeEndMark;
-
- bool _needReleaseMFStream;
-
- IMatchFinderSetNumPasses *setMfPasses;
-
- void ReleaseMatchFinder()
- {
- setMfPasses = 0;
- _matchFinder.Release();
- }
-
- HRESULT ReadMatchDistances(UInt32 &len, UInt32 &numDistancePairs);
-
- HRESULT MovePos(UInt32 num);
- UInt32 GetRepLen1Price(CState state, UInt32 posState) const
- {
- return _isRepG0[state.Index].GetPrice0() +
- _isRep0Long[state.Index][posState].GetPrice0();
- }
-
- UInt32 GetPureRepPrice(UInt32 repIndex, CState state, UInt32 posState) const
- {
- UInt32 price;
- if(repIndex == 0)
- {
- price = _isRepG0[state.Index].GetPrice0();
- price += _isRep0Long[state.Index][posState].GetPrice1();
- }
- else
- {
- price = _isRepG0[state.Index].GetPrice1();
- if (repIndex == 1)
- price += _isRepG1[state.Index].GetPrice0();
- else
- {
- price += _isRepG1[state.Index].GetPrice1();
- price += _isRepG2[state.Index].GetPrice(repIndex - 2);
- }
- }
- return price;
- }
- UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const
- {
- return _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState) +
- GetPureRepPrice(repIndex, state, posState);
- }
- /*
- UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const
- {
- if (pos >= kNumFullDistances)
- return kIfinityPrice;
- return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState);
- }
- UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const
- {
- UInt32 price;
- UInt32 lenToPosState = GetLenToPosState(len);
- if (pos < kNumFullDistances)
- price = _distancesPrices[lenToPosState][pos];
- else
- price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
- _alignPrices[pos & kAlignMask];
- return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
- }
- */
- UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const
- {
- UInt32 price;
- UInt32 lenToPosState = GetLenToPosState(len);
- if (pos < kNumFullDistances)
- price = _distancesPrices[lenToPosState][pos];
- else
- price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
- _alignPrices[pos & kAlignMask];
- return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
- }
-
- UInt32 Backward(UInt32 &backRes, UInt32 cur);
- HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
- HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
-
- void FillDistancesPrices();
- void FillAlignPrices();
-
- void ReleaseMFStream()
- {
- if (_matchFinder && _needReleaseMFStream)
- {
- _matchFinder->ReleaseStream();
- _needReleaseMFStream = false;
- }
- }
-
- void ReleaseStreams()
- {
- ReleaseMFStream();
- ReleaseOutStream();
- }
-
- HRESULT Flush(UInt32 nowPos);
- class CCoderReleaser
- {
- CEncoder *_coder;
- public:
- CCoderReleaser(CEncoder *coder): _coder(coder) {}
- ~CCoderReleaser()
- {
- _coder->ReleaseStreams();
- }
- };
- friend class CCoderReleaser;
-
- void WriteEndMarker(UInt32 posState);
-
-public:
- CEncoder();
- void SetWriteEndMarkerMode(bool writeEndMarker)
- { _writeEndMark= writeEndMarker; }
-
- HRESULT Create();
-
- MY_UNKNOWN_IMP3(
- ICompressSetOutStream,
- ICompressSetCoderProperties,
- ICompressWriteCoderProperties
- )
-
- HRESULT Init();
-
- // ICompressCoder interface
- HRESULT SetStreams(ISequentialInStream *inStream,
- ISequentialOutStream *outStream,
- const UInt64 *inSize, const UInt64 *outSize);
- HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished);
-
- HRESULT CodeReal(ISequentialInStream *inStream,
- ISequentialOutStream *outStream,
- const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress);
-
- // ICompressCoder interface
- STDMETHOD(Code)(ISequentialInStream *inStream,
- ISequentialOutStream *outStream,
- const UInt64 *inSize, const UInt64 *outSize,
- ICompressProgressInfo *progress);
-
- // ICompressSetCoderProperties2
- STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
- const PROPVARIANT *properties, UInt32 numProperties);
-
- // ICompressWriteCoderProperties
- STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
-
- STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
- STDMETHOD(ReleaseOutStream)();
-
- virtual ~CEncoder() {}
-};
-
-}}
-
-#endif
+/*
+ * LZMAEncoder.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __LZMA_ENCODER_H
+#define __LZMA_ENCODER_H
+
+#include "../../../Common/MyCom.h"
+#include "../../../Common/Alloc.h"
+#include "../../ICoder.h"
+#include "../LZ/IMatchFinder.h"
+#include "../RangeCoder/RangeCoderBitTree.h"
+
+#include "LZMA.h"
+
+namespace NCompress {
+namespace NLZMA {
+
+typedef NRangeCoder::CBitEncoder<kNumMoveBits> CMyBitEncoder;
+
+class CBaseState
+{
+protected:
+ CState _state;
+ Byte _previousByte;
+ UInt32 _repDistances[kNumRepDistances];
+ void Init()
+ {
+ _state.Init();
+ _previousByte = 0;
+ for(UInt32 i = 0 ; i < kNumRepDistances; i++)
+ _repDistances[i] = 0;
+ }
+};
+
+struct COptimal
+{
+ CState State;
+
+ bool Prev1IsChar;
+ bool Prev2;
+
+ UInt32 PosPrev2;
+ UInt32 BackPrev2;
+
+ UInt32 Price;
+ UInt32 PosPrev; // posNext;
+ UInt32 BackPrev;
+ UInt32 Backs[kNumRepDistances];
+ void MakeAsChar() { BackPrev = UInt32(-1); Prev1IsChar = false; }
+ void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; }
+ bool IsShortRep() { return (BackPrev == 0); }
+};
+
+
+extern Byte g_FastPos[1 << 11];
+inline UInt32 GetPosSlot(UInt32 pos)
+{
+ if (pos < (1 << 11))
+ return g_FastPos[pos];
+ if (pos < (1 << 21))
+ return g_FastPos[pos >> 10] + 20;
+ return g_FastPos[pos >> 20] + 40;
+}
+
+inline UInt32 GetPosSlot2(UInt32 pos)
+{
+ if (pos < (1 << 17))
+ return g_FastPos[pos >> 6] + 12;
+ if (pos < (1 << 27))
+ return g_FastPos[pos >> 16] + 32;
+ return g_FastPos[pos >> 26] + 52;
+}
+
+const UInt32 kIfinityPrice = 0xFFFFFFF;
+
+const UInt32 kNumOpts = 1 << 12;
+
+
+class CLiteralEncoder2
+{
+ CMyBitEncoder _encoders[0x300];
+public:
+ void Init()
+ {
+ for (int i = 0; i < 0x300; i++)
+ _encoders[i].Init();
+ }
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, Byte symbol);
+ void EncodeMatched(NRangeCoder::CEncoder *rangeEncoder, Byte matchByte, Byte symbol);
+ UInt32 GetPrice(bool matchMode, Byte matchByte, Byte symbol) const;
+};
+
+class CLiteralEncoder
+{
+ CLiteralEncoder2 *_coders;
+ int _numPrevBits;
+ int _numPosBits;
+ UInt32 _posMask;
+public:
+ CLiteralEncoder(): _coders(0) {}
+ ~CLiteralEncoder() { Free(); }
+ void Free()
+ {
+ MyFree(_coders);
+ _coders = 0;
+ }
+ bool Create(int numPosBits, int numPrevBits)
+ {
+ if (_coders == 0 || (numPosBits + numPrevBits) != (_numPrevBits + _numPosBits))
+ {
+ Free();
+ UInt32 numStates = 1 << (numPosBits + numPrevBits);
+ _coders = (CLiteralEncoder2 *)MyAlloc(numStates * sizeof(CLiteralEncoder2));
+ }
+ _numPosBits = numPosBits;
+ _posMask = (1 << numPosBits) - 1;
+ _numPrevBits = numPrevBits;
+ return (_coders != 0);
+ }
+ void Init()
+ {
+ UInt32 numStates = 1 << (_numPrevBits + _numPosBits);
+ for (UInt32 i = 0; i < numStates; i++)
+ _coders[i].Init();
+ }
+ CLiteralEncoder2 *GetSubCoder(UInt32 pos, Byte prevByte)
+ { return &_coders[((pos & _posMask) << _numPrevBits) + (prevByte >> (8 - _numPrevBits))]; }
+};
+
+namespace NLength {
+
+class CEncoder
+{
+ CMyBitEncoder _choice;
+ CMyBitEncoder _choice2;
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumLowBits> _lowCoder[kNumPosStatesEncodingMax];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumMidBits> _midCoder[kNumPosStatesEncodingMax];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumHighBits> _highCoder;
+public:
+ void Init(UInt32 numPosStates);
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState);
+ void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32 *prices) const;
+};
+
+const UInt32 kNumSpecSymbols = kNumLowSymbols + kNumMidSymbols;
+
+class CPriceTableEncoder: public CEncoder
+{
+ UInt32 _prices[kNumPosStatesEncodingMax][kNumSymbolsTotal];
+ UInt32 _tableSize;
+ UInt32 _counters[kNumPosStatesEncodingMax];
+public:
+ void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; }
+ UInt32 GetPrice(UInt32 symbol, UInt32 posState) const { return _prices[posState][symbol]; }
+ void UpdateTable(UInt32 posState)
+ {
+ SetPrices(posState, _tableSize, _prices[posState]);
+ _counters[posState] = _tableSize;
+ }
+ void UpdateTables(UInt32 numPosStates)
+ {
+ for (UInt32 posState = 0; posState < numPosStates; posState++)
+ UpdateTable(posState);
+ }
+ void Encode(NRangeCoder::CEncoder *rangeEncoder, UInt32 symbol, UInt32 posState, bool updatePrice)
+ {
+ CEncoder::Encode(rangeEncoder, symbol, posState);
+ if (updatePrice)
+ if (--_counters[posState] == 0)
+ UpdateTable(posState);
+ }
+};
+
+}
+
+class CEncoder :
+ public ICompressCoder,
+ public ICompressSetOutStream,
+ public ICompressSetCoderProperties,
+ public ICompressWriteCoderProperties,
+ public CBaseState,
+ public CMyUnknownImp
+{
+ COptimal _optimum[kNumOpts];
+ CMyComPtr<IMatchFinder> _matchFinder; // test it
+ NRangeCoder::CEncoder _rangeEncoder;
+
+ CMyBitEncoder _isMatch[kNumStates][NLength::kNumPosStatesEncodingMax];
+ CMyBitEncoder _isRep[kNumStates];
+ CMyBitEncoder _isRepG0[kNumStates];
+ CMyBitEncoder _isRepG1[kNumStates];
+ CMyBitEncoder _isRepG2[kNumStates];
+ CMyBitEncoder _isRep0Long[kNumStates][NLength::kNumPosStatesEncodingMax];
+
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumPosSlotBits> _posSlotEncoder[kNumLenToPosStates];
+
+ CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex];
+ NRangeCoder::CBitTreeEncoder<kNumMoveBits, kNumAlignBits> _posAlignEncoder;
+
+ NLength::CPriceTableEncoder _lenEncoder;
+ NLength::CPriceTableEncoder _repMatchLenEncoder;
+
+ CLiteralEncoder _literalEncoder;
+
+ UInt32 _matchDistances[kMatchMaxLen * 2 + 2 + 1];
+
+ bool _fastMode;
+ // bool _maxMode;
+ UInt32 _numFastBytes;
+ UInt32 _longestMatchLength;
+ UInt32 _numDistancePairs;
+
+ UInt32 _additionalOffset;
+
+ UInt32 _optimumEndIndex;
+ UInt32 _optimumCurrentIndex;
+
+ bool _longestMatchWasFound;
+
+ UInt32 _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+
+ UInt32 _distancesPrices[kNumLenToPosStates][kNumFullDistances];
+
+ UInt32 _alignPrices[kAlignTableSize];
+ UInt32 _alignPriceCount;
+
+ UInt32 _distTableSize;
+
+ UInt32 _posStateBits;
+ UInt32 _posStateMask;
+ UInt32 _numLiteralPosStateBits;
+ UInt32 _numLiteralContextBits;
+
+ UInt32 _dictionarySize;
+
+ UInt32 _dictionarySizePrev;
+ UInt32 _numFastBytesPrev;
+
+ UInt32 _matchPriceCount;
+ UInt64 nowPos64;
+ bool _finished;
+ ISequentialInStream *_inStream;
+
+ UInt32 _matchFinderCycles;
+ int _matchFinderIndex;
+ #ifdef COMPRESS_MF_MT
+ bool _multiThread;
+ #endif
+
+ bool _writeEndMark;
+
+ bool _needReleaseMFStream;
+
+ IMatchFinderSetNumPasses *setMfPasses;
+
+ void ReleaseMatchFinder()
+ {
+ setMfPasses = 0;
+ _matchFinder.Release();
+ }
+
+ HRESULT ReadMatchDistances(UInt32 &len, UInt32 &numDistancePairs);
+
+ HRESULT MovePos(UInt32 num);
+ UInt32 GetRepLen1Price(CState state, UInt32 posState) const
+ {
+ return _isRepG0[state.Index].GetPrice0() +
+ _isRep0Long[state.Index][posState].GetPrice0();
+ }
+
+ UInt32 GetPureRepPrice(UInt32 repIndex, CState state, UInt32 posState) const
+ {
+ UInt32 price;
+ if(repIndex == 0)
+ {
+ price = _isRepG0[state.Index].GetPrice0();
+ price += _isRep0Long[state.Index][posState].GetPrice1();
+ }
+ else
+ {
+ price = _isRepG0[state.Index].GetPrice1();
+ if (repIndex == 1)
+ price += _isRepG1[state.Index].GetPrice0();
+ else
+ {
+ price += _isRepG1[state.Index].GetPrice1();
+ price += _isRepG2[state.Index].GetPrice(repIndex - 2);
+ }
+ }
+ return price;
+ }
+ UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, CState state, UInt32 posState) const
+ {
+ return _repMatchLenEncoder.GetPrice(len - kMatchMinLen, posState) +
+ GetPureRepPrice(repIndex, state, posState);
+ }
+ /*
+ UInt32 GetPosLen2Price(UInt32 pos, UInt32 posState) const
+ {
+ if (pos >= kNumFullDistances)
+ return kIfinityPrice;
+ return _distancesPrices[0][pos] + _lenEncoder.GetPrice(0, posState);
+ }
+ UInt32 GetPosLen3Price(UInt32 pos, UInt32 len, UInt32 posState) const
+ {
+ UInt32 price;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ if (pos < kNumFullDistances)
+ price = _distancesPrices[lenToPosState][pos];
+ else
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
+ _alignPrices[pos & kAlignMask];
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+ }
+ */
+ UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) const
+ {
+ UInt32 price;
+ UInt32 lenToPosState = GetLenToPosState(len);
+ if (pos < kNumFullDistances)
+ price = _distancesPrices[lenToPosState][pos];
+ else
+ price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] +
+ _alignPrices[pos & kAlignMask];
+ return price + _lenEncoder.GetPrice(len - kMatchMinLen, posState);
+ }
+
+ UInt32 Backward(UInt32 &backRes, UInt32 cur);
+ HRESULT GetOptimum(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
+ HRESULT GetOptimumFast(UInt32 position, UInt32 &backRes, UInt32 &lenRes);
+
+ void FillDistancesPrices();
+ void FillAlignPrices();
+
+ void ReleaseMFStream()
+ {
+ if (_matchFinder && _needReleaseMFStream)
+ {
+ _matchFinder->ReleaseStream();
+ _needReleaseMFStream = false;
+ }
+ }
+
+ void ReleaseStreams()
+ {
+ ReleaseMFStream();
+ ReleaseOutStream();
+ }
+
+ HRESULT Flush(UInt32 nowPos);
+ class CCoderReleaser
+ {
+ CEncoder *_coder;
+ public:
+ CCoderReleaser(CEncoder *coder): _coder(coder) {}
+ ~CCoderReleaser()
+ {
+ _coder->ReleaseStreams();
+ }
+ };
+ friend class CCoderReleaser;
+
+ void WriteEndMarker(UInt32 posState);
+
+public:
+ CEncoder();
+ void SetWriteEndMarkerMode(bool writeEndMarker)
+ { _writeEndMark= writeEndMarker; }
+
+ HRESULT Create();
+
+ MY_UNKNOWN_IMP3(
+ ICompressSetOutStream,
+ ICompressSetCoderProperties,
+ ICompressWriteCoderProperties
+ )
+
+ HRESULT Init();
+
+ // ICompressCoder interface
+ HRESULT SetStreams(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize);
+ HRESULT CodeOneBlock(UInt64 *inSize, UInt64 *outSize, Int32 *finished);
+
+ HRESULT CodeReal(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // ICompressCoder interface
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize, const UInt64 *outSize,
+ ICompressProgressInfo *progress);
+
+ // ICompressSetCoderProperties2
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties);
+
+ // ICompressWriteCoderProperties
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
+
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream);
+ STDMETHOD(ReleaseOutStream)();
+
+ virtual ~CEncoder() {}
+};
+
+}}
+
+#endif
diff --git a/Source/7zip/7zip/Compress/LZMA/StdAfx.h b/Source/7zip/7zip/Compress/LZMA/StdAfx.h
index 83fdd22..e7fb698 100755
--- a/Source/7zip/7zip/Compress/LZMA/StdAfx.h
+++ b/Source/7zip/7zip/Compress/LZMA/StdAfx.h
@@ -1,8 +1,8 @@
-// StdAfx.h
-
-#ifndef __STDAFX_H
-#define __STDAFX_H
-
-#include "../../../Common/MyWindows.h"
-
-#endif
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#include "../../../Common/MyWindows.h"
+
+#endif
diff --git a/Source/7zip/7zip/Compress/RangeCoder/RangeCoder.h b/Source/7zip/7zip/Compress/RangeCoder/RangeCoder.h
index cbf5524..2373565 100755
--- a/Source/7zip/7zip/Compress/RangeCoder/RangeCoder.h
+++ b/Source/7zip/7zip/Compress/RangeCoder/RangeCoder.h
@@ -1,220 +1,220 @@
-/*
- * RangeCoder.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __COMPRESS_RANGECODER_H
-#define __COMPRESS_RANGECODER_H
-
-#include "../../Common/InBuffer.h"
-#include "../../Common/OutBuffer.h"
-
-namespace NCompress {
-namespace NRangeCoder {
-
-const int kNumTopBits = 24;
-const UInt32 kTopValue = (1 << kNumTopBits);
-
-class CEncoder
-{
- UInt32 _cacheSize;
- Byte _cache;
-public:
- UInt64 Low;
- UInt32 Range;
- COutBuffer Stream;
- bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
-
- void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
- void Init()
- {
- Stream.Init();
- Low = 0;
- Range = 0xFFFFFFFF;
- _cacheSize = 1;
- _cache = 0;
- }
-
- void FlushData()
- {
- // Low += 1;
- for(int i = 0; i < 5; i++)
- ShiftLow();
- }
-
- HRESULT FlushStream() { return Stream.Flush(); }
-
- void ReleaseStream() { Stream.ReleaseStream(); }
-
- void Encode(UInt32 start, UInt32 size, UInt32 total)
- {
- Low += start * (Range /= total);
- Range *= size;
- while (Range < kTopValue)
- {
- Range <<= 8;
- ShiftLow();
- }
- }
-
- void ShiftLow()
- {
- if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
- {
- Byte temp = _cache;
- do
- {
- Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
- temp = 0xFF;
- }
- while(--_cacheSize != 0);
- _cache = (Byte)((UInt32)Low >> 24);
- }
- _cacheSize++;
- Low = (UInt32)Low << 8;
- }
-
- void EncodeDirectBits(UInt32 value, int numTotalBits)
- {
- for (int i = numTotalBits - 1; i >= 0; i--)
- {
- Range >>= 1;
- if (((value >> i) & 1) == 1)
- Low += Range;
- if (Range < kTopValue)
- {
- Range <<= 8;
- ShiftLow();
- }
- }
- }
-
- void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
- {
- UInt32 newBound = (Range >> numTotalBits) * size0;
- if (symbol == 0)
- Range = newBound;
- else
- {
- Low += newBound;
- Range -= newBound;
- }
- while (Range < kTopValue)
- {
- Range <<= 8;
- ShiftLow();
- }
- }
-
- UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
-};
-
-class CDecoder
-{
-public:
- CInBuffer Stream;
- UInt32 Range;
- UInt32 Code;
- bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
-
- void Normalize()
- {
- while (Range < kTopValue)
- {
- Code = (Code << 8) | Stream.ReadByte();
- Range <<= 8;
- }
- }
-
- void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
- void Init()
- {
- Stream.Init();
- Code = 0;
- Range = 0xFFFFFFFF;
- for(int i = 0; i < 5; i++)
- Code = (Code << 8) | Stream.ReadByte();
- }
-
- void ReleaseStream() { Stream.ReleaseStream(); }
-
- UInt32 GetThreshold(UInt32 total)
- {
- return (Code) / ( Range /= total);
- }
-
- void Decode(UInt32 start, UInt32 size)
- {
- Code -= start * Range;
- Range *= size;
- Normalize();
- }
-
- UInt32 DecodeDirectBits(int numTotalBits)
- {
- UInt32 range = Range;
- UInt32 code = Code;
- UInt32 result = 0;
- for (int i = numTotalBits; i != 0; i--)
- {
- range >>= 1;
- /*
- result <<= 1;
- if (code >= range)
- {
- code -= range;
- result |= 1;
- }
- */
- UInt32 t = (code - range) >> 31;
- code -= range & (t - 1);
- result = (result << 1) | (1 - t);
-
- if (range < kTopValue)
- {
- code = (code << 8) | Stream.ReadByte();
- range <<= 8;
- }
- }
- Range = range;
- Code = code;
- return result;
- }
-
- UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
- {
- UInt32 newBound = (Range >> numTotalBits) * size0;
- UInt32 symbol;
- if (Code < newBound)
- {
- symbol = 0;
- Range = newBound;
- }
- else
- {
- symbol = 1;
- Code -= newBound;
- Range -= newBound;
- }
- Normalize();
- return symbol;
- }
-
- UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
-};
-
-}}
-
-#endif
+/*
+ * RangeCoder.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __COMPRESS_RANGECODER_H
+#define __COMPRESS_RANGECODER_H
+
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumTopBits = 24;
+const UInt32 kTopValue = (1 << kNumTopBits);
+
+class CEncoder
+{
+ UInt32 _cacheSize;
+ Byte _cache;
+public:
+ UInt64 Low;
+ UInt32 Range;
+ COutBuffer Stream;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Low = 0;
+ Range = 0xFFFFFFFF;
+ _cacheSize = 1;
+ _cache = 0;
+ }
+
+ void FlushData()
+ {
+ // Low += 1;
+ for(int i = 0; i < 5; i++)
+ ShiftLow();
+ }
+
+ HRESULT FlushStream() { return Stream.Flush(); }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ void Encode(UInt32 start, UInt32 size, UInt32 total)
+ {
+ Low += start * (Range /= total);
+ Range *= size;
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ void ShiftLow()
+ {
+ if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
+ {
+ Byte temp = _cache;
+ do
+ {
+ Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
+ temp = 0xFF;
+ }
+ while(--_cacheSize != 0);
+ _cache = (Byte)((UInt32)Low >> 24);
+ }
+ _cacheSize++;
+ Low = (UInt32)Low << 8;
+ }
+
+ void EncodeDirectBits(UInt32 value, int numTotalBits)
+ {
+ for (int i = numTotalBits - 1; i >= 0; i--)
+ {
+ Range >>= 1;
+ if (((value >> i) & 1) == 1)
+ Low += Range;
+ if (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+ }
+
+ void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ if (symbol == 0)
+ Range = newBound;
+ else
+ {
+ Low += newBound;
+ Range -= newBound;
+ }
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
+};
+
+class CDecoder
+{
+public:
+ CInBuffer Stream;
+ UInt32 Range;
+ UInt32 Code;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void Normalize()
+ {
+ while (Range < kTopValue)
+ {
+ Code = (Code << 8) | Stream.ReadByte();
+ Range <<= 8;
+ }
+ }
+
+ void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Code = 0;
+ Range = 0xFFFFFFFF;
+ for(int i = 0; i < 5; i++)
+ Code = (Code << 8) | Stream.ReadByte();
+ }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ UInt32 GetThreshold(UInt32 total)
+ {
+ return (Code) / ( Range /= total);
+ }
+
+ void Decode(UInt32 start, UInt32 size)
+ {
+ Code -= start * Range;
+ Range *= size;
+ Normalize();
+ }
+
+ UInt32 DecodeDirectBits(int numTotalBits)
+ {
+ UInt32 range = Range;
+ UInt32 code = Code;
+ UInt32 result = 0;
+ for (int i = numTotalBits; i != 0; i--)
+ {
+ range >>= 1;
+ /*
+ result <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ result |= 1;
+ }
+ */
+ UInt32 t = (code - range) >> 31;
+ code -= range & (t - 1);
+ result = (result << 1) | (1 - t);
+
+ if (range < kTopValue)
+ {
+ code = (code << 8) | Stream.ReadByte();
+ range <<= 8;
+ }
+ }
+ Range = range;
+ Code = code;
+ return result;
+ }
+
+ UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ UInt32 symbol;
+ if (Code < newBound)
+ {
+ symbol = 0;
+ Range = newBound;
+ }
+ else
+ {
+ symbol = 1;
+ Code -= newBound;
+ Range -= newBound;
+ }
+ Normalize();
+ return symbol;
+ }
+
+ UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
+};
+
+}}
+
+#endif
diff --git a/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp b/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp
index 235797a..dbf0f2f 100755
--- a/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp
+++ b/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp
@@ -1,95 +1,95 @@
-/*
- * RangeCoderBit.cpp
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "StdAfx.h"
-
-#include "RangeCoderBit.h"
-
-namespace NCompress {
-namespace NRangeCoder {
-
-UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
-static CPriceTables g_PriceTables;
-
-CPriceTables::CPriceTables() { Init(); }
-
-void CPriceTables::Init()
-{
- const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
- for(int i = kNumBits - 1; i >= 0; i--)
- {
- UInt32 start = 1 << (kNumBits - i - 1);
- UInt32 end = 1 << (kNumBits - i);
- for (UInt32 j = start; j < end; j++)
- ProbPrices[j] = (i << kNumBitPriceShiftBits) +
- (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
- }
-
- /*
- // simplest: bad solution
- for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
- ProbPrices[i] = kBitPrice;
- */
-
- /*
- const double kDummyMultMid = (1.0 / kBitPrice) / 2;
- const double kDummyMultMid = 0;
- // float solution
- double ln2 = log(double(2));
- double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
- for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
- ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
- */
-
- /*
- // experimental, slow, solution:
- for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
- {
- const int kCyclesBits = 5;
- const UInt32 kCycles = (1 << kCyclesBits);
-
- UInt32 range = UInt32(-1);
- UInt32 bitCount = 0;
- for (UInt32 j = 0; j < kCycles; j++)
- {
- range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
- range *= i;
- while(range < (1 << 31))
- {
- range <<= 1;
- bitCount++;
- }
- }
- bitCount <<= kNumBitPriceShiftBits;
- range -= (1 << 31);
- for (int k = kNumBitPriceShiftBits - 1; k >= 0; k--)
- {
- range <<= 1;
- if (range > (1 << 31))
- {
- bitCount += (1 << k);
- range -= (1 << 31);
- }
- }
- ProbPrices[i] = (bitCount
- // + (1 << (kCyclesBits - 1))
- ) >> kCyclesBits;
- }
- */
-}
-
-}}
+/*
+ * RangeCoderBit.cpp
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "StdAfx.h"
+
+#include "RangeCoderBit.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+static CPriceTables g_PriceTables;
+
+CPriceTables::CPriceTables() { Init(); }
+
+void CPriceTables::Init()
+{
+ const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
+ for(int i = kNumBits - 1; i >= 0; i--)
+ {
+ UInt32 start = 1 << (kNumBits - i - 1);
+ UInt32 end = 1 << (kNumBits - i);
+ for (UInt32 j = start; j < end; j++)
+ ProbPrices[j] = (i << kNumBitPriceShiftBits) +
+ (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
+ }
+
+ /*
+ // simplest: bad solution
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ ProbPrices[i] = kBitPrice;
+ */
+
+ /*
+ const double kDummyMultMid = (1.0 / kBitPrice) / 2;
+ const double kDummyMultMid = 0;
+ // float solution
+ double ln2 = log(double(2));
+ double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
+ */
+
+ /*
+ // experimental, slow, solution:
+ for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
+ {
+ const int kCyclesBits = 5;
+ const UInt32 kCycles = (1 << kCyclesBits);
+
+ UInt32 range = UInt32(-1);
+ UInt32 bitCount = 0;
+ for (UInt32 j = 0; j < kCycles; j++)
+ {
+ range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
+ range *= i;
+ while(range < (1 << 31))
+ {
+ range <<= 1;
+ bitCount++;
+ }
+ }
+ bitCount <<= kNumBitPriceShiftBits;
+ range -= (1 << 31);
+ for (int k = kNumBitPriceShiftBits - 1; k >= 0; k--)
+ {
+ range <<= 1;
+ if (range > (1 << 31))
+ {
+ bitCount += (1 << k);
+ range -= (1 << 31);
+ }
+ }
+ ProbPrices[i] = (bitCount
+ // + (1 << (kCyclesBits - 1))
+ ) >> kCyclesBits;
+ }
+ */
+}
+
+}}
diff --git a/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.h b/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.h
index e2e7902..366abbc 100755
--- a/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.h
+++ b/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBit.h
@@ -1,135 +1,135 @@
-/*
- * RangeCoderBit.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __COMPRESS_RANGECODER_BIT_H
-#define __COMPRESS_RANGECODER_BIT_H
-
-#include "RangeCoder.h"
-
-namespace NCompress {
-namespace NRangeCoder {
-
-const int kNumBitModelTotalBits = 11;
-const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
-
-const int kNumMoveReducingBits = 2;
-
-const int kNumBitPriceShiftBits = 6;
-const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
-
-class CPriceTables
-{
-public:
- static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
- static void Init();
- CPriceTables();
-};
-
-template <int numMoveBits>
-class CBitModel
-{
-public:
- UInt32 Prob;
- void UpdateModel(UInt32 symbol)
- {
- /*
- Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
- Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
- */
- if (symbol == 0)
- Prob += (kBitModelTotal - Prob) >> numMoveBits;
- else
- Prob -= (Prob) >> numMoveBits;
- }
-public:
- void Init() { Prob = kBitModelTotal / 2; }
-};
-
-template <int numMoveBits>
-class CBitEncoder: public CBitModel<numMoveBits>
-{
-public:
- void Encode(CEncoder *encoder, UInt32 symbol)
- {
- /*
- encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
- this->UpdateModel(symbol);
- */
- UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
- if (symbol == 0)
- {
- encoder->Range = newBound;
- this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
- }
- else
- {
- encoder->Low += newBound;
- encoder->Range -= newBound;
- this->Prob -= (this->Prob) >> numMoveBits;
- }
- if (encoder->Range < kTopValue)
- {
- encoder->Range <<= 8;
- encoder->ShiftLow();
- }
- }
- UInt32 GetPrice(UInt32 symbol) const
- {
- return CPriceTables::ProbPrices[
- (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
- }
- UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
- UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
-};
-
-
-template <int numMoveBits>
-class CBitDecoder: public CBitModel<numMoveBits>
-{
-public:
- UInt32 Decode(CDecoder *decoder)
- {
- UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
- if (decoder->Code < newBound)
- {
- decoder->Range = newBound;
- this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
- if (decoder->Range < kTopValue)
- {
- decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
- decoder->Range <<= 8;
- }
- return 0;
- }
- else
- {
- decoder->Range -= newBound;
- decoder->Code -= newBound;
- this->Prob -= (this->Prob) >> numMoveBits;
- if (decoder->Range < kTopValue)
- {
- decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
- decoder->Range <<= 8;
- }
- return 1;
- }
- }
-};
-
-}}
-
-#endif
+/*
+ * RangeCoderBit.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __COMPRESS_RANGECODER_BIT_H
+#define __COMPRESS_RANGECODER_BIT_H
+
+#include "RangeCoder.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumBitModelTotalBits = 11;
+const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
+
+const int kNumMoveReducingBits = 2;
+
+const int kNumBitPriceShiftBits = 6;
+const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
+
+class CPriceTables
+{
+public:
+ static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+ static void Init();
+ CPriceTables();
+};
+
+template <int numMoveBits>
+class CBitModel
+{
+public:
+ UInt32 Prob;
+ void UpdateModel(UInt32 symbol)
+ {
+ /*
+ Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
+ Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
+ */
+ if (symbol == 0)
+ Prob += (kBitModelTotal - Prob) >> numMoveBits;
+ else
+ Prob -= (Prob) >> numMoveBits;
+ }
+public:
+ void Init() { Prob = kBitModelTotal / 2; }
+};
+
+template <int numMoveBits>
+class CBitEncoder: public CBitModel<numMoveBits>
+{
+public:
+ void Encode(CEncoder *encoder, UInt32 symbol)
+ {
+ /*
+ encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
+ this->UpdateModel(symbol);
+ */
+ UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (symbol == 0)
+ {
+ encoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ }
+ else
+ {
+ encoder->Low += newBound;
+ encoder->Range -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ }
+ if (encoder->Range < kTopValue)
+ {
+ encoder->Range <<= 8;
+ encoder->ShiftLow();
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ return CPriceTables::ProbPrices[
+ (((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
+ }
+ UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
+ UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
+};
+
+
+template <int numMoveBits>
+class CBitDecoder: public CBitModel<numMoveBits>
+{
+public:
+ UInt32 Decode(CDecoder *decoder)
+ {
+ UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
+ if (decoder->Code < newBound)
+ {
+ decoder->Range = newBound;
+ this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 0;
+ }
+ else
+ {
+ decoder->Range -= newBound;
+ decoder->Code -= newBound;
+ this->Prob -= (this->Prob) >> numMoveBits;
+ if (decoder->Range < kTopValue)
+ {
+ decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
+ decoder->Range <<= 8;
+ }
+ return 1;
+ }
+ }
+};
+
+}}
+
+#endif
diff --git a/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBitTree.h b/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBitTree.h
index cd8ae5a..126f6f0 100755
--- a/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBitTree.h
+++ b/Source/7zip/7zip/Compress/RangeCoder/RangeCoderBitTree.h
@@ -1,176 +1,176 @@
-/*
- * RangeCoderBitTree.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
-#define __COMPRESS_RANGECODER_BIT_TREE_H
-
-#include "RangeCoderBit.h"
-#include "RangeCoderOpt.h"
-
-namespace NCompress {
-namespace NRangeCoder {
-
-template <int numMoveBits, int NumBitLevels>
-class CBitTreeEncoder
-{
- CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
-public:
- void Init()
- {
- for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
- Models[i].Init();
- }
- void Encode(CEncoder *rangeEncoder, UInt32 symbol)
- {
- UInt32 modelIndex = 1;
- for (int bitIndex = NumBitLevels; bitIndex != 0 ;)
- {
- bitIndex--;
- UInt32 bit = (symbol >> bitIndex) & 1;
- Models[modelIndex].Encode(rangeEncoder, bit);
- modelIndex = (modelIndex << 1) | bit;
- }
- };
- void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
- {
- UInt32 modelIndex = 1;
- for (int i = 0; i < NumBitLevels; i++)
- {
- UInt32 bit = symbol & 1;
- Models[modelIndex].Encode(rangeEncoder, bit);
- modelIndex = (modelIndex << 1) | bit;
- symbol >>= 1;
- }
- }
- UInt32 GetPrice(UInt32 symbol) const
- {
- symbol |= (1 << NumBitLevels);
- UInt32 price = 0;
- while (symbol != 1)
- {
- price += Models[symbol >> 1].GetPrice(symbol & 1);
- symbol >>= 1;
- }
- return price;
- }
- UInt32 ReverseGetPrice(UInt32 symbol) const
- {
- UInt32 price = 0;
- UInt32 modelIndex = 1;
- for (int i = NumBitLevels; i != 0; i--)
- {
- UInt32 bit = symbol & 1;
- symbol >>= 1;
- price += Models[modelIndex].GetPrice(bit);
- modelIndex = (modelIndex << 1) | bit;
- }
- return price;
- }
-};
-
-template <int numMoveBits, int NumBitLevels>
-class CBitTreeDecoder
-{
- CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
-public:
- void Init()
- {
- for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
- Models[i].Init();
- }
- UInt32 Decode(CDecoder *rangeDecoder)
- {
- UInt32 modelIndex = 1;
- RC_INIT_VAR
- for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
- {
- // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
- RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
- }
- RC_FLUSH_VAR
- return modelIndex - (1 << NumBitLevels);
- };
- UInt32 ReverseDecode(CDecoder *rangeDecoder)
- {
- UInt32 modelIndex = 1;
- UInt32 symbol = 0;
- RC_INIT_VAR
- for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
- {
- // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
- // modelIndex <<= 1;
- // modelIndex += bit;
- // symbol |= (bit << bitIndex);
- RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
- }
- RC_FLUSH_VAR
- return symbol;
- }
-};
-
-template <int numMoveBits>
-void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
- CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol)
-{
- UInt32 modelIndex = 1;
- for (int i = 0; i < NumBitLevels; i++)
- {
- UInt32 bit = symbol & 1;
- Models[modelIndex].Encode(rangeEncoder, bit);
- modelIndex = (modelIndex << 1) | bit;
- symbol >>= 1;
- }
-}
-
-template <int numMoveBits>
-UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
- UInt32 NumBitLevels, UInt32 symbol)
-{
- UInt32 price = 0;
- UInt32 modelIndex = 1;
- for (int i = NumBitLevels; i != 0; i--)
- {
- UInt32 bit = symbol & 1;
- symbol >>= 1;
- price += Models[modelIndex].GetPrice(bit);
- modelIndex = (modelIndex << 1) | bit;
- }
- return price;
-}
-
-template <int numMoveBits>
-UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
- CDecoder *rangeDecoder, int NumBitLevels)
-{
- UInt32 modelIndex = 1;
- UInt32 symbol = 0;
- RC_INIT_VAR
- for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
- {
- // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
- // modelIndex <<= 1;
- // modelIndex += bit;
- // symbol |= (bit << bitIndex);
- RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
- }
- RC_FLUSH_VAR
- return symbol;
-}
-
-}}
-
-#endif
+/*
+ * RangeCoderBitTree.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
+#define __COMPRESS_RANGECODER_BIT_TREE_H
+
+#include "RangeCoderBit.h"
+#include "RangeCoderOpt.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeEncoder
+{
+ CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ void Encode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int bitIndex = NumBitLevels; bitIndex != 0 ;)
+ {
+ bitIndex--;
+ UInt32 bit = (symbol >> bitIndex) & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ };
+ void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
+ {
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+ }
+ UInt32 GetPrice(UInt32 symbol) const
+ {
+ symbol |= (1 << NumBitLevels);
+ UInt32 price = 0;
+ while (symbol != 1)
+ {
+ price += Models[symbol >> 1].GetPrice(symbol & 1);
+ symbol >>= 1;
+ }
+ return price;
+ }
+ UInt32 ReverseGetPrice(UInt32 symbol) const
+ {
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+ }
+};
+
+template <int numMoveBits, int NumBitLevels>
+class CBitTreeDecoder
+{
+ CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
+public:
+ void Init()
+ {
+ for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
+ Models[i].Init();
+ }
+ UInt32 Decode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ RC_INIT_VAR
+ for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
+ {
+ // modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
+ RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
+ }
+ RC_FLUSH_VAR
+ return modelIndex - (1 << NumBitLevels);
+ };
+ UInt32 ReverseDecode(CDecoder *rangeDecoder)
+ {
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+ }
+};
+
+template <int numMoveBits>
+void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
+ CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol)
+{
+ UInt32 modelIndex = 1;
+ for (int i = 0; i < NumBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ Models[modelIndex].Encode(rangeEncoder, bit);
+ modelIndex = (modelIndex << 1) | bit;
+ symbol >>= 1;
+ }
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
+ UInt32 NumBitLevels, UInt32 symbol)
+{
+ UInt32 price = 0;
+ UInt32 modelIndex = 1;
+ for (int i = NumBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += Models[modelIndex].GetPrice(bit);
+ modelIndex = (modelIndex << 1) | bit;
+ }
+ return price;
+}
+
+template <int numMoveBits>
+UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
+ CDecoder *rangeDecoder, int NumBitLevels)
+{
+ UInt32 modelIndex = 1;
+ UInt32 symbol = 0;
+ RC_INIT_VAR
+ for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
+ {
+ // UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
+ // modelIndex <<= 1;
+ // modelIndex += bit;
+ // symbol |= (bit << bitIndex);
+ RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
+ }
+ RC_FLUSH_VAR
+ return symbol;
+}
+
+}}
+
+#endif
diff --git a/Source/7zip/7zip/Compress/RangeCoder/RangeCoderOpt.h b/Source/7zip/7zip/Compress/RangeCoder/RangeCoderOpt.h
index 4b59e82..e3ec84c 100755
--- a/Source/7zip/7zip/Compress/RangeCoder/RangeCoderOpt.h
+++ b/Source/7zip/7zip/Compress/RangeCoder/RangeCoderOpt.h
@@ -1,46 +1,46 @@
-/*
- * RangeCoderOpt.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __COMPRESS_RANGECODER_OPT_H
-#define __COMPRESS_RANGECODER_OPT_H
-
-#define RC_INIT_VAR \
- UInt32 range = rangeDecoder->Range; \
- UInt32 code = rangeDecoder->Code;
-
-#define RC_FLUSH_VAR \
- rangeDecoder->Range = range; \
- rangeDecoder->Code = code;
-
-#define RC_NORMALIZE \
- if (range < NCompress::NRangeCoder::kTopValue) \
- { code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; }
-
-#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \
- { UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
- if (code < bound) \
- { A0; range = bound; \
- prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
- mi <<= 1; } \
- else \
- { A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \
- mi = (mi + mi) + 1; }} \
- RC_NORMALIZE
-
-#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;)
-
-#endif
+/*
+ * RangeCoderOpt.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __COMPRESS_RANGECODER_OPT_H
+#define __COMPRESS_RANGECODER_OPT_H
+
+#define RC_INIT_VAR \
+ UInt32 range = rangeDecoder->Range; \
+ UInt32 code = rangeDecoder->Code;
+
+#define RC_FLUSH_VAR \
+ rangeDecoder->Range = range; \
+ rangeDecoder->Code = code;
+
+#define RC_NORMALIZE \
+ if (range < NCompress::NRangeCoder::kTopValue) \
+ { code = (code << 8) | rangeDecoder->Stream.ReadByte(); range <<= 8; }
+
+#define RC_GETBIT2(numMoveBits, prob, mi, A0, A1) \
+ { UInt32 bound = (range >> NCompress::NRangeCoder::kNumBitModelTotalBits) * prob; \
+ if (code < bound) \
+ { A0; range = bound; \
+ prob += (NCompress::NRangeCoder::kBitModelTotal - prob) >> numMoveBits; \
+ mi <<= 1; } \
+ else \
+ { A1; range -= bound; code -= bound; prob -= (prob) >> numMoveBits; \
+ mi = (mi + mi) + 1; }} \
+ RC_NORMALIZE
+
+#define RC_GETBIT(numMoveBits, prob, mi) RC_GETBIT2(numMoveBits, prob, mi, ; , ;)
+
+#endif
diff --git a/Source/7zip/7zip/Compress/RangeCoder/StdAfx.h b/Source/7zip/7zip/Compress/RangeCoder/StdAfx.h
index 21c2fd7..b637fd4 100755
--- a/Source/7zip/7zip/Compress/RangeCoder/StdAfx.h
+++ b/Source/7zip/7zip/Compress/RangeCoder/StdAfx.h
@@ -1,6 +1,6 @@
-// StdAfx.h
-
-#ifndef __STDAFX_H
-#define __STDAFX_H
-
-#endif
+// StdAfx.h
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+#endif
diff --git a/Source/7zip/7zip/ICoder.h b/Source/7zip/7zip/ICoder.h
index a0e93e4..7e90f2c 100755
--- a/Source/7zip/7zip/ICoder.h
+++ b/Source/7zip/7zip/ICoder.h
@@ -1,178 +1,178 @@
-/*
- * ICoder.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __ICODER_H
-#define __ICODER_H
-
-#include "IStream.h"
-
-// "23170F69-40C1-278A-0000-000400xx0000"
-#define CODER_INTERFACE(i, x) \
-DEFINE_GUID(IID_ ## i, \
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \
-struct i: public IUnknown
-
-CODER_INTERFACE(ICompressProgressInfo, 0x04)
-{
- STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;
-};
-
-CODER_INTERFACE(ICompressCoder, 0x05)
-{
- STDMETHOD(Code)(ISequentialInStream *inStream,
- ISequentialOutStream *outStream,
- const UInt64 *inSize,
- const UInt64 *outSize,
- ICompressProgressInfo *progress) PURE;
-};
-
-CODER_INTERFACE(ICompressCoder2, 0x18)
-{
- STDMETHOD(Code)(ISequentialInStream **inStreams,
- const UInt64 **inSizes,
- UInt32 numInStreams,
- ISequentialOutStream **outStreams,
- const UInt64 **outSizes,
- UInt32 numOutStreams,
- ICompressProgressInfo *progress) PURE;
-};
-
-namespace NCoderPropID
-{
- enum EEnum
- {
- kDictionarySize = 0x400,
- kUsedMemorySize,
- kOrder,
- kPosStateBits = 0x440,
- kLitContextBits,
- kLitPosBits,
- kNumFastBytes = 0x450,
- kMatchFinder,
- kMatchFinderCycles,
- kNumPasses = 0x460,
- kAlgorithm = 0x470,
- kMultiThread = 0x480,
- kNumThreads,
- kEndMarker = 0x490
- };
-}
-
-CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
-{
- STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
- const PROPVARIANT *properties, UInt32 numProperties) PURE;
-};
-
-/*
-CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
-{
- STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
-};
-*/
-
-CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
-{
- STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
-};
-
-CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
-{
- STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE;
-};
-
-CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
-{
- STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
-};
-
-CODER_INTERFACE(ICompressSetCoderMt, 0x25)
-{
- STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
-};
-
-CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
-{
- STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
-};
-
-CODER_INTERFACE(ICompressSetInStream, 0x31)
-{
- STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
- STDMETHOD(ReleaseInStream)() PURE;
-};
-
-CODER_INTERFACE(ICompressSetOutStream, 0x32)
-{
- STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
- STDMETHOD(ReleaseOutStream)() PURE;
-};
-
-CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
-{
- STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
-};
-
-CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
-{
- STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
-};
-
-CODER_INTERFACE(ICompressFilter, 0x40)
-{
- STDMETHOD(Init)() PURE;
- STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;
- // Filter return outSize (UInt32)
- // if (outSize <= size): Filter have converted outSize bytes
- // if (outSize > size): Filter have not converted anything.
- // and it needs at least outSize bytes to convert one block
- // (it's for crypto block algorithms).
-};
-
-CODER_INTERFACE(ICryptoProperties, 0x80)
-{
- STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;
- STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;
-};
-
-CODER_INTERFACE(ICryptoSetPassword, 0x90)
-{
- STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
-};
-
-CODER_INTERFACE(ICryptoSetCRC, 0xA0)
-{
- STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
-};
-
-//////////////////////
-// It's for DLL file
-namespace NMethodPropID
-{
- enum EEnum
- {
- kID,
- kName,
- kDecoder,
- kEncoder,
- kInStreams,
- kOutStreams,
- kDescription
- };
-}
-
-#endif
+/*
+ * ICoder.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __ICODER_H
+#define __ICODER_H
+
+#include "IStream.h"
+
+// "23170F69-40C1-278A-0000-000400xx0000"
+#define CODER_INTERFACE(i, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, x, 0x00, 0x00); \
+struct i: public IUnknown
+
+CODER_INTERFACE(ICompressProgressInfo, 0x04)
+{
+ STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder, 0x05)
+{
+ STDMETHOD(Code)(ISequentialInStream *inStream,
+ ISequentialOutStream *outStream,
+ const UInt64 *inSize,
+ const UInt64 *outSize,
+ ICompressProgressInfo *progress) PURE;
+};
+
+CODER_INTERFACE(ICompressCoder2, 0x18)
+{
+ STDMETHOD(Code)(ISequentialInStream **inStreams,
+ const UInt64 **inSizes,
+ UInt32 numInStreams,
+ ISequentialOutStream **outStreams,
+ const UInt64 **outSizes,
+ UInt32 numOutStreams,
+ ICompressProgressInfo *progress) PURE;
+};
+
+namespace NCoderPropID
+{
+ enum EEnum
+ {
+ kDictionarySize = 0x400,
+ kUsedMemorySize,
+ kOrder,
+ kPosStateBits = 0x440,
+ kLitContextBits,
+ kLitPosBits,
+ kNumFastBytes = 0x450,
+ kMatchFinder,
+ kMatchFinderCycles,
+ kNumPasses = 0x460,
+ kAlgorithm = 0x470,
+ kMultiThread = 0x480,
+ kNumThreads,
+ kEndMarker = 0x490
+ };
+}
+
+CODER_INTERFACE(ICompressSetCoderProperties, 0x20)
+{
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties) PURE;
+};
+
+/*
+CODER_INTERFACE(ICompressSetCoderProperties, 0x21)
+{
+ STDMETHOD(SetDecoderProperties)(ISequentialInStream *inStream) PURE;
+};
+*/
+
+CODER_INTERFACE(ICompressSetDecoderProperties2, 0x22)
+{
+ STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICompressWriteCoderProperties, 0x23)
+{
+ STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStreams) PURE;
+};
+
+CODER_INTERFACE(ICompressGetInStreamProcessedSize, 0x24)
+{
+ STDMETHOD(GetInStreamProcessedSize)(UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetCoderMt, 0x25)
+{
+ STDMETHOD(SetNumberOfThreads)(UInt32 numThreads) PURE;
+};
+
+CODER_INTERFACE(ICompressGetSubStreamSize, 0x30)
+{
+ STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value) PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStream, 0x31)
+{
+ STDMETHOD(SetInStream)(ISequentialInStream *inStream) PURE;
+ STDMETHOD(ReleaseInStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStream, 0x32)
+{
+ STDMETHOD(SetOutStream)(ISequentialOutStream *outStream) PURE;
+ STDMETHOD(ReleaseOutStream)() PURE;
+};
+
+CODER_INTERFACE(ICompressSetInStreamSize, 0x33)
+{
+ STDMETHOD(SetInStreamSize)(const UInt64 *inSize) PURE;
+};
+
+CODER_INTERFACE(ICompressSetOutStreamSize, 0x34)
+{
+ STDMETHOD(SetOutStreamSize)(const UInt64 *outSize) PURE;
+};
+
+CODER_INTERFACE(ICompressFilter, 0x40)
+{
+ STDMETHOD(Init)() PURE;
+ STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size) PURE;
+ // Filter return outSize (UInt32)
+ // if (outSize <= size): Filter have converted outSize bytes
+ // if (outSize > size): Filter have not converted anything.
+ // and it needs at least outSize bytes to convert one block
+ // (it's for crypto block algorithms).
+};
+
+CODER_INTERFACE(ICryptoProperties, 0x80)
+{
+ STDMETHOD(SetKey)(const Byte *data, UInt32 size) PURE;
+ STDMETHOD(SetInitVector)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICryptoSetPassword, 0x90)
+{
+ STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size) PURE;
+};
+
+CODER_INTERFACE(ICryptoSetCRC, 0xA0)
+{
+ STDMETHOD(CryptoSetCRC)(UInt32 crc) PURE;
+};
+
+//////////////////////
+// It's for DLL file
+namespace NMethodPropID
+{
+ enum EEnum
+ {
+ kID,
+ kName,
+ kDecoder,
+ kEncoder,
+ kInStreams,
+ kOutStreams,
+ kDescription
+ };
+}
+
+#endif
diff --git a/Source/7zip/7zip/IStream.h b/Source/7zip/7zip/IStream.h
index 62f6060..3c6d56f 100755
--- a/Source/7zip/7zip/IStream.h
+++ b/Source/7zip/7zip/IStream.h
@@ -1,77 +1,77 @@
-/*
- * IStream.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __ISTREAM_H
-#define __ISTREAM_H
-
-#include "../Common/MyUnknown.h"
-#include "../Common/Types.h"
-
-// "23170F69-40C1-278A-0000-000300xx0000"
-
-#define STREAM_INTERFACE_SUB(i, b, x) \
-DEFINE_GUID(IID_ ## i, \
-0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, x, 0x00, 0x00); \
-struct i: public b
-
-#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x)
-
-STREAM_INTERFACE(ISequentialInStream, 0x01)
-{
- STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
- /*
- Out: if size != 0, return_value = S_OK and (*processedSize == 0),
- then there are no more bytes in stream.
- if (size > 0) && there are bytes in stream,
- this function must read at least 1 byte.
- This function is allowed to read less than number of remaining bytes in stream.
- You must call Read function in loop, if you need exact amount of data
- */
-};
-
-STREAM_INTERFACE(ISequentialOutStream, 0x02)
-{
- STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;
- /*
- if (size > 0) this function must write at least 1 byte.
- This function is allowed to write less than "size".
- You must call Write function in loop, if you need to write exact amount of data
- */
-};
-
-STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
-{
- STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
-};
-
-STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)
-{
- STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
- STDMETHOD(SetSize)(Int64 newSize) PURE;
-};
-
-STREAM_INTERFACE(IStreamGetSize, 0x06)
-{
- STDMETHOD(GetSize)(UInt64 *size) PURE;
-};
-
-STREAM_INTERFACE(IOutStreamFlush, 0x07)
-{
- STDMETHOD(Flush)() PURE;
-};
-
-#endif
+/*
+ * IStream.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __ISTREAM_H
+#define __ISTREAM_H
+
+#include "../Common/MyUnknown.h"
+#include "../Common/Types.h"
+
+// "23170F69-40C1-278A-0000-000300xx0000"
+
+#define STREAM_INTERFACE_SUB(i, b, x) \
+DEFINE_GUID(IID_ ## i, \
+0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x03, 0x00, x, 0x00, 0x00); \
+struct i: public b
+
+#define STREAM_INTERFACE(i, x) STREAM_INTERFACE_SUB(i, IUnknown, x)
+
+STREAM_INTERFACE(ISequentialInStream, 0x01)
+{
+ STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) PURE;
+ /*
+ Out: if size != 0, return_value = S_OK and (*processedSize == 0),
+ then there are no more bytes in stream.
+ if (size > 0) && there are bytes in stream,
+ this function must read at least 1 byte.
+ This function is allowed to read less than number of remaining bytes in stream.
+ You must call Read function in loop, if you need exact amount of data
+ */
+};
+
+STREAM_INTERFACE(ISequentialOutStream, 0x02)
+{
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize) PURE;
+ /*
+ if (size > 0) this function must write at least 1 byte.
+ This function is allowed to write less than "size".
+ You must call Write function in loop, if you need to write exact amount of data
+ */
+};
+
+STREAM_INTERFACE_SUB(IInStream, ISequentialInStream, 0x03)
+{
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+};
+
+STREAM_INTERFACE_SUB(IOutStream, ISequentialOutStream, 0x04)
+{
+ STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) PURE;
+ STDMETHOD(SetSize)(Int64 newSize) PURE;
+};
+
+STREAM_INTERFACE(IStreamGetSize, 0x06)
+{
+ STDMETHOD(GetSize)(UInt64 *size) PURE;
+};
+
+STREAM_INTERFACE(IOutStreamFlush, 0x07)
+{
+ STDMETHOD(Flush)() PURE;
+};
+
+#endif
diff --git a/Source/7zip/Common/Alloc.cpp b/Source/7zip/Common/Alloc.cpp
index 2898c6d..9ac1946 100755
--- a/Source/7zip/Common/Alloc.cpp
+++ b/Source/7zip/Common/Alloc.cpp
@@ -1,133 +1,133 @@
-/*
- * Alloc.cpp
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "StdAfx.h"
-
-#ifdef _WIN32
-#include "MyWindows.h"
-#else
-#include <stdlib.h>
-#endif
-
-#include "Alloc.h"
-
-/* #define _SZ_ALLOC_DEBUG */
-/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
-#ifdef _SZ_ALLOC_DEBUG
-#include <stdio.h>
-int g_allocCount = 0;
-int g_allocCountMid = 0;
-int g_allocCountBig = 0;
-#endif
-
-void *MyAlloc(size_t size) throw()
-{
- if (size == 0)
- return 0;
- #ifdef _SZ_ALLOC_DEBUG
- fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++);
- #endif
- return ::malloc(size);
-}
-
-void MyFree(void *address) throw()
-{
- #ifdef _SZ_ALLOC_DEBUG
- if (address != 0)
- fprintf(stderr, "\nFree; count = %10d", --g_allocCount);
- #endif
-
- ::free(address);
-}
-
-#ifdef _WIN32
-
-void *MidAlloc(size_t size) throw()
-{
- if (size == 0)
- return 0;
- #ifdef _SZ_ALLOC_DEBUG
- fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
- #endif
- return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
-}
-
-void MidFree(void *address) throw()
-{
- #ifdef _SZ_ALLOC_DEBUG
- if (address != 0)
- fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
- #endif
- if (address == 0)
- return;
- ::VirtualFree(address, 0, MEM_RELEASE);
-}
-
-static SIZE_T g_LargePageSize =
- #ifdef _WIN64
- (1 << 21);
- #else
- (1 << 22);
- #endif
-
-typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
-
-bool SetLargePageSize()
-{
- GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
- ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
- if (largePageMinimum == 0)
- return false;
- SIZE_T size = largePageMinimum();
- if (size == 0 || (size & (size - 1)) != 0)
- return false;
- g_LargePageSize = size;
- return true;
-}
-
-
-void *BigAlloc(size_t size) throw()
-{
- if (size == 0)
- return 0;
- #ifdef _SZ_ALLOC_DEBUG
- fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
- #endif
-
- if (size >= (1 << 18))
- {
- void *res = ::VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
- MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
- if (res != 0)
- return res;
- }
- return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
-}
-
-void BigFree(void *address) throw()
-{
- #ifdef _SZ_ALLOC_DEBUG
- if (address != 0)
- fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
- #endif
-
- if (address == 0)
- return;
- ::VirtualFree(address, 0, MEM_RELEASE);
-}
-
-#endif
+/*
+ * Alloc.cpp
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "StdAfx.h"
+
+#ifdef _WIN32
+#include "MyWindows.h"
+#else
+#include <stdlib.h>
+#endif
+
+#include "Alloc.h"
+
+/* #define _SZ_ALLOC_DEBUG */
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
+#ifdef _SZ_ALLOC_DEBUG
+#include <stdio.h>
+int g_allocCount = 0;
+int g_allocCountMid = 0;
+int g_allocCountBig = 0;
+#endif
+
+void *MyAlloc(size_t size) throw()
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount++);
+ #endif
+ return ::malloc(size);
+}
+
+void MyFree(void *address) throw()
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree; count = %10d", --g_allocCount);
+ #endif
+
+ ::free(address);
+}
+
+#ifdef _WIN32
+
+void *MidAlloc(size_t size) throw()
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
+ #endif
+ return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void MidFree(void *address) throw()
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
+ #endif
+ if (address == 0)
+ return;
+ ::VirtualFree(address, 0, MEM_RELEASE);
+}
+
+static SIZE_T g_LargePageSize =
+ #ifdef _WIN64
+ (1 << 21);
+ #else
+ (1 << 22);
+ #endif
+
+typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
+
+bool SetLargePageSize()
+{
+ GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
+ ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
+ if (largePageMinimum == 0)
+ return false;
+ SIZE_T size = largePageMinimum();
+ if (size == 0 || (size & (size - 1)) != 0)
+ return false;
+ g_LargePageSize = size;
+ return true;
+}
+
+
+void *BigAlloc(size_t size) throw()
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
+ #endif
+
+ if (size >= (1 << 18))
+ {
+ void *res = ::VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
+ MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
+ if (res != 0)
+ return res;
+ }
+ return ::VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void BigFree(void *address) throw()
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
+ #endif
+
+ if (address == 0)
+ return;
+ ::VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#endif
diff --git a/Source/7zip/Common/Alloc.h b/Source/7zip/Common/Alloc.h
index 93705a1..5916ef0 100755
--- a/Source/7zip/Common/Alloc.h
+++ b/Source/7zip/Common/Alloc.h
@@ -1,44 +1,44 @@
-/*
- * Alloc.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __COMMON_ALLOC_H
-#define __COMMON_ALLOC_H
-
-#include <stddef.h>
-
-void *MyAlloc(size_t size) throw();
-void MyFree(void *address) throw();
-
-#ifdef _WIN32
-
-bool SetLargePageSize();
-
-void *MidAlloc(size_t size) throw();
-void MidFree(void *address) throw();
-void *BigAlloc(size_t size) throw();
-void BigFree(void *address) throw();
-
-#else
-
-#define MidAlloc(size) MyAlloc(size)
-#define MidFree(address) MyFree(address)
-#define BigAlloc(size) MyAlloc(size)
-#define BigFree(address) MyFree(address)
-
-#endif
-
-#endif
+/*
+ * Alloc.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __COMMON_ALLOC_H
+#define __COMMON_ALLOC_H
+
+#include <stddef.h>
+
+void *MyAlloc(size_t size) throw();
+void MyFree(void *address) throw();
+
+#ifdef _WIN32
+
+bool SetLargePageSize();
+
+void *MidAlloc(size_t size) throw();
+void MidFree(void *address) throw();
+void *BigAlloc(size_t size) throw();
+void BigFree(void *address) throw();
+
+#else
+
+#define MidAlloc(size) MyAlloc(size)
+#define MidFree(address) MyFree(address)
+#define BigAlloc(size) MyAlloc(size)
+#define BigFree(address) MyFree(address)
+
+#endif
+
+#endif
diff --git a/Source/7zip/Common/CRC.cpp b/Source/7zip/Common/CRC.cpp
index 998a579..dad6432 100755
--- a/Source/7zip/Common/CRC.cpp
+++ b/Source/7zip/Common/CRC.cpp
@@ -1,76 +1,76 @@
-/*
- * CRC.cpp
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "StdAfx.h"
-
-#include "CRC.h"
-
-static const UInt32 kCRCPoly = 0xEDB88320;
-
-UInt32 CCRC::Table[256];
-
-void CCRC::InitTable()
-{
- for (UInt32 i = 0; i < 256; i++)
- {
- UInt32 r = i;
- for (int j = 0; j < 8; j++)
- if (r & 1)
- r = (r >> 1) ^ kCRCPoly;
- else
- r >>= 1;
- CCRC::Table[i] = r;
- }
-}
-
-class CCRCTableInit
-{
-public:
- CCRCTableInit() { CCRC::InitTable(); }
-} g_CRCTableInit;
-
-void CCRC::UpdateByte(Byte b)
-{
- _value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8);
-}
-
-void CCRC::UpdateUInt16(UInt16 v)
-{
- UpdateByte(Byte(v));
- UpdateByte(Byte(v >> 8));
-}
-
-void CCRC::UpdateUInt32(UInt32 v)
-{
- for (int i = 0; i < 4; i++)
- UpdateByte((Byte)(v >> (8 * i)));
-}
-
-void CCRC::UpdateUInt64(UInt64 v)
-{
- for (int i = 0; i < 8; i++)
- UpdateByte((Byte)(v >> (8 * i)));
-}
-
-void CCRC::Update(const void *data, size_t size)
-{
- UInt32 v = _value;
- const Byte *p = (const Byte *)data;
- for (; size > 0 ; size--, p++)
- v = Table[((Byte)(v)) ^ *p] ^ (v >> 8);
- _value = v;
-}
+/*
+ * CRC.cpp
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "StdAfx.h"
+
+#include "CRC.h"
+
+static const UInt32 kCRCPoly = 0xEDB88320;
+
+UInt32 CCRC::Table[256];
+
+void CCRC::InitTable()
+{
+ for (UInt32 i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ for (int j = 0; j < 8; j++)
+ if (r & 1)
+ r = (r >> 1) ^ kCRCPoly;
+ else
+ r >>= 1;
+ CCRC::Table[i] = r;
+ }
+}
+
+class CCRCTableInit
+{
+public:
+ CCRCTableInit() { CCRC::InitTable(); }
+} g_CRCTableInit;
+
+void CCRC::UpdateByte(Byte b)
+{
+ _value = Table[((Byte)(_value)) ^ b] ^ (_value >> 8);
+}
+
+void CCRC::UpdateUInt16(UInt16 v)
+{
+ UpdateByte(Byte(v));
+ UpdateByte(Byte(v >> 8));
+}
+
+void CCRC::UpdateUInt32(UInt32 v)
+{
+ for (int i = 0; i < 4; i++)
+ UpdateByte((Byte)(v >> (8 * i)));
+}
+
+void CCRC::UpdateUInt64(UInt64 v)
+{
+ for (int i = 0; i < 8; i++)
+ UpdateByte((Byte)(v >> (8 * i)));
+}
+
+void CCRC::Update(const void *data, size_t size)
+{
+ UInt32 v = _value;
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 ; size--, p++)
+ v = Table[((Byte)(v)) ^ *p] ^ (v >> 8);
+ _value = v;
+}
diff --git a/Source/7zip/Common/CRC.h b/Source/7zip/Common/CRC.h
index e01c72f..72cb518 100755
--- a/Source/7zip/Common/CRC.h
+++ b/Source/7zip/Common/CRC.h
@@ -1,51 +1,51 @@
-/*
- * CRC.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __COMMON_CRC_H
-#define __COMMON_CRC_H
-
-#include <stddef.h>
-#include "Types.h"
-
-class CCRC
-{
- UInt32 _value;
-public:
- static UInt32 Table[256];
- static void InitTable();
-
- CCRC(): _value(0xFFFFFFFF){};
- void Init() { _value = 0xFFFFFFFF; }
- void UpdateByte(Byte v);
- void UpdateUInt16(UInt16 v);
- void UpdateUInt32(UInt32 v);
- void UpdateUInt64(UInt64 v);
- void Update(const void *data, size_t size);
- UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
- static UInt32 CalculateDigest(const void *data, size_t size)
- {
- CCRC crc;
- crc.Update(data, size);
- return crc.GetDigest();
- }
- static bool VerifyDigest(UInt32 digest, const void *data, size_t size)
- {
- return (CalculateDigest(data, size) == digest);
- }
-};
-
-#endif
+/*
+ * CRC.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __COMMON_CRC_H
+#define __COMMON_CRC_H
+
+#include <stddef.h>
+#include "Types.h"
+
+class CCRC
+{
+ UInt32 _value;
+public:
+ static UInt32 Table[256];
+ static void InitTable();
+
+ CCRC(): _value(0xFFFFFFFF){};
+ void Init() { _value = 0xFFFFFFFF; }
+ void UpdateByte(Byte v);
+ void UpdateUInt16(UInt16 v);
+ void UpdateUInt32(UInt32 v);
+ void UpdateUInt64(UInt64 v);
+ void Update(const void *data, size_t size);
+ UInt32 GetDigest() const { return _value ^ 0xFFFFFFFF; }
+ static UInt32 CalculateDigest(const void *data, size_t size)
+ {
+ CCRC crc;
+ crc.Update(data, size);
+ return crc.GetDigest();
+ }
+ static bool VerifyDigest(UInt32 digest, const void *data, size_t size)
+ {
+ return (CalculateDigest(data, size) == digest);
+ }
+};
+
+#endif
diff --git a/Source/7zip/Common/Defs.h b/Source/7zip/Common/Defs.h
index f1746a8..dd55dbe 100755
--- a/Source/7zip/Common/Defs.h
+++ b/Source/7zip/Common/Defs.h
@@ -1,35 +1,35 @@
-/*
- * Defs.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __COMMON_DEFS_H
-#define __COMMON_DEFS_H
-
-template <class T> inline T MyMin(T a, T b)
- { return a < b ? a : b; }
-template <class T> inline T MyMax(T a, T b)
- { return a > b ? a : b; }
-
-template <class T> inline int MyCompare(T a, T b)
- { return a < b ? -1 : (a == b ? 0 : 1); }
-
-inline int BoolToInt(bool value)
- { return (value ? 1: 0); }
-
-inline bool IntToBool(int value)
- { return (value != 0); }
-
-#endif
+/*
+ * Defs.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __COMMON_DEFS_H
+#define __COMMON_DEFS_H
+
+template <class T> inline T MyMin(T a, T b)
+ { return a < b ? a : b; }
+template <class T> inline T MyMax(T a, T b)
+ { return a > b ? a : b; }
+
+template <class T> inline int MyCompare(T a, T b)
+ { return a < b ? -1 : (a == b ? 0 : 1); }
+
+inline int BoolToInt(bool value)
+ { return (value ? 1: 0); }
+
+inline bool IntToBool(int value)
+ { return (value != 0); }
+
+#endif
diff --git a/Source/7zip/Common/MyCom.h b/Source/7zip/Common/MyCom.h
index 119aaff..c5e18df 100755
--- a/Source/7zip/Common/MyCom.h
+++ b/Source/7zip/Common/MyCom.h
@@ -1,218 +1,218 @@
-/*
- * MyCom.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __MYCOM_H
-#define __MYCOM_H
-
-#include "MyWindows.h"
-
-#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
-
-template <class T>
-class CMyComPtr
-{
- T* _p;
-public:
- // typedef T _PtrClass;
- CMyComPtr() { _p = NULL;}
- CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
- CMyComPtr(const CMyComPtr<T>& lp)
- {
- if ((_p = lp._p) != NULL)
- _p->AddRef();
- }
- ~CMyComPtr() { if (_p) _p->Release(); }
- void Release() { if (_p) { _p->Release(); _p = NULL; } }
- operator T*() const { return (T*)_p; }
- // T& operator*() const { return *_p; }
- T** operator&() { return &_p; }
- T* operator->() const { return _p; }
- T* operator=(T* p)
- {
- if (p != 0)
- p->AddRef();
- if (_p)
- _p->Release();
- _p = p;
- return p;
- }
- T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
- bool operator!() const { return (_p == NULL); }
- // bool operator==(T* pT) const { return _p == pT; }
- // Compare two objects for equivalence
- void Attach(T* p2)
- {
- Release();
- _p = p2;
- }
- T* Detach()
- {
- T* pt = _p;
- _p = NULL;
- return pt;
- }
- #ifdef _WIN32
- HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
- {
- return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
- }
- #endif
- /*
- HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
- {
- CLSID clsid;
- HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
- ATLASSERT(_p == NULL);
- if (SUCCEEDED(hr))
- hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
- return hr;
- }
- */
- template <class Q>
- HRESULT QueryInterface(REFGUID iid, Q** pp) const
- {
- return _p->QueryInterface(iid, (void**)pp);
- }
-};
-
-//////////////////////////////////////////////////////////
-
-class CMyComBSTR
-{
-public:
- BSTR m_str;
- CMyComBSTR() { m_str = NULL; }
- CMyComBSTR(LPCOLESTR pSrc) { m_str = ::SysAllocString(pSrc); }
- // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
- // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
- CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
- /*
- CMyComBSTR(REFGUID src)
- {
- LPOLESTR szGuid;
- StringFromCLSID(src, &szGuid);
- m_str = ::SysAllocString(szGuid);
- CoTaskMemFree(szGuid);
- }
- */
- ~CMyComBSTR() { ::SysFreeString(m_str); }
- CMyComBSTR& operator=(const CMyComBSTR& src)
- {
- if (m_str != src.m_str)
- {
- if (m_str)
- ::SysFreeString(m_str);
- m_str = src.MyCopy();
- }
- return *this;
- }
- CMyComBSTR& operator=(LPCOLESTR pSrc)
- {
- ::SysFreeString(m_str);
- m_str = ::SysAllocString(pSrc);
- return *this;
- }
- unsigned int Length() const { return ::SysStringLen(m_str); }
- operator BSTR() const { return m_str; }
- BSTR* operator&() { return &m_str; }
- BSTR MyCopy() const
- {
- int byteLen = ::SysStringByteLen(m_str);
- BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
- memmove(res, m_str, byteLen);
- return res;
- }
- void Attach(BSTR src) { m_str = src; }
- BSTR Detach()
- {
- BSTR s = m_str;
- m_str = NULL;
- return s;
- }
- void Empty()
- {
- ::SysFreeString(m_str);
- m_str = NULL;
- }
- bool operator!() const { return (m_str == NULL); }
-};
-
-
-//////////////////////////////////////////////////////////
-
-class CMyUnknownImp
-{
-public:
- ULONG __m_RefCount;
- CMyUnknownImp(): __m_RefCount(0) {}
-};
-
-#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
- (REFGUID iid, void **outObject) {
-
-#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
- { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
-
-#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
-
-#define MY_ADDREF_RELEASE \
-STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
-STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
- return __m_RefCount; delete this; return 0; }
-
-#define MY_UNKNOWN_IMP_SPEC(i) \
- MY_QUERYINTERFACE_BEGIN \
- i \
- MY_QUERYINTERFACE_END \
- MY_ADDREF_RELEASE
-
-
-#define MY_UNKNOWN_IMP STDMETHOD(QueryInterface)(REFGUID, void **) { \
- MY_QUERYINTERFACE_END \
- MY_ADDREF_RELEASE
-
-#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
- MY_QUERYINTERFACE_ENTRY(i) \
- )
-
-#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
- MY_QUERYINTERFACE_ENTRY(i1) \
- MY_QUERYINTERFACE_ENTRY(i2) \
- )
-
-#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
- MY_QUERYINTERFACE_ENTRY(i1) \
- MY_QUERYINTERFACE_ENTRY(i2) \
- MY_QUERYINTERFACE_ENTRY(i3) \
- )
-
-#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
- MY_QUERYINTERFACE_ENTRY(i1) \
- MY_QUERYINTERFACE_ENTRY(i2) \
- MY_QUERYINTERFACE_ENTRY(i3) \
- MY_QUERYINTERFACE_ENTRY(i4) \
- )
-
-#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
- MY_QUERYINTERFACE_ENTRY(i1) \
- MY_QUERYINTERFACE_ENTRY(i2) \
- MY_QUERYINTERFACE_ENTRY(i3) \
- MY_QUERYINTERFACE_ENTRY(i4) \
- MY_QUERYINTERFACE_ENTRY(i5) \
- )
-
-#endif
+/*
+ * MyCom.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __MYCOM_H
+#define __MYCOM_H
+
+#include "MyWindows.h"
+
+#define RINOK(x) { HRESULT __result_ = (x); if(__result_ != S_OK) return __result_; }
+
+template <class T>
+class CMyComPtr
+{
+ T* _p;
+public:
+ // typedef T _PtrClass;
+ CMyComPtr() { _p = NULL;}
+ CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
+ CMyComPtr(const CMyComPtr<T>& lp)
+ {
+ if ((_p = lp._p) != NULL)
+ _p->AddRef();
+ }
+ ~CMyComPtr() { if (_p) _p->Release(); }
+ void Release() { if (_p) { _p->Release(); _p = NULL; } }
+ operator T*() const { return (T*)_p; }
+ // T& operator*() const { return *_p; }
+ T** operator&() { return &_p; }
+ T* operator->() const { return _p; }
+ T* operator=(T* p)
+ {
+ if (p != 0)
+ p->AddRef();
+ if (_p)
+ _p->Release();
+ _p = p;
+ return p;
+ }
+ T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
+ bool operator!() const { return (_p == NULL); }
+ // bool operator==(T* pT) const { return _p == pT; }
+ // Compare two objects for equivalence
+ void Attach(T* p2)
+ {
+ Release();
+ _p = p2;
+ }
+ T* Detach()
+ {
+ T* pt = _p;
+ _p = NULL;
+ return pt;
+ }
+ #ifdef _WIN32
+ HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
+ }
+ #endif
+ /*
+ HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
+ {
+ CLSID clsid;
+ HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
+ ATLASSERT(_p == NULL);
+ if (SUCCEEDED(hr))
+ hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
+ return hr;
+ }
+ */
+ template <class Q>
+ HRESULT QueryInterface(REFGUID iid, Q** pp) const
+ {
+ return _p->QueryInterface(iid, (void**)pp);
+ }
+};
+
+//////////////////////////////////////////////////////////
+
+class CMyComBSTR
+{
+public:
+ BSTR m_str;
+ CMyComBSTR() { m_str = NULL; }
+ CMyComBSTR(LPCOLESTR pSrc) { m_str = ::SysAllocString(pSrc); }
+ // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
+ // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize); }
+ CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
+ /*
+ CMyComBSTR(REFGUID src)
+ {
+ LPOLESTR szGuid;
+ StringFromCLSID(src, &szGuid);
+ m_str = ::SysAllocString(szGuid);
+ CoTaskMemFree(szGuid);
+ }
+ */
+ ~CMyComBSTR() { ::SysFreeString(m_str); }
+ CMyComBSTR& operator=(const CMyComBSTR& src)
+ {
+ if (m_str != src.m_str)
+ {
+ if (m_str)
+ ::SysFreeString(m_str);
+ m_str = src.MyCopy();
+ }
+ return *this;
+ }
+ CMyComBSTR& operator=(LPCOLESTR pSrc)
+ {
+ ::SysFreeString(m_str);
+ m_str = ::SysAllocString(pSrc);
+ return *this;
+ }
+ unsigned int Length() const { return ::SysStringLen(m_str); }
+ operator BSTR() const { return m_str; }
+ BSTR* operator&() { return &m_str; }
+ BSTR MyCopy() const
+ {
+ int byteLen = ::SysStringByteLen(m_str);
+ BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
+ memmove(res, m_str, byteLen);
+ return res;
+ }
+ void Attach(BSTR src) { m_str = src; }
+ BSTR Detach()
+ {
+ BSTR s = m_str;
+ m_str = NULL;
+ return s;
+ }
+ void Empty()
+ {
+ ::SysFreeString(m_str);
+ m_str = NULL;
+ }
+ bool operator!() const { return (m_str == NULL); }
+};
+
+
+//////////////////////////////////////////////////////////
+
+class CMyUnknownImp
+{
+public:
+ ULONG __m_RefCount;
+ CMyUnknownImp(): __m_RefCount(0) {}
+};
+
+#define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
+ (REFGUID iid, void **outObject) {
+
+#define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
+ { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
+
+#define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
+
+#define MY_ADDREF_RELEASE \
+STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
+STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0) \
+ return __m_RefCount; delete this; return 0; }
+
+#define MY_UNKNOWN_IMP_SPEC(i) \
+ MY_QUERYINTERFACE_BEGIN \
+ i \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
+
+
+#define MY_UNKNOWN_IMP STDMETHOD(QueryInterface)(REFGUID, void **) { \
+ MY_QUERYINTERFACE_END \
+ MY_ADDREF_RELEASE
+
+#define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i) \
+ )
+
+#define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ )
+
+#define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ )
+
+#define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ )
+
+#define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
+ MY_QUERYINTERFACE_ENTRY(i1) \
+ MY_QUERYINTERFACE_ENTRY(i2) \
+ MY_QUERYINTERFACE_ENTRY(i3) \
+ MY_QUERYINTERFACE_ENTRY(i4) \
+ MY_QUERYINTERFACE_ENTRY(i5) \
+ )
+
+#endif
diff --git a/Source/7zip/Common/MyGuidDef.h b/Source/7zip/Common/MyGuidDef.h
index 5e2cf4a..b01a444 100755
--- a/Source/7zip/Common/MyGuidDef.h
+++ b/Source/7zip/Common/MyGuidDef.h
@@ -1,69 +1,69 @@
-/*
- * MyGuidDef.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef GUID_DEFINED
-#define GUID_DEFINED
-
-#include "Types.h"
-
-typedef struct {
- UInt32 Data1;
- UInt16 Data2;
- UInt16 Data3;
- unsigned char Data4[8];
-} GUID;
-
-#ifdef __cplusplus
-#define REFGUID const GUID &
-#else
-#define REFGUID const GUID *
-#endif
-
-#define REFCLSID REFGUID
-#define REFIID REFGUID
-
-#ifdef __cplusplus
-inline bool operator==(REFGUID g1, REFGUID g2)
-{
- for (int i = 0; i < (int)sizeof(g1); i++)
- if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
- return false;
- return true;
-}
-inline bool operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); }
-#endif
-
-#ifdef __cplusplus
- #define MY_EXTERN_C extern "C"
-#else
- #define MY_EXTERN_C extern
-#endif
-
-#endif // GUID_DEFINED
-
-
-#ifdef DEFINE_GUID
-#undef DEFINE_GUID
-#endif
-
-#ifdef INITGUID
- #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
- MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
-#else
- #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
- MY_EXTERN_C const GUID name
-#endif
+/*
+ * MyGuidDef.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
+
+#include "Types.h"
+
+typedef struct {
+ UInt32 Data1;
+ UInt16 Data2;
+ UInt16 Data3;
+ unsigned char Data4[8];
+} GUID;
+
+#ifdef __cplusplus
+#define REFGUID const GUID &
+#else
+#define REFGUID const GUID *
+#endif
+
+#define REFCLSID REFGUID
+#define REFIID REFGUID
+
+#ifdef __cplusplus
+inline bool operator==(REFGUID g1, REFGUID g2)
+{
+ for (int i = 0; i < (int)sizeof(g1); i++)
+ if (((unsigned char *)&g1)[i] != ((unsigned char *)&g2)[i])
+ return false;
+ return true;
+}
+inline bool operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); }
+#endif
+
+#ifdef __cplusplus
+ #define MY_EXTERN_C extern "C"
+#else
+ #define MY_EXTERN_C extern
+#endif
+
+#endif // GUID_DEFINED
+
+
+#ifdef DEFINE_GUID
+#undef DEFINE_GUID
+#endif
+
+#ifdef INITGUID
+ #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ MY_EXTERN_C const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
+#else
+ #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ MY_EXTERN_C const GUID name
+#endif
diff --git a/Source/7zip/Common/MyUnknown.h b/Source/7zip/Common/MyUnknown.h
index 7508b60..e45adb7 100755
--- a/Source/7zip/Common/MyUnknown.h
+++ b/Source/7zip/Common/MyUnknown.h
@@ -1,39 +1,39 @@
-/*
- * MyUnknown.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __MYUNKNOWN_H
-#define __MYUNKNOWN_H
-
-#ifdef _WIN32
-
-#ifdef _WIN32_WCE
-#if (_WIN32_WCE > 300)
-#include <basetyps.h>
-#else
-#define MIDL_INTERFACE(x) struct
-#endif
-#else
-#include <basetyps.h>
-#endif
-
-#include <unknwn.h>
-
-#else
-#include "MyWindows.h"
-#endif
-
-#endif
+/*
+ * MyUnknown.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __MYUNKNOWN_H
+#define __MYUNKNOWN_H
+
+#ifdef _WIN32
+
+#ifdef _WIN32_WCE
+#if (_WIN32_WCE > 300)
+#include <basetyps.h>
+#else
+#define MIDL_INTERFACE(x) struct
+#endif
+#else
+#include <basetyps.h>
+#endif
+
+#include <unknwn.h>
+
+#else
+#include "MyWindows.h"
+#endif
+
+#endif
diff --git a/Source/7zip/Common/MyWindows.h b/Source/7zip/Common/MyWindows.h
index 02f8710..b3977d2 100755
--- a/Source/7zip/Common/MyWindows.h
+++ b/Source/7zip/Common/MyWindows.h
@@ -1,220 +1,220 @@
-/*
- * MyWindows.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __MYWINDOWS_H
-#define __MYWINDOWS_H
-
-#include "../../Platform.h"
-
-#ifdef _WIN32
-
-#include <windows.h>
-
-/*
-#define CHAR_PATH_SEPARATOR '\\'
-#define WCHAR_PATH_SEPARATOR L'\\'
-#define STRING_PATH_SEPARATOR "\\"
-#define WSTRING_PATH_SEPARATOR L"\\"
-*/
-
-#else
-
-/*
-#define CHAR_PATH_SEPARATOR '/'
-#define WCHAR_PATH_SEPARATOR L'/'
-#define STRING_PATH_SEPARATOR "/"
-#define WSTRING_PATH_SEPARATOR L"/"
-
-#include <stddef.h> // for wchar_t
-#include <string.h>
-*/
-#include "MyGuidDef.h"
-/*
-typedef char CHAR;
-typedef unsigned char UCHAR;
-
-#undef BYTE
-typedef unsigned char BYTE;
-
-typedef short SHORT;
-typedef unsigned short USHORT;
-
-#undef WORD
-typedef unsigned short WORD;
-typedef short VARIANT_BOOL;
-
-typedef int INT;
-typedef Int32 INT32;
-typedef unsigned int UINT;
-typedef UInt32 UINT32;
-typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit
-typedef UINT32 ULONG;
-
-#undef DWORD
-typedef UINT32 DWORD;
-
-typedef Int64 LONGLONG;
-typedef UInt64 ULONGLONG;
-
-typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
-typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
-
-typedef const CHAR *LPCSTR;
-typedef CHAR TCHAR;
-typedef const TCHAR *LPCTSTR;
-typedef wchar_t WCHAR;
-typedef WCHAR OLECHAR;
-typedef const WCHAR *LPCWSTR;
-typedef OLECHAR *BSTR;
-typedef const OLECHAR *LPCOLESTR;
-typedef OLECHAR *LPOLESTR;
-*/
-typedef struct _FILETIME
-{
- DWORD dwLowDateTime;
- DWORD dwHighDateTime;
-}FILETIME;
-
-#define HRESULT LONG
-#define FAILED(Status) ((HRESULT)(Status)<0)
-typedef ULONG PROPID;
-typedef LONG SCODE;
-
-#define S_OK ((HRESULT)0x00000000L)
-#define S_FALSE ((HRESULT)0x00000001L)
-#define E_NOTIMPL ((HRESULT)0x80004001L)
-#define E_NOINTERFACE ((HRESULT)0x80004002L)
-#define E_ABORT ((HRESULT)0x80004004L)
-#define E_FAIL ((HRESULT)0x80004005L)
-#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L)
-#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
-#define E_INVALIDARG ((HRESULT)0x80070057L)
-
-#ifdef _MSC_VER
-#define STDMETHODCALLTYPE __stdcall
-#else
-#define STDMETHODCALLTYPE
-#endif
-
-#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
-#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
-#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
-#define STDMETHODIMP STDMETHODIMP_(HRESULT)
-
-#define PURE = 0
-
-#define MIDL_INTERFACE(x) struct
-
-struct IUnknown
-{
- STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;
- STDMETHOD_(ULONG, AddRef)() PURE;
- STDMETHOD_(ULONG, Release)() PURE;
-};
-
-typedef IUnknown *LPUNKNOWN;
-
-#define VARIANT_TRUE ((VARIANT_BOOL)-1)
-#define VARIANT_FALSE ((VARIANT_BOOL)0)
-
-enum VARENUM
-{
- VT_EMPTY = 0,
- VT_NULL = 1,
- VT_I2 = 2,
- VT_I4 = 3,
- VT_R4 = 4,
- VT_R8 = 5,
- VT_CY = 6,
- VT_DATE = 7,
- VT_BSTR = 8,
- VT_DISPATCH = 9,
- VT_ERROR = 10,
- VT_BOOL = 11,
- VT_VARIANT = 12,
- VT_UNKNOWN = 13,
- VT_DECIMAL = 14,
- VT_I1 = 16,
- VT_UI1 = 17,
- VT_UI2 = 18,
- VT_UI4 = 19,
- VT_I8 = 20,
- VT_UI8 = 21,
- VT_INT = 22,
- VT_UINT = 23,
- VT_VOID = 24,
- VT_HRESULT = 25,
- VT_FILETIME = 64
-};
-
-typedef unsigned short VARTYPE;
-typedef WORD PROPVAR_PAD1;
-typedef WORD PROPVAR_PAD2;
-typedef WORD PROPVAR_PAD3;
-
-typedef struct tagPROPVARIANT
-{
- VARTYPE vt;
- PROPVAR_PAD1 wReserved1;
- PROPVAR_PAD2 wReserved2;
- PROPVAR_PAD3 wReserved3;
- union
- {
- CHAR cVal;
- UCHAR bVal;
- SHORT iVal;
- USHORT uiVal;
- LONG lVal;
- ULONG ulVal;
- INT intVal;
- UINT uintVal;
- LARGE_INTEGER hVal;
- ULARGE_INTEGER uhVal;
- VARIANT_BOOL boolVal;
- SCODE scode;
- FILETIME filetime;
- BSTR bstrVal;
- };
-} PROPVARIANT;
-
-typedef PROPVARIANT tagVARIANT;
-typedef tagVARIANT VARIANT;
-typedef VARIANT VARIANTARG;
-
-MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
-MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
-MY_EXTERN_C void SysFreeString(BSTR bstr);
-MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
-MY_EXTERN_C UINT SysStringLen(BSTR bstr);
-
-MY_EXTERN_C DWORD GetLastError();
-MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
-MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
-MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
-
-#define CP_ACP 0
-#define CP_OEMCP 1
-
-typedef enum tagSTREAM_SEEK
-{
- STREAM_SEEK_SET = 0,
- STREAM_SEEK_CUR = 1,
- STREAM_SEEK_END = 2
-} STREAM_SEEK;
-
-#endif
-#endif
+/*
+ * MyWindows.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __MYWINDOWS_H
+#define __MYWINDOWS_H
+
+#include "../../Platform.h"
+
+#ifdef _WIN32
+
+#include <windows.h>
+
+/*
+#define CHAR_PATH_SEPARATOR '\\'
+#define WCHAR_PATH_SEPARATOR L'\\'
+#define STRING_PATH_SEPARATOR "\\"
+#define WSTRING_PATH_SEPARATOR L"\\"
+*/
+
+#else
+
+/*
+#define CHAR_PATH_SEPARATOR '/'
+#define WCHAR_PATH_SEPARATOR L'/'
+#define STRING_PATH_SEPARATOR "/"
+#define WSTRING_PATH_SEPARATOR L"/"
+
+#include <stddef.h> // for wchar_t
+#include <string.h>
+*/
+#include "MyGuidDef.h"
+/*
+typedef char CHAR;
+typedef unsigned char UCHAR;
+
+#undef BYTE
+typedef unsigned char BYTE;
+
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+#undef WORD
+typedef unsigned short WORD;
+typedef short VARIANT_BOOL;
+
+typedef int INT;
+typedef Int32 INT32;
+typedef unsigned int UINT;
+typedef UInt32 UINT32;
+typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit
+typedef UINT32 ULONG;
+
+#undef DWORD
+typedef UINT32 DWORD;
+
+typedef Int64 LONGLONG;
+typedef UInt64 ULONGLONG;
+
+typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
+typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
+
+typedef const CHAR *LPCSTR;
+typedef CHAR TCHAR;
+typedef const TCHAR *LPCTSTR;
+typedef wchar_t WCHAR;
+typedef WCHAR OLECHAR;
+typedef const WCHAR *LPCWSTR;
+typedef OLECHAR *BSTR;
+typedef const OLECHAR *LPCOLESTR;
+typedef OLECHAR *LPOLESTR;
+*/
+typedef struct _FILETIME
+{
+ DWORD dwLowDateTime;
+ DWORD dwHighDateTime;
+}FILETIME;
+
+#define HRESULT LONG
+#define FAILED(Status) ((HRESULT)(Status)<0)
+typedef ULONG PROPID;
+typedef LONG SCODE;
+
+#define S_OK ((HRESULT)0x00000000L)
+#define S_FALSE ((HRESULT)0x00000001L)
+#define E_NOTIMPL ((HRESULT)0x80004001L)
+#define E_NOINTERFACE ((HRESULT)0x80004002L)
+#define E_ABORT ((HRESULT)0x80004004L)
+#define E_FAIL ((HRESULT)0x80004005L)
+#define STG_E_INVALIDFUNCTION ((HRESULT)0x80030001L)
+#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
+#define E_INVALIDARG ((HRESULT)0x80070057L)
+
+#ifdef _MSC_VER
+#define STDMETHODCALLTYPE __stdcall
+#else
+#define STDMETHODCALLTYPE
+#endif
+
+#define STDMETHOD_(t, f) virtual t STDMETHODCALLTYPE f
+#define STDMETHOD(f) STDMETHOD_(HRESULT, f)
+#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
+#define STDMETHODIMP STDMETHODIMP_(HRESULT)
+
+#define PURE = 0
+
+#define MIDL_INTERFACE(x) struct
+
+struct IUnknown
+{
+ STDMETHOD(QueryInterface) (REFIID iid, void **outObject) PURE;
+ STDMETHOD_(ULONG, AddRef)() PURE;
+ STDMETHOD_(ULONG, Release)() PURE;
+};
+
+typedef IUnknown *LPUNKNOWN;
+
+#define VARIANT_TRUE ((VARIANT_BOOL)-1)
+#define VARIANT_FALSE ((VARIANT_BOOL)0)
+
+enum VARENUM
+{
+ VT_EMPTY = 0,
+ VT_NULL = 1,
+ VT_I2 = 2,
+ VT_I4 = 3,
+ VT_R4 = 4,
+ VT_R8 = 5,
+ VT_CY = 6,
+ VT_DATE = 7,
+ VT_BSTR = 8,
+ VT_DISPATCH = 9,
+ VT_ERROR = 10,
+ VT_BOOL = 11,
+ VT_VARIANT = 12,
+ VT_UNKNOWN = 13,
+ VT_DECIMAL = 14,
+ VT_I1 = 16,
+ VT_UI1 = 17,
+ VT_UI2 = 18,
+ VT_UI4 = 19,
+ VT_I8 = 20,
+ VT_UI8 = 21,
+ VT_INT = 22,
+ VT_UINT = 23,
+ VT_VOID = 24,
+ VT_HRESULT = 25,
+ VT_FILETIME = 64
+};
+
+typedef unsigned short VARTYPE;
+typedef WORD PROPVAR_PAD1;
+typedef WORD PROPVAR_PAD2;
+typedef WORD PROPVAR_PAD3;
+
+typedef struct tagPROPVARIANT
+{
+ VARTYPE vt;
+ PROPVAR_PAD1 wReserved1;
+ PROPVAR_PAD2 wReserved2;
+ PROPVAR_PAD3 wReserved3;
+ union
+ {
+ CHAR cVal;
+ UCHAR bVal;
+ SHORT iVal;
+ USHORT uiVal;
+ LONG lVal;
+ ULONG ulVal;
+ INT intVal;
+ UINT uintVal;
+ LARGE_INTEGER hVal;
+ ULARGE_INTEGER uhVal;
+ VARIANT_BOOL boolVal;
+ SCODE scode;
+ FILETIME filetime;
+ BSTR bstrVal;
+ };
+} PROPVARIANT;
+
+typedef PROPVARIANT tagVARIANT;
+typedef tagVARIANT VARIANT;
+typedef VARIANT VARIANTARG;
+
+MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
+MY_EXTERN_C BSTR SysAllocString(const OLECHAR *sz);
+MY_EXTERN_C void SysFreeString(BSTR bstr);
+MY_EXTERN_C UINT SysStringByteLen(BSTR bstr);
+MY_EXTERN_C UINT SysStringLen(BSTR bstr);
+
+MY_EXTERN_C DWORD GetLastError();
+MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
+MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
+MY_EXTERN_C LONG CompareFileTime(const FILETIME* ft1, const FILETIME* ft2);
+
+#define CP_ACP 0
+#define CP_OEMCP 1
+
+typedef enum tagSTREAM_SEEK
+{
+ STREAM_SEEK_SET = 0,
+ STREAM_SEEK_CUR = 1,
+ STREAM_SEEK_END = 2
+} STREAM_SEEK;
+
+#endif
+#endif
diff --git a/Source/7zip/Common/StdAfx.h b/Source/7zip/Common/StdAfx.h
index af02b27..d83e5c0 100755
--- a/Source/7zip/Common/StdAfx.h
+++ b/Source/7zip/Common/StdAfx.h
@@ -1,23 +1,23 @@
-/*
- * StdAfx.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __STDAFX_H
-#define __STDAFX_H
-
-// #include "MyWindows.h"
-
-#endif
+/*
+ * StdAfx.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __STDAFX_H
+#define __STDAFX_H
+
+// #include "MyWindows.h"
+
+#endif
diff --git a/Source/7zip/Common/Types.h b/Source/7zip/Common/Types.h
index 10791e4..4e28bf4 100755
--- a/Source/7zip/Common/Types.h
+++ b/Source/7zip/Common/Types.h
@@ -1,72 +1,72 @@
-/*
- * Types.h
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __COMMON_TYPES_H
-#define __COMMON_TYPES_H
-
-#ifndef _7ZIP_BYTE_DEFINED
-#define _7ZIP_BYTE_DEFINED
-typedef unsigned char Byte;
-#endif
-
-#ifndef _7ZIP_INT16_DEFINED
-#define _7ZIP_INT16_DEFINED
-typedef short Int16;
-#endif
-
-#ifndef _7ZIP_UINT16_DEFINED
-#define _7ZIP_UINT16_DEFINED
-typedef unsigned short UInt16;
-#endif
-
-#ifndef _7ZIP_INT32_DEFINED
-#define _7ZIP_INT32_DEFINED
-typedef int Int32;
-#endif
-
-#ifndef _7ZIP_UINT32_DEFINED
-#define _7ZIP_UINT32_DEFINED
-typedef unsigned int UInt32;
-#endif
-
-#ifdef _MSC_VER
-
-#ifndef _7ZIP_INT64_DEFINED
-#define _7ZIP_INT64_DEFINED
-typedef __int64 Int64;
-#endif
-
-#ifndef _7ZIP_UINT64_DEFINED
-#define _7ZIP_UINT64_DEFINED
-typedef unsigned __int64 UInt64;
-#endif
-
-#else
-
-#ifndef _7ZIP_INT64_DEFINED
-#define _7ZIP_INT64_DEFINED
-typedef long long int Int64;
-#endif
-
-#ifndef _7ZIP_UINT64_DEFINED
-#define _7ZIP_UINT64_DEFINED
-typedef unsigned long long int UInt64;
-#endif
-
-#endif
-
-#endif
+/*
+ * Types.h
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2006 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __COMMON_TYPES_H
+#define __COMMON_TYPES_H
+
+#ifndef _7ZIP_BYTE_DEFINED
+#define _7ZIP_BYTE_DEFINED
+typedef unsigned char Byte;
+#endif
+
+#ifndef _7ZIP_INT16_DEFINED
+#define _7ZIP_INT16_DEFINED
+typedef short Int16;
+#endif
+
+#ifndef _7ZIP_UINT16_DEFINED
+#define _7ZIP_UINT16_DEFINED
+typedef unsigned short UInt16;
+#endif
+
+#ifndef _7ZIP_INT32_DEFINED
+#define _7ZIP_INT32_DEFINED
+typedef int Int32;
+#endif
+
+#ifndef _7ZIP_UINT32_DEFINED
+#define _7ZIP_UINT32_DEFINED
+typedef unsigned int UInt32;
+#endif
+
+#ifdef _MSC_VER
+
+#ifndef _7ZIP_INT64_DEFINED
+#define _7ZIP_INT64_DEFINED
+typedef __int64 Int64;
+#endif
+
+#ifndef _7ZIP_UINT64_DEFINED
+#define _7ZIP_UINT64_DEFINED
+typedef unsigned __int64 UInt64;
+#endif
+
+#else
+
+#ifndef _7ZIP_INT64_DEFINED
+#define _7ZIP_INT64_DEFINED
+typedef long long int Int64;
+#endif
+
+#ifndef _7ZIP_UINT64_DEFINED
+#define _7ZIP_UINT64_DEFINED
+typedef unsigned long long int UInt64;
+#endif
+
+#endif
+
+#endif
diff --git a/Source/7zip/LZMADecode.c b/Source/7zip/LZMADecode.c
index e16d4c0..8b8fe0a 100755
--- a/Source/7zip/LZMADecode.c
+++ b/Source/7zip/LZMADecode.c
@@ -1,546 +1,546 @@
-/*
- * LZMADecode.c
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2007 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include <stdlib.h>
-#include "LZMADecode.h"
-
-#define LEAVE { goto saveStateAndReturn; }
-#define NEED_BYTE(c) case c: if (!avail_in) { mode = c; LEAVE; }
-#define NEED_BYTE_ if (!avail_in) LEAVE;
-#define NEXT_BYTE (avail_in--, *next_in++)
-#define NEED_OUT(c) case c: if (!avail_out) { mode = c; LEAVE; }
-#define PUT_BYTE_(b) { *next_out = b; next_out++; avail_out--; }
-#define PUT_BYTE(b) { totalOut++; PUT_BYTE_(b) }
-#define DECODE_BIT(c, x) prob = x; last = c; goto _LZMA_C_RDBD; case c:
-#define DECODE_LEN(c, x) probs = x; last2 = c; goto _LZMA_C_LEND; case c:
-#define DECODE_BIT_TREE(c, x, y) probs = x; numLevels = y; last3 = c; goto _LZMA_C_BTD; case c:
-
-enum {
- /* 0 */ LZMA_C_INIT = 0,
- /* 1 */ LZMA_C_GETDICT,
- /* 2 */ LZMA_C_BLOCK,
- /* 3 */ LZMA_C_RDI, /* RangeDecoderInit */
- /* 4 */ LZMA_C_RDBD, /* RangeDecoderBitDecode */
- /* 5 */ LZMA_C_RDBD_IN, /* RangeDecoderBitDecode */
- /* 6 */ LZMA_C_TYPE,
- /* 7 */ LZMA_C_ISREP,
- /* 8 */ LZMA_C_ISREPG0,
- /* 9 */ LZMA_C_ISREP0LONG,
- /* 10 */ LZMA_C_ISREPG1,
- /* 11 */ LZMA_C_ISREPG2,
- /* 12 */ LZMA_C_NORM,
- /* 13 */ LZMA_C_LITDM1, /* LzmaLiteralDecodeMatch */
- /* 14 */ LZMA_C_LITDM2, /* LzmaLiteralDecodeMatch */
- /* 15 */ LZMA_C_LITD, /* LzmaLiteralDecode */
- /* 16 */ LZMA_C_RDRBTD, /* RangeDecoderReverseBitTreeDecode */
- /* 17 */ LZMA_C_LEND, /* LzmaLenDecode */
- /* 18 */ LZMA_C_LEND1, /* LzmaLenDecode */
- /* 19 */ LZMA_C_LEND2, /* LzmaLenDecode */
- /* 20 */ LZMA_C_LEND_RES, /* LzmaLenDecode */
- /* 21 */ LZMA_C_LEND_C1,
- /* 22 */ LZMA_C_LEND_C2,
- /* 23 */ LZMA_C_BTD, /* RangeDecoderBitTreeDecode */
- /* 24 */ LZMA_C_BTD_LOOP,
- /* 25 */ LZMA_C_BTD_C1,
- /* 26 */ LZMA_C_OUTPUT_1,
- /* 27 */ LZMA_C_OUTPUT_2,
- /* 28 */ LZMA_C_OUTPUT_3
-};
-
-#define kNumTopBits 24
-#define kTopValue ((UInt32)1 << kNumTopBits)
-
-#define kNumBitModelTotalBits 11
-#define kBitModelTotal (1 << kNumBitModelTotalBits)
-#define kNumMoveBits 5
-
-#define RC_NORMALIZE(c) if (range < kTopValue) { NEED_BYTE(c); range <<= 8; code = (code << 8) | NEXT_BYTE; }
-
-#define RC_GET_BIT2(c, prob, mi, A0, A1) { \
- UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
- if (code < bound) \
- { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
- else \
- { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
- RC_NORMALIZE(c) \
-}
-
-#define RC_GET_BIT(c, prob, mi) RC_GET_BIT2(c, prob, mi, ; , ;)
-
-#define kNumPosBitsMax 4
-#define kNumPosStatesMax (1 << kNumPosBitsMax)
-
-#define kLenNumLowBits 3
-#define kLenNumLowSymbols (1 << kLenNumLowBits)
-#define kLenNumMidBits 3
-#define kLenNumMidSymbols (1 << kLenNumMidBits)
-#define kLenNumHighBits 8
-#define kLenNumHighSymbols (1 << kLenNumHighBits)
-
-#define LenChoice 0
-#define LenChoice2 (LenChoice + 1)
-#define LenLow (LenChoice2 + 1)
-#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
-#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
-#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
-
-#define kNumStates 12
-
-#define kStartPosModelIndex 4
-#define kEndPosModelIndex 14
-#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-
-#define kNumPosSlotBits 6
-#define kNumLenToPosStates 4
-
-#define kNumAlignBits 4
-#define kAlignTableSize (1 << kNumAlignBits)
-
-#define kMatchMinLen 2
-
-#define IsMatch 0
-#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
-#define IsRepG0 (IsRep + kNumStates)
-#define IsRepG1 (IsRepG0 + kNumStates)
-#define IsRepG2 (IsRepG1 + kNumStates)
-#define IsRep0Long (IsRepG2 + kNumStates)
-#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
-#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
-#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
-#define LenCoder (Align + kAlignTableSize)
-#define RepLenCoder (LenCoder + kNumLenProbs)
-#define Literal (RepLenCoder + kNumLenProbs)
-
-#define LZMA_BASE_SIZE 1846
-#define LZMA_LIT_SIZE 768
-
-#if Literal != LZMA_BASE_SIZE
-StopCompilingDueBUG
-#endif
-
-void LZMACALL lzmaInit(lzma_stream *s)
-{
- /* size of lzma_stream minus the size of the two allocated buffer pointers.
- we don't want to lose to pointer or else we won't be able to free them. */
- size_t i = sizeof(lzma_stream) - (sizeof(unsigned char *) * 2);
- while (i--)
- ((Byte *)s)[i] = 0;
-
- s->rep0 = s->rep1 = s->rep2 = s->rep3 = 1;
- s->range = (0xFFFFFFFF);
-}
-
-int LZMACALL lzmaDecode(lzma_stream *s)
-{
- /* restore decoder state */
- lzma_stream _s = *s;
-
-#define mode _s.mode
-#define last _s.last
-#define last2 _s.last2
-#define last3 _s.last3
-
-#define p (*(CProb **) &_s.dynamicData)
-#define dynamicDataSize _s.dynamicDataSize
-
-#define state _s.state
-#define isPreviousMatch _s.isPreviousMatch
-#define previousByte _s.previousByte
-#define rep0 _s.rep0
-#define rep1 _s.rep1
-#define rep2 _s.rep2
-#define rep3 _s.rep3
-#define lc _s.lc
-#define len _s.len
-#define totalOut _s.totalOut
-
-#define dictionary _s.dictionary
-#define dictionarySize _s.dictionarySize
-#define dictionaryPos _s.dictionaryPos
-
-#define posStateMask _s.posStateMask
-#define literalPosMask _s.literalPosMask
-
-#define avail_in _s.avail_in
-#define next_in _s.next_in
-#define avail_out _s.avail_out
-#define next_out _s.next_out
-
-#define range _s.range
-#define code _s.code
-
-#define probs _s.probs
-#define prob _s.prob
-
-#define symbol _s.temp2
-#define bit _s.temp3
-#define matchBit _s.temp1
-#define i _s.temp1
-#define result _s.temp2
-#define numLevels _s.temp3
-#define posSlot _s.temp2
-#define newDictionarySize (*(UInt32*) &_s.temp3)
-
-#define matchByte _s.matchByte
-#define mi _s.mi
-#define posState _s.posState
-
- if (len == -1)
- return LZMA_STREAM_END;
-
- for (;;) switch (mode)
- {
- case LZMA_C_INIT:
- {
- Byte firstByte;
- UInt32 newDynamicDataSize;
- UInt32 numProbs;
- int lp;
- int pb;
-
- NEED_BYTE_;
-
- firstByte = NEXT_BYTE;
-
- if (firstByte > (9*5*5))
- return LZMA_DATA_ERROR;
-
- pb = firstByte / (9*5);
- firstByte %= (9*5);
- lp = firstByte / 9;
- firstByte %= 9;
- lc = firstByte;
-
- posStateMask = (1 << (pb)) - 1;
- literalPosMask = (1 << (lp)) - 1;
-
- numProbs = Literal + (LZMA_LIT_SIZE << (lc + pb));
- newDynamicDataSize = numProbs * sizeof(CProb);
-
- if (newDynamicDataSize != dynamicDataSize)
- {
- if (p)
- lzmafree(p);
- p = lzmaalloc(newDynamicDataSize);
- if (!p)
- return LZMA_NOT_ENOUGH_MEM;
- dynamicDataSize = newDynamicDataSize;
- }
-
- while (numProbs--)
- p[numProbs] = kBitModelTotal >> 1;
-
- for (i = 0, newDictionarySize = 0; i < 4; i++)
- {
- NEED_BYTE(LZMA_C_GETDICT);
- newDictionarySize |= NEXT_BYTE << (i * 8);
- }
-
- if (newDictionarySize != dictionarySize)
- {
- dictionarySize = newDictionarySize;
- if (dictionary)
- lzmafree(dictionary);
- dictionary = lzmaalloc(dictionarySize);
- if (!dictionary)
- return LZMA_NOT_ENOUGH_MEM;
- }
-
- dictionary[dictionarySize - 1] = 0;
-
- i = 5;
- while (i--)
- {
- NEED_BYTE(LZMA_C_RDI);
- code = (code << 8) | NEXT_BYTE;
- }
- }
- case LZMA_C_BLOCK:
- posState = (int)(totalOut & posStateMask);
- DECODE_BIT(LZMA_C_TYPE, p + IsMatch + (state << kNumPosBitsMax) + posState);
- if (bit == 0)
- {
- probs = p + Literal + (LZMA_LIT_SIZE *
- (((totalOut & literalPosMask) << lc) + (previousByte >> (8 - lc))));
-
- if (state < 4) state = 0;
- else if (state < 10) state -= 3;
- else state -= 6;
- if (isPreviousMatch)
- {
- UInt32 pos = dictionaryPos - rep0;
- if (pos >= dictionarySize)
- pos += dictionarySize;
- matchByte = dictionary[pos];
- {
- symbol = 1;
- do
- {
- matchBit = (matchByte >> 7) & 1;
- matchByte <<= 1;
- {
- prob = probs + ((1 + matchBit) << 8) + symbol;
- RC_GET_BIT2(LZMA_C_LITDM1, prob, symbol, bit = 0, bit = 1)
- }
- if (matchBit != bit)
- {
- while (symbol < 0x100)
- {
- prob = probs + symbol;
- RC_GET_BIT(LZMA_C_LITDM2, prob, symbol)
- }
- break;
- }
- }
- while (symbol < 0x100);
- previousByte = symbol;
- }
- isPreviousMatch = 0;
- }
- else
- {
- symbol = 1;
- do
- {
- prob = probs + symbol;
- RC_GET_BIT(LZMA_C_LITD, prob, symbol)
- }
- while (symbol < 0x100);
- previousByte = symbol;
- }
- NEED_OUT(LZMA_C_OUTPUT_1);
- PUT_BYTE(previousByte);
- dictionary[dictionaryPos] = previousByte;
- dictionaryPos = (dictionaryPos + 1) % dictionarySize;
- }
- /* bit == 1 */
- else
- {
- isPreviousMatch = 1;
- DECODE_BIT(LZMA_C_ISREP, p + IsRep + state);
- if (bit == 1)
- {
- DECODE_BIT(LZMA_C_ISREPG0, p + IsRepG0 + state);
- if (bit == 0)
- {
- DECODE_BIT(LZMA_C_ISREP0LONG, p + IsRep0Long + (state << kNumPosBitsMax) + posState);
- if (bit == 0)
- {
- UInt32 pos;
- if (totalOut == 0)
- return LZMA_DATA_ERROR;
- state = state < 7 ? 9 : 11;
- NEED_OUT(LZMA_C_OUTPUT_2);
- pos = dictionaryPos - rep0;
- if (pos >= dictionarySize)
- pos += dictionarySize;
- previousByte = dictionary[pos];
- dictionary[dictionaryPos] = previousByte;
- dictionaryPos = (dictionaryPos + 1) % dictionarySize;
- PUT_BYTE(previousByte);
- mode = LZMA_C_BLOCK;
- break;
- }
- }
- else
- {
- UInt32 distance;
- DECODE_BIT(LZMA_C_ISREPG1, p + IsRepG1 + state);
- if (bit == 0)
- {
- distance = rep1;
- }
- else
- {
- DECODE_BIT(LZMA_C_ISREPG2, p + IsRepG2 + state);
- if (bit == 0)
- distance = rep2;
- else
- {
- distance = rep3;
- rep3 = rep2;
- }
- rep2 = rep1;
- }
- rep1 = rep0;
- rep0 = distance;
- }
- DECODE_LEN(LZMA_C_LEND_C1, p + RepLenCoder);
- state = state < 7 ? 8 : 11;
- }
- else
- {
- rep3 = rep2;
- rep2 = rep1;
- rep1 = rep0;
- state = state < 7 ? 7 : 10;
- DECODE_LEN(LZMA_C_LEND_C2, p + LenCoder);
- DECODE_BIT_TREE(
- LZMA_C_BTD_C1,
- p + PosSlot + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits),
- kNumPosSlotBits
- );
- if (posSlot >= kStartPosModelIndex)
- {
- int numDirectBits = ((posSlot >> 1) - 1);
- rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
- if (posSlot < kEndPosModelIndex)
- {
- probs = p + SpecPos + rep0 - posSlot - 1;
- numLevels = numDirectBits;
- }
- else
- {
- int numTotalBits = numDirectBits - kNumAlignBits;
- result = 0;
- for (i = numTotalBits; i > 0; i--)
- {
- /* UInt32 t; */
- range >>= 1;
-
- result <<= 1;
- if (code >= range)
- {
- code -= range;
- result |= 1;
- }
- /*
- t = (code - range) >> 31;
- t &= 1;
- code -= range & (t - 1);
- result = (result + result) | (1 - t);
- */
- RC_NORMALIZE(LZMA_C_NORM)
- }
- rep0 += result << kNumAlignBits;
- probs = p + Align;
- numLevels = kNumAlignBits;
- }
- mi = 1;
- symbol = 0;
- for(i = 0; i < numLevels; i++)
- {
- prob = probs + mi;
- RC_GET_BIT2(LZMA_C_RDRBTD, prob, mi, ; , symbol |= (1 << i));
- }
- rep0 += symbol;
- }
- else
- rep0 = posSlot;
- rep0++;
- }
- if (rep0 == (UInt32)(0))
- {
- len = -1;
- LEAVE;
- }
- if (rep0 > totalOut)
- {
- return LZMA_DATA_ERROR;
- }
- len += kMatchMinLen;
- totalOut += len;
- do
- {
- UInt32 pos;
- NEED_OUT(LZMA_C_OUTPUT_3);
- pos = dictionaryPos - rep0;
- if (pos >= dictionarySize)
- pos += dictionarySize;
- previousByte = dictionary[pos];
- dictionary[dictionaryPos] = previousByte;
- dictionaryPos = (dictionaryPos + 1) % dictionarySize;
- PUT_BYTE_(previousByte);
- len--;
- }
- while(len > 0);
- }
- mode = LZMA_C_BLOCK;
- break;
- case LZMA_C_RDBD:
- _LZMA_C_RDBD:
- {
- UInt32 bound = (range >> kNumBitModelTotalBits) * *prob;
- if (code < bound)
- {
- range = bound;
- *prob += (kBitModelTotal - *prob) >> kNumMoveBits;
- bit = 0;
- }
- else
- {
- range -= bound;
- code -= bound;
- *prob -= (*prob) >> kNumMoveBits;
- bit = 1;
- }
- RC_NORMALIZE(LZMA_C_RDBD_IN);
- }
- mode = last;
- break;
- case LZMA_C_LEND:
- _LZMA_C_LEND:
- DECODE_BIT(LZMA_C_LEND1, probs + LenChoice);
- if (bit == 0)
- {
- len = 0;
- probs += LenLow + (posState << kLenNumLowBits);
- numLevels = kLenNumLowBits;
- }
- else {
- DECODE_BIT(LZMA_C_LEND2, probs + LenChoice2);
- if (bit == 0)
- {
- len = kLenNumLowSymbols;
- probs += + LenMid + (posState << kLenNumMidBits);
- numLevels = kLenNumMidBits;
- }
- else
- {
- len = kLenNumLowSymbols + kLenNumMidSymbols;
- probs += LenHigh;
- numLevels = kLenNumHighBits;
- }
- }
-
- last3 = LZMA_C_LEND_RES;
- case LZMA_C_BTD:
- _LZMA_C_BTD:
- mi = 1;
- for(i = numLevels; i > 0; i--)
- {
- prob = probs + mi;
- RC_GET_BIT(LZMA_C_BTD_LOOP, prob, mi)
- }
- result = mi - (1 << numLevels);
- mode = last3;
- break;
- case LZMA_C_LEND_RES:
- len += result;
- mode = last2;
- break;
- default:
- return LZMA_DATA_ERROR;
- }
-
-saveStateAndReturn:
-
- /* save decoder state */
- *s = _s;
-
- return LZMA_OK;
-}
+/*
+ * LZMADecode.c
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2007 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include <stdlib.h>
+#include "LZMADecode.h"
+
+#define LEAVE { goto saveStateAndReturn; }
+#define NEED_BYTE(c) case c: if (!avail_in) { mode = c; LEAVE; }
+#define NEED_BYTE_ if (!avail_in) LEAVE;
+#define NEXT_BYTE (avail_in--, *next_in++)
+#define NEED_OUT(c) case c: if (!avail_out) { mode = c; LEAVE; }
+#define PUT_BYTE_(b) { *next_out = b; next_out++; avail_out--; }
+#define PUT_BYTE(b) { totalOut++; PUT_BYTE_(b) }
+#define DECODE_BIT(c, x) prob = x; last = c; goto _LZMA_C_RDBD; case c:
+#define DECODE_LEN(c, x) probs = x; last2 = c; goto _LZMA_C_LEND; case c:
+#define DECODE_BIT_TREE(c, x, y) probs = x; numLevels = y; last3 = c; goto _LZMA_C_BTD; case c:
+
+enum {
+ /* 0 */ LZMA_C_INIT = 0,
+ /* 1 */ LZMA_C_GETDICT,
+ /* 2 */ LZMA_C_BLOCK,
+ /* 3 */ LZMA_C_RDI, /* RangeDecoderInit */
+ /* 4 */ LZMA_C_RDBD, /* RangeDecoderBitDecode */
+ /* 5 */ LZMA_C_RDBD_IN, /* RangeDecoderBitDecode */
+ /* 6 */ LZMA_C_TYPE,
+ /* 7 */ LZMA_C_ISREP,
+ /* 8 */ LZMA_C_ISREPG0,
+ /* 9 */ LZMA_C_ISREP0LONG,
+ /* 10 */ LZMA_C_ISREPG1,
+ /* 11 */ LZMA_C_ISREPG2,
+ /* 12 */ LZMA_C_NORM,
+ /* 13 */ LZMA_C_LITDM1, /* LzmaLiteralDecodeMatch */
+ /* 14 */ LZMA_C_LITDM2, /* LzmaLiteralDecodeMatch */
+ /* 15 */ LZMA_C_LITD, /* LzmaLiteralDecode */
+ /* 16 */ LZMA_C_RDRBTD, /* RangeDecoderReverseBitTreeDecode */
+ /* 17 */ LZMA_C_LEND, /* LzmaLenDecode */
+ /* 18 */ LZMA_C_LEND1, /* LzmaLenDecode */
+ /* 19 */ LZMA_C_LEND2, /* LzmaLenDecode */
+ /* 20 */ LZMA_C_LEND_RES, /* LzmaLenDecode */
+ /* 21 */ LZMA_C_LEND_C1,
+ /* 22 */ LZMA_C_LEND_C2,
+ /* 23 */ LZMA_C_BTD, /* RangeDecoderBitTreeDecode */
+ /* 24 */ LZMA_C_BTD_LOOP,
+ /* 25 */ LZMA_C_BTD_C1,
+ /* 26 */ LZMA_C_OUTPUT_1,
+ /* 27 */ LZMA_C_OUTPUT_2,
+ /* 28 */ LZMA_C_OUTPUT_3
+};
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_NORMALIZE(c) if (range < kTopValue) { NEED_BYTE(c); range <<= 8; code = (code << 8) | NEXT_BYTE; }
+
+#define RC_GET_BIT2(c, prob, mi, A0, A1) { \
+ UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \
+ if (code < bound) \
+ { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \
+ else \
+ { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \
+ RC_NORMALIZE(c) \
+}
+
+#define RC_GET_BIT(c, prob, mi) RC_GET_BIT2(c, prob, mi, ; , ;)
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+#define kNumStates 12
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+void LZMACALL lzmaInit(lzma_stream *s)
+{
+ /* size of lzma_stream minus the size of the two allocated buffer pointers.
+ we don't want to lose to pointer or else we won't be able to free them. */
+ size_t i = sizeof(lzma_stream) - (sizeof(unsigned char *) * 2);
+ while (i--)
+ ((Byte *)s)[i] = 0;
+
+ s->rep0 = s->rep1 = s->rep2 = s->rep3 = 1;
+ s->range = (0xFFFFFFFF);
+}
+
+int LZMACALL lzmaDecode(lzma_stream *s)
+{
+ /* restore decoder state */
+ lzma_stream _s = *s;
+
+#define mode _s.mode
+#define last _s.last
+#define last2 _s.last2
+#define last3 _s.last3
+
+#define p (*(CProb **) &_s.dynamicData)
+#define dynamicDataSize _s.dynamicDataSize
+
+#define state _s.state
+#define isPreviousMatch _s.isPreviousMatch
+#define previousByte _s.previousByte
+#define rep0 _s.rep0
+#define rep1 _s.rep1
+#define rep2 _s.rep2
+#define rep3 _s.rep3
+#define lc _s.lc
+#define len _s.len
+#define totalOut _s.totalOut
+
+#define dictionary _s.dictionary
+#define dictionarySize _s.dictionarySize
+#define dictionaryPos _s.dictionaryPos
+
+#define posStateMask _s.posStateMask
+#define literalPosMask _s.literalPosMask
+
+#define avail_in _s.avail_in
+#define next_in _s.next_in
+#define avail_out _s.avail_out
+#define next_out _s.next_out
+
+#define range _s.range
+#define code _s.code
+
+#define probs _s.probs
+#define prob _s.prob
+
+#define symbol _s.temp2
+#define bit _s.temp3
+#define matchBit _s.temp1
+#define i _s.temp1
+#define result _s.temp2
+#define numLevels _s.temp3
+#define posSlot _s.temp2
+#define newDictionarySize (*(UInt32*) &_s.temp3)
+
+#define matchByte _s.matchByte
+#define mi _s.mi
+#define posState _s.posState
+
+ if (len == -1)
+ return LZMA_STREAM_END;
+
+ for (;;) switch (mode)
+ {
+ case LZMA_C_INIT:
+ {
+ Byte firstByte;
+ UInt32 newDynamicDataSize;
+ UInt32 numProbs;
+ int lp;
+ int pb;
+
+ NEED_BYTE_;
+
+ firstByte = NEXT_BYTE;
+
+ if (firstByte > (9*5*5))
+ return LZMA_DATA_ERROR;
+
+ pb = firstByte / (9*5);
+ firstByte %= (9*5);
+ lp = firstByte / 9;
+ firstByte %= 9;
+ lc = firstByte;
+
+ posStateMask = (1 << (pb)) - 1;
+ literalPosMask = (1 << (lp)) - 1;
+
+ numProbs = Literal + (LZMA_LIT_SIZE << (lc + pb));
+ newDynamicDataSize = numProbs * sizeof(CProb);
+
+ if (newDynamicDataSize != dynamicDataSize)
+ {
+ if (p)
+ lzmafree(p);
+ p = lzmaalloc(newDynamicDataSize);
+ if (!p)
+ return LZMA_NOT_ENOUGH_MEM;
+ dynamicDataSize = newDynamicDataSize;
+ }
+
+ while (numProbs--)
+ p[numProbs] = kBitModelTotal >> 1;
+
+ for (i = 0, newDictionarySize = 0; i < 4; i++)
+ {
+ NEED_BYTE(LZMA_C_GETDICT);
+ newDictionarySize |= NEXT_BYTE << (i * 8);
+ }
+
+ if (newDictionarySize != dictionarySize)
+ {
+ dictionarySize = newDictionarySize;
+ if (dictionary)
+ lzmafree(dictionary);
+ dictionary = lzmaalloc(dictionarySize);
+ if (!dictionary)
+ return LZMA_NOT_ENOUGH_MEM;
+ }
+
+ dictionary[dictionarySize - 1] = 0;
+
+ i = 5;
+ while (i--)
+ {
+ NEED_BYTE(LZMA_C_RDI);
+ code = (code << 8) | NEXT_BYTE;
+ }
+ }
+ case LZMA_C_BLOCK:
+ posState = (int)(totalOut & posStateMask);
+ DECODE_BIT(LZMA_C_TYPE, p + IsMatch + (state << kNumPosBitsMax) + posState);
+ if (bit == 0)
+ {
+ probs = p + Literal + (LZMA_LIT_SIZE *
+ (((totalOut & literalPosMask) << lc) + (previousByte >> (8 - lc))));
+
+ if (state < 4) state = 0;
+ else if (state < 10) state -= 3;
+ else state -= 6;
+ if (isPreviousMatch)
+ {
+ UInt32 pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ matchByte = dictionary[pos];
+ {
+ symbol = 1;
+ do
+ {
+ matchBit = (matchByte >> 7) & 1;
+ matchByte <<= 1;
+ {
+ prob = probs + ((1 + matchBit) << 8) + symbol;
+ RC_GET_BIT2(LZMA_C_LITDM1, prob, symbol, bit = 0, bit = 1)
+ }
+ if (matchBit != bit)
+ {
+ while (symbol < 0x100)
+ {
+ prob = probs + symbol;
+ RC_GET_BIT(LZMA_C_LITDM2, prob, symbol)
+ }
+ break;
+ }
+ }
+ while (symbol < 0x100);
+ previousByte = symbol;
+ }
+ isPreviousMatch = 0;
+ }
+ else
+ {
+ symbol = 1;
+ do
+ {
+ prob = probs + symbol;
+ RC_GET_BIT(LZMA_C_LITD, prob, symbol)
+ }
+ while (symbol < 0x100);
+ previousByte = symbol;
+ }
+ NEED_OUT(LZMA_C_OUTPUT_1);
+ PUT_BYTE(previousByte);
+ dictionary[dictionaryPos] = previousByte;
+ dictionaryPos = (dictionaryPos + 1) % dictionarySize;
+ }
+ /* bit == 1 */
+ else
+ {
+ isPreviousMatch = 1;
+ DECODE_BIT(LZMA_C_ISREP, p + IsRep + state);
+ if (bit == 1)
+ {
+ DECODE_BIT(LZMA_C_ISREPG0, p + IsRepG0 + state);
+ if (bit == 0)
+ {
+ DECODE_BIT(LZMA_C_ISREP0LONG, p + IsRep0Long + (state << kNumPosBitsMax) + posState);
+ if (bit == 0)
+ {
+ UInt32 pos;
+ if (totalOut == 0)
+ return LZMA_DATA_ERROR;
+ state = state < 7 ? 9 : 11;
+ NEED_OUT(LZMA_C_OUTPUT_2);
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ dictionaryPos = (dictionaryPos + 1) % dictionarySize;
+ PUT_BYTE(previousByte);
+ mode = LZMA_C_BLOCK;
+ break;
+ }
+ }
+ else
+ {
+ UInt32 distance;
+ DECODE_BIT(LZMA_C_ISREPG1, p + IsRepG1 + state);
+ if (bit == 0)
+ {
+ distance = rep1;
+ }
+ else
+ {
+ DECODE_BIT(LZMA_C_ISREPG2, p + IsRepG2 + state);
+ if (bit == 0)
+ distance = rep2;
+ else
+ {
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ DECODE_LEN(LZMA_C_LEND_C1, p + RepLenCoder);
+ state = state < 7 ? 8 : 11;
+ }
+ else
+ {
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ state = state < 7 ? 7 : 10;
+ DECODE_LEN(LZMA_C_LEND_C2, p + LenCoder);
+ DECODE_BIT_TREE(
+ LZMA_C_BTD_C1,
+ p + PosSlot + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits),
+ kNumPosSlotBits
+ );
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = ((posSlot >> 1) - 1);
+ rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits);
+ if (posSlot < kEndPosModelIndex)
+ {
+ probs = p + SpecPos + rep0 - posSlot - 1;
+ numLevels = numDirectBits;
+ }
+ else
+ {
+ int numTotalBits = numDirectBits - kNumAlignBits;
+ result = 0;
+ for (i = numTotalBits; i > 0; i--)
+ {
+ /* UInt32 t; */
+ range >>= 1;
+
+ result <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ result |= 1;
+ }
+ /*
+ t = (code - range) >> 31;
+ t &= 1;
+ code -= range & (t - 1);
+ result = (result + result) | (1 - t);
+ */
+ RC_NORMALIZE(LZMA_C_NORM)
+ }
+ rep0 += result << kNumAlignBits;
+ probs = p + Align;
+ numLevels = kNumAlignBits;
+ }
+ mi = 1;
+ symbol = 0;
+ for(i = 0; i < numLevels; i++)
+ {
+ prob = probs + mi;
+ RC_GET_BIT2(LZMA_C_RDRBTD, prob, mi, ; , symbol |= (1 << i));
+ }
+ rep0 += symbol;
+ }
+ else
+ rep0 = posSlot;
+ rep0++;
+ }
+ if (rep0 == (UInt32)(0))
+ {
+ len = -1;
+ LEAVE;
+ }
+ if (rep0 > totalOut)
+ {
+ return LZMA_DATA_ERROR;
+ }
+ len += kMatchMinLen;
+ totalOut += len;
+ do
+ {
+ UInt32 pos;
+ NEED_OUT(LZMA_C_OUTPUT_3);
+ pos = dictionaryPos - rep0;
+ if (pos >= dictionarySize)
+ pos += dictionarySize;
+ previousByte = dictionary[pos];
+ dictionary[dictionaryPos] = previousByte;
+ dictionaryPos = (dictionaryPos + 1) % dictionarySize;
+ PUT_BYTE_(previousByte);
+ len--;
+ }
+ while(len > 0);
+ }
+ mode = LZMA_C_BLOCK;
+ break;
+ case LZMA_C_RDBD:
+ _LZMA_C_RDBD:
+ {
+ UInt32 bound = (range >> kNumBitModelTotalBits) * *prob;
+ if (code < bound)
+ {
+ range = bound;
+ *prob += (kBitModelTotal - *prob) >> kNumMoveBits;
+ bit = 0;
+ }
+ else
+ {
+ range -= bound;
+ code -= bound;
+ *prob -= (*prob) >> kNumMoveBits;
+ bit = 1;
+ }
+ RC_NORMALIZE(LZMA_C_RDBD_IN);
+ }
+ mode = last;
+ break;
+ case LZMA_C_LEND:
+ _LZMA_C_LEND:
+ DECODE_BIT(LZMA_C_LEND1, probs + LenChoice);
+ if (bit == 0)
+ {
+ len = 0;
+ probs += LenLow + (posState << kLenNumLowBits);
+ numLevels = kLenNumLowBits;
+ }
+ else {
+ DECODE_BIT(LZMA_C_LEND2, probs + LenChoice2);
+ if (bit == 0)
+ {
+ len = kLenNumLowSymbols;
+ probs += + LenMid + (posState << kLenNumMidBits);
+ numLevels = kLenNumMidBits;
+ }
+ else
+ {
+ len = kLenNumLowSymbols + kLenNumMidSymbols;
+ probs += LenHigh;
+ numLevels = kLenNumHighBits;
+ }
+ }
+
+ last3 = LZMA_C_LEND_RES;
+ case LZMA_C_BTD:
+ _LZMA_C_BTD:
+ mi = 1;
+ for(i = numLevels; i > 0; i--)
+ {
+ prob = probs + mi;
+ RC_GET_BIT(LZMA_C_BTD_LOOP, prob, mi)
+ }
+ result = mi - (1 << numLevels);
+ mode = last3;
+ break;
+ case LZMA_C_LEND_RES:
+ len += result;
+ mode = last2;
+ break;
+ default:
+ return LZMA_DATA_ERROR;
+ }
+
+saveStateAndReturn:
+
+ /* save decoder state */
+ *s = _s;
+
+ return LZMA_OK;
+}
diff --git a/Source/7zip/LZMADecode.h b/Source/7zip/LZMADecode.h
index dddf709..fd87af7 100755
--- a/Source/7zip/LZMADecode.h
+++ b/Source/7zip/LZMADecode.h
@@ -1,138 +1,138 @@
-/*
- * LZMADecode.c
- *
- * This file is a part of LZMA compression module for NSIS.
- *
- * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
- * Modifications Copyright (C) 2003-2007 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the Common Public License version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __LZMADECODE_H
-#define __LZMADECODE_H
-
-/***********************
- * Configuration *
- ***********************/
-
-#include "../Platform.h"
-
-/* #define _LZMA_PROB32 */
-/* It can increase speed on some 32-bit CPUs,
- but memory usage will be doubled in that case */
-
-#ifdef _WIN32
-# define lzmaalloc(bytes) GlobalAlloc(GPTR,bytes)
-# define lzmafree GlobalFree
-#endif
-
-/***********************
- * Configuration End *
- ***********************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef lzmaalloc
-#define lzmaalloc malloc
-#endif
-
-#ifndef lzmafree
-#define lzmafree free
-#endif
-
-#ifndef LZMACALL
-# define LZMACALL
-#endif
-
-#ifndef UInt32
-#ifdef _LZMA_UINT32_IS_ULONG
-#define UInt32 unsigned long
-#else
-#define UInt32 unsigned int
-#endif
-#endif
-
-#ifdef _LZMA_PROB32
-#define CProb UInt32
-#else
-#define CProb unsigned short
-#endif
-
-typedef unsigned char Byte;
-
-#define LZMA_STREAM_END 1
-#define LZMA_OK 0
-#define LZMA_DATA_ERROR -1
-/* we don't really care what the problem is... */
-/* #define LZMA_RESULT_NOT_ENOUGH_MEM -2 */
-#define LZMA_NOT_ENOUGH_MEM -1
-
-typedef struct
-{
- /* mode control */
- int mode;
- int last;
- int last2;
- int last3;
-
- /* properties */
- UInt32 dynamicDataSize;
- UInt32 dictionarySize;
-
- /* io */
- Byte *next_in; /* next input byte */
- UInt32 avail_in; /* number of bytes available at next_in */
-
- Byte *next_out; /* next output byte should be put there */
- UInt32 avail_out; /* remaining free space at next_out */
-
- UInt32 totalOut; /* total output - not always correct when lzmaDecode returns */
-
- /* saved state */
- Byte previousByte;
- Byte matchByte;
- CProb *probs;
- CProb *prob;
- int mi;
- int posState;
- int temp1;
- int temp2;
- int temp3;
- int lc;
- int state;
- int isPreviousMatch;
- int len;
- UInt32 rep0;
- UInt32 rep1;
- UInt32 rep2;
- UInt32 rep3;
- UInt32 posStateMask;
- UInt32 literalPosMask;
- UInt32 dictionaryPos;
-
- /* range coder */
- UInt32 range;
- UInt32 code;
-
- /* allocated buffers */
- Byte *dictionary;
- Byte *dynamicData;
-} lzma_stream;
-
-void LZMACALL lzmaInit(lzma_stream *);
-int LZMACALL lzmaDecode(lzma_stream *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+ * LZMADecode.c
+ *
+ * This file is a part of LZMA compression module for NSIS.
+ *
+ * Original LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
+ * Modifications Copyright (C) 2003-2007 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the Common Public License version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __LZMADECODE_H
+#define __LZMADECODE_H
+
+/***********************
+ * Configuration *
+ ***********************/
+
+#include "../Platform.h"
+
+/* #define _LZMA_PROB32 */
+/* It can increase speed on some 32-bit CPUs,
+ but memory usage will be doubled in that case */
+
+#ifdef _WIN32
+# define lzmaalloc(bytes) GlobalAlloc(GPTR,bytes)
+# define lzmafree GlobalFree
+#endif
+
+/***********************
+ * Configuration End *
+ ***********************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef lzmaalloc
+#define lzmaalloc malloc
+#endif
+
+#ifndef lzmafree
+#define lzmafree free
+#endif
+
+#ifndef LZMACALL
+# define LZMACALL
+#endif
+
+#ifndef UInt32
+#ifdef _LZMA_UINT32_IS_ULONG
+#define UInt32 unsigned long
+#else
+#define UInt32 unsigned int
+#endif
+#endif
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb unsigned short
+#endif
+
+typedef unsigned char Byte;
+
+#define LZMA_STREAM_END 1
+#define LZMA_OK 0
+#define LZMA_DATA_ERROR -1
+/* we don't really care what the problem is... */
+/* #define LZMA_RESULT_NOT_ENOUGH_MEM -2 */
+#define LZMA_NOT_ENOUGH_MEM -1
+
+typedef struct
+{
+ /* mode control */
+ int mode;
+ int last;
+ int last2;
+ int last3;
+
+ /* properties */
+ UInt32 dynamicDataSize;
+ UInt32 dictionarySize;
+
+ /* io */
+ Byte *next_in; /* next input byte */
+ UInt32 avail_in; /* number of bytes available at next_in */
+
+ Byte *next_out; /* next output byte should be put there */
+ UInt32 avail_out; /* remaining free space at next_out */
+
+ UInt32 totalOut; /* total output - not always correct when lzmaDecode returns */
+
+ /* saved state */
+ Byte previousByte;
+ Byte matchByte;
+ CProb *probs;
+ CProb *prob;
+ int mi;
+ int posState;
+ int temp1;
+ int temp2;
+ int temp3;
+ int lc;
+ int state;
+ int isPreviousMatch;
+ int len;
+ UInt32 rep0;
+ UInt32 rep1;
+ UInt32 rep2;
+ UInt32 rep3;
+ UInt32 posStateMask;
+ UInt32 literalPosMask;
+ UInt32 dictionaryPos;
+
+ /* range coder */
+ UInt32 range;
+ UInt32 code;
+
+ /* allocated buffers */
+ Byte *dictionary;
+ Byte *dynamicData;
+} lzma_stream;
+
+void LZMACALL lzmaInit(lzma_stream *);
+int LZMACALL lzmaDecode(lzma_stream *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Source/7zip/sdk.diff b/Source/7zip/sdk.diff
index 3390ad0..647ed11 100755
--- a/Source/7zip/sdk.diff
+++ b/Source/7zip/sdk.diff
@@ -1,167 +1,167 @@
-Only in 7zip: 7zGuids.cpp
-Only in 7zip-orig/7zip: Archive
-Only in 7zip/7zip: CVS
-Only in 7zip/7zip/Common: CVS
-Only in 7zip-orig/7zip/Common: FileStreams.cpp
-Only in 7zip-orig/7zip/Common: FileStreams.h
-diff -ru 7zip-orig/7zip/Common/StdAfx.h 7zip/7zip/Common/StdAfx.h
---- 7zip-orig/7zip/Common/StdAfx.h Mon Jul 11 15:14:54 2005
-+++ 7zip/7zip/Common/StdAfx.h Mon Oct 16 10:39:10 2006
-@@ -4,6 +4,5 @@
- #define __STDAFX_H
-
- #include "../../Common/MyWindows.h"
--#include "../../Common/NewHandler.h"
-
- #endif
-Only in 7zip-orig/7zip/Compress: Branch
-Only in 7zip/7zip/Compress: CVS
-Only in 7zip/7zip/Compress/LZ/BinTree: BinTree3ZMain.h
-Only in 7zip/7zip/Compress/LZ/BinTree: BinTree4b.h
-Only in 7zip/7zip/Compress/LZ/BinTree: BinTreeMF.h
-Only in 7zip/7zip/Compress/LZ/BinTree: BinTreeMFMain.h
-Only in 7zip/7zip/Compress/LZ/BinTree: CVS
-Only in 7zip/7zip/Compress/LZ: CVS
-Only in 7zip-orig/7zip/Compress/LZ: HashChain
-Only in 7zip/7zip/Compress/LZMA: CVS
-Only in 7zip-orig/7zip/Compress/LZMA: LZMADecoder.cpp
-Only in 7zip-orig/7zip/Compress/LZMA: LZMADecoder.h
-diff -ru 7zip-orig/7zip/Compress/LZMA/LZMAEncoder.cpp 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
---- 7zip-orig/7zip/Compress/LZMA/LZMAEncoder.cpp Sat May 20 08:23:48 2006
-+++ 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp Mon Oct 16 10:26:43 2006
-@@ -55,13 +55,13 @@
- kHC4
- };
-
--static const wchar_t *kMatchFinderIDs[] =
-+/*static const wchar_t *kMatchFinderIDs[] =
- {
- L"BT2",
- L"BT3",
- L"BT4",
- L"HC4"
--};
-+};*/
-
- Byte g_FastPos[1 << 11];
-
-@@ -318,7 +318,7 @@
- return S_OK;
- }
-
--static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString)
-+/*static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString)
- {
- while (true)
- {
-@@ -340,7 +340,7 @@
- if (AreStringsEqual(kMatchFinderIDs[m], s))
- return m;
- return -1;
--}
-+}*/
-
- STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
- const PROPVARIANT *properties, UInt32 numProperties)
-@@ -378,7 +378,8 @@
- }
- case NCoderPropID::kMatchFinder:
- {
-- if (prop.vt != VT_BSTR)
-+ return E_NOTIMPL;
-+ /*if (prop.vt != VT_BSTR)
- return E_INVALIDARG;
- int matchFinderIndexPrev = _matchFinderIndex;
- int m = FindMatchFinder(prop.bstrVal);
-@@ -390,7 +391,7 @@
- _dictionarySizePrev = (UInt32)-1;
- ReleaseMatchFinder();
- }
-- break;
-+ break;*/
- }
- #ifdef COMPRESS_MF_MT
- case NCoderPropID::kMultiThread:
-Only in 7zip-orig/7zip/Compress: LZMA_Alone
-Only in 7zip-orig/7zip/Compress: LZMA_C
-Only in 7zip/7zip/Compress/RangeCoder: CVS
-Only in 7zip: CVS
-Only in 7zip/Common: CVS
-Only in 7zip-orig/Common: C_FileIO.cpp
-Only in 7zip-orig/Common: C_FileIO.h
-Only in 7zip-orig/Common: ComTry.h
-Only in 7zip-orig/Common: CommandLineParser.cpp
-Only in 7zip-orig/Common: CommandLineParser.h
-Only in 7zip-orig/Common: MyInitGuid.h
-diff -ru 7zip-orig/Common/MyWindows.h 7zip/Common/MyWindows.h
---- 7zip-orig/Common/MyWindows.h Sun Apr 16 16:53:43 2006
-+++ 7zip/Common/MyWindows.h Mon Oct 16 10:20:04 2006
-@@ -3,17 +3,22 @@
- #ifndef __MYWINDOWS_H
- #define __MYWINDOWS_H
-
-+#include "../../Platform.h"
-+
- #ifdef _WIN32
-
- #include <windows.h>
-
-+/*
- #define CHAR_PATH_SEPARATOR '\\'
- #define WCHAR_PATH_SEPARATOR L'\\'
- #define STRING_PATH_SEPARATOR "\\"
- #define WSTRING_PATH_SEPARATOR L"\\"
-+*/
-
- #else
-
-+/*
- #define CHAR_PATH_SEPARATOR '/'
- #define WCHAR_PATH_SEPARATOR L'/'
- #define STRING_PATH_SEPARATOR "/"
-@@ -21,9 +26,9 @@
-
- #include <stddef.h> // for wchar_t
- #include <string.h>
--
-+*/
- #include "MyGuidDef.h"
--
-+/*
- typedef char CHAR;
- typedef unsigned char UCHAR;
-
-@@ -62,7 +67,7 @@
- typedef OLECHAR *BSTR;
- typedef const OLECHAR *LPCOLESTR;
- typedef OLECHAR *LPOLESTR;
--
-+*/
- typedef struct _FILETIME
- {
- DWORD dwLowDateTime;
-Only in 7zip-orig/Common: NewHandler.cpp
-Only in 7zip-orig/Common: NewHandler.h
-diff -ru 7zip-orig/Common/StdAfx.h 7zip/Common/StdAfx.h
---- 7zip-orig/Common/StdAfx.h Mon Jul 11 15:16:00 2005
-+++ 7zip/Common/StdAfx.h Mon Oct 16 10:39:16 2006
-@@ -4,6 +4,5 @@
- #define __STDAFX_H
-
- // #include "MyWindows.h"
--#include "NewHandler.h"
-
- #endif
-Only in 7zip-orig/Common: String.cpp
-Only in 7zip-orig/Common: String.h
-Only in 7zip-orig/Common: StringConvert.cpp
-Only in 7zip-orig/Common: StringConvert.h
-Only in 7zip-orig/Common: StringToInt.cpp
-Only in 7zip-orig/Common: StringToInt.h
-Only in 7zip-orig/Common: Vector.cpp
-Only in 7zip-orig/Common: Vector.h
-Only in 7zip: LZMADecode.c
-Only in 7zip: LZMADecode.h
-Only in 7zip-orig: Windows
-Only in 7zip: copying.txt
-Only in 7zip: readme.txt
+Only in 7zip: 7zGuids.cpp
+Only in 7zip-orig/7zip: Archive
+Only in 7zip/7zip: CVS
+Only in 7zip/7zip/Common: CVS
+Only in 7zip-orig/7zip/Common: FileStreams.cpp
+Only in 7zip-orig/7zip/Common: FileStreams.h
+diff -ru 7zip-orig/7zip/Common/StdAfx.h 7zip/7zip/Common/StdAfx.h
+--- 7zip-orig/7zip/Common/StdAfx.h Mon Jul 11 15:14:54 2005
++++ 7zip/7zip/Common/StdAfx.h Mon Oct 16 10:39:10 2006
+@@ -4,6 +4,5 @@
+ #define __STDAFX_H
+
+ #include "../../Common/MyWindows.h"
+-#include "../../Common/NewHandler.h"
+
+ #endif
+Only in 7zip-orig/7zip/Compress: Branch
+Only in 7zip/7zip/Compress: CVS
+Only in 7zip/7zip/Compress/LZ/BinTree: BinTree3ZMain.h
+Only in 7zip/7zip/Compress/LZ/BinTree: BinTree4b.h
+Only in 7zip/7zip/Compress/LZ/BinTree: BinTreeMF.h
+Only in 7zip/7zip/Compress/LZ/BinTree: BinTreeMFMain.h
+Only in 7zip/7zip/Compress/LZ/BinTree: CVS
+Only in 7zip/7zip/Compress/LZ: CVS
+Only in 7zip-orig/7zip/Compress/LZ: HashChain
+Only in 7zip/7zip/Compress/LZMA: CVS
+Only in 7zip-orig/7zip/Compress/LZMA: LZMADecoder.cpp
+Only in 7zip-orig/7zip/Compress/LZMA: LZMADecoder.h
+diff -ru 7zip-orig/7zip/Compress/LZMA/LZMAEncoder.cpp 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
+--- 7zip-orig/7zip/Compress/LZMA/LZMAEncoder.cpp Sat May 20 08:23:48 2006
++++ 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp Mon Oct 16 10:26:43 2006
+@@ -55,13 +55,13 @@
+ kHC4
+ };
+
+-static const wchar_t *kMatchFinderIDs[] =
++/*static const wchar_t *kMatchFinderIDs[] =
+ {
+ L"BT2",
+ L"BT3",
+ L"BT4",
+ L"HC4"
+-};
++};*/
+
+ Byte g_FastPos[1 << 11];
+
+@@ -318,7 +318,7 @@
+ return S_OK;
+ }
+
+-static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString)
++/*static bool AreStringsEqual(const wchar_t *base, const wchar_t *testString)
+ {
+ while (true)
+ {
+@@ -340,7 +340,7 @@
+ if (AreStringsEqual(kMatchFinderIDs[m], s))
+ return m;
+ return -1;
+-}
++}*/
+
+ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
+ const PROPVARIANT *properties, UInt32 numProperties)
+@@ -378,7 +378,8 @@
+ }
+ case NCoderPropID::kMatchFinder:
+ {
+- if (prop.vt != VT_BSTR)
++ return E_NOTIMPL;
++ /*if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
+ int matchFinderIndexPrev = _matchFinderIndex;
+ int m = FindMatchFinder(prop.bstrVal);
+@@ -390,7 +391,7 @@
+ _dictionarySizePrev = (UInt32)-1;
+ ReleaseMatchFinder();
+ }
+- break;
++ break;*/
+ }
+ #ifdef COMPRESS_MF_MT
+ case NCoderPropID::kMultiThread:
+Only in 7zip-orig/7zip/Compress: LZMA_Alone
+Only in 7zip-orig/7zip/Compress: LZMA_C
+Only in 7zip/7zip/Compress/RangeCoder: CVS
+Only in 7zip: CVS
+Only in 7zip/Common: CVS
+Only in 7zip-orig/Common: C_FileIO.cpp
+Only in 7zip-orig/Common: C_FileIO.h
+Only in 7zip-orig/Common: ComTry.h
+Only in 7zip-orig/Common: CommandLineParser.cpp
+Only in 7zip-orig/Common: CommandLineParser.h
+Only in 7zip-orig/Common: MyInitGuid.h
+diff -ru 7zip-orig/Common/MyWindows.h 7zip/Common/MyWindows.h
+--- 7zip-orig/Common/MyWindows.h Sun Apr 16 16:53:43 2006
++++ 7zip/Common/MyWindows.h Mon Oct 16 10:20:04 2006
+@@ -3,17 +3,22 @@
+ #ifndef __MYWINDOWS_H
+ #define __MYWINDOWS_H
+
++#include "../../Platform.h"
++
+ #ifdef _WIN32
+
+ #include <windows.h>
+
++/*
+ #define CHAR_PATH_SEPARATOR '\\'
+ #define WCHAR_PATH_SEPARATOR L'\\'
+ #define STRING_PATH_SEPARATOR "\\"
+ #define WSTRING_PATH_SEPARATOR L"\\"
++*/
+
+ #else
+
++/*
+ #define CHAR_PATH_SEPARATOR '/'
+ #define WCHAR_PATH_SEPARATOR L'/'
+ #define STRING_PATH_SEPARATOR "/"
+@@ -21,9 +26,9 @@
+
+ #include <stddef.h> // for wchar_t
+ #include <string.h>
+-
++*/
+ #include "MyGuidDef.h"
+-
++/*
+ typedef char CHAR;
+ typedef unsigned char UCHAR;
+
+@@ -62,7 +67,7 @@
+ typedef OLECHAR *BSTR;
+ typedef const OLECHAR *LPCOLESTR;
+ typedef OLECHAR *LPOLESTR;
+-
++*/
+ typedef struct _FILETIME
+ {
+ DWORD dwLowDateTime;
+Only in 7zip-orig/Common: NewHandler.cpp
+Only in 7zip-orig/Common: NewHandler.h
+diff -ru 7zip-orig/Common/StdAfx.h 7zip/Common/StdAfx.h
+--- 7zip-orig/Common/StdAfx.h Mon Jul 11 15:16:00 2005
++++ 7zip/Common/StdAfx.h Mon Oct 16 10:39:16 2006
+@@ -4,6 +4,5 @@
+ #define __STDAFX_H
+
+ // #include "MyWindows.h"
+-#include "NewHandler.h"
+
+ #endif
+Only in 7zip-orig/Common: String.cpp
+Only in 7zip-orig/Common: String.h
+Only in 7zip-orig/Common: StringConvert.cpp
+Only in 7zip-orig/Common: StringConvert.h
+Only in 7zip-orig/Common: StringToInt.cpp
+Only in 7zip-orig/Common: StringToInt.h
+Only in 7zip-orig/Common: Vector.cpp
+Only in 7zip-orig/Common: Vector.h
+Only in 7zip: LZMADecode.c
+Only in 7zip: LZMADecode.h
+Only in 7zip-orig: Windows
+Only in 7zip: copying.txt
+Only in 7zip: readme.txt
diff --git a/Source/DialogTemplate.cpp b/Source/DialogTemplate.cpp
index 099bfee..0ece79d 100755
--- a/Source/DialogTemplate.cpp
+++ b/Source/DialogTemplate.cpp
@@ -1,654 +1,654 @@
-/*
- * DialogTemplate.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 2002 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "DialogTemplate.h"
-#include "winchar.h"
-#include <cassert> // for assert(3)
-#ifndef _WIN32
-# include "util.h" // for Unicode conversion functions
-# include <stdio.h>
-# include <stdlib.h>
-# include <iconv.h>
-# include <errno.h>
-#endif
-
-using namespace std;
-
-//////////////////////////////////////////////////////////////////////
-// Utilities
-//////////////////////////////////////////////////////////////////////
-
-static inline DWORD ConvertEndianness(DWORD d) {
- return FIX_ENDIAN_INT32(d);
-}
-
-static inline WORD ConvertEndianness(WORD w) {
- return FIX_ENDIAN_INT16(w);
-}
-
-static inline short ConvertEndianness(short s) {
- return ConvertEndianness(WORD(s));
-}
-
-#define ALIGN(dwToAlign, dwAlignOn) dwToAlign = (dwToAlign%dwAlignOn == 0) ? dwToAlign : dwToAlign - (dwToAlign%dwAlignOn) + dwAlignOn
-
-// Reads a variant length array from seeker into readInto and advances seeker
-void ReadVarLenArr(LPBYTE &seeker, WCHAR* &readInto, unsigned int uCodePage) {
- WORD* arr = (WORD*)seeker;
- switch (ConvertEndianness(arr[0])) {
- case 0x0000:
- readInto = 0;
- seeker += sizeof(WORD);
- break;
- case 0xFFFF:
- readInto = MAKEINTRESOURCEW(ConvertEndianness(arr[1]));
- seeker += 2*sizeof(WORD);
- break;
- default:
- {
- readInto = winchar_strdup((WCHAR *) arr);
- PWCHAR wseeker = PWCHAR(seeker);
- while (*wseeker++);
- seeker = LPBYTE(wseeker);
- }
- break;
- }
-}
-
-// A macro that writes a given string (that can be a number too) into the buffer
-#define WriteStringOrId(x) \
- if (x) \
- if (IS_INTRESOURCE(x)) { \
- *(WORD*)seeker = 0xFFFF; \
- seeker += sizeof(WORD); \
- *(WORD*)seeker = ConvertEndianness(WORD(DWORD(x))); \
- seeker += sizeof(WORD); \
- } \
- else { \
- winchar_strcpy((WCHAR *) seeker, x); \
- seeker += winchar_strlen((WCHAR *) seeker) * sizeof(WCHAR) + sizeof(WCHAR); \
- } \
- else \
- seeker += sizeof(WORD);
-
-// A macro that adds the size of x (which can be a string a number, or nothing) to dwSize
-#define AddStringOrIdSize(x) dwSize += x ? (IS_INTRESOURCE(x) ? sizeof(DWORD) : (winchar_strlen(x) + 1) * sizeof(WCHAR)) : sizeof(WORD)
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-CDialogTemplate::CDialogTemplate(BYTE* pbData, unsigned int uCodePage) {
- m_uCodePage = uCodePage;
-
- m_dwHelpId = 0;
- m_szClass = 0;
- m_szFont = 0;
- m_sFontSize = 0;
- m_sFontWeight = 0;
- m_bItalic = 0;
- m_bCharset = 0;
- m_szMenu = 0;
- m_szTitle = 0;
-
- WORD wItems = 0;
-
- if (*(DWORD*)pbData == EXTENDED_DIALOG) { // Extended dialog template signature
- m_bExtended = true;
-
- DLGTEMPLATEEX* dTemplateEx = (DLGTEMPLATEEX*)pbData;
-
- m_dwHelpId = ConvertEndianness(dTemplateEx->helpID);
- m_dwStyle = ConvertEndianness(dTemplateEx->style);
- m_dwExtStyle = ConvertEndianness(dTemplateEx->exStyle);
- m_sX = ConvertEndianness(dTemplateEx->x);
- m_sY = ConvertEndianness(dTemplateEx->y);
- m_sWidth = ConvertEndianness(dTemplateEx->cx);
- m_sHeight = ConvertEndianness(dTemplateEx->cy);
-
- wItems = ConvertEndianness(dTemplateEx->cDlgItems);
- }
- else {
- m_bExtended = false;
-
- DLGTEMPLATE* dTemplate = (DLGTEMPLATE*)pbData;
-
- m_dwStyle = ConvertEndianness(dTemplate->style);
- m_dwExtStyle = ConvertEndianness(dTemplate->dwExtendedStyle);
- m_sX = ConvertEndianness(dTemplate->x);
- m_sY = ConvertEndianness(dTemplate->y);
- m_sWidth = ConvertEndianness(dTemplate->cx);
- m_sHeight = ConvertEndianness(dTemplate->cy);
-
- wItems = ConvertEndianness(dTemplate->cdit);
- }
-
- BYTE* seeker = pbData + (m_bExtended ? sizeof(DLGTEMPLATEEX) : sizeof(DLGTEMPLATE));
-
- // Read menu variant length array
- ReadVarLenArr(seeker, m_szMenu, m_uCodePage);
- // Read class variant length array
- ReadVarLenArr(seeker, m_szClass, m_uCodePage);
- // Read title variant length array
- ReadVarLenArr(seeker, m_szTitle, m_uCodePage);
- // Read font size and variant length array (only if style DS_SETFONT is used!)
- if (m_dwStyle & DS_SETFONT) {
- m_sFontSize = ConvertEndianness(*(short*)seeker);
- seeker += sizeof(short);
- if (m_bExtended) {
- m_sFontWeight = ConvertEndianness(*(short*)seeker);
- seeker += sizeof(short);
- m_bItalic = *(BYTE*)seeker;
- seeker += sizeof(BYTE);
- m_bCharset = *(BYTE*)seeker;
- seeker += sizeof(BYTE);
- }
- ReadVarLenArr(seeker, m_szFont, m_uCodePage);
- }
-
- // Read items
- for (int i = 0; i < wItems; i++) {
- // DLGITEMTEMPLATE[EX]s must be aligned on DWORD boundary
- if (DWORD(seeker - pbData) % sizeof(DWORD))
- seeker += sizeof(WORD);
-
- DialogItemTemplate* item = new DialogItemTemplate;
- ZeroMemory(item, sizeof(DialogItemTemplate));
-
- if (m_bExtended) {
- DLGITEMTEMPLATEEX* rawItem = (DLGITEMTEMPLATEEX*)seeker;
-
- item->dwHelpId = ConvertEndianness(rawItem->helpID);
- item->dwStyle = ConvertEndianness(rawItem->style);
- item->dwExtStyle = ConvertEndianness(rawItem->exStyle);
- item->sX = ConvertEndianness(rawItem->x);
- item->sY = ConvertEndianness(rawItem->y);
- item->sWidth = ConvertEndianness(rawItem->cx);
- item->sHeight = ConvertEndianness(rawItem->cy);
- item->wId = ConvertEndianness(rawItem->id);
-
- seeker += sizeof(DLGITEMTEMPLATEEX);
- }
- else {
- DLGITEMTEMPLATE* rawItem = (DLGITEMTEMPLATE*)seeker;
-
- item->dwHelpId = 0;
- item->dwStyle = ConvertEndianness(rawItem->style);
- item->dwExtStyle = ConvertEndianness(rawItem->dwExtendedStyle);
- item->sX = ConvertEndianness(rawItem->x);
- item->sY = ConvertEndianness(rawItem->y);
- item->sWidth = ConvertEndianness(rawItem->cx);
- item->sHeight = ConvertEndianness(rawItem->cy);
- item->wId = ConvertEndianness(rawItem->id);
-
- seeker += sizeof(DLGITEMTEMPLATE);
- }
-
- // Read class variant length array
- ReadVarLenArr(seeker, item->szClass, m_uCodePage);
- // Read title variant length array
- ReadVarLenArr(seeker, item->szTitle, m_uCodePage);
-
- // Read creation data variant length array
- // First read the size of the array (no null termination)
- item->wCreateDataSize = ConvertEndianness(*(WORD*)seeker);
- seeker += sizeof(WORD);
- // Then read the array it self (if size is not 0)
- if (item->wCreateDataSize) {
- item->wCreateDataSize -= sizeof(WORD); // Size includes size field itself...
- item->szCreationData = new char[item->wCreateDataSize];
- CopyMemory(item->szCreationData, seeker, item->wCreateDataSize);
- seeker += item->wCreateDataSize;
- }
-
- // Add the item to the vector
- m_vItems.push_back(item);
- }
-}
-
-CDialogTemplate::~CDialogTemplate() {
- if (m_szMenu && !IS_INTRESOURCE(m_szMenu))
- delete [] m_szMenu;
- if (m_szClass && !IS_INTRESOURCE(m_szClass))
- delete [] m_szClass;
- if (m_szTitle)
- delete [] m_szTitle;
- if (m_szFont)
- delete [] m_szFont;
-
- for (unsigned int i = 0; i < m_vItems.size(); i++) {
- if (m_vItems[i]->szClass && !IS_INTRESOURCE(m_vItems[i]->szClass))
- delete [] m_vItems[i]->szClass;
- if (m_vItems[i]->szTitle && !IS_INTRESOURCE(m_vItems[i]->szTitle))
- delete [] m_vItems[i]->szTitle;
- if (m_vItems[i]->szCreationData)
- delete [] m_vItems[i]->szCreationData;
- }
-}
-
-//////////////////////////////////////////////////////////////////////
-// Methods
-//////////////////////////////////////////////////////////////////////
-
-// Returns the width of the dialog
-short CDialogTemplate::GetWidth() {
- return m_sWidth;
-}
-
-// Returns the height of the dialog
-short CDialogTemplate::GetHeight() {
- return m_sHeight;
-}
-
-// Returns info about the item with the id wId
-DialogItemTemplate* CDialogTemplate::GetItem(WORD wId) {
- for (unsigned int i = 0; i < m_vItems.size(); i++)
- if (m_vItems[i]->wId == wId)
- return m_vItems[i];
- return 0;
-}
-
-// Returns info about the item with the indexed i
-DialogItemTemplate* CDialogTemplate::GetItemByIdx(DWORD i) {
- if (i >= m_vItems.size()) return 0;
- return m_vItems[i];
-}
-
-// Removes an item
-// Returns 1 if removed, 0 otherwise
-int CDialogTemplate::RemoveItem(WORD wId) {
- for (unsigned int i = 0; i < m_vItems.size(); i++) {
- if (m_vItems[i]->wId == wId) {
- m_vItems.erase(m_vItems.begin() + i);
- return 1;
- }
- }
- return 0;
-}
-
-// Sets the font of the dialog
-void CDialogTemplate::SetFont(char* szFaceName, WORD wFontSize) {
- if (strcmp(szFaceName, "MS Shell Dlg")) {
- // not MS Shell Dlg
- m_dwStyle &= ~DS_SHELLFONT;
- }
- else {
- // MS Shell Dlg
- m_dwStyle |= DS_SHELLFONT;
- }
- m_bCharset = DEFAULT_CHARSET;
- m_dwStyle |= DS_SETFONT;
- if (m_szFont) delete [] m_szFont;
- m_szFont = winchar_fromansi(szFaceName, m_uCodePage);
- m_sFontSize = wFontSize;
-}
-
-// Adds an item to the dialog
-void CDialogTemplate::AddItem(DialogItemTemplate item) {
- DialogItemTemplate* newItem = new DialogItemTemplate;
- CopyMemory(newItem, &item, sizeof(DialogItemTemplate));
-
- if (item.szClass && !IS_INTRESOURCE(item.szClass)) {
- newItem->szClass = winchar_strdup(item.szClass);
- }
- if (item.szTitle && !IS_INTRESOURCE(item.szTitle)) {
- newItem->szTitle = winchar_strdup(item.szTitle);
- }
- if (item.wCreateDataSize) {
- newItem->szCreationData = new char[item.wCreateDataSize];
- memcpy(newItem->szCreationData, item.szCreationData, item.wCreateDataSize);
- }
- m_vItems.push_back(newItem);
-}
-
-// Moves all of the items in the dialog by (x,y)
-void CDialogTemplate::MoveAll(short x, short y) {
- for (unsigned int i = 0; i < m_vItems.size(); i++) {
- m_vItems[i]->sX += x;
- m_vItems[i]->sY += y;
- }
-}
-
-// Resizes the dialog by (x,y)
-void CDialogTemplate::Resize(short x, short y) {
- m_sWidth += x;
- m_sHeight += y;
-}
-
-#ifdef _WIN32
-// Creates a dummy dialog that is used for converting units
-HWND CDialogTemplate::CreateDummyDialog() {
- DWORD dwTemp;
- BYTE* pbDlg = Save(dwTemp);
- HWND hDlg = CreateDialogIndirect(GetModuleHandle(0), (DLGTEMPLATE*)pbDlg, 0, 0);
- delete [] pbDlg;
- if (!hDlg)
- throw runtime_error("Can't create dialog from template!");
-
- return hDlg;
-}
-
-// Converts pixels to this dialog's units
-void CDialogTemplate::PixelsToDlgUnits(short& x, short& y) {
- HWND hDlg = CreateDummyDialog();
- RECT r = {0, 0, 10000, 10000};
- MapDialogRect(hDlg, &r);
- DestroyWindow(hDlg);
-
- x = short(float(x) / (float(r.right)/10000));
- y = short(float(y) / (float(r.bottom)/10000));
-}
-
-// Converts pixels to this dialog's units
-void CDialogTemplate::DlgUnitsToPixels(short& x, short& y) {
- HWND hDlg = CreateDummyDialog();
- RECT r = {0, 0, 10000, 10000};
- MapDialogRect(hDlg, &r);
- DestroyWindow(hDlg);
-
- x = short(float(x) * (float(r.right)/10000));
- y = short(float(y) * (float(r.bottom)/10000));
-}
-
-// Returns the size of a string in the dialog (in dialog units)
-SIZE CDialogTemplate::GetStringSize(WORD id, char *str) {
- HWND hDlg = CreateDummyDialog();
-
- LOGFONT f;
- GetObject((HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0), sizeof(LOGFONT), &f);
-
- HDC memDC = CreateCompatibleDC(GetDC(hDlg));
- HFONT font = CreateFontIndirect(&f);
- SelectObject(memDC, font);
-
- SIZE size;
- GetTextExtentPoint32(memDC, str, strlen(str), &size);
-
- DestroyWindow(hDlg);
- DeleteObject(font);
- DeleteDC(memDC);
-
- PixelsToDlgUnits((short&)size.cx, (short&)size.cy);
-
- return size;
-}
-
-// Trims the right margins of a control to fit a given text string size.
-void CDialogTemplate::RTrimToString(WORD id, char *str, int margins) {
- DialogItemTemplate* item = GetItem(id);
- if (!item) return;
-
- SIZE size = GetStringSize(id, str);
-
- size.cx += margins;
- size.cy += 2;
-
- item->sWidth = short(size.cx);
- item->sHeight = short(size.cy);
-}
-
-// Trims the left margins of a control to fit a given text string size.
-void CDialogTemplate::LTrimToString(WORD id, char *str, int margins) {
- DialogItemTemplate* item = GetItem(id);
- if (!item) return;
-
- SIZE size = GetStringSize(id, str);
-
- size.cx += margins;
- size.cy += 2;
-
- item->sX += item->sWidth - short(size.cx);
- item->sWidth = short(size.cx);
- item->sHeight = short(size.cy);
-}
-
-// Trims the left and right margins of a control to fit a given text string size.
-void CDialogTemplate::CTrimToString(WORD id, char *str, int margins) {
- DialogItemTemplate* item = GetItem(id);
- if (!item) return;
-
- SIZE size = GetStringSize(id, str);
-
- size.cx += margins;
- size.cy += 2;
-
- item->sX += item->sWidth/2 - short(size.cx/2);
- item->sWidth = short(size.cx);
- item->sHeight = short(size.cy);
-}
-#endif
-
-// Moves every item right and gives it the WS_EX_RIGHT extended style
-void CDialogTemplate::ConvertToRTL() {
- for (unsigned int i = 0; i < m_vItems.size(); i++) {
- bool addExStyle = false;
- char *szClass;
-
- if (IS_INTRESOURCE(m_vItems[i]->szClass))
- szClass = (char *) m_vItems[i]->szClass;
- else
- szClass = winchar_toansi(m_vItems[i]->szClass);
-
- // Button
- if (long(m_vItems[i]->szClass) == 0x80) {
- m_vItems[i]->dwStyle ^= BS_LEFTTEXT;
- m_vItems[i]->dwStyle ^= BS_RIGHT;
- m_vItems[i]->dwStyle ^= BS_LEFT;
-
- if ((m_vItems[i]->dwStyle & (BS_LEFT|BS_RIGHT)) == (BS_LEFT|BS_RIGHT)) {
- m_vItems[i]->dwStyle ^= BS_LEFT;
- m_vItems[i]->dwStyle ^= BS_RIGHT;
- if (m_vItems[i]->dwStyle & (BS_RADIOBUTTON|BS_CHECKBOX|BS_USERBUTTON)) {
- m_vItems[i]->dwStyle |= BS_RIGHT;
- }
- }
- }
- // Edit
- else if (long(m_vItems[i]->szClass) == 0x81) {
- if ((m_vItems[i]->dwStyle & ES_CENTER) == 0) {
- m_vItems[i]->dwStyle ^= ES_RIGHT;
- }
- }
- // Static
- else if (long(m_vItems[i]->szClass) == 0x82) {
- if ((m_vItems[i]->dwStyle & SS_TYPEMASK) == SS_LEFT || (m_vItems[i]->dwStyle & SS_TYPEMASK) == SS_LEFTNOWORDWRAP)
- {
- m_vItems[i]->dwStyle &= ~SS_TYPEMASK;
- m_vItems[i]->dwStyle |= SS_RIGHT;
- }
- else if ((m_vItems[i]->dwStyle & SS_TYPEMASK) == SS_ICON) {
- m_vItems[i]->dwStyle |= SS_CENTERIMAGE;
- }
- }
- else if (!IS_INTRESOURCE(m_vItems[i]->szClass) && !stricmp(szClass, "RichEdit20A")) {
- if ((m_vItems[i]->dwStyle & ES_CENTER) == 0) {
- m_vItems[i]->dwStyle ^= ES_RIGHT;
- }
- }
- else if (!IS_INTRESOURCE(m_vItems[i]->szClass) && !stricmp(szClass, "SysTreeView32")) {
- m_vItems[i]->dwStyle |= TVS_RTLREADING;
- addExStyle = true;
- }
- else addExStyle = true;
-
- if (addExStyle)
- m_vItems[i]->dwExtStyle |= WS_EX_RIGHT;
-
- m_vItems[i]->dwExtStyle |= WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR;
-
- m_vItems[i]->sX = m_sWidth - m_vItems[i]->sWidth - m_vItems[i]->sX;
-
- if (!IS_INTRESOURCE(m_vItems[i]->szClass))
- delete [] szClass;
- }
- m_dwExtStyle |= WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR;
-}
-
-// Saves the dialog in the form of DLGTEMPLATE[EX]
-BYTE* CDialogTemplate::Save(DWORD& dwSize) {
- // We need the size first to know how much memory to allocate
- dwSize = GetSize();
- BYTE* pbDlg = new BYTE[dwSize];
- ZeroMemory(pbDlg, dwSize);
- BYTE* seeker = pbDlg;
-
- if (m_bExtended) {
- DLGTEMPLATEEX dh = {
- ConvertEndianness(WORD(0x0001)),
- ConvertEndianness(WORD(0xFFFF)),
- ConvertEndianness(m_dwHelpId),
- ConvertEndianness(m_dwExtStyle),
- ConvertEndianness(m_dwStyle),
- ConvertEndianness(WORD(m_vItems.size())),
- ConvertEndianness(m_sX),
- ConvertEndianness(m_sY),
- ConvertEndianness(m_sWidth),
- ConvertEndianness(m_sHeight)
- };
-
- CopyMemory(seeker, &dh, sizeof(DLGTEMPLATEEX));
- seeker += sizeof(DLGTEMPLATEEX);
- }
- else {
- DLGTEMPLATE dh = {
- ConvertEndianness(m_dwStyle),
- ConvertEndianness(m_dwExtStyle),
- ConvertEndianness(WORD(m_vItems.size())),
- ConvertEndianness(m_sX),
- ConvertEndianness(m_sY),
- ConvertEndianness(m_sWidth),
- ConvertEndianness(m_sHeight)
- };
-
- CopyMemory(seeker, &dh, sizeof(DLGTEMPLATE));
- seeker += sizeof(DLGTEMPLATE);
- }
-
- // Write menu variant length array
- WriteStringOrId(m_szMenu);
- // Write class variant length array
- WriteStringOrId(m_szClass);
- // Write title variant length array
- WriteStringOrId(m_szTitle);
-
- // Write font variant length array, size, and extended info (if needed)
- if (m_dwStyle & DS_SETFONT) {
- *(short*)seeker = ConvertEndianness(m_sFontSize);
- seeker += sizeof(short);
- if (m_bExtended) {
- *(short*)seeker = ConvertEndianness(m_sFontWeight);
- seeker += sizeof(short);
- *(BYTE*)seeker = m_bItalic;
- seeker += sizeof(BYTE);
- *(BYTE*)seeker = m_bCharset;
- seeker += sizeof(BYTE);
- }
- WriteStringOrId(m_szFont);
- }
-
- // Write all of the items
- for (unsigned int i = 0; i < m_vItems.size(); i++) {
- // DLGITEMTEMPLATE[EX]s must be aligned on DWORD boundary
- if (DWORD(seeker - pbDlg) % sizeof(DWORD))
- seeker += sizeof(WORD);
-
- if (m_bExtended) {
- DLGITEMTEMPLATEEX dih = {
- ConvertEndianness(m_vItems[i]->dwHelpId),
- ConvertEndianness(m_vItems[i]->dwExtStyle),
- ConvertEndianness(m_vItems[i]->dwStyle),
- ConvertEndianness(m_vItems[i]->sX),
- ConvertEndianness(m_vItems[i]->sY),
- ConvertEndianness(m_vItems[i]->sWidth),
- ConvertEndianness(m_vItems[i]->sHeight),
- ConvertEndianness(m_vItems[i]->wId)
- };
-
- CopyMemory(seeker, &dih, sizeof(DLGITEMTEMPLATEEX));
- seeker += sizeof(DLGITEMTEMPLATEEX);
- }
- else {
- DLGITEMTEMPLATE dih = {
- ConvertEndianness(m_vItems[i]->dwStyle),
- ConvertEndianness(m_vItems[i]->dwExtStyle),
- ConvertEndianness(m_vItems[i]->sX),
- ConvertEndianness(m_vItems[i]->sY),
- ConvertEndianness(m_vItems[i]->sWidth),
- ConvertEndianness(m_vItems[i]->sHeight),
- ConvertEndianness(m_vItems[i]->wId)
- };
-
- CopyMemory(seeker, &dih, sizeof(DLGITEMTEMPLATE));
- seeker += sizeof(DLGITEMTEMPLATE);
- }
-
- // Write class variant length array
- WriteStringOrId(m_vItems[i]->szClass);
- // Write title variant length array
- WriteStringOrId(m_vItems[i]->szTitle);
-
- // Write creation data variant length array
- // First write its size
- WORD wCreateDataSize = m_vItems[i]->wCreateDataSize;
- if (m_vItems[i]->wCreateDataSize) wCreateDataSize += sizeof(WORD);
- *(WORD*)seeker = ConvertEndianness(wCreateDataSize);
- seeker += sizeof(WORD);
- // If size is nonzero write the data too
- if (m_vItems[i]->wCreateDataSize) {
- CopyMemory(seeker, m_vItems[i]->szCreationData, m_vItems[i]->wCreateDataSize);
- seeker += m_vItems[i]->wCreateDataSize;
- }
- }
-
- assert((DWORD) seeker - (DWORD) pbDlg == dwSize);
-
- // DONE!
- return pbDlg;
-}
-
-// Returns the size that the DLGTEMPLATE[EX] will take when saved
-DWORD CDialogTemplate::GetSize() {
- DWORD dwSize = m_bExtended ? sizeof(DLGTEMPLATEEX) : sizeof(DLGTEMPLATE);
-
- // Menu
- AddStringOrIdSize(m_szMenu);
- // Class
- AddStringOrIdSize(m_szClass);
- // Title
- AddStringOrIdSize(m_szTitle);
-
- // Font
- if (m_dwStyle & DS_SETFONT) {
- dwSize += sizeof(WORD) + (m_bExtended ? sizeof(short) + 2*sizeof(BYTE) : 0);
- AddStringOrIdSize(m_szFont);
- }
-
- for (unsigned int i = 0; i < m_vItems.size(); i++) {
- // DLGITEMTEMPLATE[EX]s must be aligned on DWORD boundary
- ALIGN(dwSize, sizeof(DWORD));
-
- dwSize += m_bExtended ? sizeof(DLGITEMTEMPLATEEX) : sizeof(DLGITEMTEMPLATE);
-
- // Class
- AddStringOrIdSize(m_vItems[i]->szClass);
- // Title
- AddStringOrIdSize(m_vItems[i]->szTitle);
-
- dwSize += sizeof(WORD) + m_vItems[i]->wCreateDataSize;
- }
-
- return dwSize;
-}
+/*
+ * DialogTemplate.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 2002 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "DialogTemplate.h"
+#include "winchar.h"
+#include <cassert> // for assert(3)
+#ifndef _WIN32
+# include "util.h" // for Unicode conversion functions
+# include <stdio.h>
+# include <stdlib.h>
+# include <iconv.h>
+# include <errno.h>
+#endif
+
+using namespace std;
+
+//////////////////////////////////////////////////////////////////////
+// Utilities
+//////////////////////////////////////////////////////////////////////
+
+static inline DWORD ConvertEndianness(DWORD d) {
+ return FIX_ENDIAN_INT32(d);
+}
+
+static inline WORD ConvertEndianness(WORD w) {
+ return FIX_ENDIAN_INT16(w);
+}
+
+static inline short ConvertEndianness(short s) {
+ return ConvertEndianness(WORD(s));
+}
+
+#define ALIGN(dwToAlign, dwAlignOn) dwToAlign = (dwToAlign%dwAlignOn == 0) ? dwToAlign : dwToAlign - (dwToAlign%dwAlignOn) + dwAlignOn
+
+// Reads a variant length array from seeker into readInto and advances seeker
+void ReadVarLenArr(LPBYTE &seeker, WCHAR* &readInto, unsigned int uCodePage) {
+ WORD* arr = (WORD*)seeker;
+ switch (ConvertEndianness(arr[0])) {
+ case 0x0000:
+ readInto = 0;
+ seeker += sizeof(WORD);
+ break;
+ case 0xFFFF:
+ readInto = MAKEINTRESOURCEW(ConvertEndianness(arr[1]));
+ seeker += 2*sizeof(WORD);
+ break;
+ default:
+ {
+ readInto = winchar_strdup((WCHAR *) arr);
+ PWCHAR wseeker = PWCHAR(seeker);
+ while (*wseeker++);
+ seeker = LPBYTE(wseeker);
+ }
+ break;
+ }
+}
+
+// A macro that writes a given string (that can be a number too) into the buffer
+#define WriteStringOrId(x) \
+ if (x) \
+ if (IS_INTRESOURCE(x)) { \
+ *(WORD*)seeker = 0xFFFF; \
+ seeker += sizeof(WORD); \
+ *(WORD*)seeker = ConvertEndianness(WORD(DWORD(x))); \
+ seeker += sizeof(WORD); \
+ } \
+ else { \
+ winchar_strcpy((WCHAR *) seeker, x); \
+ seeker += winchar_strlen((WCHAR *) seeker) * sizeof(WCHAR) + sizeof(WCHAR); \
+ } \
+ else \
+ seeker += sizeof(WORD);
+
+// A macro that adds the size of x (which can be a string a number, or nothing) to dwSize
+#define AddStringOrIdSize(x) dwSize += x ? (IS_INTRESOURCE(x) ? sizeof(DWORD) : (winchar_strlen(x) + 1) * sizeof(WCHAR)) : sizeof(WORD)
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CDialogTemplate::CDialogTemplate(BYTE* pbData, unsigned int uCodePage) {
+ m_uCodePage = uCodePage;
+
+ m_dwHelpId = 0;
+ m_szClass = 0;
+ m_szFont = 0;
+ m_sFontSize = 0;
+ m_sFontWeight = 0;
+ m_bItalic = 0;
+ m_bCharset = 0;
+ m_szMenu = 0;
+ m_szTitle = 0;
+
+ WORD wItems = 0;
+
+ if (*(DWORD*)pbData == EXTENDED_DIALOG) { // Extended dialog template signature
+ m_bExtended = true;
+
+ DLGTEMPLATEEX* dTemplateEx = (DLGTEMPLATEEX*)pbData;
+
+ m_dwHelpId = ConvertEndianness(dTemplateEx->helpID);
+ m_dwStyle = ConvertEndianness(dTemplateEx->style);
+ m_dwExtStyle = ConvertEndianness(dTemplateEx->exStyle);
+ m_sX = ConvertEndianness(dTemplateEx->x);
+ m_sY = ConvertEndianness(dTemplateEx->y);
+ m_sWidth = ConvertEndianness(dTemplateEx->cx);
+ m_sHeight = ConvertEndianness(dTemplateEx->cy);
+
+ wItems = ConvertEndianness(dTemplateEx->cDlgItems);
+ }
+ else {
+ m_bExtended = false;
+
+ DLGTEMPLATE* dTemplate = (DLGTEMPLATE*)pbData;
+
+ m_dwStyle = ConvertEndianness(dTemplate->style);
+ m_dwExtStyle = ConvertEndianness(dTemplate->dwExtendedStyle);
+ m_sX = ConvertEndianness(dTemplate->x);
+ m_sY = ConvertEndianness(dTemplate->y);
+ m_sWidth = ConvertEndianness(dTemplate->cx);
+ m_sHeight = ConvertEndianness(dTemplate->cy);
+
+ wItems = ConvertEndianness(dTemplate->cdit);
+ }
+
+ BYTE* seeker = pbData + (m_bExtended ? sizeof(DLGTEMPLATEEX) : sizeof(DLGTEMPLATE));
+
+ // Read menu variant length array
+ ReadVarLenArr(seeker, m_szMenu, m_uCodePage);
+ // Read class variant length array
+ ReadVarLenArr(seeker, m_szClass, m_uCodePage);
+ // Read title variant length array
+ ReadVarLenArr(seeker, m_szTitle, m_uCodePage);
+ // Read font size and variant length array (only if style DS_SETFONT is used!)
+ if (m_dwStyle & DS_SETFONT) {
+ m_sFontSize = ConvertEndianness(*(short*)seeker);
+ seeker += sizeof(short);
+ if (m_bExtended) {
+ m_sFontWeight = ConvertEndianness(*(short*)seeker);
+ seeker += sizeof(short);
+ m_bItalic = *(BYTE*)seeker;
+ seeker += sizeof(BYTE);
+ m_bCharset = *(BYTE*)seeker;
+ seeker += sizeof(BYTE);
+ }
+ ReadVarLenArr(seeker, m_szFont, m_uCodePage);
+ }
+
+ // Read items
+ for (int i = 0; i < wItems; i++) {
+ // DLGITEMTEMPLATE[EX]s must be aligned on DWORD boundary
+ if (DWORD(seeker - pbData) % sizeof(DWORD))
+ seeker += sizeof(WORD);
+
+ DialogItemTemplate* item = new DialogItemTemplate;
+ ZeroMemory(item, sizeof(DialogItemTemplate));
+
+ if (m_bExtended) {
+ DLGITEMTEMPLATEEX* rawItem = (DLGITEMTEMPLATEEX*)seeker;
+
+ item->dwHelpId = ConvertEndianness(rawItem->helpID);
+ item->dwStyle = ConvertEndianness(rawItem->style);
+ item->dwExtStyle = ConvertEndianness(rawItem->exStyle);
+ item->sX = ConvertEndianness(rawItem->x);
+ item->sY = ConvertEndianness(rawItem->y);
+ item->sWidth = ConvertEndianness(rawItem->cx);
+ item->sHeight = ConvertEndianness(rawItem->cy);
+ item->wId = ConvertEndianness(rawItem->id);
+
+ seeker += sizeof(DLGITEMTEMPLATEEX);
+ }
+ else {
+ DLGITEMTEMPLATE* rawItem = (DLGITEMTEMPLATE*)seeker;
+
+ item->dwHelpId = 0;
+ item->dwStyle = ConvertEndianness(rawItem->style);
+ item->dwExtStyle = ConvertEndianness(rawItem->dwExtendedStyle);
+ item->sX = ConvertEndianness(rawItem->x);
+ item->sY = ConvertEndianness(rawItem->y);
+ item->sWidth = ConvertEndianness(rawItem->cx);
+ item->sHeight = ConvertEndianness(rawItem->cy);
+ item->wId = ConvertEndianness(rawItem->id);
+
+ seeker += sizeof(DLGITEMTEMPLATE);
+ }
+
+ // Read class variant length array
+ ReadVarLenArr(seeker, item->szClass, m_uCodePage);
+ // Read title variant length array
+ ReadVarLenArr(seeker, item->szTitle, m_uCodePage);
+
+ // Read creation data variant length array
+ // First read the size of the array (no null termination)
+ item->wCreateDataSize = ConvertEndianness(*(WORD*)seeker);
+ seeker += sizeof(WORD);
+ // Then read the array it self (if size is not 0)
+ if (item->wCreateDataSize) {
+ item->wCreateDataSize -= sizeof(WORD); // Size includes size field itself...
+ item->szCreationData = new char[item->wCreateDataSize];
+ CopyMemory(item->szCreationData, seeker, item->wCreateDataSize);
+ seeker += item->wCreateDataSize;
+ }
+
+ // Add the item to the vector
+ m_vItems.push_back(item);
+ }
+}
+
+CDialogTemplate::~CDialogTemplate() {
+ if (m_szMenu && !IS_INTRESOURCE(m_szMenu))
+ delete [] m_szMenu;
+ if (m_szClass && !IS_INTRESOURCE(m_szClass))
+ delete [] m_szClass;
+ if (m_szTitle)
+ delete [] m_szTitle;
+ if (m_szFont)
+ delete [] m_szFont;
+
+ for (unsigned int i = 0; i < m_vItems.size(); i++) {
+ if (m_vItems[i]->szClass && !IS_INTRESOURCE(m_vItems[i]->szClass))
+ delete [] m_vItems[i]->szClass;
+ if (m_vItems[i]->szTitle && !IS_INTRESOURCE(m_vItems[i]->szTitle))
+ delete [] m_vItems[i]->szTitle;
+ if (m_vItems[i]->szCreationData)
+ delete [] m_vItems[i]->szCreationData;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// Methods
+//////////////////////////////////////////////////////////////////////
+
+// Returns the width of the dialog
+short CDialogTemplate::GetWidth() {
+ return m_sWidth;
+}
+
+// Returns the height of the dialog
+short CDialogTemplate::GetHeight() {
+ return m_sHeight;
+}
+
+// Returns info about the item with the id wId
+DialogItemTemplate* CDialogTemplate::GetItem(WORD wId) {
+ for (unsigned int i = 0; i < m_vItems.size(); i++)
+ if (m_vItems[i]->wId == wId)
+ return m_vItems[i];
+ return 0;
+}
+
+// Returns info about the item with the indexed i
+DialogItemTemplate* CDialogTemplate::GetItemByIdx(DWORD i) {
+ if (i >= m_vItems.size()) return 0;
+ return m_vItems[i];
+}
+
+// Removes an item
+// Returns 1 if removed, 0 otherwise
+int CDialogTemplate::RemoveItem(WORD wId) {
+ for (unsigned int i = 0; i < m_vItems.size(); i++) {
+ if (m_vItems[i]->wId == wId) {
+ m_vItems.erase(m_vItems.begin() + i);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+// Sets the font of the dialog
+void CDialogTemplate::SetFont(char* szFaceName, WORD wFontSize) {
+ if (strcmp(szFaceName, "MS Shell Dlg")) {
+ // not MS Shell Dlg
+ m_dwStyle &= ~DS_SHELLFONT;
+ }
+ else {
+ // MS Shell Dlg
+ m_dwStyle |= DS_SHELLFONT;
+ }
+ m_bCharset = DEFAULT_CHARSET;
+ m_dwStyle |= DS_SETFONT;
+ if (m_szFont) delete [] m_szFont;
+ m_szFont = winchar_fromansi(szFaceName, m_uCodePage);
+ m_sFontSize = wFontSize;
+}
+
+// Adds an item to the dialog
+void CDialogTemplate::AddItem(DialogItemTemplate item) {
+ DialogItemTemplate* newItem = new DialogItemTemplate;
+ CopyMemory(newItem, &item, sizeof(DialogItemTemplate));
+
+ if (item.szClass && !IS_INTRESOURCE(item.szClass)) {
+ newItem->szClass = winchar_strdup(item.szClass);
+ }
+ if (item.szTitle && !IS_INTRESOURCE(item.szTitle)) {
+ newItem->szTitle = winchar_strdup(item.szTitle);
+ }
+ if (item.wCreateDataSize) {
+ newItem->szCreationData = new char[item.wCreateDataSize];
+ memcpy(newItem->szCreationData, item.szCreationData, item.wCreateDataSize);
+ }
+ m_vItems.push_back(newItem);
+}
+
+// Moves all of the items in the dialog by (x,y)
+void CDialogTemplate::MoveAll(short x, short y) {
+ for (unsigned int i = 0; i < m_vItems.size(); i++) {
+ m_vItems[i]->sX += x;
+ m_vItems[i]->sY += y;
+ }
+}
+
+// Resizes the dialog by (x,y)
+void CDialogTemplate::Resize(short x, short y) {
+ m_sWidth += x;
+ m_sHeight += y;
+}
+
+#ifdef _WIN32
+// Creates a dummy dialog that is used for converting units
+HWND CDialogTemplate::CreateDummyDialog() {
+ DWORD dwTemp;
+ BYTE* pbDlg = Save(dwTemp);
+ HWND hDlg = CreateDialogIndirect(GetModuleHandle(0), (DLGTEMPLATE*)pbDlg, 0, 0);
+ delete [] pbDlg;
+ if (!hDlg)
+ throw runtime_error("Can't create dialog from template!");
+
+ return hDlg;
+}
+
+// Converts pixels to this dialog's units
+void CDialogTemplate::PixelsToDlgUnits(short& x, short& y) {
+ HWND hDlg = CreateDummyDialog();
+ RECT r = {0, 0, 10000, 10000};
+ MapDialogRect(hDlg, &r);
+ DestroyWindow(hDlg);
+
+ x = short(float(x) / (float(r.right)/10000));
+ y = short(float(y) / (float(r.bottom)/10000));
+}
+
+// Converts pixels to this dialog's units
+void CDialogTemplate::DlgUnitsToPixels(short& x, short& y) {
+ HWND hDlg = CreateDummyDialog();
+ RECT r = {0, 0, 10000, 10000};
+ MapDialogRect(hDlg, &r);
+ DestroyWindow(hDlg);
+
+ x = short(float(x) * (float(r.right)/10000));
+ y = short(float(y) * (float(r.bottom)/10000));
+}
+
+// Returns the size of a string in the dialog (in dialog units)
+SIZE CDialogTemplate::GetStringSize(WORD id, char *str) {
+ HWND hDlg = CreateDummyDialog();
+
+ LOGFONT f;
+ GetObject((HFONT)SendMessage(hDlg, WM_GETFONT, 0, 0), sizeof(LOGFONT), &f);
+
+ HDC memDC = CreateCompatibleDC(GetDC(hDlg));
+ HFONT font = CreateFontIndirect(&f);
+ SelectObject(memDC, font);
+
+ SIZE size;
+ GetTextExtentPoint32(memDC, str, strlen(str), &size);
+
+ DestroyWindow(hDlg);
+ DeleteObject(font);
+ DeleteDC(memDC);
+
+ PixelsToDlgUnits((short&)size.cx, (short&)size.cy);
+
+ return size;
+}
+
+// Trims the right margins of a control to fit a given text string size.
+void CDialogTemplate::RTrimToString(WORD id, char *str, int margins) {
+ DialogItemTemplate* item = GetItem(id);
+ if (!item) return;
+
+ SIZE size = GetStringSize(id, str);
+
+ size.cx += margins;
+ size.cy += 2;
+
+ item->sWidth = short(size.cx);
+ item->sHeight = short(size.cy);
+}
+
+// Trims the left margins of a control to fit a given text string size.
+void CDialogTemplate::LTrimToString(WORD id, char *str, int margins) {
+ DialogItemTemplate* item = GetItem(id);
+ if (!item) return;
+
+ SIZE size = GetStringSize(id, str);
+
+ size.cx += margins;
+ size.cy += 2;
+
+ item->sX += item->sWidth - short(size.cx);
+ item->sWidth = short(size.cx);
+ item->sHeight = short(size.cy);
+}
+
+// Trims the left and right margins of a control to fit a given text string size.
+void CDialogTemplate::CTrimToString(WORD id, char *str, int margins) {
+ DialogItemTemplate* item = GetItem(id);
+ if (!item) return;
+
+ SIZE size = GetStringSize(id, str);
+
+ size.cx += margins;
+ size.cy += 2;
+
+ item->sX += item->sWidth/2 - short(size.cx/2);
+ item->sWidth = short(size.cx);
+ item->sHeight = short(size.cy);
+}
+#endif
+
+// Moves every item right and gives it the WS_EX_RIGHT extended style
+void CDialogTemplate::ConvertToRTL() {
+ for (unsigned int i = 0; i < m_vItems.size(); i++) {
+ bool addExStyle = false;
+ char *szClass;
+
+ if (IS_INTRESOURCE(m_vItems[i]->szClass))
+ szClass = (char *) m_vItems[i]->szClass;
+ else
+ szClass = winchar_toansi(m_vItems[i]->szClass);
+
+ // Button
+ if (long(m_vItems[i]->szClass) == 0x80) {
+ m_vItems[i]->dwStyle ^= BS_LEFTTEXT;
+ m_vItems[i]->dwStyle ^= BS_RIGHT;
+ m_vItems[i]->dwStyle ^= BS_LEFT;
+
+ if ((m_vItems[i]->dwStyle & (BS_LEFT|BS_RIGHT)) == (BS_LEFT|BS_RIGHT)) {
+ m_vItems[i]->dwStyle ^= BS_LEFT;
+ m_vItems[i]->dwStyle ^= BS_RIGHT;
+ if (m_vItems[i]->dwStyle & (BS_RADIOBUTTON|BS_CHECKBOX|BS_USERBUTTON)) {
+ m_vItems[i]->dwStyle |= BS_RIGHT;
+ }
+ }
+ }
+ // Edit
+ else if (long(m_vItems[i]->szClass) == 0x81) {
+ if ((m_vItems[i]->dwStyle & ES_CENTER) == 0) {
+ m_vItems[i]->dwStyle ^= ES_RIGHT;
+ }
+ }
+ // Static
+ else if (long(m_vItems[i]->szClass) == 0x82) {
+ if ((m_vItems[i]->dwStyle & SS_TYPEMASK) == SS_LEFT || (m_vItems[i]->dwStyle & SS_TYPEMASK) == SS_LEFTNOWORDWRAP)
+ {
+ m_vItems[i]->dwStyle &= ~SS_TYPEMASK;
+ m_vItems[i]->dwStyle |= SS_RIGHT;
+ }
+ else if ((m_vItems[i]->dwStyle & SS_TYPEMASK) == SS_ICON) {
+ m_vItems[i]->dwStyle |= SS_CENTERIMAGE;
+ }
+ }
+ else if (!IS_INTRESOURCE(m_vItems[i]->szClass) && !stricmp(szClass, "RichEdit20A")) {
+ if ((m_vItems[i]->dwStyle & ES_CENTER) == 0) {
+ m_vItems[i]->dwStyle ^= ES_RIGHT;
+ }
+ }
+ else if (!IS_INTRESOURCE(m_vItems[i]->szClass) && !stricmp(szClass, "SysTreeView32")) {
+ m_vItems[i]->dwStyle |= TVS_RTLREADING;
+ addExStyle = true;
+ }
+ else addExStyle = true;
+
+ if (addExStyle)
+ m_vItems[i]->dwExtStyle |= WS_EX_RIGHT;
+
+ m_vItems[i]->dwExtStyle |= WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR;
+
+ m_vItems[i]->sX = m_sWidth - m_vItems[i]->sWidth - m_vItems[i]->sX;
+
+ if (!IS_INTRESOURCE(m_vItems[i]->szClass))
+ delete [] szClass;
+ }
+ m_dwExtStyle |= WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR;
+}
+
+// Saves the dialog in the form of DLGTEMPLATE[EX]
+BYTE* CDialogTemplate::Save(DWORD& dwSize) {
+ // We need the size first to know how much memory to allocate
+ dwSize = GetSize();
+ BYTE* pbDlg = new BYTE[dwSize];
+ ZeroMemory(pbDlg, dwSize);
+ BYTE* seeker = pbDlg;
+
+ if (m_bExtended) {
+ DLGTEMPLATEEX dh = {
+ ConvertEndianness(WORD(0x0001)),
+ ConvertEndianness(WORD(0xFFFF)),
+ ConvertEndianness(m_dwHelpId),
+ ConvertEndianness(m_dwExtStyle),
+ ConvertEndianness(m_dwStyle),
+ ConvertEndianness(WORD(m_vItems.size())),
+ ConvertEndianness(m_sX),
+ ConvertEndianness(m_sY),
+ ConvertEndianness(m_sWidth),
+ ConvertEndianness(m_sHeight)
+ };
+
+ CopyMemory(seeker, &dh, sizeof(DLGTEMPLATEEX));
+ seeker += sizeof(DLGTEMPLATEEX);
+ }
+ else {
+ DLGTEMPLATE dh = {
+ ConvertEndianness(m_dwStyle),
+ ConvertEndianness(m_dwExtStyle),
+ ConvertEndianness(WORD(m_vItems.size())),
+ ConvertEndianness(m_sX),
+ ConvertEndianness(m_sY),
+ ConvertEndianness(m_sWidth),
+ ConvertEndianness(m_sHeight)
+ };
+
+ CopyMemory(seeker, &dh, sizeof(DLGTEMPLATE));
+ seeker += sizeof(DLGTEMPLATE);
+ }
+
+ // Write menu variant length array
+ WriteStringOrId(m_szMenu);
+ // Write class variant length array
+ WriteStringOrId(m_szClass);
+ // Write title variant length array
+ WriteStringOrId(m_szTitle);
+
+ // Write font variant length array, size, and extended info (if needed)
+ if (m_dwStyle & DS_SETFONT) {
+ *(short*)seeker = ConvertEndianness(m_sFontSize);
+ seeker += sizeof(short);
+ if (m_bExtended) {
+ *(short*)seeker = ConvertEndianness(m_sFontWeight);
+ seeker += sizeof(short);
+ *(BYTE*)seeker = m_bItalic;
+ seeker += sizeof(BYTE);
+ *(BYTE*)seeker = m_bCharset;
+ seeker += sizeof(BYTE);
+ }
+ WriteStringOrId(m_szFont);
+ }
+
+ // Write all of the items
+ for (unsigned int i = 0; i < m_vItems.size(); i++) {
+ // DLGITEMTEMPLATE[EX]s must be aligned on DWORD boundary
+ if (DWORD(seeker - pbDlg) % sizeof(DWORD))
+ seeker += sizeof(WORD);
+
+ if (m_bExtended) {
+ DLGITEMTEMPLATEEX dih = {
+ ConvertEndianness(m_vItems[i]->dwHelpId),
+ ConvertEndianness(m_vItems[i]->dwExtStyle),
+ ConvertEndianness(m_vItems[i]->dwStyle),
+ ConvertEndianness(m_vItems[i]->sX),
+ ConvertEndianness(m_vItems[i]->sY),
+ ConvertEndianness(m_vItems[i]->sWidth),
+ ConvertEndianness(m_vItems[i]->sHeight),
+ ConvertEndianness(m_vItems[i]->wId)
+ };
+
+ CopyMemory(seeker, &dih, sizeof(DLGITEMTEMPLATEEX));
+ seeker += sizeof(DLGITEMTEMPLATEEX);
+ }
+ else {
+ DLGITEMTEMPLATE dih = {
+ ConvertEndianness(m_vItems[i]->dwStyle),
+ ConvertEndianness(m_vItems[i]->dwExtStyle),
+ ConvertEndianness(m_vItems[i]->sX),
+ ConvertEndianness(m_vItems[i]->sY),
+ ConvertEndianness(m_vItems[i]->sWidth),
+ ConvertEndianness(m_vItems[i]->sHeight),
+ ConvertEndianness(m_vItems[i]->wId)
+ };
+
+ CopyMemory(seeker, &dih, sizeof(DLGITEMTEMPLATE));
+ seeker += sizeof(DLGITEMTEMPLATE);
+ }
+
+ // Write class variant length array
+ WriteStringOrId(m_vItems[i]->szClass);
+ // Write title variant length array
+ WriteStringOrId(m_vItems[i]->szTitle);
+
+ // Write creation data variant length array
+ // First write its size
+ WORD wCreateDataSize = m_vItems[i]->wCreateDataSize;
+ if (m_vItems[i]->wCreateDataSize) wCreateDataSize += sizeof(WORD);
+ *(WORD*)seeker = ConvertEndianness(wCreateDataSize);
+ seeker += sizeof(WORD);
+ // If size is nonzero write the data too
+ if (m_vItems[i]->wCreateDataSize) {
+ CopyMemory(seeker, m_vItems[i]->szCreationData, m_vItems[i]->wCreateDataSize);
+ seeker += m_vItems[i]->wCreateDataSize;
+ }
+ }
+
+ assert((DWORD) seeker - (DWORD) pbDlg == dwSize);
+
+ // DONE!
+ return pbDlg;
+}
+
+// Returns the size that the DLGTEMPLATE[EX] will take when saved
+DWORD CDialogTemplate::GetSize() {
+ DWORD dwSize = m_bExtended ? sizeof(DLGTEMPLATEEX) : sizeof(DLGTEMPLATE);
+
+ // Menu
+ AddStringOrIdSize(m_szMenu);
+ // Class
+ AddStringOrIdSize(m_szClass);
+ // Title
+ AddStringOrIdSize(m_szTitle);
+
+ // Font
+ if (m_dwStyle & DS_SETFONT) {
+ dwSize += sizeof(WORD) + (m_bExtended ? sizeof(short) + 2*sizeof(BYTE) : 0);
+ AddStringOrIdSize(m_szFont);
+ }
+
+ for (unsigned int i = 0; i < m_vItems.size(); i++) {
+ // DLGITEMTEMPLATE[EX]s must be aligned on DWORD boundary
+ ALIGN(dwSize, sizeof(DWORD));
+
+ dwSize += m_bExtended ? sizeof(DLGITEMTEMPLATEEX) : sizeof(DLGITEMTEMPLATE);
+
+ // Class
+ AddStringOrIdSize(m_vItems[i]->szClass);
+ // Title
+ AddStringOrIdSize(m_vItems[i]->szTitle);
+
+ dwSize += sizeof(WORD) + m_vItems[i]->wCreateDataSize;
+ }
+
+ return dwSize;
+}
diff --git a/Source/DialogTemplate.h b/Source/DialogTemplate.h
index c6bc58e..918ca23 100755
--- a/Source/DialogTemplate.h
+++ b/Source/DialogTemplate.h
@@ -1,165 +1,165 @@
-/*
- * DialogTemplate.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 2002 Amir Szekely <kichik@netvision.net.il>
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#if !defined(AFX_DIALOGTEMPLATE_H__C5A973AF_0F56_4BEC_814A_79318E2EB4AC__INCLUDED_)
-#define AFX_DIALOGTEMPLATE_H__C5A973AF_0F56_4BEC_814A_79318E2EB4AC__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include "Platform.h"
-
-#include <vector>
-#include <stdexcept>
-
-#ifndef __BIG_ENDIAN__
-# define EXTENDED_DIALOG ((DWORD) 0xFFFF0001)
-#else
-# define EXTENDED_DIALOG ((DWORD) 0x0100FFFF)
-#endif
-
-struct DialogItemTemplate {
- DWORD dwHelpId; // Extended only
-
- short sX;
- short sY;
- short sWidth;
- short sHeight;
- DWORD dwExtStyle;
- DWORD dwStyle;
- WORD wId;
-
- WCHAR *szClass;
- WCHAR *szTitle;
- char *szCreationData;
-
- WORD wCreateDataSize;
-};
-
-#pragma pack(1)
-
-#ifndef _WIN32
-typedef struct {
- DWORD style;
- DWORD dwExtendedStyle;
- WORD cdit;
- short x;
- short y;
- short cx;
- short cy;
-} DLGTEMPLATE;
-#endif
-
-typedef struct {
- WORD dlgVer;
- WORD signature;
- DWORD helpID;
- DWORD exStyle;
- DWORD style;
- WORD cDlgItems;
- short x;
- short y;
- short cx;
- short cy;
-} DLGTEMPLATEEX;
-
-#ifndef _WIN32
-typedef struct {
- DWORD style;
- DWORD dwExtendedStyle;
- short x;
- short y;
- short cx;
- short cy;
- WORD id;
-} DLGITEMTEMPLATE;
-#endif
-
-typedef struct {
- DWORD helpID;
- DWORD exStyle;
- DWORD style;
- short x;
- short y;
- short cx;
- short cy;
- WORD id;
- WORD _miscrosoft_docs_are_wrong;
-} DLGITEMTEMPLATEEX;
-
-#pragma pack()
-
-class CDialogTemplate {
-public:
- CDialogTemplate(BYTE* pbData, unsigned int uCodePage=CP_ACP);
- virtual ~CDialogTemplate();
-
- short GetWidth();
- short GetHeight();
- DialogItemTemplate* GetItem(WORD wId);
- DialogItemTemplate* GetItemByIdx(DWORD i);
- int RemoveItem(WORD wId);
- void SetFont(char* szFaceName, WORD wFontSize);
- void AddItem(DialogItemTemplate item);
-#ifdef _WIN32
- HWND CreateDummyDialog();
-#endif
- void MoveAll(short x, short y);
- void Resize(short x, short y);
-#ifdef _WIN32
- void PixelsToDlgUnits(short& x, short& y);
- void DlgUnitsToPixels(short& x, short& y);
- SIZE GetStringSize(WORD id, char *str);
- void RTrimToString(WORD id, char *str, int margins);
- void LTrimToString(WORD id, char *str, int margins);
- void CTrimToString(WORD id, char *str, int margins);
-#endif
- void ConvertToRTL();
- BYTE* Save(DWORD& dwSize);
- DWORD GetSize();
-
-private:
- bool m_bExtended;
-
- DWORD m_dwHelpId; // Extended only
-
- short m_sX;
- short m_sY;
- short m_sWidth;
- short m_sHeight;
- DWORD m_dwExtStyle;
- DWORD m_dwStyle;
-
- WCHAR *m_szMenu;
- WCHAR *m_szClass;
- WCHAR *m_szTitle;
-
- // Only if DS_FONT style is set
- short m_sFontSize;
- short m_sFontWeight; // Extended only
- BYTE m_bItalic; // Extended only
- BYTE m_bCharset; // Extended only
- WCHAR *m_szFont;
-
- // For (en/de)coding Unicode
- unsigned int m_uCodePage;
-
- // Items vector
- std::vector<DialogItemTemplate*> m_vItems;
-};
-
-#endif // !defined(AFX_DIALOGTEMPLATE_H__C5A973AF_0F56_4BEC_814A_79318E2EB4AC__INCLUDED_)
+/*
+ * DialogTemplate.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 2002 Amir Szekely <kichik@netvision.net.il>
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#if !defined(AFX_DIALOGTEMPLATE_H__C5A973AF_0F56_4BEC_814A_79318E2EB4AC__INCLUDED_)
+#define AFX_DIALOGTEMPLATE_H__C5A973AF_0F56_4BEC_814A_79318E2EB4AC__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "Platform.h"
+
+#include <vector>
+#include <stdexcept>
+
+#ifndef __BIG_ENDIAN__
+# define EXTENDED_DIALOG ((DWORD) 0xFFFF0001)
+#else
+# define EXTENDED_DIALOG ((DWORD) 0x0100FFFF)
+#endif
+
+struct DialogItemTemplate {
+ DWORD dwHelpId; // Extended only
+
+ short sX;
+ short sY;
+ short sWidth;
+ short sHeight;
+ DWORD dwExtStyle;
+ DWORD dwStyle;
+ WORD wId;
+
+ WCHAR *szClass;
+ WCHAR *szTitle;
+ char *szCreationData;
+
+ WORD wCreateDataSize;
+};
+
+#pragma pack(1)
+
+#ifndef _WIN32
+typedef struct {
+ DWORD style;
+ DWORD dwExtendedStyle;
+ WORD cdit;
+ short x;
+ short y;
+ short cx;
+ short cy;
+} DLGTEMPLATE;
+#endif
+
+typedef struct {
+ WORD dlgVer;
+ WORD signature;
+ DWORD helpID;
+ DWORD exStyle;
+ DWORD style;
+ WORD cDlgItems;
+ short x;
+ short y;
+ short cx;
+ short cy;
+} DLGTEMPLATEEX;
+
+#ifndef _WIN32
+typedef struct {
+ DWORD style;
+ DWORD dwExtendedStyle;
+ short x;
+ short y;
+ short cx;
+ short cy;
+ WORD id;
+} DLGITEMTEMPLATE;
+#endif
+
+typedef struct {
+ DWORD helpID;
+ DWORD exStyle;
+ DWORD style;
+ short x;
+ short y;
+ short cx;
+ short cy;
+ WORD id;
+ WORD _miscrosoft_docs_are_wrong;
+} DLGITEMTEMPLATEEX;
+
+#pragma pack()
+
+class CDialogTemplate {
+public:
+ CDialogTemplate(BYTE* pbData, unsigned int uCodePage=CP_ACP);
+ virtual ~CDialogTemplate();
+
+ short GetWidth();
+ short GetHeight();
+ DialogItemTemplate* GetItem(WORD wId);
+ DialogItemTemplate* GetItemByIdx(DWORD i);
+ int RemoveItem(WORD wId);
+ void SetFont(char* szFaceName, WORD wFontSize);
+ void AddItem(DialogItemTemplate item);
+#ifdef _WIN32
+ HWND CreateDummyDialog();
+#endif
+ void MoveAll(short x, short y);
+ void Resize(short x, short y);
+#ifdef _WIN32
+ void PixelsToDlgUnits(short& x, short& y);
+ void DlgUnitsToPixels(short& x, short& y);
+ SIZE GetStringSize(WORD id, char *str);
+ void RTrimToString(WORD id, char *str, int margins);
+ void LTrimToString(WORD id, char *str, int margins);
+ void CTrimToString(WORD id, char *str, int margins);
+#endif
+ void ConvertToRTL();
+ BYTE* Save(DWORD& dwSize);
+ DWORD GetSize();
+
+private:
+ bool m_bExtended;
+
+ DWORD m_dwHelpId; // Extended only
+
+ short m_sX;
+ short m_sY;
+ short m_sWidth;
+ short m_sHeight;
+ DWORD m_dwExtStyle;
+ DWORD m_dwStyle;
+
+ WCHAR *m_szMenu;
+ WCHAR *m_szClass;
+ WCHAR *m_szTitle;
+
+ // Only if DS_FONT style is set
+ short m_sFontSize;
+ short m_sFontWeight; // Extended only
+ BYTE m_bItalic; // Extended only
+ BYTE m_bCharset; // Extended only
+ WCHAR *m_szFont;
+
+ // For (en/de)coding Unicode
+ unsigned int m_uCodePage;
+
+ // Items vector
+ std::vector<DialogItemTemplate*> m_vItems;
+};
+
+#endif // !defined(AFX_DIALOGTEMPLATE_H__C5A973AF_0F56_4BEC_814A_79318E2EB4AC__INCLUDED_)
diff --git a/Source/Platform.h b/Source/Platform.h
index 28d7209..98ef2cf 100755
--- a/Source/Platform.h
+++ b/Source/Platform.h
@@ -1,875 +1,875 @@
-/*
- * Platform.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef ___PLATFORM__H___
-#define ___PLATFORM__H___
-
-// some definitions for non Win32 platforms were taken from MinGW's free Win32 library
-
-// includes
-
-#ifdef _WIN32
-# include <windows.h>
-# include <commctrl.h>
-#else
-# ifndef EXEHEAD
-# include <string.h>
-# include <stdlib.h>
-# endif
-// basic types
-typedef unsigned char BYTE, *PBYTE, *LPBYTE;
-typedef unsigned short WORD, *LPWORD;
-typedef unsigned int DWORD, *LPDWORD;
-typedef short SHORT;
-typedef unsigned short USHORT;
-typedef unsigned int UINT;
-typedef unsigned int UINT32;
-typedef int INT;
-typedef int INT32;
-typedef long LONG;
-typedef unsigned long ULONG;
-typedef long long INT64, LARGE_INTEGER;
-typedef unsigned long long UINT64, ULARGE_INTEGER;
-typedef int BOOL, *LPBOOL;
-typedef short VARIANT_BOOL;
-typedef void VOID;
-typedef void *LPVOID;
-typedef char CHAR, *PCHAR, *LPCH, *PCH, *NPSTR, *LPSTR, *PSTR;
-typedef unsigned char UCHAR;
-typedef const char *LPCCH, *PCSTR, *LPCSTR;
-typedef unsigned short WCHAR, OLECHAR, *PWCHAR, *LPWCH, *PWCH, *NWPSTR, *LPWSTR, *PWSTR, *BSTR;
-typedef const unsigned short *LPCWCH, *PCWCH, *LPCWSTR, *PCWSTR, *LPCOLESTR;
-typedef unsigned int UINT_PTR;
-// basic stuff
-typedef void * HANDLE;
-typedef HANDLE HWND;
-typedef unsigned long HKEY;
-// some gdi
-typedef unsigned long COLORREF;
-typedef unsigned long HBRUSH;
-// bool
-# define FALSE 0
-# define TRUE 1
-// more
-typedef WORD LANGID;
-// ULONGLONG
-#ifdef __GNUC__
-#define _HAVE_INT64
-#define _INTEGRAL_MAX_BITS 64
-#undef __int64
-#define __int64 long long
-#elif defined(__WATCOMC__) && (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64 )
-#define _HAVE_INT64
-#endif /* __GNUC__/__WATCOMC */
-#if defined(_HAVE_INT64) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64)
-typedef __int64 LONGLONG;
-typedef unsigned __int64 DWORDLONG;
-#else
-typedef double LONGLONG,DWORDLONG;
-#endif
-typedef LONGLONG *PLONGLONG;
-typedef DWORDLONG *PDWORDLONG;
-typedef DWORDLONG ULONGLONG,*PULONGLONG;
-#endif
-
-#ifndef __BIG_ENDIAN__
-# define FIX_ENDIAN_INT32_INPLACE(x) ((void)(x))
-# define FIX_ENDIAN_INT32(x) (x)
-# define FIX_ENDIAN_INT16_INPLACE(x) ((void)(x))
-# define FIX_ENDIAN_INT16(x) (x)
-#else
-# define FIX_ENDIAN_INT32_INPLACE(x) ((x) = SWAP_ENDIAN_INT32(x))
-# define FIX_ENDIAN_INT32(x) SWAP_ENDIAN_INT32(x)
-# define FIX_ENDIAN_INT16_INPLACE(x) ((x) = SWAP_ENDIAN_INT16(x))
-# define FIX_ENDIAN_INT16(x) SWAP_ENDIAN_INT16(x)
-#endif
-#define SWAP_ENDIAN_INT32(x) ( \
- (((x)&0xFF000000) >> 24) | \
- (((x)&0x00FF0000) >> 8) | \
- (((x)&0x0000FF00) << 8) | \
- (((x)&0x000000FF) << 24) )
-#define SWAP_ENDIAN_INT16(x) ( \
- (((x)&0xFF00) >> 8) | \
- (((x)&0x00FF) << 8) )
-
-// script path separator
-
-# define PATH_SEPARATOR_STR "\\"
-# define PATH_SEPARATOR_C '\\'
-
-// system specific characters
-
-#ifdef _WIN32
-# define PLATFORM_PATH_SEPARATOR_STR "\\"
-# define PLATFORM_PATH_SEPARATOR_C '\\'
-# define OPT_STR "/"
-# define OPT_C '/'
-# define IS_OPT(a) (a[0]==OPT_C||a[0]=='-')
-#else
-# define PLATFORM_PATH_SEPARATOR_STR "/"
-# define PLATFORM_PATH_SEPARATOR_C '/'
-# define OPT_STR "-"
-# define OPT_C '-'
-# define IS_OPT(a) (a[0]==OPT_C)
-#endif
-
-// attributes
-
-#ifdef _MSC_VER
-# define FORCE_INLINE __forceinline
-#else
-# ifdef __GNUC__
-# if __GNUC__ < 3
-# define FORCE_INLINE inline
-# else
-# define FORCE_INLINE inline __attribute__ ((always_inline))
-# endif
-# else
-# define FORCE_INLINE inline
-# endif
-#endif
-
-// Added by Dave Laundon 19th August 2002
-// For all internal functions, use of stdcall calling convention moves the
-// responsibility for tidying the stack to callee from caller, reducing the code
-// involved considerably. Gives an instant saving of 0.5K.
-// NB - the zlib and bzip2 portions have been given the same treatment, but with
-// project compiler-options settings and/or project-wide defines.
-// NB - safer for NSIS's routines to be defined explicitly to avoid problems
-// calling DLL functions.
-#if defined(_WIN32) && ((_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED))
-# define NSISCALL __stdcall // Ordinary functions
-# define NSISCALLV __cdecl // Variable-argument-list functions
-#else
-# if defined(__GNUC__) && defined(__i386__)
-# define NSISCALL __attribute__((__stdcall__)) // Ordinary functions
-# define NSISCALLV __attribute__((__cdecl__)) // Variable-argument-list functions
-# else
-# define NSISCALL
-# define NSISCALLV
-# endif
-#endif
-
-#if defined(__GNUC__)
-#define UNUSED __attribute__((unused))
-#else
-#define UNUSED
-#endif
-
-// macros
-
-#ifndef _WIN32
-# ifndef FIELD_OFFSET
-# define FIELD_OFFSET(t,f) ((LONG)&(((t*)0)->f))
-# endif
-# ifndef MAKEINTRESOURCEA
-# define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
-# endif
-# ifndef MAKEINTRESOURCEW
-# define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))
-# endif
-# ifndef MAKEINTRESOURCE
-# define MAKEINTRESOURCE MAKEINTRESOURCEA
-# endif
-# ifndef IMAGE_FIRST_SECTION
-# define IMAGE_FIRST_SECTION(h) ( PIMAGE_SECTION_HEADER( (DWORD) h + \
- FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + \
- FIX_ENDIAN_INT16(PIMAGE_NT_HEADERS(h)->FileHeader.SizeOfOptionalHeader) ) )
-# endif
-# ifndef RGB
-# define RGB(r,g,b) ((DWORD)(((BYTE)(r)|((WORD)(g)<<8))|(((DWORD)(BYTE)(b))<<16)))
-# endif
-# ifndef MAKELONG
-# define MAKELONG(a,b) ((LONG)(((WORD)(a))|(((DWORD)((WORD)(b)))<<16)))
-# endif
-#endif
-#ifndef IS_INTRESOURCE
-# define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
-#endif
-
-// functions
-
-#ifndef _WIN32
-# define stricmp strcasecmp
-# define strcmpi strcasecmp
-# define strnicmp strncasecmp
-# define CopyMemory memcpy
-# define ZeroMemory(x, y) memset(x, 0, y)
-#endif
-
-// defines
-
-#ifndef FOF_NOERRORUI
-# define FOF_NOERRORUI 0x0400
-#endif
-
-#ifndef ULONG_PTR
-# define ULONG_PTR DWORD
-#endif
-
-#ifndef IDC_HAND
-# define IDC_HAND MAKEINTRESOURCE(32649)
-#endif
-
-#ifndef BIF_NEWDIALOGSTYLE
-# define BIF_NEWDIALOGSTYLE 0x0040
-#endif
-
-#ifndef TVITEM
-# define TVITEM TV_ITEM
-#endif
-
-#ifndef TVM_SETITEMHEIGHT
-# define TVM_SETITEMHEIGHT (TV_FIRST + 27)
-#endif
-
-#ifndef TVM_GETITEMHEIGHT
-# define TVM_GETITEMHEIGHT (TV_FIRST + 28)
-#endif
-
-#ifndef LVS_EX_LABELTIP
-# define LVS_EX_LABELTIP 0x00004000
-#endif
-
-#ifndef EXEHEAD
-# ifndef SF_TEXT
-# define SF_TEXT 1
-# endif
-# ifndef SF_RTF
-# define SF_RTF 2
-# endif
-#endif
-
-#ifdef __GNUC__
-# undef INVALID_FILE_ATTRIBUTES
-#endif
-#ifndef INVALID_FILE_ATTRIBUTES
-# define INVALID_FILE_ATTRIBUTES ((unsigned long) -1)
-#endif
-
-// shell folders
-
-#ifdef _WIN32
-# include <shlobj.h>
-#endif
-
-#ifndef CSIDL_FLAG_CREATE
-# define CSIDL_FLAG_CREATE 0x8000
-#endif
-
-#ifndef CSIDL_PROGRAMS
-# define CSIDL_PROGRAMS 0x2
-#endif
-#ifndef CSIDL_COMMON_PROGRAMS
-# define CSIDL_COMMON_PROGRAMS 0x17
-#endif
-#ifndef CSIDL_PRINTERS
-# define CSIDL_PRINTERS 0x4
-#endif
-#ifndef CSIDL_PERSONAL
-# define CSIDL_PERSONAL 0x5
-#endif
-#ifndef CSIDL_COMMON_DOCUMENTS
-# define CSIDL_COMMON_DOCUMENTS 0x2E
-#endif
-#ifndef CSIDL_FAVORITES
-# define CSIDL_FAVORITES 0x6
-#endif
-#ifndef CSIDL_COMMON_FAVORITES
-# define CSIDL_COMMON_FAVORITES 0x1F
-#endif
-#ifndef CSIDL_STARTUP
-# define CSIDL_STARTUP 0x7
-#endif
-#ifndef CSIDL_COMMON_STARTUP
-# define CSIDL_COMMON_STARTUP 0x18
-#endif
-#ifndef CSIDL_RECENT
-# define CSIDL_RECENT 0x8
-#endif
-#ifndef CSIDL_SENDTO
-# define CSIDL_SENDTO 0x9
-#endif
-#ifndef CSIDL_STARTMENU
-# define CSIDL_STARTMENU 0xB
-#endif
-#ifndef CSIDL_COMMON_STARTMENU
-# define CSIDL_COMMON_STARTMENU 0x16
-#endif
-#ifndef CSIDL_DESKTOPDIRECTORY
-# define CSIDL_DESKTOPDIRECTORY 0x10
-#endif
-#ifndef CSIDL_COMMON_DESKTOPDIRECTORY
-# define CSIDL_COMMON_DESKTOPDIRECTORY 0x19
-#endif
-#ifndef CSIDL_NETHOOD
-# define CSIDL_NETHOOD 0x13
-#endif
-#ifndef CSIDL_FONTS
-# define CSIDL_FONTS 0x14
-#endif
-#ifndef CSIDL_TEMPLATES
-# define CSIDL_TEMPLATES 0x15
-#endif
-#ifndef CSIDL_COMMON_TEMPLATES
-# define CSIDL_COMMON_TEMPLATES 0x2D
-#endif
-#ifndef CSIDL_APPDATA
-# define CSIDL_APPDATA 0x1A
-#endif
-#ifndef CSIDL_COMMON_APPDATA
-# define CSIDL_COMMON_APPDATA 0x23
-#endif
-#ifndef CSIDL_LOCAL_APPDATA
-# define CSIDL_LOCAL_APPDATA 0x1C
-#endif
-#ifndef CSIDL_PRINTHOOD
-# define CSIDL_PRINTHOOD 0x1B
-#endif
-#ifndef CSIDL_ALTSTARTUP
-# define CSIDL_ALTSTARTUP 0x1D
-#endif
-#ifndef CSIDL_COMMON_ALTSTARTUP
-# define CSIDL_COMMON_ALTSTARTUP 0x1E
-#endif
-#ifndef CSIDL_INTERNET_CACHE
-# define CSIDL_INTERNET_CACHE 0x20
-#endif
-#ifndef CSIDL_COOKIES
-# define CSIDL_COOKIES 0x21
-#endif
-#ifndef CSIDL_HISTORY
-# define CSIDL_HISTORY 0x22
-#endif
-#ifndef CSIDL_WINDOWS
-# define CSIDL_WINDOWS 0x24
-#endif
-#ifndef CSIDL_SYSTEM
-# define CSIDL_SYSTEM 0x25
-#endif
-#ifndef CSIDL_PROGRAM_FILES
-# define CSIDL_PROGRAM_FILES 0x26
-#endif
-#ifndef CSIDL_PROGRAM_FILES_COMMON
-# define CSIDL_PROGRAM_FILES_COMMON 0x2B
-#endif
-#ifndef CSIDL_MYPICTURES
-# define CSIDL_MYPICTURES 0x27
-#endif
-#ifndef CSIDL_COMMON_PICTURES
-# define CSIDL_COMMON_PICTURES 0x36
-#endif
-#ifndef CSIDL_PROFILE
-# define CSIDL_PROFILE 0x28
-#endif
-#ifndef CSIDL_ADMINTOOLS
-# define CSIDL_ADMINTOOLS 0x30
-#endif
-#ifndef CSIDL_COMMON_ADMINTOOLS
-# define CSIDL_COMMON_ADMINTOOLS 0x2F
-#endif
-#ifndef CSIDL_MYMUSIC
-# define CSIDL_MYMUSIC 0xD
-#endif
-#ifndef CSIDL_COMMON_MUSIC
-# define CSIDL_COMMON_MUSIC 0x35
-#endif
-#ifndef CSIDL_MYVIDEO
-# define CSIDL_MYVIDEO 0xE
-#endif
-#ifndef CSIDL_COMMON_VIDEO
-# define CSIDL_COMMON_VIDEO 0x37
-#endif
-#ifndef CSIDL_RESOURCES
-# define CSIDL_RESOURCES 0x38
-#endif
-#ifndef CSIDL_RESOURCES_LOCALIZED
-# define CSIDL_RESOURCES_LOCALIZED 0x39
-#endif
-#ifndef CSIDL_CDBURN_AREA
-# define CSIDL_CDBURN_AREA 0x3B
-#endif
-
-// other shell stuff
-
-#ifndef SHACF_FILESYSTEM
-# define SHACF_FILESYSTEM 1
-#endif
-
-// other stuff
-
-#ifndef CP_ACP
-# define CP_ACP 0
-#endif
-
-#ifndef COLOR_BTNFACE
-# define COLOR_BTNFACE 15
-#endif
-#ifndef COLOR_WINDOW
-# define COLOR_WINDOW 5
-#endif
-
-// resources
-
-#ifndef RT_BITMAP
-# define RT_BITMAP MAKEINTRESOURCE(2)
-#endif
-#ifndef RT_ICON
-# define RT_ICON MAKEINTRESOURCE(3)
-#endif
-#ifndef RT_DIALOG
-# define RT_DIALOG MAKEINTRESOURCE(5)
-#endif
-#ifndef RT_GROUP_ICON
-# define RT_GROUP_ICON MAKEINTRESOURCE(14)
-#endif
-#ifndef RT_VERSION
-# define RT_VERSION MAKEINTRESOURCE(16)
-#endif
-
-// version
-
-#ifndef VS_FILE_INFO
-# define VS_FILE_INFO RT_VERSION
-#endif
-#ifndef VS_VERSION_INFO
-# define VS_VERSION_INFO 1
-#endif
-#ifndef VS_FFI_SIGNATURE
-# define VS_FFI_SIGNATURE 0xFEEF04BD
-#endif
-
-// message box
-
-#ifndef MB_OK
-# define MB_OK 0
-# define MB_OKCANCEL 1
-# define MB_ABORTRETRYIGNORE 2
-# define MB_YESNOCANCEL 3
-# define MB_YESNO 4
-# define MB_RETRYCANCEL 5
-# define MB_DEFBUTTON1 0
-# define MB_DEFBUTTON2 256
-# define MB_DEFBUTTON3 512
-# define MB_DEFBUTTON4 768
-# define MB_ICONSTOP 16
-# define MB_ICONQUESTION 32
-# define MB_ICONEXCLAMATION 48
-# define MB_ICONINFORMATION 64
-# define MB_USERICON 128
-# define MB_SETFOREGROUND 0x10000
-# define MB_TOPMOST 0x40000
-# define MB_RIGHT 0x80000
-# define MB_RTLREADING 0x100000
-#endif
-
-#ifndef IDOK
-# define IDOK 1
-# define IDCANCEL 2
-# define IDABORT 3
-# define IDRETRY 4
-# define IDIGNORE 5
-# define IDYES 6
-# define IDNO 7
-#endif
-
-// window styles
-
-#ifndef _WIN32
-# define WS_CHILD 0x40000000
-# define WS_VISIBLE 0x10000000
-
-# define BS_CHECKBOX 2
-# define BS_LEFT 256
-# define BS_LEFTTEXT 32
-# define BS_RADIOBUTTON 4
-# define BS_RIGHT 512
-# define BS_USERBUTTON 8
-
-# define ES_LEFT 0
-# define ES_CENTER 1
-# define ES_RIGHT 2
-
-# define SS_BITMAP 14
-# define SS_CENTER 1
-# define SS_CENTERIMAGE 512
-# define SS_ICON 3
-# define SS_LEFT 0
-# define SS_LEFTNOWORDWRAP 0xc
-# define SS_RIGHT 2
-# define SS_RIGHTJUST 0x400
-# define SS_USERITEM 10
-# define SS_TYPEMASK 0x0000001FL
-
-# define DS_FIXEDSYS 8
-# define DS_SETFONT 64
-
-# define WS_EX_RIGHT 0x1000
-# define WS_EX_RIGHTSCROLLBAR 0
-# define WS_EX_RTLREADING 0x2000
-# define WS_EX_LEFTSCROLLBAR 0x4000
-
-# define TVS_RTLREADING 64
-
-# define PBS_SMOOTH 1
-#endif
-
-#ifndef DS_SHELLFONT
-# define DS_SHELLFONT (DS_SETFONT | DS_FIXEDSYS)
-#endif
-
-// brush styles
-
-#ifndef BS_SOLID
-# define BS_SOLID 0
-#endif
-#ifndef BS_NULL
-# define BS_NULL 1
-#endif
-
-// reg
-#ifndef HKEY_CLASSES_ROOT
-# define HKEY_CLASSES_ROOT ((HKEY)0x80000000)
-# define HKEY_CURRENT_USER ((HKEY)0x80000001)
-# define HKEY_LOCAL_MACHINE ((HKEY)0x80000002)
-# define HKEY_USERS ((HKEY)0x80000003)
-# define HKEY_PERFORMANCE_DATA ((HKEY)0x80000004)
-# define HKEY_CURRENT_CONFIG ((HKEY)0x80000005)
-# define HKEY_DYN_DATA ((HKEY)0x80000006)
-#endif
-
-#ifndef KEY_WOW64_64KEY
-# define KEY_WOW64_64KEY 0x100
-#endif
-
-// show modes
-
-#ifndef SW_SHOWNORMAL
-# define SW_HIDE 0
-# define SW_SHOWNORMAL 1
-# define SW_SHOWMINIMIZED 2
-# define SW_SHOWMAXIMIZED 3
-# define SW_SHOWNOACTIVATE 4
-# define SW_SHOWMINNOACTIVE 7
-# define SW_SHOWNA 8
-#endif
-
-// hotkeys
-
-#ifndef HOTKEYF_SHIFT
-# define HOTKEYF_SHIFT 1
-# define HOTKEYF_CONTROL 2
-# define HOTKEYF_ALT 4
-# define HOTKEYF_EXT 8
-#endif
-
-// vk
-#ifndef VK_F1
-# define VK_F1 0x70
-#endif
-
-// gdi
-
-#ifndef OPAQUE
-# define OPAQUE 2
-#endif
-#ifndef TRANSPARENT
-# define TRANSPARENT 1
-#endif
-#ifndef LF_FACESIZE
-# define LF_FACESIZE 32
-#endif
-#ifndef FW_NORMAL
-# define FW_NORMAL 400
-#endif
-#ifndef FW_BOLD
-# define FW_BOLD 700
-#endif
-#ifndef DEFAULT_CHARSET
-# define DEFAULT_CHARSET 1
-#endif
-#ifndef OUT_DEFAULT_PRECIS
-# define OUT_DEFAULT_PRECIS 0
-#endif
-#ifndef CLIP_DEFAULT_PRECIS
-# define CLIP_DEFAULT_PRECIS 0
-#endif
-#ifndef DEFAULT_QUALITY
-# define DEFAULT_QUALITY 0
-#endif
-#ifndef DEFAULT_PITCH
-# define DEFAULT_PITCH 0
-#endif
-
-// file ops
-
-#ifndef FOF_SILENT
-# define FOF_SILENT 4
-# define FOF_NOCONFIRMATION 16
-# define FOF_FILESONLY 128
-# define FOF_SIMPLEPROGRESS 256
-# define FOF_NOCONFIRMMKDIR 512
-#endif
-
-// file attribs
-
-#ifndef FILE_ATTRIBUTE_READONLY
-# define FILE_ATTRIBUTE_READONLY 0x00000001
-# define FILE_ATTRIBUTE_HIDDEN 0x00000002
-# define FILE_ATTRIBUTE_SYSTEM 0x00000004
-# define FILE_ATTRIBUTE_ARCHIVE 0x00000020
-# define FILE_ATTRIBUTE_NORMAL 0x00000080
-# define FILE_ATTRIBUTE_TEMPORARY 0x00000100
-# define FILE_ATTRIBUTE_OFFLINE 0x00001000
-#endif
-
-// registry
-
-#ifndef REG_SZ
-# define REG_SZ 1
-# define REG_EXPAND_SZ 2
-# define REG_BINARY 3
-# define REG_DWORD 4
-#endif
-
-// fopen
-#ifndef GENERIC_READ
-# define GENERIC_READ 0x80000000
-# define GENERIC_WRITE 0x40000000
-#endif
-
-#ifndef CREATE_NEW
-# define CREATE_NEW 1
-# define CREATE_ALWAYS 2
-# define OPEN_EXISTING 3
-# define OPEN_ALWAYS 4
-#endif
-
-// fseek
-
-#ifndef FILE_BEGIN
-# define FILE_BEGIN 0
-# define FILE_CURRENT 1
-# define FILE_END 2
-#endif
-
-// PE
-
-#ifndef _WIN32
-# define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
-# ifndef __BIG_ENDIAN__
-# define IMAGE_DOS_SIGNATURE 0x5A4D
-# define IMAGE_NT_SIGNATURE 0x00004550
-# else
-# define IMAGE_DOS_SIGNATURE 0x4D5A
-# define IMAGE_NT_SIGNATURE 0x50450000
-# endif
-# define IMAGE_FILE_DLL 8192
-# define IMAGE_DIRECTORY_ENTRY_EXPORT 0
-# define IMAGE_SIZEOF_SHORT_NAME 8
-#endif
-
-// structures
-
-#ifndef _WIN32
-typedef struct _LOGFONT {
- LONG lfHeight;
- LONG lfWidth;
- LONG lfEscapement;
- LONG lfOrientation;
- LONG lfWeight;
- BYTE lfItalic;
- BYTE lfUnderline;
- BYTE lfStrikeOut;
- BYTE lfCharSet;
- BYTE lfOutPrecision;
- BYTE lfClipPrecision;
- BYTE lfQuality;
- BYTE lfPitchAndFamily;
- CHAR lfFaceName[LF_FACESIZE];
-} LOGFONT;
-# pragma pack(2)
-typedef struct _IMAGE_DOS_HEADER {
- WORD e_magic;
- WORD e_cblp;
- WORD e_cp;
- WORD e_crlc;
- WORD e_cparhdr;
- WORD e_minalloc;
- WORD e_maxalloc;
- WORD e_ss;
- WORD e_sp;
- WORD e_csum;
- WORD e_ip;
- WORD e_cs;
- WORD e_lfarlc;
- WORD e_ovno;
- WORD e_res[4];
- WORD e_oemid;
- WORD e_oeminfo;
- WORD e_res2[10];
- LONG e_lfanew;
-} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
-# pragma pack()
-# pragma pack(4)
-typedef struct _IMAGE_FILE_HEADER {
- WORD Machine;
- WORD NumberOfSections;
- DWORD TimeDateStamp;
- DWORD PointerToSymbolTable;
- DWORD NumberOfSymbols;
- WORD SizeOfOptionalHeader;
- WORD Characteristics;
-} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
-typedef struct _IMAGE_DATA_DIRECTORY {
- DWORD VirtualAddress;
- DWORD Size;
-} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
-typedef struct _IMAGE_OPTIONAL_HEADER {
- WORD Magic;
- BYTE MajorLinkerVersion;
- BYTE MinorLinkerVersion;
- DWORD SizeOfCode;
- DWORD SizeOfInitializedData;
- DWORD SizeOfUninitializedData;
- DWORD AddressOfEntryPoint;
- DWORD BaseOfCode;
- DWORD BaseOfData;
- DWORD ImageBase;
- DWORD SectionAlignment;
- DWORD FileAlignment;
- WORD MajorOperatingSystemVersion;
- WORD MinorOperatingSystemVersion;
- WORD MajorImageVersion;
- WORD MinorImageVersion;
- WORD MajorSubsystemVersion;
- WORD MinorSubsystemVersion;
- DWORD Reserved1;
- DWORD SizeOfImage;
- DWORD SizeOfHeaders;
- DWORD CheckSum;
- WORD Subsystem;
- WORD DllCharacteristics;
- DWORD SizeOfStackReserve;
- DWORD SizeOfStackCommit;
- DWORD SizeOfHeapReserve;
- DWORD SizeOfHeapCommit;
- DWORD LoaderFlags;
- DWORD NumberOfRvaAndSizes;
- IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
-} IMAGE_OPTIONAL_HEADER32,*PIMAGE_OPTIONAL_HEADER32;
-typedef struct _IMAGE_OPTIONAL_HEADER64 {
- WORD Magic;
- BYTE MajorLinkerVersion;
- BYTE MinorLinkerVersion;
- DWORD SizeOfCode;
- DWORD SizeOfInitializedData;
- DWORD SizeOfUninitializedData;
- DWORD AddressOfEntryPoint;
- DWORD BaseOfCode;
- ULONGLONG ImageBase;
- DWORD SectionAlignment;
- DWORD FileAlignment;
- WORD MajorOperatingSystemVersion;
- WORD MinorOperatingSystemVersion;
- WORD MajorImageVersion;
- WORD MinorImageVersion;
- WORD MajorSubsystemVersion;
- WORD MinorSubsystemVersion;
- DWORD Win32VersionValue;
- DWORD SizeOfImage;
- DWORD SizeOfHeaders;
- DWORD CheckSum;
- WORD Subsystem;
- WORD DllCharacteristics;
- ULONGLONG SizeOfStackReserve;
- ULONGLONG SizeOfStackCommit;
- ULONGLONG SizeOfHeapReserve;
- ULONGLONG SizeOfHeapCommit;
- DWORD LoaderFlags;
- DWORD NumberOfRvaAndSizes;
- IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
-} IMAGE_OPTIONAL_HEADER64,*PIMAGE_OPTIONAL_HEADER64;
-#ifdef _WIN64
-typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER;
-typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER;
-#else
-typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER;
-typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER;
-#endif
-#ifndef __BIG_ENDIAN__
-# define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
-# define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
-#else
-# define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x0b01
-# define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x0b02
-#endif
-typedef struct _IMAGE_NT_HEADERS {
- DWORD Signature;
- IMAGE_FILE_HEADER FileHeader;
- IMAGE_OPTIONAL_HEADER OptionalHeader;
-} IMAGE_NT_HEADERS,*PIMAGE_NT_HEADERS;
-typedef struct _IMAGE_SECTION_HEADER {
- BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
- union {
- DWORD PhysicalAddress;
- DWORD VirtualSize;
- } Misc;
- DWORD VirtualAddress;
- DWORD SizeOfRawData;
- DWORD PointerToRawData;
- DWORD PointerToRelocations;
- DWORD PointerToLinenumbers;
- WORD NumberOfRelocations;
- WORD NumberOfLinenumbers;
- DWORD Characteristics;
-} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
-typedef struct _IMAGE_EXPORT_DIRECTORY {
- DWORD Characteristics;
- DWORD TimeDateStamp;
- WORD MajorVersion;
- WORD MinorVersion;
- DWORD Name;
- DWORD Base;
- DWORD NumberOfFunctions;
- DWORD NumberOfNames;
- DWORD AddressOfFunctions;
- DWORD AddressOfNames;
- DWORD AddressOfNameOrdinals;
-} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
-typedef struct tagVS_FIXEDFILEINFO {
- DWORD dwSignature;
- DWORD dwStrucVersion;
- DWORD dwFileVersionMS;
- DWORD dwFileVersionLS;
- DWORD dwProductVersionMS;
- DWORD dwProductVersionLS;
- DWORD dwFileFlagsMask;
- DWORD dwFileFlags;
- DWORD dwFileOS;
- DWORD dwFileType;
- DWORD dwFileSubtype;
- DWORD dwFileDateMS;
- DWORD dwFileDateLS;
-} VS_FIXEDFILEINFO;
-# pragma pack()
-#endif
-
-#ifndef SHGFP_TYPE_CURRENT
- #define SHGFP_TYPE_CURRENT 0
-#endif
-
-#endif
+/*
+ * Platform.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef ___PLATFORM__H___
+#define ___PLATFORM__H___
+
+// some definitions for non Win32 platforms were taken from MinGW's free Win32 library
+
+// includes
+
+#ifdef _WIN32
+# include <windows.h>
+# include <commctrl.h>
+#else
+# ifndef EXEHEAD
+# include <string.h>
+# include <stdlib.h>
+# endif
+// basic types
+typedef unsigned char BYTE, *PBYTE, *LPBYTE;
+typedef unsigned short WORD, *LPWORD;
+typedef unsigned int DWORD, *LPDWORD;
+typedef short SHORT;
+typedef unsigned short USHORT;
+typedef unsigned int UINT;
+typedef unsigned int UINT32;
+typedef int INT;
+typedef int INT32;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef long long INT64, LARGE_INTEGER;
+typedef unsigned long long UINT64, ULARGE_INTEGER;
+typedef int BOOL, *LPBOOL;
+typedef short VARIANT_BOOL;
+typedef void VOID;
+typedef void *LPVOID;
+typedef char CHAR, *PCHAR, *LPCH, *PCH, *NPSTR, *LPSTR, *PSTR;
+typedef unsigned char UCHAR;
+typedef const char *LPCCH, *PCSTR, *LPCSTR;
+typedef unsigned short WCHAR, OLECHAR, *PWCHAR, *LPWCH, *PWCH, *NWPSTR, *LPWSTR, *PWSTR, *BSTR;
+typedef const unsigned short *LPCWCH, *PCWCH, *LPCWSTR, *PCWSTR, *LPCOLESTR;
+typedef unsigned int UINT_PTR;
+// basic stuff
+typedef void * HANDLE;
+typedef HANDLE HWND;
+typedef unsigned long HKEY;
+// some gdi
+typedef unsigned long COLORREF;
+typedef unsigned long HBRUSH;
+// bool
+# define FALSE 0
+# define TRUE 1
+// more
+typedef WORD LANGID;
+// ULONGLONG
+#ifdef __GNUC__
+#define _HAVE_INT64
+#define _INTEGRAL_MAX_BITS 64
+#undef __int64
+#define __int64 long long
+#elif defined(__WATCOMC__) && (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64 )
+#define _HAVE_INT64
+#endif /* __GNUC__/__WATCOMC */
+#if defined(_HAVE_INT64) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64)
+typedef __int64 LONGLONG;
+typedef unsigned __int64 DWORDLONG;
+#else
+typedef double LONGLONG,DWORDLONG;
+#endif
+typedef LONGLONG *PLONGLONG;
+typedef DWORDLONG *PDWORDLONG;
+typedef DWORDLONG ULONGLONG,*PULONGLONG;
+#endif
+
+#ifndef __BIG_ENDIAN__
+# define FIX_ENDIAN_INT32_INPLACE(x) ((void)(x))
+# define FIX_ENDIAN_INT32(x) (x)
+# define FIX_ENDIAN_INT16_INPLACE(x) ((void)(x))
+# define FIX_ENDIAN_INT16(x) (x)
+#else
+# define FIX_ENDIAN_INT32_INPLACE(x) ((x) = SWAP_ENDIAN_INT32(x))
+# define FIX_ENDIAN_INT32(x) SWAP_ENDIAN_INT32(x)
+# define FIX_ENDIAN_INT16_INPLACE(x) ((x) = SWAP_ENDIAN_INT16(x))
+# define FIX_ENDIAN_INT16(x) SWAP_ENDIAN_INT16(x)
+#endif
+#define SWAP_ENDIAN_INT32(x) ( \
+ (((x)&0xFF000000) >> 24) | \
+ (((x)&0x00FF0000) >> 8) | \
+ (((x)&0x0000FF00) << 8) | \
+ (((x)&0x000000FF) << 24) )
+#define SWAP_ENDIAN_INT16(x) ( \
+ (((x)&0xFF00) >> 8) | \
+ (((x)&0x00FF) << 8) )
+
+// script path separator
+
+# define PATH_SEPARATOR_STR "\\"
+# define PATH_SEPARATOR_C '\\'
+
+// system specific characters
+
+#ifdef _WIN32
+# define PLATFORM_PATH_SEPARATOR_STR "\\"
+# define PLATFORM_PATH_SEPARATOR_C '\\'
+# define OPT_STR "/"
+# define OPT_C '/'
+# define IS_OPT(a) (a[0]==OPT_C||a[0]=='-')
+#else
+# define PLATFORM_PATH_SEPARATOR_STR "/"
+# define PLATFORM_PATH_SEPARATOR_C '/'
+# define OPT_STR "-"
+# define OPT_C '-'
+# define IS_OPT(a) (a[0]==OPT_C)
+#endif
+
+// attributes
+
+#ifdef _MSC_VER
+# define FORCE_INLINE __forceinline
+#else
+# ifdef __GNUC__
+# if __GNUC__ < 3
+# define FORCE_INLINE inline
+# else
+# define FORCE_INLINE inline __attribute__ ((always_inline))
+# endif
+# else
+# define FORCE_INLINE inline
+# endif
+#endif
+
+// Added by Dave Laundon 19th August 2002
+// For all internal functions, use of stdcall calling convention moves the
+// responsibility for tidying the stack to callee from caller, reducing the code
+// involved considerably. Gives an instant saving of 0.5K.
+// NB - the zlib and bzip2 portions have been given the same treatment, but with
+// project compiler-options settings and/or project-wide defines.
+// NB - safer for NSIS's routines to be defined explicitly to avoid problems
+// calling DLL functions.
+#if defined(_WIN32) && ((_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED))
+# define NSISCALL __stdcall // Ordinary functions
+# define NSISCALLV __cdecl // Variable-argument-list functions
+#else
+# if defined(__GNUC__) && defined(__i386__)
+# define NSISCALL __attribute__((__stdcall__)) // Ordinary functions
+# define NSISCALLV __attribute__((__cdecl__)) // Variable-argument-list functions
+# else
+# define NSISCALL
+# define NSISCALLV
+# endif
+#endif
+
+#if defined(__GNUC__)
+#define UNUSED __attribute__((unused))
+#else
+#define UNUSED
+#endif
+
+// macros
+
+#ifndef _WIN32
+# ifndef FIELD_OFFSET
+# define FIELD_OFFSET(t,f) ((LONG)&(((t*)0)->f))
+# endif
+# ifndef MAKEINTRESOURCEA
+# define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
+# endif
+# ifndef MAKEINTRESOURCEW
+# define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))
+# endif
+# ifndef MAKEINTRESOURCE
+# define MAKEINTRESOURCE MAKEINTRESOURCEA
+# endif
+# ifndef IMAGE_FIRST_SECTION
+# define IMAGE_FIRST_SECTION(h) ( PIMAGE_SECTION_HEADER( (DWORD) h + \
+ FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + \
+ FIX_ENDIAN_INT16(PIMAGE_NT_HEADERS(h)->FileHeader.SizeOfOptionalHeader) ) )
+# endif
+# ifndef RGB
+# define RGB(r,g,b) ((DWORD)(((BYTE)(r)|((WORD)(g)<<8))|(((DWORD)(BYTE)(b))<<16)))
+# endif
+# ifndef MAKELONG
+# define MAKELONG(a,b) ((LONG)(((WORD)(a))|(((DWORD)((WORD)(b)))<<16)))
+# endif
+#endif
+#ifndef IS_INTRESOURCE
+# define IS_INTRESOURCE(_r) (((ULONG_PTR)(_r) >> 16) == 0)
+#endif
+
+// functions
+
+#ifndef _WIN32
+# define stricmp strcasecmp
+# define strcmpi strcasecmp
+# define strnicmp strncasecmp
+# define CopyMemory memcpy
+# define ZeroMemory(x, y) memset(x, 0, y)
+#endif
+
+// defines
+
+#ifndef FOF_NOERRORUI
+# define FOF_NOERRORUI 0x0400
+#endif
+
+#ifndef ULONG_PTR
+# define ULONG_PTR DWORD
+#endif
+
+#ifndef IDC_HAND
+# define IDC_HAND MAKEINTRESOURCE(32649)
+#endif
+
+#ifndef BIF_NEWDIALOGSTYLE
+# define BIF_NEWDIALOGSTYLE 0x0040
+#endif
+
+#ifndef TVITEM
+# define TVITEM TV_ITEM
+#endif
+
+#ifndef TVM_SETITEMHEIGHT
+# define TVM_SETITEMHEIGHT (TV_FIRST + 27)
+#endif
+
+#ifndef TVM_GETITEMHEIGHT
+# define TVM_GETITEMHEIGHT (TV_FIRST + 28)
+#endif
+
+#ifndef LVS_EX_LABELTIP
+# define LVS_EX_LABELTIP 0x00004000
+#endif
+
+#ifndef EXEHEAD
+# ifndef SF_TEXT
+# define SF_TEXT 1
+# endif
+# ifndef SF_RTF
+# define SF_RTF 2
+# endif
+#endif
+
+#ifdef __GNUC__
+# undef INVALID_FILE_ATTRIBUTES
+#endif
+#ifndef INVALID_FILE_ATTRIBUTES
+# define INVALID_FILE_ATTRIBUTES ((unsigned long) -1)
+#endif
+
+// shell folders
+
+#ifdef _WIN32
+# include <shlobj.h>
+#endif
+
+#ifndef CSIDL_FLAG_CREATE
+# define CSIDL_FLAG_CREATE 0x8000
+#endif
+
+#ifndef CSIDL_PROGRAMS
+# define CSIDL_PROGRAMS 0x2
+#endif
+#ifndef CSIDL_COMMON_PROGRAMS
+# define CSIDL_COMMON_PROGRAMS 0x17
+#endif
+#ifndef CSIDL_PRINTERS
+# define CSIDL_PRINTERS 0x4
+#endif
+#ifndef CSIDL_PERSONAL
+# define CSIDL_PERSONAL 0x5
+#endif
+#ifndef CSIDL_COMMON_DOCUMENTS
+# define CSIDL_COMMON_DOCUMENTS 0x2E
+#endif
+#ifndef CSIDL_FAVORITES
+# define CSIDL_FAVORITES 0x6
+#endif
+#ifndef CSIDL_COMMON_FAVORITES
+# define CSIDL_COMMON_FAVORITES 0x1F
+#endif
+#ifndef CSIDL_STARTUP
+# define CSIDL_STARTUP 0x7
+#endif
+#ifndef CSIDL_COMMON_STARTUP
+# define CSIDL_COMMON_STARTUP 0x18
+#endif
+#ifndef CSIDL_RECENT
+# define CSIDL_RECENT 0x8
+#endif
+#ifndef CSIDL_SENDTO
+# define CSIDL_SENDTO 0x9
+#endif
+#ifndef CSIDL_STARTMENU
+# define CSIDL_STARTMENU 0xB
+#endif
+#ifndef CSIDL_COMMON_STARTMENU
+# define CSIDL_COMMON_STARTMENU 0x16
+#endif
+#ifndef CSIDL_DESKTOPDIRECTORY
+# define CSIDL_DESKTOPDIRECTORY 0x10
+#endif
+#ifndef CSIDL_COMMON_DESKTOPDIRECTORY
+# define CSIDL_COMMON_DESKTOPDIRECTORY 0x19
+#endif
+#ifndef CSIDL_NETHOOD
+# define CSIDL_NETHOOD 0x13
+#endif
+#ifndef CSIDL_FONTS
+# define CSIDL_FONTS 0x14
+#endif
+#ifndef CSIDL_TEMPLATES
+# define CSIDL_TEMPLATES 0x15
+#endif
+#ifndef CSIDL_COMMON_TEMPLATES
+# define CSIDL_COMMON_TEMPLATES 0x2D
+#endif
+#ifndef CSIDL_APPDATA
+# define CSIDL_APPDATA 0x1A
+#endif
+#ifndef CSIDL_COMMON_APPDATA
+# define CSIDL_COMMON_APPDATA 0x23
+#endif
+#ifndef CSIDL_LOCAL_APPDATA
+# define CSIDL_LOCAL_APPDATA 0x1C
+#endif
+#ifndef CSIDL_PRINTHOOD
+# define CSIDL_PRINTHOOD 0x1B
+#endif
+#ifndef CSIDL_ALTSTARTUP
+# define CSIDL_ALTSTARTUP 0x1D
+#endif
+#ifndef CSIDL_COMMON_ALTSTARTUP
+# define CSIDL_COMMON_ALTSTARTUP 0x1E
+#endif
+#ifndef CSIDL_INTERNET_CACHE
+# define CSIDL_INTERNET_CACHE 0x20
+#endif
+#ifndef CSIDL_COOKIES
+# define CSIDL_COOKIES 0x21
+#endif
+#ifndef CSIDL_HISTORY
+# define CSIDL_HISTORY 0x22
+#endif
+#ifndef CSIDL_WINDOWS
+# define CSIDL_WINDOWS 0x24
+#endif
+#ifndef CSIDL_SYSTEM
+# define CSIDL_SYSTEM 0x25
+#endif
+#ifndef CSIDL_PROGRAM_FILES
+# define CSIDL_PROGRAM_FILES 0x26
+#endif
+#ifndef CSIDL_PROGRAM_FILES_COMMON
+# define CSIDL_PROGRAM_FILES_COMMON 0x2B
+#endif
+#ifndef CSIDL_MYPICTURES
+# define CSIDL_MYPICTURES 0x27
+#endif
+#ifndef CSIDL_COMMON_PICTURES
+# define CSIDL_COMMON_PICTURES 0x36
+#endif
+#ifndef CSIDL_PROFILE
+# define CSIDL_PROFILE 0x28
+#endif
+#ifndef CSIDL_ADMINTOOLS
+# define CSIDL_ADMINTOOLS 0x30
+#endif
+#ifndef CSIDL_COMMON_ADMINTOOLS
+# define CSIDL_COMMON_ADMINTOOLS 0x2F
+#endif
+#ifndef CSIDL_MYMUSIC
+# define CSIDL_MYMUSIC 0xD
+#endif
+#ifndef CSIDL_COMMON_MUSIC
+# define CSIDL_COMMON_MUSIC 0x35
+#endif
+#ifndef CSIDL_MYVIDEO
+# define CSIDL_MYVIDEO 0xE
+#endif
+#ifndef CSIDL_COMMON_VIDEO
+# define CSIDL_COMMON_VIDEO 0x37
+#endif
+#ifndef CSIDL_RESOURCES
+# define CSIDL_RESOURCES 0x38
+#endif
+#ifndef CSIDL_RESOURCES_LOCALIZED
+# define CSIDL_RESOURCES_LOCALIZED 0x39
+#endif
+#ifndef CSIDL_CDBURN_AREA
+# define CSIDL_CDBURN_AREA 0x3B
+#endif
+
+// other shell stuff
+
+#ifndef SHACF_FILESYSTEM
+# define SHACF_FILESYSTEM 1
+#endif
+
+// other stuff
+
+#ifndef CP_ACP
+# define CP_ACP 0
+#endif
+
+#ifndef COLOR_BTNFACE
+# define COLOR_BTNFACE 15
+#endif
+#ifndef COLOR_WINDOW
+# define COLOR_WINDOW 5
+#endif
+
+// resources
+
+#ifndef RT_BITMAP
+# define RT_BITMAP MAKEINTRESOURCE(2)
+#endif
+#ifndef RT_ICON
+# define RT_ICON MAKEINTRESOURCE(3)
+#endif
+#ifndef RT_DIALOG
+# define RT_DIALOG MAKEINTRESOURCE(5)
+#endif
+#ifndef RT_GROUP_ICON
+# define RT_GROUP_ICON MAKEINTRESOURCE(14)
+#endif
+#ifndef RT_VERSION
+# define RT_VERSION MAKEINTRESOURCE(16)
+#endif
+
+// version
+
+#ifndef VS_FILE_INFO
+# define VS_FILE_INFO RT_VERSION
+#endif
+#ifndef VS_VERSION_INFO
+# define VS_VERSION_INFO 1
+#endif
+#ifndef VS_FFI_SIGNATURE
+# define VS_FFI_SIGNATURE 0xFEEF04BD
+#endif
+
+// message box
+
+#ifndef MB_OK
+# define MB_OK 0
+# define MB_OKCANCEL 1
+# define MB_ABORTRETRYIGNORE 2
+# define MB_YESNOCANCEL 3
+# define MB_YESNO 4
+# define MB_RETRYCANCEL 5
+# define MB_DEFBUTTON1 0
+# define MB_DEFBUTTON2 256
+# define MB_DEFBUTTON3 512
+# define MB_DEFBUTTON4 768
+# define MB_ICONSTOP 16
+# define MB_ICONQUESTION 32
+# define MB_ICONEXCLAMATION 48
+# define MB_ICONINFORMATION 64
+# define MB_USERICON 128
+# define MB_SETFOREGROUND 0x10000
+# define MB_TOPMOST 0x40000
+# define MB_RIGHT 0x80000
+# define MB_RTLREADING 0x100000
+#endif
+
+#ifndef IDOK
+# define IDOK 1
+# define IDCANCEL 2
+# define IDABORT 3
+# define IDRETRY 4
+# define IDIGNORE 5
+# define IDYES 6
+# define IDNO 7
+#endif
+
+// window styles
+
+#ifndef _WIN32
+# define WS_CHILD 0x40000000
+# define WS_VISIBLE 0x10000000
+
+# define BS_CHECKBOX 2
+# define BS_LEFT 256
+# define BS_LEFTTEXT 32
+# define BS_RADIOBUTTON 4
+# define BS_RIGHT 512
+# define BS_USERBUTTON 8
+
+# define ES_LEFT 0
+# define ES_CENTER 1
+# define ES_RIGHT 2
+
+# define SS_BITMAP 14
+# define SS_CENTER 1
+# define SS_CENTERIMAGE 512
+# define SS_ICON 3
+# define SS_LEFT 0
+# define SS_LEFTNOWORDWRAP 0xc
+# define SS_RIGHT 2
+# define SS_RIGHTJUST 0x400
+# define SS_USERITEM 10
+# define SS_TYPEMASK 0x0000001FL
+
+# define DS_FIXEDSYS 8
+# define DS_SETFONT 64
+
+# define WS_EX_RIGHT 0x1000
+# define WS_EX_RIGHTSCROLLBAR 0
+# define WS_EX_RTLREADING 0x2000
+# define WS_EX_LEFTSCROLLBAR 0x4000
+
+# define TVS_RTLREADING 64
+
+# define PBS_SMOOTH 1
+#endif
+
+#ifndef DS_SHELLFONT
+# define DS_SHELLFONT (DS_SETFONT | DS_FIXEDSYS)
+#endif
+
+// brush styles
+
+#ifndef BS_SOLID
+# define BS_SOLID 0
+#endif
+#ifndef BS_NULL
+# define BS_NULL 1
+#endif
+
+// reg
+#ifndef HKEY_CLASSES_ROOT
+# define HKEY_CLASSES_ROOT ((HKEY)0x80000000)
+# define HKEY_CURRENT_USER ((HKEY)0x80000001)
+# define HKEY_LOCAL_MACHINE ((HKEY)0x80000002)
+# define HKEY_USERS ((HKEY)0x80000003)
+# define HKEY_PERFORMANCE_DATA ((HKEY)0x80000004)
+# define HKEY_CURRENT_CONFIG ((HKEY)0x80000005)
+# define HKEY_DYN_DATA ((HKEY)0x80000006)
+#endif
+
+#ifndef KEY_WOW64_64KEY
+# define KEY_WOW64_64KEY 0x100
+#endif
+
+// show modes
+
+#ifndef SW_SHOWNORMAL
+# define SW_HIDE 0
+# define SW_SHOWNORMAL 1
+# define SW_SHOWMINIMIZED 2
+# define SW_SHOWMAXIMIZED 3
+# define SW_SHOWNOACTIVATE 4
+# define SW_SHOWMINNOACTIVE 7
+# define SW_SHOWNA 8
+#endif
+
+// hotkeys
+
+#ifndef HOTKEYF_SHIFT
+# define HOTKEYF_SHIFT 1
+# define HOTKEYF_CONTROL 2
+# define HOTKEYF_ALT 4
+# define HOTKEYF_EXT 8
+#endif
+
+// vk
+#ifndef VK_F1
+# define VK_F1 0x70
+#endif
+
+// gdi
+
+#ifndef OPAQUE
+# define OPAQUE 2
+#endif
+#ifndef TRANSPARENT
+# define TRANSPARENT 1
+#endif
+#ifndef LF_FACESIZE
+# define LF_FACESIZE 32
+#endif
+#ifndef FW_NORMAL
+# define FW_NORMAL 400
+#endif
+#ifndef FW_BOLD
+# define FW_BOLD 700
+#endif
+#ifndef DEFAULT_CHARSET
+# define DEFAULT_CHARSET 1
+#endif
+#ifndef OUT_DEFAULT_PRECIS
+# define OUT_DEFAULT_PRECIS 0
+#endif
+#ifndef CLIP_DEFAULT_PRECIS
+# define CLIP_DEFAULT_PRECIS 0
+#endif
+#ifndef DEFAULT_QUALITY
+# define DEFAULT_QUALITY 0
+#endif
+#ifndef DEFAULT_PITCH
+# define DEFAULT_PITCH 0
+#endif
+
+// file ops
+
+#ifndef FOF_SILENT
+# define FOF_SILENT 4
+# define FOF_NOCONFIRMATION 16
+# define FOF_FILESONLY 128
+# define FOF_SIMPLEPROGRESS 256
+# define FOF_NOCONFIRMMKDIR 512
+#endif
+
+// file attribs
+
+#ifndef FILE_ATTRIBUTE_READONLY
+# define FILE_ATTRIBUTE_READONLY 0x00000001
+# define FILE_ATTRIBUTE_HIDDEN 0x00000002
+# define FILE_ATTRIBUTE_SYSTEM 0x00000004
+# define FILE_ATTRIBUTE_ARCHIVE 0x00000020
+# define FILE_ATTRIBUTE_NORMAL 0x00000080
+# define FILE_ATTRIBUTE_TEMPORARY 0x00000100
+# define FILE_ATTRIBUTE_OFFLINE 0x00001000
+#endif
+
+// registry
+
+#ifndef REG_SZ
+# define REG_SZ 1
+# define REG_EXPAND_SZ 2
+# define REG_BINARY 3
+# define REG_DWORD 4
+#endif
+
+// fopen
+#ifndef GENERIC_READ
+# define GENERIC_READ 0x80000000
+# define GENERIC_WRITE 0x40000000
+#endif
+
+#ifndef CREATE_NEW
+# define CREATE_NEW 1
+# define CREATE_ALWAYS 2
+# define OPEN_EXISTING 3
+# define OPEN_ALWAYS 4
+#endif
+
+// fseek
+
+#ifndef FILE_BEGIN
+# define FILE_BEGIN 0
+# define FILE_CURRENT 1
+# define FILE_END 2
+#endif
+
+// PE
+
+#ifndef _WIN32
+# define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+# ifndef __BIG_ENDIAN__
+# define IMAGE_DOS_SIGNATURE 0x5A4D
+# define IMAGE_NT_SIGNATURE 0x00004550
+# else
+# define IMAGE_DOS_SIGNATURE 0x4D5A
+# define IMAGE_NT_SIGNATURE 0x50450000
+# endif
+# define IMAGE_FILE_DLL 8192
+# define IMAGE_DIRECTORY_ENTRY_EXPORT 0
+# define IMAGE_SIZEOF_SHORT_NAME 8
+#endif
+
+// structures
+
+#ifndef _WIN32
+typedef struct _LOGFONT {
+ LONG lfHeight;
+ LONG lfWidth;
+ LONG lfEscapement;
+ LONG lfOrientation;
+ LONG lfWeight;
+ BYTE lfItalic;
+ BYTE lfUnderline;
+ BYTE lfStrikeOut;
+ BYTE lfCharSet;
+ BYTE lfOutPrecision;
+ BYTE lfClipPrecision;
+ BYTE lfQuality;
+ BYTE lfPitchAndFamily;
+ CHAR lfFaceName[LF_FACESIZE];
+} LOGFONT;
+# pragma pack(2)
+typedef struct _IMAGE_DOS_HEADER {
+ WORD e_magic;
+ WORD e_cblp;
+ WORD e_cp;
+ WORD e_crlc;
+ WORD e_cparhdr;
+ WORD e_minalloc;
+ WORD e_maxalloc;
+ WORD e_ss;
+ WORD e_sp;
+ WORD e_csum;
+ WORD e_ip;
+ WORD e_cs;
+ WORD e_lfarlc;
+ WORD e_ovno;
+ WORD e_res[4];
+ WORD e_oemid;
+ WORD e_oeminfo;
+ WORD e_res2[10];
+ LONG e_lfanew;
+} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
+# pragma pack()
+# pragma pack(4)
+typedef struct _IMAGE_FILE_HEADER {
+ WORD Machine;
+ WORD NumberOfSections;
+ DWORD TimeDateStamp;
+ DWORD PointerToSymbolTable;
+ DWORD NumberOfSymbols;
+ WORD SizeOfOptionalHeader;
+ WORD Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+typedef struct _IMAGE_DATA_DIRECTORY {
+ DWORD VirtualAddress;
+ DWORD Size;
+} IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;
+typedef struct _IMAGE_OPTIONAL_HEADER {
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+ DWORD BaseOfData;
+ DWORD ImageBase;
+ DWORD SectionAlignment;
+ DWORD FileAlignment;
+ WORD MajorOperatingSystemVersion;
+ WORD MinorOperatingSystemVersion;
+ WORD MajorImageVersion;
+ WORD MinorImageVersion;
+ WORD MajorSubsystemVersion;
+ WORD MinorSubsystemVersion;
+ DWORD Reserved1;
+ DWORD SizeOfImage;
+ DWORD SizeOfHeaders;
+ DWORD CheckSum;
+ WORD Subsystem;
+ WORD DllCharacteristics;
+ DWORD SizeOfStackReserve;
+ DWORD SizeOfStackCommit;
+ DWORD SizeOfHeapReserve;
+ DWORD SizeOfHeapCommit;
+ DWORD LoaderFlags;
+ DWORD NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER32,*PIMAGE_OPTIONAL_HEADER32;
+typedef struct _IMAGE_OPTIONAL_HEADER64 {
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+ ULONGLONG ImageBase;
+ DWORD SectionAlignment;
+ DWORD FileAlignment;
+ WORD MajorOperatingSystemVersion;
+ WORD MinorOperatingSystemVersion;
+ WORD MajorImageVersion;
+ WORD MinorImageVersion;
+ WORD MajorSubsystemVersion;
+ WORD MinorSubsystemVersion;
+ DWORD Win32VersionValue;
+ DWORD SizeOfImage;
+ DWORD SizeOfHeaders;
+ DWORD CheckSum;
+ WORD Subsystem;
+ WORD DllCharacteristics;
+ ULONGLONG SizeOfStackReserve;
+ ULONGLONG SizeOfStackCommit;
+ ULONGLONG SizeOfHeapReserve;
+ ULONGLONG SizeOfHeapCommit;
+ DWORD LoaderFlags;
+ DWORD NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER64,*PIMAGE_OPTIONAL_HEADER64;
+#ifdef _WIN64
+typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER;
+typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER;
+#else
+typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER;
+typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER;
+#endif
+#ifndef __BIG_ENDIAN__
+# define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
+# define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
+#else
+# define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x0b01
+# define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x0b02
+#endif
+typedef struct _IMAGE_NT_HEADERS {
+ DWORD Signature;
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_NT_HEADERS,*PIMAGE_NT_HEADERS;
+typedef struct _IMAGE_SECTION_HEADER {
+ BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ DWORD PhysicalAddress;
+ DWORD VirtualSize;
+ } Misc;
+ DWORD VirtualAddress;
+ DWORD SizeOfRawData;
+ DWORD PointerToRawData;
+ DWORD PointerToRelocations;
+ DWORD PointerToLinenumbers;
+ WORD NumberOfRelocations;
+ WORD NumberOfLinenumbers;
+ DWORD Characteristics;
+} IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
+typedef struct _IMAGE_EXPORT_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD Name;
+ DWORD Base;
+ DWORD NumberOfFunctions;
+ DWORD NumberOfNames;
+ DWORD AddressOfFunctions;
+ DWORD AddressOfNames;
+ DWORD AddressOfNameOrdinals;
+} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
+typedef struct tagVS_FIXEDFILEINFO {
+ DWORD dwSignature;
+ DWORD dwStrucVersion;
+ DWORD dwFileVersionMS;
+ DWORD dwFileVersionLS;
+ DWORD dwProductVersionMS;
+ DWORD dwProductVersionLS;
+ DWORD dwFileFlagsMask;
+ DWORD dwFileFlags;
+ DWORD dwFileOS;
+ DWORD dwFileType;
+ DWORD dwFileSubtype;
+ DWORD dwFileDateMS;
+ DWORD dwFileDateLS;
+} VS_FIXEDFILEINFO;
+# pragma pack()
+#endif
+
+#ifndef SHGFP_TYPE_CURRENT
+ #define SHGFP_TYPE_CURRENT 0
+#endif
+
+#endif
diff --git a/Source/Plugins.cpp b/Source/Plugins.cpp
index 9e4d5c5..9c2999e 100755
--- a/Source/Plugins.cpp
+++ b/Source/Plugins.cpp
@@ -1,207 +1,207 @@
-/*
- * Plugins.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "exehead/config.h"
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
-
-#include <map>
-#include <string>
-#include <fstream>
-
-#include "Plugins.h"
-#include "Platform.h"
-#include "util.h"
-#include "ResourceEditor.h"
-
-#include "dirreader.h"
-
-#ifdef _WIN32
-# include <WinNT.h>
-#else
-# include <sys/stat.h>
-#endif
-
-#include "boost/scoped_ptr.hpp"
-
-using namespace std;
-
-extern FILE *g_output;
-
-void Plugins::FindCommands(const string &path, bool displayInfo)
-{
- boost::scoped_ptr<dir_reader> dr( new_dir_reader() );
- dr->read(path);
-
- for (dir_reader::iterator files_itr = dr->files().begin();
- files_itr != dr->files().end();
- files_itr++)
- {
- if (!dir_reader::matches(*files_itr, "*.dll"))
- continue;
-
- const string plugin = path + PLATFORM_PATH_SEPARATOR_C + *files_itr;
- GetExports(plugin, displayInfo);
- }
-}
-
-struct NSISException : public std::runtime_error
-{
- NSISException(const string& msg) : std::runtime_error(msg) {}
-};
-
-namespace {
-size_t file_size(ifstream& file) {
- const ifstream::pos_type pos = file.tellg();
-
- file.seekg(0, ios::end);
-
- ifstream::pos_type result = file.tellg();
- assert(result >= (ifstream::pos_type)0);
-
- file.seekg(pos);
-
- return (size_t)result;
-}
-
-vector<unsigned char> read_file(const string& filename) {
- ifstream file(filename.c_str(), ios::binary);
-
- if (!file) {
- throw NSISException("Can't open file '" + filename + "'");
- }
-
- // get the file size
- size_t filesize = file_size(file);
-
- vector<unsigned char> result;
- result.resize(filesize);
-
- file.read(reinterpret_cast<char*>(&result[0]), filesize);
-
- if (size_t(file.tellg()) != filesize) { // ifstream::eof doesn't return true here
- throw NSISException("Couldn't read entire file '" + filename + "'");
- }
-
- return result;
-}
-}
-
-void Plugins::GetExports(const string &pathToDll, bool displayInfo)
-{
- vector<unsigned char> dlldata;
- PIMAGE_NT_HEADERS NTHeaders;
- try {
- dlldata = read_file(pathToDll);
- NTHeaders = CResourceEditor::GetNTHeaders(&dlldata[0]);
- } catch (std::runtime_error&) {
- return;
- }
-
- const string dllName = remove_file_extension(get_file_name(pathToDll));
-
- FIX_ENDIAN_INT16_INPLACE(NTHeaders->FileHeader.Characteristics);
- if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
- {
- FIX_ENDIAN_INT32_INPLACE(NTHeaders->OptionalHeader.NumberOfRvaAndSizes);
- if (NTHeaders->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_EXPORT) return;
-
- DWORD ExportDirVA = NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
- DWORD ExportDirSize = NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
- PIMAGE_SECTION_HEADER sections = IMAGE_FIRST_SECTION(NTHeaders);
-
- FIX_ENDIAN_INT32_INPLACE(ExportDirVA);
- FIX_ENDIAN_INT32_INPLACE(ExportDirSize);
-
- WORD num_sections = FIX_ENDIAN_INT16(NTHeaders->FileHeader.NumberOfSections);
-
- for (DWORD i = 0; i < num_sections; i++)
- {
- DWORD va = FIX_ENDIAN_INT32(sections[i].VirtualAddress);
- if (va <= ExportDirVA
- && va + FIX_ENDIAN_INT32(sections[i].Misc.VirtualSize) >= ExportDirVA + ExportDirSize)
- {
- DWORD prd = FIX_ENDIAN_INT32(sections[i].PointerToRawData);
- PIMAGE_EXPORT_DIRECTORY exports = PIMAGE_EXPORT_DIRECTORY(&dlldata[0] + prd + ExportDirVA - va);
- DWORD na = FIX_ENDIAN_INT32(exports->AddressOfNames);
- unsigned long *names = (unsigned long*)((unsigned long) exports + (char *) na - ExportDirVA);
- for (unsigned long j = 0; j < FIX_ENDIAN_INT32(exports->NumberOfNames); j++)
- {
- const string name = string((char*)exports + FIX_ENDIAN_INT32(names[j]) - ExportDirVA);
- const string signature = dllName + "::" + name;
- const string lcsig = lowercase(signature);
- m_command_to_path[lcsig] = pathToDll;
- m_command_lowercase_to_command[lcsig] = signature;
- if (displayInfo)
- fprintf(g_output, " - %s\n", signature.c_str());
- }
- break;
- }
- }
- }
-}
-
-bool Plugins::IsPluginCommand(const string& token) const {
- return m_command_to_path.find(lowercase(token)) != m_command_to_path.end();
-}
-
-namespace {
-template <class Key, class Value>
-Value get_value(const map<Key, Value>& the_map,
- const Key& key)
-{
- assert(the_map.find(key) != the_map.end());
- return the_map.find(key)->second;
-}
-
-template <class Key, class Value>
-Value get_value(const map<Key, Value>& the_map,
- const Key& key,
- const Value& defaultValue)
-{
- if (the_map.find(key) == the_map.end())
- return defaultValue;
- return the_map.find(key)->second;
-}
-}
-
-string Plugins::NormalizedCommand(const string& command) const {
- return get_value(m_command_lowercase_to_command, lowercase(command));
-}
-
-int Plugins::GetPluginHandle(bool uninst, const string& command) const {
- if (uninst) {
- return get_value(m_command_to_uninstall_data_handle, command, -1);
- }
- else {
- return get_value(m_command_to_data_handle, command, -1);
- }
-}
-
-string Plugins::GetPluginPath(const string& command) const {
- return get_value(m_command_to_path, lowercase(command));
-}
-
-void Plugins::SetDllDataHandle(bool uninst, const string& command, int dataHandle)
-{
- if (uninst) {
- m_command_to_uninstall_data_handle[command] = dataHandle;
- }
- else {
- m_command_to_data_handle[command] = dataHandle;
- }
-}
-
-#endif
+/*
+ * Plugins.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "exehead/config.h"
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+
+#include <map>
+#include <string>
+#include <fstream>
+
+#include "Plugins.h"
+#include "Platform.h"
+#include "util.h"
+#include "ResourceEditor.h"
+
+#include "dirreader.h"
+
+#ifdef _WIN32
+# include <WinNT.h>
+#else
+# include <sys/stat.h>
+#endif
+
+#include "boost/scoped_ptr.hpp"
+
+using namespace std;
+
+extern FILE *g_output;
+
+void Plugins::FindCommands(const string &path, bool displayInfo)
+{
+ boost::scoped_ptr<dir_reader> dr( new_dir_reader() );
+ dr->read(path);
+
+ for (dir_reader::iterator files_itr = dr->files().begin();
+ files_itr != dr->files().end();
+ files_itr++)
+ {
+ if (!dir_reader::matches(*files_itr, "*.dll"))
+ continue;
+
+ const string plugin = path + PLATFORM_PATH_SEPARATOR_C + *files_itr;
+ GetExports(plugin, displayInfo);
+ }
+}
+
+struct NSISException : public std::runtime_error
+{
+ NSISException(const string& msg) : std::runtime_error(msg) {}
+};
+
+namespace {
+size_t file_size(ifstream& file) {
+ const ifstream::pos_type pos = file.tellg();
+
+ file.seekg(0, ios::end);
+
+ ifstream::pos_type result = file.tellg();
+ assert(result >= (ifstream::pos_type)0);
+
+ file.seekg(pos);
+
+ return (size_t)result;
+}
+
+vector<unsigned char> read_file(const string& filename) {
+ ifstream file(filename.c_str(), ios::binary);
+
+ if (!file) {
+ throw NSISException("Can't open file '" + filename + "'");
+ }
+
+ // get the file size
+ size_t filesize = file_size(file);
+
+ vector<unsigned char> result;
+ result.resize(filesize);
+
+ file.read(reinterpret_cast<char*>(&result[0]), filesize);
+
+ if (size_t(file.tellg()) != filesize) { // ifstream::eof doesn't return true here
+ throw NSISException("Couldn't read entire file '" + filename + "'");
+ }
+
+ return result;
+}
+}
+
+void Plugins::GetExports(const string &pathToDll, bool displayInfo)
+{
+ vector<unsigned char> dlldata;
+ PIMAGE_NT_HEADERS NTHeaders;
+ try {
+ dlldata = read_file(pathToDll);
+ NTHeaders = CResourceEditor::GetNTHeaders(&dlldata[0]);
+ } catch (std::runtime_error&) {
+ return;
+ }
+
+ const string dllName = remove_file_extension(get_file_name(pathToDll));
+
+ FIX_ENDIAN_INT16_INPLACE(NTHeaders->FileHeader.Characteristics);
+ if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
+ {
+ FIX_ENDIAN_INT32_INPLACE(NTHeaders->OptionalHeader.NumberOfRvaAndSizes);
+ if (NTHeaders->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_EXPORT) return;
+
+ DWORD ExportDirVA = NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ DWORD ExportDirSize = NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
+ PIMAGE_SECTION_HEADER sections = IMAGE_FIRST_SECTION(NTHeaders);
+
+ FIX_ENDIAN_INT32_INPLACE(ExportDirVA);
+ FIX_ENDIAN_INT32_INPLACE(ExportDirSize);
+
+ WORD num_sections = FIX_ENDIAN_INT16(NTHeaders->FileHeader.NumberOfSections);
+
+ for (DWORD i = 0; i < num_sections; i++)
+ {
+ DWORD va = FIX_ENDIAN_INT32(sections[i].VirtualAddress);
+ if (va <= ExportDirVA
+ && va + FIX_ENDIAN_INT32(sections[i].Misc.VirtualSize) >= ExportDirVA + ExportDirSize)
+ {
+ DWORD prd = FIX_ENDIAN_INT32(sections[i].PointerToRawData);
+ PIMAGE_EXPORT_DIRECTORY exports = PIMAGE_EXPORT_DIRECTORY(&dlldata[0] + prd + ExportDirVA - va);
+ DWORD na = FIX_ENDIAN_INT32(exports->AddressOfNames);
+ unsigned long *names = (unsigned long*)((unsigned long) exports + (char *) na - ExportDirVA);
+ for (unsigned long j = 0; j < FIX_ENDIAN_INT32(exports->NumberOfNames); j++)
+ {
+ const string name = string((char*)exports + FIX_ENDIAN_INT32(names[j]) - ExportDirVA);
+ const string signature = dllName + "::" + name;
+ const string lcsig = lowercase(signature);
+ m_command_to_path[lcsig] = pathToDll;
+ m_command_lowercase_to_command[lcsig] = signature;
+ if (displayInfo)
+ fprintf(g_output, " - %s\n", signature.c_str());
+ }
+ break;
+ }
+ }
+ }
+}
+
+bool Plugins::IsPluginCommand(const string& token) const {
+ return m_command_to_path.find(lowercase(token)) != m_command_to_path.end();
+}
+
+namespace {
+template <class Key, class Value>
+Value get_value(const map<Key, Value>& the_map,
+ const Key& key)
+{
+ assert(the_map.find(key) != the_map.end());
+ return the_map.find(key)->second;
+}
+
+template <class Key, class Value>
+Value get_value(const map<Key, Value>& the_map,
+ const Key& key,
+ const Value& defaultValue)
+{
+ if (the_map.find(key) == the_map.end())
+ return defaultValue;
+ return the_map.find(key)->second;
+}
+}
+
+string Plugins::NormalizedCommand(const string& command) const {
+ return get_value(m_command_lowercase_to_command, lowercase(command));
+}
+
+int Plugins::GetPluginHandle(bool uninst, const string& command) const {
+ if (uninst) {
+ return get_value(m_command_to_uninstall_data_handle, command, -1);
+ }
+ else {
+ return get_value(m_command_to_data_handle, command, -1);
+ }
+}
+
+string Plugins::GetPluginPath(const string& command) const {
+ return get_value(m_command_to_path, lowercase(command));
+}
+
+void Plugins::SetDllDataHandle(bool uninst, const string& command, int dataHandle)
+{
+ if (uninst) {
+ m_command_to_uninstall_data_handle[command] = dataHandle;
+ }
+ else {
+ m_command_to_data_handle[command] = dataHandle;
+ }
+}
+
+#endif
diff --git a/Source/Plugins.h b/Source/Plugins.h
index 932cf1d..ec9e809 100755
--- a/Source/Plugins.h
+++ b/Source/Plugins.h
@@ -1,43 +1,43 @@
-/*
- * Plugins.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __X18_PLUGINS_H
-#define __X18_PLUGINS_H
-
-#include <map>
-#include <string>
-
-class Plugins
-{
- public:
- void FindCommands(const std::string& path, bool displayInfo);
- bool IsPluginCommand(const std::string& command) const;
- std::string NormalizedCommand(const std::string& command) const;
- int GetPluginHandle(bool uninst, const std::string& command) const;
- std::string GetPluginPath(const std::string& command) const;
- void SetDllDataHandle(bool uninst, const std::string& command, int dataHandle);
-
- private: // methods
- void GetExports(const std::string &pathToDll, bool displayInfo);
-
- private: // data members
- std::map<std::string, std::string> m_command_lowercase_to_command;
- std::map<std::string, std::string> m_command_to_path;
- std::map<std::string, int> m_command_to_data_handle;
- std::map<std::string, int> m_command_to_uninstall_data_handle;
-};
-
-#endif
+/*
+ * Plugins.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __X18_PLUGINS_H
+#define __X18_PLUGINS_H
+
+#include <map>
+#include <string>
+
+class Plugins
+{
+ public:
+ void FindCommands(const std::string& path, bool displayInfo);
+ bool IsPluginCommand(const std::string& command) const;
+ std::string NormalizedCommand(const std::string& command) const;
+ int GetPluginHandle(bool uninst, const std::string& command) const;
+ std::string GetPluginPath(const std::string& command) const;
+ void SetDllDataHandle(bool uninst, const std::string& command, int dataHandle);
+
+ private: // methods
+ void GetExports(const std::string &pathToDll, bool displayInfo);
+
+ private: // data members
+ std::map<std::string, std::string> m_command_lowercase_to_command;
+ std::map<std::string, std::string> m_command_to_path;
+ std::map<std::string, int> m_command_to_data_handle;
+ std::map<std::string, int> m_command_to_uninstall_data_handle;
+};
+
+#endif
diff --git a/Source/ResourceEditor.cpp b/Source/ResourceEditor.cpp
index 0c42202..13e286f 100755
--- a/Source/ResourceEditor.cpp
+++ b/Source/ResourceEditor.cpp
@@ -1,1019 +1,1073 @@
-/*
- * ResourceEditor.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 2002-2007 Amir Szekely <kichik@users.sourceforge.net>
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "ResourceEditor.h"
-#include "util.h"
-#include "winchar.h"
-#include <queue>
-using namespace std;
-
-//////////////////////////////////////////////////////////////////////
-// Utilities
-//////////////////////////////////////////////////////////////////////
-
-#define ALIGN(dwToAlign, dwAlignOn) dwToAlign = (dwToAlign%dwAlignOn == 0) ? dwToAlign : dwToAlign - (dwToAlign%dwAlignOn) + dwAlignOn
-#define RALIGN(dwToAlign, dwAlignOn) ((dwToAlign%dwAlignOn == 0) ? dwToAlign : dwToAlign - (dwToAlign%dwAlignOn) + dwAlignOn)
-
-#ifndef _WIN32
-static inline ULONG ConvertEndianness(ULONG u) {
- return FIX_ENDIAN_INT32(u);
-}
-#endif
-
-static inline DWORD ConvertEndianness(DWORD d) {
- return FIX_ENDIAN_INT32(d);
-}
-
-static inline LONG ConvertEndianness(LONG l) {
- return FIX_ENDIAN_INT32(l);
-}
-
-static inline WORD ConvertEndianness(WORD w) {
- return FIX_ENDIAN_INT16(w);
-}
-
-PIMAGE_NT_HEADERS CResourceEditor::GetNTHeaders(BYTE* pbPE) {
- // Get dos header
- PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER) pbPE;
- if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
- throw runtime_error("PE file contains invalid DOS header");
-
- // Get NT headers
- PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(pbPE + ConvertEndianness(dosHeader->e_lfanew));
- if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
- throw runtime_error("PE file missing NT signature");
-
- // Make sure this is a supported PE format
- if (ntHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
- ntHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)
- throw runtime_error("Unsupported PE format");
-
- return ntHeaders;
-}
-
-PRESOURCE_DIRECTORY CResourceEditor::GetResourceDirectory(
- BYTE* pbPE,
- DWORD dwSize,
- PIMAGE_NT_HEADERS ntHeaders,
- DWORD *pdwResSecVA /*=NULL*/,
- DWORD *pdwSectionIndex /*=NULL*/
-) {
- PIMAGE_DATA_DIRECTORY dataDirectory = *GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, DataDirectory);
- DWORD dwNumberOfRvaAndSizes = *GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, NumberOfRvaAndSizes);
-
- if (ConvertEndianness(dwNumberOfRvaAndSizes) <= IMAGE_DIRECTORY_ENTRY_RESOURCE)
- throw runtime_error("No resource section found");
- // Get resource section virtual address
- DWORD dwResSecVA = ConvertEndianness(dataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
- // Pointer to the sections headers array
- PIMAGE_SECTION_HEADER sectionHeadersArray = IMAGE_FIRST_SECTION(ntHeaders);
-
- DWORD dwSectionIndex = (DWORD) -1;
-
- // Find resource section index in the array
- for (int i = 0; i < ConvertEndianness(ntHeaders->FileHeader.NumberOfSections); i++) {
- if (dwResSecVA == ConvertEndianness(sectionHeadersArray[i].VirtualAddress)) {
- // Remember resource section index
- dwSectionIndex = i;
- // Check for invalid resource section pointer
- if (!sectionHeadersArray[i].PointerToRawData)
- throw runtime_error("Invalid resource section pointer");
-
- break;
- }
-
- // Invalid section pointer (goes beyond the PE image)
- if (ConvertEndianness(sectionHeadersArray[i].PointerToRawData) > dwSize)
- throw runtime_error("Invalid section pointer");
- }
-
- // No resource section...
- if (dwSectionIndex == (DWORD) -1)
- throw runtime_error("PE file doesn't contain any resource section");
-
- // Return extra parameters
- if (pdwSectionIndex)
- *pdwSectionIndex = dwSectionIndex;
- if (pdwResSecVA)
- *pdwResSecVA = dwResSecVA;
-
- // Pointer to section data, the first resource directory
- DWORD dwResSecPtr = ConvertEndianness(sectionHeadersArray[dwSectionIndex].PointerToRawData);
- return PRESOURCE_DIRECTORY(pbPE + dwResSecPtr);
-}
-
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
-// CResourceEditor
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-CResourceEditor::CResourceEditor(BYTE* pbPE, int iSize) {
- // Copy the data pointer
- m_pbPE = pbPE;
- m_iSize = iSize;
-
- // Get NT headers
- m_ntHeaders = GetNTHeaders(m_pbPE);
-
- // No check sum support yet...
- DWORD* pdwCheckSum = GetMemberFromOptionalHeader(m_ntHeaders->OptionalHeader, CheckSum);
- if (*pdwCheckSum)
- {
- // clear checksum (should be [re]calculated after all changes done)
- pdwCheckSum = 0;
- //throw runtime_error("CResourceEditor doesn't yet support check sum");
- }
-
- // Get resource section virtual address, resource section index and pointer to resource directory
- PRESOURCE_DIRECTORY rdRoot = GetResourceDirectory(m_pbPE, iSize, m_ntHeaders, &m_dwResourceSectionVA, &m_dwResourceSectionIndex);
-
- // Scan the resource directory
- m_cResDir = ScanDirectory(rdRoot, rdRoot);
-}
-
-CResourceEditor::~CResourceEditor() {
- if (m_cResDir) {
- m_cResDir->Destroy();
- delete m_cResDir;
- }
-}
-
-//////////////////////////////////////////////////////////////////////
-// Methods
-//////////////////////////////////////////////////////////////////////
-
-// Adds/Replaces/Removes a resource.
-// If lpData is 0 UpdateResource removes the resource.
-bool CResourceEditor::UpdateResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
- CResourceDirectory* nameDir = 0;
- CResourceDirectory* langDir = 0;
- CResourceDataEntry* data = 0;
- IMAGE_RESOURCE_DIRECTORY rd = {0, /*time(0),*/};
- int iTypeIdx = -1, iNameIdx = -1, iLangIdx = -1;
-
- iTypeIdx = m_cResDir->Find(szType);
- if (iTypeIdx > -1) {
- nameDir = m_cResDir->GetEntry(iTypeIdx)->GetSubDirectory();
- iNameIdx = nameDir->Find(szName);
- if (iNameIdx > -1) {
- langDir = nameDir->GetEntry(iNameIdx)->GetSubDirectory();
- iLangIdx = langDir->Find(wLanguage);
- if (iLangIdx > -1) {
- data = langDir->GetEntry(iLangIdx)->GetDataEntry();
- }
- }
- }
-
- if (lpData) {
- // Replace/Add the resource
- if (data) {
- data->SetData(lpData, dwSize);
- return true;
- }
-
- if (!nameDir) {
- // Type doesn't yet exist
- nameDir = new CResourceDirectory(&rd);
- m_cResDir->AddEntry(new CResourceDirectoryEntry(szType, nameDir));
- }
- if (!langDir) {
- // Name doesn't yet exist
- langDir = new CResourceDirectory(&rd);
- nameDir->AddEntry(new CResourceDirectoryEntry(szName, langDir));
- }
- if (!data) {
- // Language doesn't yet exist, hence data nither
- data = new CResourceDataEntry(lpData, dwSize);
- langDir->AddEntry(new CResourceDirectoryEntry(MAKEINTRESOURCEW(wLanguage), data));
- }
- }
- else if (data) {
- // Delete the resource
- delete data;
- langDir->RemoveEntry(iLangIdx);
- // Delete directories holding the resource if empty
- if (!langDir->CountEntries()) {
- delete langDir;
- nameDir->RemoveEntry(iNameIdx);
- if (!nameDir->CountEntries()) {
- delete nameDir;
- m_cResDir->RemoveEntry(iTypeIdx);
- }
- }
- }
- else return false;
- return true;
-}
-
-static WCHAR* ResStringToUnicode(const char *szString) {
- if (IS_INTRESOURCE(szString))
- return MAKEINTRESOURCEW((ULONG_PTR)szString);
- else
- return winchar_fromansi(szString);
-}
-
-static void FreeUnicodeResString(WCHAR* szwString) {
- if (!IS_INTRESOURCE(szwString))
- delete [] szwString;
-}
-
-bool CResourceEditor::UpdateResourceW(WORD szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
- return UpdateResourceW(MAKEINTRESOURCEW(szType), szName, wLanguage, lpData, dwSize);
-}
-
-bool CResourceEditor::UpdateResourceW(WCHAR* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
- return UpdateResourceW(szType, MAKEINTRESOURCEW(szName), wLanguage, lpData, dwSize);
-}
-
-bool CResourceEditor::UpdateResourceA(char* szType, char* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
- WCHAR* szwType = ResStringToUnicode(szType);
- WCHAR* szwName = ResStringToUnicode(szName);
-
- bool result = UpdateResourceW(szwType, szwName, wLanguage, lpData, dwSize);
-
- FreeUnicodeResString(szwType);
- FreeUnicodeResString(szwName);
-
- return result;
-}
-
-bool CResourceEditor::UpdateResourceA(WORD szType, char* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
- return UpdateResourceA(MAKEINTRESOURCE(szType), szName, wLanguage, lpData, dwSize);
-}
-
-bool CResourceEditor::UpdateResourceA(char* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
- return UpdateResourceA(szType, MAKEINTRESOURCE(szName), wLanguage, lpData, dwSize);
-}
-
-bool CResourceEditor::UpdateResource(WORD szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
- return UpdateResourceW(MAKEINTRESOURCEW(szType), MAKEINTRESOURCEW(szName), wLanguage, lpData, dwSize);
-}
-
-// Returns a copy of the requested resource
-// Returns 0 if the requested resource can't be found
-BYTE* CResourceEditor::GetResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage) {
- CResourceDirectory* nameDir = 0;
- CResourceDirectory* langDir = 0;
- CResourceDataEntry* data = 0;
-
- int i = m_cResDir->Find(szType);
- if (i > -1) {
- nameDir = m_cResDir->GetEntry(i)->GetSubDirectory();
- i = nameDir->Find(szName);
- if (i > -1) {
- langDir = nameDir->GetEntry(i)->GetSubDirectory();
- i = 0;
- if (wLanguage)
- i = langDir->Find(wLanguage);
- if (i > -1) {
- data = langDir->GetEntry(i)->GetDataEntry();
- }
- }
- }
-
- if (data) {
- BYTE* toReturn = new BYTE[data->GetSize()];
- CopyMemory(toReturn, data->GetData(), data->GetSize());
- return toReturn;
- }
- else
- return NULL;
-}
-
-BYTE* CResourceEditor::GetResourceA(char* szType, char* szName, LANGID wLanguage) {
- WCHAR* szwType = ResStringToUnicode(szType);
- WCHAR* szwName = ResStringToUnicode(szName);
-
- BYTE* result = GetResourceW(szwType, szwName, wLanguage);
-
- FreeUnicodeResString(szwType);
- FreeUnicodeResString(szwName);
-
- return result;
-}
-
-// Returns the size of the requested resource
-// Returns -1 if the requested resource can't be found
-int CResourceEditor::GetResourceSizeW(WCHAR* szType, WCHAR* szName, LANGID wLanguage) {
- CResourceDirectory* nameDir = 0;
- CResourceDirectory* langDir = 0;
- CResourceDataEntry* data = 0;
-
- int i = m_cResDir->Find(szType);
- if (i > -1) {
- nameDir = m_cResDir->GetEntry(i)->GetSubDirectory();
- i = nameDir->Find(szName);
- if (i > -1) {
- langDir = nameDir->GetEntry(i)->GetSubDirectory();
- i = 0;
- if (wLanguage)
- i = langDir->Find(wLanguage);
- if (i > -1) {
- data = langDir->GetEntry(i)->GetDataEntry();
- }
- }
- }
-
- if (data)
- return (int) data->GetSize();
- else
- return -1;
-}
-
-int CResourceEditor::GetResourceSizeA(char* szType, char* szName, LANGID wLanguage) {
- WCHAR* szwType = ResStringToUnicode(szType);
- WCHAR* szwName = ResStringToUnicode(szName);
-
- int result = GetResourceSizeW(szwType, szwName, wLanguage);
-
- FreeUnicodeResString(szwType);
- FreeUnicodeResString(szwName);
-
- return result;
-}
-
-void CResourceEditor::FreeResource(BYTE* pbResource)
-{
- if (pbResource)
- delete [] pbResource;
-}
-
-// Saves the edited PE into a buffer and returns it.
-DWORD CResourceEditor::Save(BYTE* pbBuf, DWORD &dwSize) {
- unsigned int i;
- DWORD dwReqSize;
-
- DWORD dwFileAlign = ConvertEndianness(m_ntHeaders->OptionalHeader.FileAlignment);
- DWORD dwSecAlign = ConvertEndianness(m_ntHeaders->OptionalHeader.SectionAlignment);
-
- DWORD dwRsrcSize = m_cResDir->GetSize(); // Size of new resource section
- DWORD dwRsrcSizeAligned = RALIGN(dwRsrcSize, dwFileAlign); // Align it to FileAlignment
-
- // Calculate the total new PE size
- DWORD dwOldRsrcSize = ConvertEndianness(IMAGE_FIRST_SECTION(m_ntHeaders)[m_dwResourceSectionIndex].SizeOfRawData);
- dwReqSize = m_iSize - dwOldRsrcSize + dwRsrcSizeAligned;
-
- if (!pbBuf || dwSize < dwReqSize)
- return dwReqSize;
-
- // Use buffer
- BYTE* pbNewPE = pbBuf;
- dwSize = dwReqSize;
- // Fill buffer with zeros
- ZeroMemory(pbNewPE, dwSize);
-
- BYTE* seeker = pbNewPE;
- BYTE* oldSeeker = m_pbPE;
-
- PIMAGE_SECTION_HEADER old_sectionHeadersArray = IMAGE_FIRST_SECTION(m_ntHeaders);
-
- DWORD dwHeaderSize = ConvertEndianness(old_sectionHeadersArray[m_dwResourceSectionIndex].PointerToRawData);
- WORD wNumberOfSections = ConvertEndianness(m_ntHeaders->FileHeader.NumberOfSections);
-
- // Copy everything until the resource section (including headers and everything that might come after them)
- // We don't use SizeOfHeaders because sometimes (using VC6) it can extend beyond the first section
- // or (Borland) there could be some more information between the headers and the first section.
- CopyMemory(seeker, oldSeeker, dwHeaderSize);
-
- // Skip the headers and whatever comes after them
- seeker += dwHeaderSize;
- oldSeeker += dwHeaderSize;
-
- // Get new nt headers pointer
- PIMAGE_NT_HEADERS ntHeaders = GetNTHeaders(pbNewPE);
- // Get a pointer to the new section headers
- PIMAGE_SECTION_HEADER sectionHeadersArray = IMAGE_FIRST_SECTION(ntHeaders);
-
- // Skip the resource section in the old PE seeker.
- oldSeeker += dwOldRsrcSize;
-
- // Save the old virtual size of the resource section
- DWORD dwNewVirtualSize = RALIGN(dwRsrcSize, dwSecAlign);
- DWORD dwOldVirtualSize = ConvertEndianness(sectionHeadersArray[m_dwResourceSectionIndex].Misc.VirtualSize);
- ALIGN(dwOldVirtualSize, dwSecAlign);
- DWORD dwVAAdjustment = dwNewVirtualSize - dwOldVirtualSize;
-
- // Set the new size of the resource section (size aligned to FileAlignment)
- sectionHeadersArray[m_dwResourceSectionIndex].SizeOfRawData = ConvertEndianness(dwRsrcSizeAligned);
- // Set the virtual size as well (in memory)
- sectionHeadersArray[m_dwResourceSectionIndex].Misc.VirtualSize = ConvertEndianness(dwRsrcSize);
- (*GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, DataDirectory))[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = ConvertEndianness(dwRsrcSize);
-
- // Set the new virtual size of the image
- DWORD* pdwSizeOfImage = GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, SizeOfImage);
- *pdwSizeOfImage = AlignVA(*GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, SizeOfHeaders));
- for (i = 0; i < wNumberOfSections; i++) {
- DWORD dwSecSize = ConvertEndianness(sectionHeadersArray[i].Misc.VirtualSize);
- *pdwSizeOfImage = AlignVA(AdjustVA(*pdwSizeOfImage, dwSecSize));
- }
-
- // Set the new AddressOfEntryPoint if needed
- DWORD* pdwAddressOfEntryPoint = GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, AddressOfEntryPoint);
- if (ConvertEndianness(*pdwAddressOfEntryPoint) > m_dwResourceSectionVA)
- *pdwAddressOfEntryPoint = AdjustVA(*pdwAddressOfEntryPoint, dwVAAdjustment);
-
- // Set the new BaseOfCode if needed
- DWORD* pdwBaseOfCode = GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, BaseOfCode);
- if (ConvertEndianness(*pdwBaseOfCode) > m_dwResourceSectionVA)
- *pdwBaseOfCode = AdjustVA(*pdwBaseOfCode, dwVAAdjustment);
-
- // Set the new BaseOfData if needed
- if (ntHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
- DWORD* pdwBaseOfData = &((PIMAGE_OPTIONAL_HEADER32)&ntHeaders->OptionalHeader)->BaseOfData;
- if (*pdwBaseOfData > m_dwResourceSectionVA)
- *pdwBaseOfData = AdjustVA(*pdwBaseOfData, dwVAAdjustment);
- }
-
- // Refresh the headers of the sections that come after the resource section, and the data directory
- DWORD dwNumberOfRvaAndSizes = *GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, NumberOfRvaAndSizes);
- PIMAGE_DATA_DIRECTORY pDataDirectory = *GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, DataDirectory);
- for (i = m_dwResourceSectionIndex + 1; i < wNumberOfSections; i++) {
- if (sectionHeadersArray[i].PointerToRawData) {
- AdjustVA(sectionHeadersArray[i].PointerToRawData, dwRsrcSizeAligned - dwOldRsrcSize);
- }
-
- // We must find the right data directory entry before we change the virtual address
- unsigned int uDataDirIdx = 0;
- for (unsigned int j = 0; j < ConvertEndianness(dwNumberOfRvaAndSizes); j++)
- if (pDataDirectory[j].VirtualAddress == sectionHeadersArray[i].VirtualAddress)
- uDataDirIdx = j;
-
- sectionHeadersArray[i].VirtualAddress = AdjustVA(sectionHeadersArray[i].VirtualAddress, dwVAAdjustment);
-
- // Change the virtual address in the data directory too
- if (uDataDirIdx)
- pDataDirectory[uDataDirIdx].VirtualAddress = sectionHeadersArray[i].VirtualAddress;
- }
-
- // Write the resource section
- WriteRsrcSec(seeker);
- // Advance the pointer
- seeker += dwRsrcSizeAligned;
-
- // Copy everything that comes after the resource section (other sections and tacked data)
- DWORD dwLeft = m_iSize - (oldSeeker - m_pbPE);
- if (dwLeft)
- CopyMemory(seeker, oldSeeker, dwLeft);
-
- seeker += dwLeft;
- oldSeeker += dwLeft;
-
- /**********************************************************
- * To add checksum to the header use MapFileAndCheckSum
- **********************************************************/
-
- // From now on, we are working on the new PE
- // Freeing the old PE memory is up to the user
- m_pbPE = pbNewPE;
- m_iSize = dwSize;
- m_ntHeaders = ntHeaders;
- // We just wrote the resource section according to m_cResDir, so we don't need to rescan
- // m_dwResourceSectionIndex and m_dwResourceSectionVA have also been left unchanged as
- // we didn't move the resources section
-
- return 0;
-}
-
-// This function scans exe sections and after find a match with given name
-// increments it's virtual size (auto fixes image size based on section alignment, etc)
-bool CResourceEditor::AddExtraVirtualSize2PESection(const char* pszSectionName, int addsize)
-{
- PIMAGE_SECTION_HEADER sectionHeadersArray = IMAGE_FIRST_SECTION(m_ntHeaders);
-
- // Refresh the headers of the sections that come after the resource section, and the data directory
- for (int i = 0; i < ConvertEndianness(m_ntHeaders->FileHeader.NumberOfSections); i++) {
- if (!strcmp((LPCSTR)sectionHeadersArray[i].Name, pszSectionName)) {
- sectionHeadersArray[i].Misc.VirtualSize = AlignVA(AdjustVA(sectionHeadersArray[i].Misc.VirtualSize, addsize));
-
- sectionHeadersArray[i].Characteristics &= ConvertEndianness((DWORD) ~IMAGE_SCN_MEM_DISCARDABLE);
-
- // now fix any section after
- for (int k = i + 1; k < ConvertEndianness(m_ntHeaders->FileHeader.NumberOfSections); k++, i++) {
- DWORD dwLastSecVA = ConvertEndianness(sectionHeadersArray[i].VirtualAddress);
- DWORD dwLastSecSize = ConvertEndianness(sectionHeadersArray[i].Misc.VirtualSize);
- DWORD dwSecVA = AlignVA(ConvertEndianness(dwLastSecVA + dwLastSecSize));
-
- sectionHeadersArray[k].VirtualAddress = dwSecVA;
-
- if (m_dwResourceSectionIndex == (DWORD) k)
- {
- // fix the resources virtual address if it changed
- PIMAGE_DATA_DIRECTORY pDataDirectory = *GetMemberFromOptionalHeader(m_ntHeaders->OptionalHeader, DataDirectory);
- pDataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = dwSecVA;
- m_dwResourceSectionVA = ConvertEndianness(dwSecVA);
- }
- }
-
- return true;
- }
- }
-
- return false;
-}
-
-//////////////////////////////////////////////////////////////////////
-// Private Methods
-//////////////////////////////////////////////////////////////////////
-
-// This function scans a give resource directory and return a CResourceDirectory object
-// rdRoot must point to the root directory of the resource section
-CResourceDirectory* CResourceEditor::ScanDirectory(PRESOURCE_DIRECTORY rdRoot, PRESOURCE_DIRECTORY rdToScan) {
- // Create CResourceDirectory from rdToScan
- CResourceDirectory* rdc = new CResourceDirectory(PIMAGE_RESOURCE_DIRECTORY(rdToScan));
- WCHAR* szName;
- PIMAGE_RESOURCE_DATA_ENTRY rde = NULL;
-
- // Go through all entries of this resource directory
- int entries = ConvertEndianness(rdToScan->Header.NumberOfNamedEntries);
- entries += ConvertEndianness(rdToScan->Header.NumberOfIdEntries);
-
- for (int i = 0; i < entries; i++) {
- MY_IMAGE_RESOURCE_DIRECTORY_ENTRY rd = rdToScan->Entries[i];
- rd.UOffset.OffsetToData = ConvertEndianness(rd.UOffset.OffsetToData);
- rd.UName.Name = ConvertEndianness(rd.UName.Name);
-
- // If this entry points to data entry get a pointer to it
- if (!rd.UOffset.DirectoryOffset.DataIsDirectory)
- rde = PIMAGE_RESOURCE_DATA_ENTRY(rd.UOffset.OffsetToData + (BYTE*)rdRoot);
-
- // If this entry has a name, translate it from Unicode
- if (rd.UName.NameString.NameIsString) {
- PIMAGE_RESOURCE_DIR_STRING_U rds = PIMAGE_RESOURCE_DIR_STRING_U(rd.UName.NameString.NameOffset + (char*)rdRoot);
-
- size_t nameSize = ConvertEndianness(rds->Length);
- szName = new WCHAR[nameSize+1];
- winchar_strncpy(szName, rds->NameString, nameSize);
- szName[nameSize] = 0;
- }
- // Else, set the name to this entry's id
- else
- szName = MAKEINTRESOURCEW(ConvertEndianness(rdToScan->Entries[i].UName.Id));
-
- if (rd.UOffset.DirectoryOffset.DataIsDirectory)
- rdc->AddEntry(
- new CResourceDirectoryEntry(
- szName,
- ScanDirectory(
- rdRoot,
- PRESOURCE_DIRECTORY(rd.UOffset.DirectoryOffset.OffsetToDirectory + (BYTE*)rdRoot)
- )
- )
- );
- else
- rdc->AddEntry(
- new CResourceDirectoryEntry(
- szName,
- new CResourceDataEntry(
- (BYTE*)rdRoot + ConvertEndianness(rde->OffsetToData) - m_dwResourceSectionVA,
- ConvertEndianness(rde->Size),
- ConvertEndianness(rde->CodePage)
- )
- )
- );
-
- // Delete the dynamicly allocated name if it is a name and not an id
- if (!IS_INTRESOURCE(szName))
- delete [] szName;
- }
-
- return rdc;
-}
-
-// This function writes into a given place in memory (pbRsrcSec) the edited resource section
-void CResourceEditor::WriteRsrcSec(BYTE* pbRsrcSec) {
- BYTE* seeker = pbRsrcSec;
-
- queue<CResourceDirectory*> qDirs; // Used to scan the tree by level
- queue<CResourceDataEntry*> qDataEntries; // Used for writing the data entries
- queue<CResourceDataEntry*> qDataEntries2; // Used for writing raw resources data
- queue<CResourceDirectoryEntry*> qStrings; // Used for writing resources' names
-
- qDirs.push(m_cResDir);
-
- while (!qDirs.empty()) {
- CResourceDirectory* crd = qDirs.front();
-
- IMAGE_RESOURCE_DIRECTORY rdDir = crd->GetInfo();
-
- rdDir.NumberOfNamedEntries = ConvertEndianness(rdDir.NumberOfNamedEntries);
- rdDir.NumberOfIdEntries = ConvertEndianness(rdDir.NumberOfIdEntries);
-
- CopyMemory(seeker, &rdDir, sizeof(IMAGE_RESOURCE_DIRECTORY));
- crd->m_dwWrittenAt = DWORD(seeker);
- seeker += sizeof(IMAGE_RESOURCE_DIRECTORY);
-
- for (int i = 0; i < crd->CountEntries(); i++) {
- if (crd->GetEntry(i)->HasName())
- qStrings.push(crd->GetEntry(i));
- if (crd->GetEntry(i)->IsDataDirectory())
- qDirs.push(crd->GetEntry(i)->GetSubDirectory());
- else {
- qDataEntries.push(crd->GetEntry(i)->GetDataEntry());
- qDataEntries2.push(crd->GetEntry(i)->GetDataEntry());
- }
-
- MY_IMAGE_RESOURCE_DIRECTORY_ENTRY rDirE;
- ZeroMemory(&rDirE, sizeof(rDirE));
- rDirE.UOffset.DirectoryOffset.DataIsDirectory = crd->GetEntry(i)->IsDataDirectory();
- rDirE.UName.Id = crd->GetEntry(i)->HasName() ? 0 : crd->GetEntry(i)->GetId();
- rDirE.UName.Id = ConvertEndianness(rDirE.UName.Id);
- rDirE.UName.NameString.NameIsString = (crd->GetEntry(i)->HasName()) ? 1 : 0;
-
- CopyMemory(seeker, &rDirE, sizeof(MY_IMAGE_RESOURCE_DIRECTORY_ENTRY));
- crd->GetEntry(i)->m_dwWrittenAt = DWORD(seeker);
- seeker += sizeof(MY_IMAGE_RESOURCE_DIRECTORY_ENTRY);
- }
- qDirs.pop();
- }
-
- /*
- * Write IMAGE_RESOURCE_DATA_ENTRYs.
- */
- while (!qDataEntries.empty()) {
- CResourceDataEntry* cRDataE = qDataEntries.front();
- IMAGE_RESOURCE_DATA_ENTRY rDataE = {0,};
- rDataE.CodePage = ConvertEndianness(cRDataE->GetCodePage());
- rDataE.Size = ConvertEndianness(cRDataE->GetSize());
-
- CopyMemory(seeker, &rDataE, sizeof(IMAGE_RESOURCE_DATA_ENTRY));
- cRDataE->m_dwWrittenAt = DWORD(seeker);
- seeker += sizeof(IMAGE_RESOURCE_DATA_ENTRY);
-
- qDataEntries.pop();
- }
-
- /*
- * Write strings
- */
- while (!qStrings.empty()) {
- CResourceDirectoryEntry* cRDirE = qStrings.front();
-
- PMY_IMAGE_RESOURCE_DIRECTORY_ENTRY(cRDirE->m_dwWrittenAt)->UName.NameString.NameOffset = ConvertEndianness(DWORD(seeker) - DWORD(pbRsrcSec));
-
- WCHAR* szName = cRDirE->GetName();
- WORD iLen = winchar_strlen(szName) + 1;
-
- *(WORD*)seeker = ConvertEndianness(iLen);
- CopyMemory(seeker + sizeof(WORD), szName, iLen*sizeof(WCHAR));
-
- seeker += RALIGN(iLen * sizeof(WCHAR) + sizeof(WORD), 4);
-
- delete [] szName;
-
- qStrings.pop();
- }
-
- /*
- * Write raw resource data and set offsets in IMAGE_RESOURCE_DATA_ENTRYs.
- */
- while (!qDataEntries2.empty()) {
- CResourceDataEntry* cRDataE = qDataEntries2.front();
- CopyMemory(seeker, cRDataE->GetData(), cRDataE->GetSize());
- PIMAGE_RESOURCE_DATA_ENTRY(cRDataE->m_dwWrittenAt)->OffsetToData = ConvertEndianness(seeker - pbRsrcSec + m_dwResourceSectionVA);
-
- seeker += RALIGN(cRDataE->GetSize(), 8);
-
- qDataEntries2.pop();
- }
-
- /*
- * Set all of the directory entries offsets.
- */
- SetOffsets(m_cResDir, DWORD(pbRsrcSec));
-}
-
-// Sets the offsets in directory entries
-void CResourceEditor::SetOffsets(CResourceDirectory* resDir, DWORD newResDirAt) {
- for (int i = 0; i < resDir->CountEntries(); i++) {
- PMY_IMAGE_RESOURCE_DIRECTORY_ENTRY rde = PMY_IMAGE_RESOURCE_DIRECTORY_ENTRY(resDir->GetEntry(i)->m_dwWrittenAt);
- if (resDir->GetEntry(i)->IsDataDirectory()) {
- rde->UOffset.DirectoryOffset.DataIsDirectory = 1;
- rde->UOffset.DirectoryOffset.OffsetToDirectory = resDir->GetEntry(i)->GetSubDirectory()->m_dwWrittenAt - newResDirAt;
- rde->UOffset.OffsetToData = ConvertEndianness(rde->UOffset.OffsetToData);
- SetOffsets(resDir->GetEntry(i)->GetSubDirectory(), newResDirAt);
- }
- else {
- rde->UOffset.OffsetToData = ConvertEndianness(resDir->GetEntry(i)->GetDataEntry()->m_dwWrittenAt - newResDirAt);
- }
- }
-}
-
-// Adjusts a virtual address by a specific amount
-DWORD CResourceEditor::AdjustVA(DWORD dwVirtualAddress, DWORD dwAdjustment) {
- dwVirtualAddress = ConvertEndianness(dwVirtualAddress);
- dwVirtualAddress += dwAdjustment;
- dwVirtualAddress = ConvertEndianness(dwVirtualAddress);
-
- return dwVirtualAddress;
-}
-
-// Aligns a virtual address to the section alignment
-DWORD CResourceEditor::AlignVA(DWORD dwVirtualAddress) {
- DWORD dwSectionAlignment = *GetMemberFromOptionalHeader(m_ntHeaders->OptionalHeader, SectionAlignment);
- DWORD dwAlignment = ConvertEndianness(dwSectionAlignment);
-
- dwVirtualAddress = ConvertEndianness(dwVirtualAddress);
- dwVirtualAddress = RALIGN(dwVirtualAddress, dwAlignment);
- dwVirtualAddress = ConvertEndianness(dwVirtualAddress);
-
- return dwVirtualAddress;
-}
-
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
-// CResourceDirectory
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-CResourceDirectory::CResourceDirectory(PIMAGE_RESOURCE_DIRECTORY prd) {
- m_rdDir = *prd;
- m_rdDir.NumberOfIdEntries = 0;
- m_rdDir.NumberOfNamedEntries = 0;
-}
-
-CResourceDirectory::~CResourceDirectory() {
-}
-
-//////////////////////////////////////////////////////////////////////
-// Methods
-//////////////////////////////////////////////////////////////////////
-
-IMAGE_RESOURCE_DIRECTORY CResourceDirectory::GetInfo() {
- return m_rdDir;
-}
-
-CResourceDirectoryEntry* CResourceDirectory::GetEntry(unsigned int i) {
- if (m_vEntries.size() < i)
- return 0;
- return m_vEntries[i];
-}
-
-// This function inserts a new directory entry
-// It also keeps the directory entries sorted
-void CResourceDirectory::AddEntry(CResourceDirectoryEntry* entry) {
- int i = 0;
- if (entry->HasName()) {
- WCHAR* szEntName = entry->GetName();
- for (i = 0; i < m_rdDir.NumberOfNamedEntries; i++) {
- WCHAR* szName = m_vEntries[i]->GetName();
- int cmp = winchar_strcmp(szName, szEntName);
- delete [] szName;
- if (cmp == 0) {
- delete [] szEntName;
- return;
- }
- if (cmp > 0)
- break;
- }
- delete [] szEntName;
- m_rdDir.NumberOfNamedEntries++;
- }
- else {
- for (i = m_rdDir.NumberOfNamedEntries; i < m_rdDir.NumberOfNamedEntries+m_rdDir.NumberOfIdEntries; i++) {
- if (m_vEntries[i]->GetId() == entry->GetId())
- return;
- if (m_vEntries[i]->GetId() > entry->GetId())
- break;
- }
- m_rdDir.NumberOfIdEntries++;
- }
- m_vEntries.insert(m_vEntries.begin() + i, entry);
-}
-
-void CResourceDirectory::RemoveEntry(int i) {
- if (m_vEntries[i]->HasName())
- m_rdDir.NumberOfNamedEntries--;
- else
- m_rdDir.NumberOfIdEntries--;
- delete m_vEntries[i];
- m_vEntries.erase(m_vEntries.begin() + i);
-}
-
-int CResourceDirectory::CountEntries() {
- return m_vEntries.size();
-}
-
-// Returns the index of a directory entry with the specified name
-// Name can be a string or an id
-// Returns -1 if can not be found
-int CResourceDirectory::Find(WCHAR* szName) {
- if (IS_INTRESOURCE(szName))
- return Find((WORD) (DWORD) szName);
- else
- if (szName[0] == '#')
- return Find(WORD(winchar_stoi(szName + 1)));
-
- for (unsigned int i = 0; i < m_vEntries.size(); i++) {
- if (!m_vEntries[i]->HasName())
- continue;
-
- WCHAR* szEntName = m_vEntries[i]->GetName();
- int cmp = winchar_strcmp(szName, szEntName);
- delete [] szEntName;
-
- if (!cmp)
- return i;
- }
-
- return -1;
-}
-
-// Returns the index of a directory entry with the specified id
-// Returns -1 if can not be found
-int CResourceDirectory::Find(WORD wId) {
- for (unsigned int i = 0; i < m_vEntries.size(); i++) {
- if (m_vEntries[i]->HasName())
- continue;
-
- if (wId == m_vEntries[i]->GetId())
- return i;
- }
-
- return -1;
-}
-
-// Get the size of this resource directory (including all of its children)
-DWORD CResourceDirectory::GetSize() {
- DWORD dwSize = sizeof(IMAGE_RESOURCE_DIRECTORY);
- for (unsigned int i = 0; i < m_vEntries.size(); i++) {
- dwSize += sizeof(MY_IMAGE_RESOURCE_DIRECTORY_ENTRY);
- if (m_vEntries[i]->HasName())
- dwSize += sizeof(IMAGE_RESOURCE_DIR_STRING_U) + (m_vEntries[i]->GetNameLength()+1)*sizeof(WCHAR);
- if (m_vEntries[i]->IsDataDirectory())
- dwSize += m_vEntries[i]->GetSubDirectory()->GetSize();
- else {
- DWORD dwAligned = m_vEntries[i]->GetDataEntry()->GetSize();
- ALIGN(dwAligned, 8);
- dwSize += sizeof(IMAGE_RESOURCE_DATA_ENTRY) + dwAligned;
- }
- }
- return dwSize;
-}
-
-// Destroys this directory and all of its children
-void CResourceDirectory::Destroy() {
- for (unsigned int i = 0; i < m_vEntries.size(); i++) {
- if (m_vEntries[i]->IsDataDirectory()) {
- m_vEntries[i]->GetSubDirectory()->Destroy();
- delete m_vEntries[i]->GetSubDirectory();
- }
- else
- delete m_vEntries[i]->GetDataEntry();
- }
-}
-
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
-// CResourceDirectoryEntry
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-CResourceDirectoryEntry::CResourceDirectoryEntry(WCHAR* szName, CResourceDirectory* rdSubDir) {
- if (IS_INTRESOURCE(szName)) {
- m_bHasName = false;
- m_szName = 0;
- m_wId = (WORD) (DWORD) szName;
- }
- else {
- m_bHasName = true;
- m_szName = winchar_strdup(szName);
- }
- m_bIsDataDirectory = true;
- m_rdSubDir = rdSubDir;
-}
-
-CResourceDirectoryEntry::CResourceDirectoryEntry(WCHAR* szName, CResourceDataEntry* rdeData) {
- if (IS_INTRESOURCE(szName)) {
- m_bHasName = false;
- m_szName = 0;
- m_wId = (WORD) (DWORD) szName;
- }
- else {
- m_bHasName = true;
- m_szName = winchar_strdup(szName);
- }
- m_bIsDataDirectory = false;
- m_rdeData = rdeData;
-}
-
-CResourceDirectoryEntry::~CResourceDirectoryEntry() {
- if (m_szName && m_bHasName)
- delete [] m_szName;
-}
-
-//////////////////////////////////////////////////////////////////////
-// Methods
-//////////////////////////////////////////////////////////////////////
-
-bool CResourceDirectoryEntry::HasName() {
- return m_bHasName;
-}
-
-// Don't forget to free the memory used by the string after usage!
-WCHAR* CResourceDirectoryEntry::GetName() {
- if (!m_bHasName)
- return 0;
- return winchar_strdup(m_szName);
-}
-
-int CResourceDirectoryEntry::GetNameLength() {
- return winchar_strlen(m_szName);
-}
-
-WORD CResourceDirectoryEntry::GetId() {
- if (m_bHasName)
- return 0;
- return m_wId;
-}
-
-bool CResourceDirectoryEntry::IsDataDirectory() {
- return m_bIsDataDirectory;
-}
-
-CResourceDirectory* CResourceDirectoryEntry::GetSubDirectory() {
- if (!m_bIsDataDirectory)
- return NULL;
- return m_rdSubDir;
-}
-
-CResourceDataEntry* CResourceDirectoryEntry::GetDataEntry() {
- if (m_bIsDataDirectory)
- return NULL;
- return m_rdeData;
-}
-
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
-// CResourceDataEntry
-//////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-CResourceDataEntry::CResourceDataEntry(BYTE* pbData, DWORD dwSize, DWORD dwCodePage) {
- m_pbData = 0;
- SetData(pbData, dwSize, dwCodePage);
-}
-
-CResourceDataEntry::~CResourceDataEntry() {
- if (m_pbData)
- delete [] m_pbData;
-}
-
-//////////////////////////////////////////////////////////////////////
-// Methods
-//////////////////////////////////////////////////////////////////////
-
-// To save memory this function doesn't give you a copy of the data
-// Don't mess with the data returned from this function!
-BYTE* CResourceDataEntry::GetData() {
- return m_pbData;
-}
-
-void CResourceDataEntry::SetData(BYTE* pbData, DWORD dwSize) {
- SetData(pbData, dwSize, m_dwCodePage);
-}
-
-void CResourceDataEntry::SetData(BYTE* pbData, DWORD dwSize, DWORD dwCodePage) {
- if (m_pbData) delete [] m_pbData;
- m_pbData = new BYTE[dwSize];
- CopyMemory(m_pbData, pbData, dwSize);
- m_dwSize = dwSize;
- m_dwCodePage = dwCodePage;
-}
-
-DWORD CResourceDataEntry::GetSize() {
- return m_dwSize;
-}
-
-DWORD CResourceDataEntry::GetCodePage() {
- return m_dwCodePage;
-}
+/*
+ * ResourceEditor.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 2002-2007 Amir Szekely <kichik@users.sourceforge.net>
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "ResourceEditor.h"
+#include "util.h"
+#include "winchar.h"
+#include <queue>
+using namespace std;
+
+//////////////////////////////////////////////////////////////////////
+// Utilities
+//////////////////////////////////////////////////////////////////////
+
+#define ALIGN(dwToAlign, dwAlignOn) dwToAlign = (dwToAlign%dwAlignOn == 0) ? dwToAlign : dwToAlign - (dwToAlign%dwAlignOn) + dwAlignOn
+#define RALIGN(dwToAlign, dwAlignOn) ((dwToAlign%dwAlignOn == 0) ? dwToAlign : dwToAlign - (dwToAlign%dwAlignOn) + dwAlignOn)
+
+#ifndef _WIN32
+static inline ULONG ConvertEndianness(ULONG u) {
+ return FIX_ENDIAN_INT32(u);
+}
+#endif
+
+static inline DWORD ConvertEndianness(DWORD d) {
+ return FIX_ENDIAN_INT32(d);
+}
+
+static inline LONG ConvertEndianness(LONG l) {
+ return FIX_ENDIAN_INT32(l);
+}
+
+static inline WORD ConvertEndianness(WORD w) {
+ return FIX_ENDIAN_INT16(w);
+}
+
+PIMAGE_NT_HEADERS CResourceEditor::GetNTHeaders(BYTE* pbPE) {
+ // Get dos header
+ PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER) pbPE;
+ if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
+ throw runtime_error("PE file contains invalid DOS header");
+
+ // Get NT headers
+ PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(pbPE + ConvertEndianness(dosHeader->e_lfanew));
+ if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
+ throw runtime_error("PE file missing NT signature");
+
+ // Make sure this is a supported PE format
+ if (ntHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
+ ntHeaders->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+ throw runtime_error("Unsupported PE format");
+
+ return ntHeaders;
+}
+
+PRESOURCE_DIRECTORY CResourceEditor::GetResourceDirectory(
+ BYTE* pbPE,
+ DWORD dwSize,
+ PIMAGE_NT_HEADERS ntHeaders,
+ DWORD *pdwResSecVA /*=NULL*/,
+ DWORD *pdwSectionIndex /*=NULL*/
+) {
+ PIMAGE_DATA_DIRECTORY dataDirectory = *GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, DataDirectory);
+ DWORD dwNumberOfRvaAndSizes = *GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, NumberOfRvaAndSizes);
+
+ if (ConvertEndianness(dwNumberOfRvaAndSizes) <= IMAGE_DIRECTORY_ENTRY_RESOURCE)
+ throw runtime_error("No resource section found");
+ // Get resource section virtual address
+ DWORD dwResSecVA = ConvertEndianness(dataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
+ // Pointer to the sections headers array
+ PIMAGE_SECTION_HEADER sectionHeadersArray = IMAGE_FIRST_SECTION(ntHeaders);
+
+ DWORD dwSectionIndex = (DWORD) -1;
+
+ // Find resource section index in the array
+ for (int i = 0; i < ConvertEndianness(ntHeaders->FileHeader.NumberOfSections); i++) {
+ if (dwResSecVA == ConvertEndianness(sectionHeadersArray[i].VirtualAddress)) {
+ // Remember resource section index
+ dwSectionIndex = i;
+ // Check for invalid resource section pointer
+ if (!sectionHeadersArray[i].PointerToRawData)
+ throw runtime_error("Invalid resource section pointer");
+
+ break;
+ }
+
+ // Invalid section pointer (goes beyond the PE image)
+ if (ConvertEndianness(sectionHeadersArray[i].PointerToRawData) > dwSize)
+ throw runtime_error("Invalid section pointer");
+ }
+
+ // No resource section...
+ if (dwSectionIndex == (DWORD) -1)
+ throw runtime_error("PE file doesn't contain any resource section");
+
+ // Return extra parameters
+ if (pdwSectionIndex)
+ *pdwSectionIndex = dwSectionIndex;
+ if (pdwResSecVA)
+ *pdwResSecVA = dwResSecVA;
+
+ // Pointer to section data, the first resource directory
+ DWORD dwResSecPtr = ConvertEndianness(sectionHeadersArray[dwSectionIndex].PointerToRawData);
+ return PRESOURCE_DIRECTORY(pbPE + dwResSecPtr);
+}
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+// CResourceEditor
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CResourceEditor::CResourceEditor(BYTE* pbPE, int iSize) {
+ // Copy the data pointer
+ m_pbPE = pbPE;
+ m_iSize = iSize;
+
+ // Get NT headers
+ m_ntHeaders = GetNTHeaders(m_pbPE);
+
+ // No check sum support yet...
+ DWORD* pdwCheckSum = GetMemberFromOptionalHeader(m_ntHeaders->OptionalHeader, CheckSum);
+ if (*pdwCheckSum)
+ {
+ // clear checksum (should be [re]calculated after all changes done)
+ pdwCheckSum = 0;
+ //throw runtime_error("CResourceEditor doesn't yet support check sum");
+ }
+
+ // Get resource section virtual address, resource section index and pointer to resource directory
+ PRESOURCE_DIRECTORY rdRoot = GetResourceDirectory(m_pbPE, iSize, m_ntHeaders, &m_dwResourceSectionVA, &m_dwResourceSectionIndex);
+
+ // Scan the resource directory
+ m_cResDir = ScanDirectory(rdRoot, rdRoot);
+}
+
+CResourceEditor::~CResourceEditor() {
+ if (m_cResDir) {
+ m_cResDir->Destroy();
+ delete m_cResDir;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// Methods
+//////////////////////////////////////////////////////////////////////
+
+// Adds/Replaces/Removes a resource.
+// If lpData is 0 UpdateResource removes the resource.
+bool CResourceEditor::UpdateResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
+ CResourceDirectory* nameDir = 0;
+ CResourceDirectory* langDir = 0;
+ CResourceDataEntry* data = 0;
+ IMAGE_RESOURCE_DIRECTORY rd = {0, /*time(0),*/};
+ int iTypeIdx = -1, iNameIdx = -1, iLangIdx = -1;
+
+ iTypeIdx = m_cResDir->Find(szType);
+ if (iTypeIdx > -1) {
+ nameDir = m_cResDir->GetEntry(iTypeIdx)->GetSubDirectory();
+ iNameIdx = nameDir->Find(szName);
+ if (iNameIdx > -1) {
+ langDir = nameDir->GetEntry(iNameIdx)->GetSubDirectory();
+ iLangIdx = langDir->Find(wLanguage);
+ if (iLangIdx > -1) {
+ data = langDir->GetEntry(iLangIdx)->GetDataEntry();
+ }
+ }
+ }
+
+ if (lpData) {
+ // Replace/Add the resource
+ if (data) {
+ data->SetData(lpData, dwSize);
+ return true;
+ }
+
+ if (!nameDir) {
+ // Type doesn't yet exist
+ nameDir = new CResourceDirectory(&rd);
+ m_cResDir->AddEntry(new CResourceDirectoryEntry(szType, nameDir));
+ }
+ if (!langDir) {
+ // Name doesn't yet exist
+ langDir = new CResourceDirectory(&rd);
+ nameDir->AddEntry(new CResourceDirectoryEntry(szName, langDir));
+ }
+ if (!data) {
+ // Language doesn't yet exist, hence data nither
+ data = new CResourceDataEntry(lpData, dwSize);
+ langDir->AddEntry(new CResourceDirectoryEntry(MAKEINTRESOURCEW(wLanguage), data));
+ }
+ }
+ else if (data) {
+ // Delete the resource
+ delete data;
+ langDir->RemoveEntry(iLangIdx);
+ // Delete directories holding the resource if empty
+ if (!langDir->CountEntries()) {
+ delete langDir;
+ nameDir->RemoveEntry(iNameIdx);
+ if (!nameDir->CountEntries()) {
+ delete nameDir;
+ m_cResDir->RemoveEntry(iTypeIdx);
+ }
+ }
+ }
+ else return false;
+ return true;
+}
+
+static WCHAR* ResStringToUnicode(const char *szString) {
+ if (IS_INTRESOURCE(szString))
+ return MAKEINTRESOURCEW((ULONG_PTR)szString);
+ else
+ return winchar_fromansi(szString);
+}
+
+static void FreeUnicodeResString(WCHAR* szwString) {
+ if (!IS_INTRESOURCE(szwString))
+ delete [] szwString;
+}
+
+bool CResourceEditor::UpdateResourceW(WORD szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
+ return UpdateResourceW(MAKEINTRESOURCEW(szType), szName, wLanguage, lpData, dwSize);
+}
+
+bool CResourceEditor::UpdateResourceW(WCHAR* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
+ return UpdateResourceW(szType, MAKEINTRESOURCEW(szName), wLanguage, lpData, dwSize);
+}
+
+bool CResourceEditor::UpdateResourceA(char* szType, char* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
+ WCHAR* szwType = ResStringToUnicode(szType);
+ WCHAR* szwName = ResStringToUnicode(szName);
+
+ bool result = UpdateResourceW(szwType, szwName, wLanguage, lpData, dwSize);
+
+ FreeUnicodeResString(szwType);
+ FreeUnicodeResString(szwName);
+
+ return result;
+}
+
+bool CResourceEditor::UpdateResourceA(WORD szType, char* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
+ return UpdateResourceA(MAKEINTRESOURCE(szType), szName, wLanguage, lpData, dwSize);
+}
+
+bool CResourceEditor::UpdateResourceA(char* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
+ return UpdateResourceA(szType, MAKEINTRESOURCE(szName), wLanguage, lpData, dwSize);
+}
+
+bool CResourceEditor::UpdateResource(WORD szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
+ return UpdateResourceW(MAKEINTRESOURCEW(szType), MAKEINTRESOURCEW(szName), wLanguage, lpData, dwSize);
+}
+
+// Returns a copy of the requested resource
+// Returns 0 if the requested resource can't be found
+BYTE* CResourceEditor::GetResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage) {
+ CResourceDirectory* nameDir = 0;
+ CResourceDirectory* langDir = 0;
+ CResourceDataEntry* data = 0;
+
+ int i = m_cResDir->Find(szType);
+ if (i > -1) {
+ nameDir = m_cResDir->GetEntry(i)->GetSubDirectory();
+ i = nameDir->Find(szName);
+ if (i > -1) {
+ langDir = nameDir->GetEntry(i)->GetSubDirectory();
+ i = 0;
+ if (wLanguage)
+ i = langDir->Find(wLanguage);
+ if (i > -1) {
+ data = langDir->GetEntry(i)->GetDataEntry();
+ }
+ }
+ }
+
+ if (data) {
+ BYTE* toReturn = new BYTE[data->GetSize()];
+ CopyMemory(toReturn, data->GetData(), data->GetSize());
+ return toReturn;
+ }
+ else
+ return NULL;
+}
+
+BYTE* CResourceEditor::GetResourceA(char* szType, char* szName, LANGID wLanguage) {
+ WCHAR* szwType = ResStringToUnicode(szType);
+ WCHAR* szwName = ResStringToUnicode(szName);
+
+ BYTE* result = GetResourceW(szwType, szwName, wLanguage);
+
+ FreeUnicodeResString(szwType);
+ FreeUnicodeResString(szwName);
+
+ return result;
+}
+
+// Returns the size of the requested resource
+// Returns -1 if the requested resource can't be found
+int CResourceEditor::GetResourceSizeW(WCHAR* szType, WCHAR* szName, LANGID wLanguage) {
+ CResourceDirectory* nameDir = 0;
+ CResourceDirectory* langDir = 0;
+ CResourceDataEntry* data = 0;
+
+ int i = m_cResDir->Find(szType);
+ if (i > -1) {
+ nameDir = m_cResDir->GetEntry(i)->GetSubDirectory();
+ i = nameDir->Find(szName);
+ if (i > -1) {
+ langDir = nameDir->GetEntry(i)->GetSubDirectory();
+ i = 0;
+ if (wLanguage)
+ i = langDir->Find(wLanguage);
+ if (i > -1) {
+ data = langDir->GetEntry(i)->GetDataEntry();
+ }
+ }
+ }
+
+ if (data)
+ return (int) data->GetSize();
+ else
+ return -1;
+}
+
+int CResourceEditor::GetResourceSizeA(char* szType, char* szName, LANGID wLanguage) {
+ WCHAR* szwType = ResStringToUnicode(szType);
+ WCHAR* szwName = ResStringToUnicode(szName);
+
+ int result = GetResourceSizeW(szwType, szwName, wLanguage);
+
+ FreeUnicodeResString(szwType);
+ FreeUnicodeResString(szwName);
+
+ return result;
+}
+
+// Returns the offset of the requested resource in the original PE
+// Returns -1 if the requested resource can't be found
+DWORD CResourceEditor::GetResourceOffsetW(WCHAR* szType, WCHAR* szName, LANGID wLanguage) {
+ CResourceDirectory* nameDir = 0;
+ CResourceDirectory* langDir = 0;
+ CResourceDataEntry* data = 0;
+
+ int i = m_cResDir->Find(szType);
+ if (i > -1) {
+ nameDir = m_cResDir->GetEntry(i)->GetSubDirectory();
+ i = nameDir->Find(szName);
+ if (i > -1) {
+ langDir = nameDir->GetEntry(i)->GetSubDirectory();
+ i = 0;
+ if (wLanguage)
+ i = langDir->Find(wLanguage);
+ if (i > -1) {
+ data = langDir->GetEntry(i)->GetDataEntry();
+ }
+ }
+ }
+
+ if (data)
+ return data->GetOffset();
+ else
+ return DWORD(-1);
+}
+
+DWORD CResourceEditor::GetResourceOffsetA(char* szType, char* szName, LANGID wLanguage) {
+ WCHAR* szwType = ResStringToUnicode(szType);
+ WCHAR* szwName = ResStringToUnicode(szName);
+
+ DWORD result = GetResourceOffsetW(szwType, szwName, wLanguage);
+
+ FreeUnicodeResString(szwType);
+ FreeUnicodeResString(szwName);
+
+ return result;
+}
+
+void CResourceEditor::FreeResource(BYTE* pbResource)
+{
+ if (pbResource)
+ delete [] pbResource;
+}
+
+// Saves the edited PE into a buffer and returns it.
+DWORD CResourceEditor::Save(BYTE* pbBuf, DWORD &dwSize) {
+ unsigned int i;
+ DWORD dwReqSize;
+
+ DWORD dwFileAlign = ConvertEndianness(m_ntHeaders->OptionalHeader.FileAlignment);
+ DWORD dwSecAlign = ConvertEndianness(m_ntHeaders->OptionalHeader.SectionAlignment);
+
+ DWORD dwRsrcSize = m_cResDir->GetSize(); // Size of new resource section
+ DWORD dwRsrcSizeAligned = RALIGN(dwRsrcSize, dwFileAlign); // Align it to FileAlignment
+
+ // Calculate the total new PE size
+ DWORD dwOldRsrcSize = ConvertEndianness(IMAGE_FIRST_SECTION(m_ntHeaders)[m_dwResourceSectionIndex].SizeOfRawData);
+ dwReqSize = m_iSize - dwOldRsrcSize + dwRsrcSizeAligned;
+
+ if (!pbBuf || dwSize < dwReqSize)
+ return dwReqSize;
+
+ // Use buffer
+ BYTE* pbNewPE = pbBuf;
+ dwSize = dwReqSize;
+ // Fill buffer with zeros
+ ZeroMemory(pbNewPE, dwSize);
+
+ BYTE* seeker = pbNewPE;
+ BYTE* oldSeeker = m_pbPE;
+
+ PIMAGE_SECTION_HEADER old_sectionHeadersArray = IMAGE_FIRST_SECTION(m_ntHeaders);
+
+ DWORD dwHeaderSize = ConvertEndianness(old_sectionHeadersArray[m_dwResourceSectionIndex].PointerToRawData);
+ WORD wNumberOfSections = ConvertEndianness(m_ntHeaders->FileHeader.NumberOfSections);
+
+ // Copy everything until the resource section (including headers and everything that might come after them)
+ // We don't use SizeOfHeaders because sometimes (using VC6) it can extend beyond the first section
+ // or (Borland) there could be some more information between the headers and the first section.
+ CopyMemory(seeker, oldSeeker, dwHeaderSize);
+
+ // Skip the headers and whatever comes after them
+ seeker += dwHeaderSize;
+ oldSeeker += dwHeaderSize;
+
+ // Get new nt headers pointer
+ PIMAGE_NT_HEADERS ntHeaders = GetNTHeaders(pbNewPE);
+ // Get a pointer to the new section headers
+ PIMAGE_SECTION_HEADER sectionHeadersArray = IMAGE_FIRST_SECTION(ntHeaders);
+
+ // Skip the resource section in the old PE seeker.
+ oldSeeker += dwOldRsrcSize;
+
+ // Save the old virtual size of the resource section
+ DWORD dwNewVirtualSize = RALIGN(dwRsrcSize, dwSecAlign);
+ DWORD dwOldVirtualSize = ConvertEndianness(sectionHeadersArray[m_dwResourceSectionIndex].Misc.VirtualSize);
+ ALIGN(dwOldVirtualSize, dwSecAlign);
+ DWORD dwVAAdjustment = dwNewVirtualSize - dwOldVirtualSize;
+
+ // Set the new size of the resource section (size aligned to FileAlignment)
+ sectionHeadersArray[m_dwResourceSectionIndex].SizeOfRawData = ConvertEndianness(dwRsrcSizeAligned);
+ // Set the virtual size as well (in memory)
+ sectionHeadersArray[m_dwResourceSectionIndex].Misc.VirtualSize = ConvertEndianness(dwRsrcSize);
+ (*GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, DataDirectory))[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = ConvertEndianness(dwRsrcSize);
+
+ // Set the new virtual size of the image
+ DWORD* pdwSizeOfImage = GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, SizeOfImage);
+ *pdwSizeOfImage = AlignVA(*GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, SizeOfHeaders));
+ for (i = 0; i < wNumberOfSections; i++) {
+ DWORD dwSecSize = ConvertEndianness(sectionHeadersArray[i].Misc.VirtualSize);
+ *pdwSizeOfImage = AlignVA(AdjustVA(*pdwSizeOfImage, dwSecSize));
+ }
+
+ // Set the new AddressOfEntryPoint if needed
+ DWORD* pdwAddressOfEntryPoint = GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, AddressOfEntryPoint);
+ if (ConvertEndianness(*pdwAddressOfEntryPoint) > m_dwResourceSectionVA)
+ *pdwAddressOfEntryPoint = AdjustVA(*pdwAddressOfEntryPoint, dwVAAdjustment);
+
+ // Set the new BaseOfCode if needed
+ DWORD* pdwBaseOfCode = GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, BaseOfCode);
+ if (ConvertEndianness(*pdwBaseOfCode) > m_dwResourceSectionVA)
+ *pdwBaseOfCode = AdjustVA(*pdwBaseOfCode, dwVAAdjustment);
+
+ // Set the new BaseOfData if needed
+ if (ntHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ DWORD* pdwBaseOfData = &((PIMAGE_OPTIONAL_HEADER32)&ntHeaders->OptionalHeader)->BaseOfData;
+ if (*pdwBaseOfData > m_dwResourceSectionVA)
+ *pdwBaseOfData = AdjustVA(*pdwBaseOfData, dwVAAdjustment);
+ }
+
+ // Refresh the headers of the sections that come after the resource section, and the data directory
+ DWORD dwNumberOfRvaAndSizes = *GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, NumberOfRvaAndSizes);
+ PIMAGE_DATA_DIRECTORY pDataDirectory = *GetMemberFromOptionalHeader(ntHeaders->OptionalHeader, DataDirectory);
+ for (i = m_dwResourceSectionIndex + 1; i < wNumberOfSections; i++) {
+ if (sectionHeadersArray[i].PointerToRawData) {
+ AdjustVA(sectionHeadersArray[i].PointerToRawData, dwRsrcSizeAligned - dwOldRsrcSize);
+ }
+
+ // We must find the right data directory entry before we change the virtual address
+ unsigned int uDataDirIdx = 0;
+ for (unsigned int j = 0; j < ConvertEndianness(dwNumberOfRvaAndSizes); j++)
+ if (pDataDirectory[j].VirtualAddress == sectionHeadersArray[i].VirtualAddress)
+ uDataDirIdx = j;
+
+ sectionHeadersArray[i].VirtualAddress = AdjustVA(sectionHeadersArray[i].VirtualAddress, dwVAAdjustment);
+
+ // Change the virtual address in the data directory too
+ if (uDataDirIdx)
+ pDataDirectory[uDataDirIdx].VirtualAddress = sectionHeadersArray[i].VirtualAddress;
+ }
+
+ // Write the resource section
+ WriteRsrcSec(seeker);
+ // Advance the pointer
+ seeker += dwRsrcSizeAligned;
+
+ // Copy everything that comes after the resource section (other sections and tacked data)
+ DWORD dwLeft = m_iSize - (oldSeeker - m_pbPE);
+ if (dwLeft)
+ CopyMemory(seeker, oldSeeker, dwLeft);
+
+ seeker += dwLeft;
+ oldSeeker += dwLeft;
+
+ /**********************************************************
+ * To add checksum to the header use MapFileAndCheckSum
+ **********************************************************/
+
+ // From now on, we are working on the new PE
+ // Freeing the old PE memory is up to the user
+ m_pbPE = pbNewPE;
+ m_iSize = dwSize;
+ m_ntHeaders = ntHeaders;
+ // We just wrote the resource section according to m_cResDir, so we don't need to rescan
+ // m_dwResourceSectionIndex and m_dwResourceSectionVA have also been left unchanged as
+ // we didn't move the resources section
+
+ return 0;
+}
+
+// This function scans exe sections and after find a match with given name
+// increments it's virtual size (auto fixes image size based on section alignment, etc)
+bool CResourceEditor::AddExtraVirtualSize2PESection(const char* pszSectionName, int addsize)
+{
+ PIMAGE_SECTION_HEADER sectionHeadersArray = IMAGE_FIRST_SECTION(m_ntHeaders);
+
+ // Refresh the headers of the sections that come after the resource section, and the data directory
+ for (int i = 0; i < ConvertEndianness(m_ntHeaders->FileHeader.NumberOfSections); i++) {
+ if (!strcmp((LPCSTR)sectionHeadersArray[i].Name, pszSectionName)) {
+ sectionHeadersArray[i].Misc.VirtualSize = AlignVA(AdjustVA(sectionHeadersArray[i].Misc.VirtualSize, addsize));
+
+ sectionHeadersArray[i].Characteristics &= ConvertEndianness((DWORD) ~IMAGE_SCN_MEM_DISCARDABLE);
+
+ // now fix any section after
+ for (int k = i + 1; k < ConvertEndianness(m_ntHeaders->FileHeader.NumberOfSections); k++, i++) {
+ DWORD dwLastSecVA = ConvertEndianness(sectionHeadersArray[i].VirtualAddress);
+ DWORD dwLastSecSize = ConvertEndianness(sectionHeadersArray[i].Misc.VirtualSize);
+ DWORD dwSecVA = AlignVA(ConvertEndianness(dwLastSecVA + dwLastSecSize));
+
+ sectionHeadersArray[k].VirtualAddress = dwSecVA;
+
+ if (m_dwResourceSectionIndex == (DWORD) k)
+ {
+ // fix the resources virtual address if it changed
+ PIMAGE_DATA_DIRECTORY pDataDirectory = *GetMemberFromOptionalHeader(m_ntHeaders->OptionalHeader, DataDirectory);
+ pDataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = dwSecVA;
+ m_dwResourceSectionVA = ConvertEndianness(dwSecVA);
+ }
+ }
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Private Methods
+//////////////////////////////////////////////////////////////////////
+
+// This function scans a give resource directory and return a CResourceDirectory object
+// rdRoot must point to the root directory of the resource section
+CResourceDirectory* CResourceEditor::ScanDirectory(PRESOURCE_DIRECTORY rdRoot, PRESOURCE_DIRECTORY rdToScan) {
+ // Create CResourceDirectory from rdToScan
+ CResourceDirectory* rdc = new CResourceDirectory(PIMAGE_RESOURCE_DIRECTORY(rdToScan));
+ WCHAR* szName;
+ PIMAGE_RESOURCE_DATA_ENTRY rde = NULL;
+
+ // Go through all entries of this resource directory
+ int entries = ConvertEndianness(rdToScan->Header.NumberOfNamedEntries);
+ entries += ConvertEndianness(rdToScan->Header.NumberOfIdEntries);
+
+ for (int i = 0; i < entries; i++) {
+ MY_IMAGE_RESOURCE_DIRECTORY_ENTRY rd = rdToScan->Entries[i];
+ rd.UOffset.OffsetToData = ConvertEndianness(rd.UOffset.OffsetToData);
+ rd.UName.Name = ConvertEndianness(rd.UName.Name);
+
+ // If this entry points to data entry get a pointer to it
+ if (!rd.UOffset.DirectoryOffset.DataIsDirectory)
+ rde = PIMAGE_RESOURCE_DATA_ENTRY(rd.UOffset.OffsetToData + (BYTE*)rdRoot);
+
+ // If this entry has a name, translate it from Unicode
+ if (rd.UName.NameString.NameIsString) {
+ PIMAGE_RESOURCE_DIR_STRING_U rds = PIMAGE_RESOURCE_DIR_STRING_U(rd.UName.NameString.NameOffset + (char*)rdRoot);
+
+ size_t nameSize = ConvertEndianness(rds->Length);
+ szName = new WCHAR[nameSize+1];
+ winchar_strncpy(szName, rds->NameString, nameSize);
+ szName[nameSize] = 0;
+ }
+ // Else, set the name to this entry's id
+ else
+ szName = MAKEINTRESOURCEW(ConvertEndianness(rdToScan->Entries[i].UName.Id));
+
+ if (rd.UOffset.DirectoryOffset.DataIsDirectory)
+ {
+ rdc->AddEntry(
+ new CResourceDirectoryEntry(
+ szName,
+ ScanDirectory(
+ rdRoot,
+ PRESOURCE_DIRECTORY(rd.UOffset.DirectoryOffset.OffsetToDirectory + (LPBYTE)rdRoot)
+ )
+ )
+ );
+ }
+ else
+ {
+ LPBYTE pbData = (LPBYTE)rdRoot + ConvertEndianness(rde->OffsetToData) - m_dwResourceSectionVA;
+ DWORD dwOffset = DWORD(pbData - m_pbPE);
+
+ rdc->AddEntry(
+ new CResourceDirectoryEntry(
+ szName,
+ new CResourceDataEntry(
+ pbData,
+ ConvertEndianness(rde->Size),
+ ConvertEndianness(rde->CodePage),
+ dwOffset
+ )
+ )
+ );
+ }
+
+ // Delete the dynamicly allocated name if it is a name and not an id
+ if (!IS_INTRESOURCE(szName))
+ delete [] szName;
+ }
+
+ return rdc;
+}
+
+// This function writes into a given place in memory (pbRsrcSec) the edited resource section
+void CResourceEditor::WriteRsrcSec(BYTE* pbRsrcSec) {
+ BYTE* seeker = pbRsrcSec;
+
+ queue<CResourceDirectory*> qDirs; // Used to scan the tree by level
+ queue<CResourceDataEntry*> qDataEntries; // Used for writing the data entries
+ queue<CResourceDataEntry*> qDataEntries2; // Used for writing raw resources data
+ queue<CResourceDirectoryEntry*> qStrings; // Used for writing resources' names
+
+ qDirs.push(m_cResDir);
+
+ while (!qDirs.empty()) {
+ CResourceDirectory* crd = qDirs.front();
+
+ IMAGE_RESOURCE_DIRECTORY rdDir = crd->GetInfo();
+
+ rdDir.NumberOfNamedEntries = ConvertEndianness(rdDir.NumberOfNamedEntries);
+ rdDir.NumberOfIdEntries = ConvertEndianness(rdDir.NumberOfIdEntries);
+
+ CopyMemory(seeker, &rdDir, sizeof(IMAGE_RESOURCE_DIRECTORY));
+ crd->m_dwWrittenAt = DWORD(seeker);
+ seeker += sizeof(IMAGE_RESOURCE_DIRECTORY);
+
+ for (int i = 0; i < crd->CountEntries(); i++) {
+ if (crd->GetEntry(i)->HasName())
+ qStrings.push(crd->GetEntry(i));
+ if (crd->GetEntry(i)->IsDataDirectory())
+ qDirs.push(crd->GetEntry(i)->GetSubDirectory());
+ else {
+ qDataEntries.push(crd->GetEntry(i)->GetDataEntry());
+ qDataEntries2.push(crd->GetEntry(i)->GetDataEntry());
+ }
+
+ MY_IMAGE_RESOURCE_DIRECTORY_ENTRY rDirE;
+ ZeroMemory(&rDirE, sizeof(rDirE));
+ rDirE.UOffset.DirectoryOffset.DataIsDirectory = crd->GetEntry(i)->IsDataDirectory();
+ rDirE.UName.Id = crd->GetEntry(i)->HasName() ? 0 : crd->GetEntry(i)->GetId();
+ rDirE.UName.Id = ConvertEndianness(rDirE.UName.Id);
+ rDirE.UName.NameString.NameIsString = (crd->GetEntry(i)->HasName()) ? 1 : 0;
+
+ CopyMemory(seeker, &rDirE, sizeof(MY_IMAGE_RESOURCE_DIRECTORY_ENTRY));
+ crd->GetEntry(i)->m_dwWrittenAt = DWORD(seeker);
+ seeker += sizeof(MY_IMAGE_RESOURCE_DIRECTORY_ENTRY);
+ }
+ qDirs.pop();
+ }
+
+ /*
+ * Write IMAGE_RESOURCE_DATA_ENTRYs.
+ */
+ while (!qDataEntries.empty()) {
+ CResourceDataEntry* cRDataE = qDataEntries.front();
+ IMAGE_RESOURCE_DATA_ENTRY rDataE = {0,};
+ rDataE.CodePage = ConvertEndianness(cRDataE->GetCodePage());
+ rDataE.Size = ConvertEndianness(cRDataE->GetSize());
+
+ CopyMemory(seeker, &rDataE, sizeof(IMAGE_RESOURCE_DATA_ENTRY));
+ cRDataE->m_dwWrittenAt = DWORD(seeker);
+ seeker += sizeof(IMAGE_RESOURCE_DATA_ENTRY);
+
+ qDataEntries.pop();
+ }
+
+ /*
+ * Write strings
+ */
+ while (!qStrings.empty()) {
+ CResourceDirectoryEntry* cRDirE = qStrings.front();
+
+ PMY_IMAGE_RESOURCE_DIRECTORY_ENTRY(cRDirE->m_dwWrittenAt)->UName.NameString.NameOffset = ConvertEndianness(DWORD(seeker) - DWORD(pbRsrcSec));
+
+ WCHAR* szName = cRDirE->GetName();
+ WORD iLen = winchar_strlen(szName) + 1;
+
+ *(WORD*)seeker = ConvertEndianness(iLen);
+ CopyMemory(seeker + sizeof(WORD), szName, iLen*sizeof(WCHAR));
+
+ seeker += RALIGN(iLen * sizeof(WCHAR) + sizeof(WORD), 4);
+
+ delete [] szName;
+
+ qStrings.pop();
+ }
+
+ /*
+ * Write raw resource data and set offsets in IMAGE_RESOURCE_DATA_ENTRYs.
+ */
+ while (!qDataEntries2.empty()) {
+ CResourceDataEntry* cRDataE = qDataEntries2.front();
+ CopyMemory(seeker, cRDataE->GetData(), cRDataE->GetSize());
+ PIMAGE_RESOURCE_DATA_ENTRY(cRDataE->m_dwWrittenAt)->OffsetToData = ConvertEndianness(seeker - pbRsrcSec + m_dwResourceSectionVA);
+
+ seeker += RALIGN(cRDataE->GetSize(), 8);
+
+ qDataEntries2.pop();
+ }
+
+ /*
+ * Set all of the directory entries offsets.
+ */
+ SetOffsets(m_cResDir, DWORD(pbRsrcSec));
+}
+
+// Sets the offsets in directory entries
+void CResourceEditor::SetOffsets(CResourceDirectory* resDir, DWORD newResDirAt) {
+ for (int i = 0; i < resDir->CountEntries(); i++) {
+ PMY_IMAGE_RESOURCE_DIRECTORY_ENTRY rde = PMY_IMAGE_RESOURCE_DIRECTORY_ENTRY(resDir->GetEntry(i)->m_dwWrittenAt);
+ if (resDir->GetEntry(i)->IsDataDirectory()) {
+ rde->UOffset.DirectoryOffset.DataIsDirectory = 1;
+ rde->UOffset.DirectoryOffset.OffsetToDirectory = resDir->GetEntry(i)->GetSubDirectory()->m_dwWrittenAt - newResDirAt;
+ rde->UOffset.OffsetToData = ConvertEndianness(rde->UOffset.OffsetToData);
+ SetOffsets(resDir->GetEntry(i)->GetSubDirectory(), newResDirAt);
+ }
+ else {
+ rde->UOffset.OffsetToData = ConvertEndianness(resDir->GetEntry(i)->GetDataEntry()->m_dwWrittenAt - newResDirAt);
+ }
+ }
+}
+
+// Adjusts a virtual address by a specific amount
+DWORD CResourceEditor::AdjustVA(DWORD dwVirtualAddress, DWORD dwAdjustment) {
+ dwVirtualAddress = ConvertEndianness(dwVirtualAddress);
+ dwVirtualAddress += dwAdjustment;
+ dwVirtualAddress = ConvertEndianness(dwVirtualAddress);
+
+ return dwVirtualAddress;
+}
+
+// Aligns a virtual address to the section alignment
+DWORD CResourceEditor::AlignVA(DWORD dwVirtualAddress) {
+ DWORD dwSectionAlignment = *GetMemberFromOptionalHeader(m_ntHeaders->OptionalHeader, SectionAlignment);
+ DWORD dwAlignment = ConvertEndianness(dwSectionAlignment);
+
+ dwVirtualAddress = ConvertEndianness(dwVirtualAddress);
+ dwVirtualAddress = RALIGN(dwVirtualAddress, dwAlignment);
+ dwVirtualAddress = ConvertEndianness(dwVirtualAddress);
+
+ return dwVirtualAddress;
+}
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+// CResourceDirectory
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CResourceDirectory::CResourceDirectory(PIMAGE_RESOURCE_DIRECTORY prd) {
+ m_rdDir = *prd;
+ m_rdDir.NumberOfIdEntries = 0;
+ m_rdDir.NumberOfNamedEntries = 0;
+}
+
+CResourceDirectory::~CResourceDirectory() {
+}
+
+//////////////////////////////////////////////////////////////////////
+// Methods
+//////////////////////////////////////////////////////////////////////
+
+IMAGE_RESOURCE_DIRECTORY CResourceDirectory::GetInfo() {
+ return m_rdDir;
+}
+
+CResourceDirectoryEntry* CResourceDirectory::GetEntry(unsigned int i) {
+ if (m_vEntries.size() < i)
+ return 0;
+ return m_vEntries[i];
+}
+
+// This function inserts a new directory entry
+// It also keeps the directory entries sorted
+void CResourceDirectory::AddEntry(CResourceDirectoryEntry* entry) {
+ int i = 0;
+ if (entry->HasName()) {
+ WCHAR* szEntName = entry->GetName();
+ for (i = 0; i < m_rdDir.NumberOfNamedEntries; i++) {
+ WCHAR* szName = m_vEntries[i]->GetName();
+ int cmp = winchar_strcmp(szName, szEntName);
+ delete [] szName;
+ if (cmp == 0) {
+ delete [] szEntName;
+ return;
+ }
+ if (cmp > 0)
+ break;
+ }
+ delete [] szEntName;
+ m_rdDir.NumberOfNamedEntries++;
+ }
+ else {
+ for (i = m_rdDir.NumberOfNamedEntries; i < m_rdDir.NumberOfNamedEntries+m_rdDir.NumberOfIdEntries; i++) {
+ if (m_vEntries[i]->GetId() == entry->GetId())
+ return;
+ if (m_vEntries[i]->GetId() > entry->GetId())
+ break;
+ }
+ m_rdDir.NumberOfIdEntries++;
+ }
+ m_vEntries.insert(m_vEntries.begin() + i, entry);
+}
+
+void CResourceDirectory::RemoveEntry(int i) {
+ if (m_vEntries[i]->HasName())
+ m_rdDir.NumberOfNamedEntries--;
+ else
+ m_rdDir.NumberOfIdEntries--;
+ delete m_vEntries[i];
+ m_vEntries.erase(m_vEntries.begin() + i);
+}
+
+int CResourceDirectory::CountEntries() {
+ return m_vEntries.size();
+}
+
+// Returns the index of a directory entry with the specified name
+// Name can be a string or an id
+// Returns -1 if can not be found
+int CResourceDirectory::Find(WCHAR* szName) {
+ if (IS_INTRESOURCE(szName))
+ return Find((WORD) (DWORD) szName);
+ else
+ if (szName[0] == '#')
+ return Find(WORD(winchar_stoi(szName + 1)));
+
+ for (unsigned int i = 0; i < m_vEntries.size(); i++) {
+ if (!m_vEntries[i]->HasName())
+ continue;
+
+ WCHAR* szEntName = m_vEntries[i]->GetName();
+ int cmp = winchar_strcmp(szName, szEntName);
+ delete [] szEntName;
+
+ if (!cmp)
+ return i;
+ }
+
+ return -1;
+}
+
+// Returns the index of a directory entry with the specified id
+// Returns -1 if can not be found
+int CResourceDirectory::Find(WORD wId) {
+ for (unsigned int i = 0; i < m_vEntries.size(); i++) {
+ if (m_vEntries[i]->HasName())
+ continue;
+
+ if (wId == m_vEntries[i]->GetId())
+ return i;
+ }
+
+ return -1;
+}
+
+// Get the size of this resource directory (including all of its children)
+DWORD CResourceDirectory::GetSize() {
+ DWORD dwSize = sizeof(IMAGE_RESOURCE_DIRECTORY);
+ for (unsigned int i = 0; i < m_vEntries.size(); i++) {
+ dwSize += sizeof(MY_IMAGE_RESOURCE_DIRECTORY_ENTRY);
+ if (m_vEntries[i]->HasName())
+ dwSize += sizeof(IMAGE_RESOURCE_DIR_STRING_U) + (m_vEntries[i]->GetNameLength()+1)*sizeof(WCHAR);
+ if (m_vEntries[i]->IsDataDirectory())
+ dwSize += m_vEntries[i]->GetSubDirectory()->GetSize();
+ else {
+ DWORD dwAligned = m_vEntries[i]->GetDataEntry()->GetSize();
+ ALIGN(dwAligned, 8);
+ dwSize += sizeof(IMAGE_RESOURCE_DATA_ENTRY) + dwAligned;
+ }
+ }
+ return dwSize;
+}
+
+// Destroys this directory and all of its children
+void CResourceDirectory::Destroy() {
+ for (unsigned int i = 0; i < m_vEntries.size(); i++) {
+ if (m_vEntries[i]->IsDataDirectory()) {
+ m_vEntries[i]->GetSubDirectory()->Destroy();
+ delete m_vEntries[i]->GetSubDirectory();
+ }
+ else
+ delete m_vEntries[i]->GetDataEntry();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+// CResourceDirectoryEntry
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CResourceDirectoryEntry::CResourceDirectoryEntry(WCHAR* szName, CResourceDirectory* rdSubDir) {
+ if (IS_INTRESOURCE(szName)) {
+ m_bHasName = false;
+ m_szName = 0;
+ m_wId = (WORD) (DWORD) szName;
+ }
+ else {
+ m_bHasName = true;
+ m_szName = winchar_strdup(szName);
+ }
+ m_bIsDataDirectory = true;
+ m_rdSubDir = rdSubDir;
+}
+
+CResourceDirectoryEntry::CResourceDirectoryEntry(WCHAR* szName, CResourceDataEntry* rdeData) {
+ if (IS_INTRESOURCE(szName)) {
+ m_bHasName = false;
+ m_szName = 0;
+ m_wId = (WORD) (DWORD) szName;
+ }
+ else {
+ m_bHasName = true;
+ m_szName = winchar_strdup(szName);
+ }
+ m_bIsDataDirectory = false;
+ m_rdeData = rdeData;
+}
+
+CResourceDirectoryEntry::~CResourceDirectoryEntry() {
+ if (m_szName && m_bHasName)
+ delete [] m_szName;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Methods
+//////////////////////////////////////////////////////////////////////
+
+bool CResourceDirectoryEntry::HasName() {
+ return m_bHasName;
+}
+
+// Don't forget to free the memory used by the string after usage!
+WCHAR* CResourceDirectoryEntry::GetName() {
+ if (!m_bHasName)
+ return 0;
+ return winchar_strdup(m_szName);
+}
+
+int CResourceDirectoryEntry::GetNameLength() {
+ return winchar_strlen(m_szName);
+}
+
+WORD CResourceDirectoryEntry::GetId() {
+ if (m_bHasName)
+ return 0;
+ return m_wId;
+}
+
+bool CResourceDirectoryEntry::IsDataDirectory() {
+ return m_bIsDataDirectory;
+}
+
+CResourceDirectory* CResourceDirectoryEntry::GetSubDirectory() {
+ if (!m_bIsDataDirectory)
+ return NULL;
+ return m_rdSubDir;
+}
+
+CResourceDataEntry* CResourceDirectoryEntry::GetDataEntry() {
+ if (m_bIsDataDirectory)
+ return NULL;
+ return m_rdeData;
+}
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+// CResourceDataEntry
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CResourceDataEntry::CResourceDataEntry(BYTE* pbData, DWORD dwSize, DWORD dwCodePage, DWORD dwOffset) {
+ m_pbData = 0;
+ SetData(pbData, dwSize, dwCodePage);
+ m_dwOffset = dwOffset;
+}
+
+CResourceDataEntry::~CResourceDataEntry() {
+ if (m_pbData)
+ delete [] m_pbData;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Methods
+//////////////////////////////////////////////////////////////////////
+
+// To save memory this function doesn't give you a copy of the data
+// Don't mess with the data returned from this function!
+BYTE* CResourceDataEntry::GetData() {
+ return m_pbData;
+}
+
+void CResourceDataEntry::SetData(BYTE* pbData, DWORD dwSize) {
+ SetData(pbData, dwSize, m_dwCodePage);
+}
+
+void CResourceDataEntry::SetData(BYTE* pbData, DWORD dwSize, DWORD dwCodePage) {
+ if (m_pbData) delete [] m_pbData;
+ m_pbData = new BYTE[dwSize];
+ CopyMemory(m_pbData, pbData, dwSize);
+ m_dwSize = dwSize;
+ m_dwCodePage = dwCodePage;
+ m_dwOffset = DWORD(-1); // unset
+}
+
+DWORD CResourceDataEntry::GetSize() {
+ return m_dwSize;
+}
+
+DWORD CResourceDataEntry::GetCodePage() {
+ return m_dwCodePage;
+}
+
+DWORD CResourceDataEntry::GetOffset() {
+ return m_dwOffset;
+}
diff --git a/Source/ResourceEditor.h b/Source/ResourceEditor.h
index eb542c8..d821fe2 100755
--- a/Source/ResourceEditor.h
+++ b/Source/ResourceEditor.h
@@ -1,239 +1,243 @@
-/*
- * ResourceEditor.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 2002-2007 Amir Szekely <kichik@users.sourceforge.net>
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#if !defined(AFX_RESOURCEEDITOR_H__683BF710_E805_4093_975B_D5729186A89A__INCLUDED_)
-#define AFX_RESOURCEEDITOR_H__683BF710_E805_4093_975B_D5729186A89A__INCLUDED_
-
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-
-#include <vector>
-
-#include "Platform.h"
-#ifdef _WIN32
-# include <WinNT.h>
-#else
-// all definitions for non Win32 platforms were taken from MinGW's free Win32 library
-# define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
-# define IMAGE_SCN_MEM_DISCARDABLE 0x2000000
-# pragma pack(4)
-typedef struct _IMAGE_RESOURCE_DIRECTORY {
- DWORD Characteristics;
- DWORD TimeDateStamp;
- WORD MajorVersion;
- WORD MinorVersion;
- WORD NumberOfNamedEntries;
- WORD NumberOfIdEntries;
-} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY;
-typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
- DWORD OffsetToData;
- DWORD Size;
- DWORD CodePage;
- DWORD Reserved;
-} IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY;
-typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING {
- WORD Length;
- CHAR NameString[1];
-} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING;
-typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
- WORD Length;
- WCHAR NameString[1];
-} IMAGE_RESOURCE_DIR_STRING_U,*PIMAGE_RESOURCE_DIR_STRING_U;
-# pragma pack()
-#endif
-
-#pragma pack(4)
-typedef struct _MY_IMAGE_RESOURCE_DIRECTORY_ENTRY {
- union {
- struct {
-#ifndef __BIG_ENDIAN__
- DWORD NameOffset:31;
- DWORD NameIsString:1;
-#else
- DWORD NameIsString:1;
- DWORD NameOffset:31;
-#endif
- } NameString;
- DWORD Name;
- WORD Id;
- } UName;
- union {
- DWORD OffsetToData;
- struct {
-#ifndef __BIG_ENDIAN__
- DWORD OffsetToDirectory:31;
- DWORD DataIsDirectory:1;
-#else
- DWORD DataIsDirectory:1;
- DWORD OffsetToDirectory:31;
-#endif
- } DirectoryOffset;
- } UOffset;
-} MY_IMAGE_RESOURCE_DIRECTORY_ENTRY,*PMY_IMAGE_RESOURCE_DIRECTORY_ENTRY;
-
-#pragma pack()
-
-#include <stdexcept>
-
-// classes
-class CResourceDirectory;
-class CResourceDirectoryEntry;
-class CResourceDataEntry;
-
-// Resource directory with entries
-typedef struct RESOURCE_DIRECTORY {
- IMAGE_RESOURCE_DIRECTORY Header;
- MY_IMAGE_RESOURCE_DIRECTORY_ENTRY Entries[1];
-} *PRESOURCE_DIRECTORY;
-
-#define GetMemberFromOptionalHeader(optionalHeader, member) \
- ( (optionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) ? \
- &((PIMAGE_OPTIONAL_HEADER32)&optionalHeader)->member : \
- &((PIMAGE_OPTIONAL_HEADER64)&optionalHeader)->member \
- )
-class CResourceEditor {
-public:
- CResourceEditor(BYTE* pbPE, int iSize);
- virtual ~CResourceEditor();
-
- bool UpdateResource(WORD szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
- bool UpdateResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
- bool UpdateResourceW(WORD szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
- bool UpdateResourceW(WCHAR* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
- bool UpdateResourceA(char* szType, char* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
- bool UpdateResourceA(WORD szType, char* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
- bool UpdateResourceA(char* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
- BYTE* GetResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage);
- BYTE* GetResourceA(char* szType, char* szName, LANGID wLanguage);
- int GetResourceSizeW(WCHAR* szType, WCHAR* szName, LANGID wLanguage);
- int GetResourceSizeA(char* szType, char* szName, LANGID wLanguage);
- void FreeResource(BYTE* pbResource);
-
- bool AddExtraVirtualSize2PESection(const char* pszSectionName, int addsize);
- DWORD Save(BYTE* pbBuf, DWORD &dwSize);
-
- // utitlity functions
- static PIMAGE_NT_HEADERS GetNTHeaders(BYTE* pbPE);
-
- static PRESOURCE_DIRECTORY GetResourceDirectory(
- BYTE* pbPE,
- DWORD dwSize,
- PIMAGE_NT_HEADERS ntHeaders,
- DWORD *pdwResSecVA = NULL,
- DWORD *pdwSectionIndex = NULL
- );
-
-private:
- BYTE* m_pbPE;
- int m_iSize;
-
- PIMAGE_NT_HEADERS m_ntHeaders;
-
- DWORD m_dwResourceSectionIndex;
- DWORD m_dwResourceSectionVA;
-
- CResourceDirectory* m_cResDir;
-
- CResourceDirectory* ScanDirectory(PRESOURCE_DIRECTORY rdRoot, PRESOURCE_DIRECTORY rdToScan);
-
- void WriteRsrcSec(BYTE* pbRsrcSec);
- void SetOffsets(CResourceDirectory* resDir, DWORD newResDirAt);
-
- DWORD AdjustVA(DWORD dwVirtualAddress, DWORD dwAdjustment);
- DWORD AlignVA(DWORD dwVirtualAddress);
-};
-
-class CResourceDirectory {
-public:
- CResourceDirectory(PIMAGE_RESOURCE_DIRECTORY prd);
- virtual ~CResourceDirectory();
-
- IMAGE_RESOURCE_DIRECTORY GetInfo();
-
- CResourceDirectoryEntry* GetEntry(unsigned int i);
- void AddEntry(CResourceDirectoryEntry* entry);
- void RemoveEntry(int i);
- int CountEntries();
- int Find(WCHAR* szName);
- int Find(WORD wId);
-
- DWORD GetSize();
-
- void Destroy();
-
- DWORD m_dwWrittenAt;
-
-private:
- IMAGE_RESOURCE_DIRECTORY m_rdDir;
- std::vector<CResourceDirectoryEntry*> m_vEntries;
-};
-
-class CResourceDirectoryEntry {
-public:
- CResourceDirectoryEntry(WCHAR* szName, CResourceDirectory* rdSubDir);
- CResourceDirectoryEntry(WCHAR* szName, CResourceDataEntry* rdeData);
- virtual ~CResourceDirectoryEntry();
-
- bool HasName();
- WCHAR* GetName();
- int GetNameLength();
-
- WORD GetId();
-
- bool IsDataDirectory();
- CResourceDirectory* GetSubDirectory();
-
- CResourceDataEntry* GetDataEntry();
-
- DWORD m_dwWrittenAt;
-
-private:
- bool m_bHasName;
- WCHAR* m_szName;
- WORD m_wId;
-
- bool m_bIsDataDirectory;
- union {
- CResourceDirectory* m_rdSubDir;
- CResourceDataEntry* m_rdeData;
- };
-};
-
-class CResourceDataEntry {
-public:
- CResourceDataEntry(BYTE* pbData, DWORD dwSize, DWORD dwCodePage = 0);
- ~CResourceDataEntry();
-
- BYTE* GetData();
-
- void SetData(BYTE* pbData, DWORD dwSize);
- void SetData(BYTE* pbData, DWORD dwSize, DWORD dwCodePage);
-
- DWORD GetSize();
- DWORD GetCodePage();
-
- DWORD m_dwWrittenAt;
-
-private:
- BYTE* m_pbData;
- DWORD m_dwSize;
- DWORD m_dwCodePage;
-};
-
-#endif // !defined(AFX_RESOURCEEDITOR_H__683BF710_E805_4093_975B_D5729186A89A__INCLUDED_)
+/*
+ * ResourceEditor.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 2002-2007 Amir Szekely <kichik@users.sourceforge.net>
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#if !defined(AFX_RESOURCEEDITOR_H__683BF710_E805_4093_975B_D5729186A89A__INCLUDED_)
+#define AFX_RESOURCEEDITOR_H__683BF710_E805_4093_975B_D5729186A89A__INCLUDED_
+
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+#include <vector>
+
+#include "Platform.h"
+#ifdef _WIN32
+# include <WinNT.h>
+#else
+// all definitions for non Win32 platforms were taken from MinGW's free Win32 library
+# define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
+# define IMAGE_SCN_MEM_DISCARDABLE 0x2000000
+# pragma pack(4)
+typedef struct _IMAGE_RESOURCE_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ WORD NumberOfNamedEntries;
+ WORD NumberOfIdEntries;
+} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY;
+typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
+ DWORD OffsetToData;
+ DWORD Size;
+ DWORD CodePage;
+ DWORD Reserved;
+} IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY;
+typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING {
+ WORD Length;
+ CHAR NameString[1];
+} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING;
+typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
+ WORD Length;
+ WCHAR NameString[1];
+} IMAGE_RESOURCE_DIR_STRING_U,*PIMAGE_RESOURCE_DIR_STRING_U;
+# pragma pack()
+#endif
+
+#pragma pack(4)
+typedef struct _MY_IMAGE_RESOURCE_DIRECTORY_ENTRY {
+ union {
+ struct {
+#ifndef __BIG_ENDIAN__
+ DWORD NameOffset:31;
+ DWORD NameIsString:1;
+#else
+ DWORD NameIsString:1;
+ DWORD NameOffset:31;
+#endif
+ } NameString;
+ DWORD Name;
+ WORD Id;
+ } UName;
+ union {
+ DWORD OffsetToData;
+ struct {
+#ifndef __BIG_ENDIAN__
+ DWORD OffsetToDirectory:31;
+ DWORD DataIsDirectory:1;
+#else
+ DWORD DataIsDirectory:1;
+ DWORD OffsetToDirectory:31;
+#endif
+ } DirectoryOffset;
+ } UOffset;
+} MY_IMAGE_RESOURCE_DIRECTORY_ENTRY,*PMY_IMAGE_RESOURCE_DIRECTORY_ENTRY;
+
+#pragma pack()
+
+#include <stdexcept>
+
+// classes
+class CResourceDirectory;
+class CResourceDirectoryEntry;
+class CResourceDataEntry;
+
+// Resource directory with entries
+typedef struct RESOURCE_DIRECTORY {
+ IMAGE_RESOURCE_DIRECTORY Header;
+ MY_IMAGE_RESOURCE_DIRECTORY_ENTRY Entries[1];
+} *PRESOURCE_DIRECTORY;
+
+#define GetMemberFromOptionalHeader(optionalHeader, member) \
+ ( (optionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) ? \
+ &((PIMAGE_OPTIONAL_HEADER32)&optionalHeader)->member : \
+ &((PIMAGE_OPTIONAL_HEADER64)&optionalHeader)->member \
+ )
+class CResourceEditor {
+public:
+ CResourceEditor(BYTE* pbPE, int iSize);
+ virtual ~CResourceEditor();
+
+ bool UpdateResource(WORD szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
+ bool UpdateResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
+ bool UpdateResourceW(WORD szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
+ bool UpdateResourceW(WCHAR* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
+ bool UpdateResourceA(char* szType, char* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
+ bool UpdateResourceA(WORD szType, char* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
+ bool UpdateResourceA(char* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
+ BYTE* GetResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage);
+ BYTE* GetResourceA(char* szType, char* szName, LANGID wLanguage);
+ int GetResourceSizeW(WCHAR* szType, WCHAR* szName, LANGID wLanguage);
+ int GetResourceSizeA(char* szType, char* szName, LANGID wLanguage);
+ DWORD GetResourceOffsetW(WCHAR* szType, WCHAR* szName, LANGID wLanguage);
+ DWORD GetResourceOffsetA(char* szType, char* szName, LANGID wLanguage);
+ void FreeResource(BYTE* pbResource);
+
+ bool AddExtraVirtualSize2PESection(const char* pszSectionName, int addsize);
+ DWORD Save(BYTE* pbBuf, DWORD &dwSize);
+
+ // utitlity functions
+ static PIMAGE_NT_HEADERS GetNTHeaders(BYTE* pbPE);
+
+ static PRESOURCE_DIRECTORY GetResourceDirectory(
+ BYTE* pbPE,
+ DWORD dwSize,
+ PIMAGE_NT_HEADERS ntHeaders,
+ DWORD *pdwResSecVA = NULL,
+ DWORD *pdwSectionIndex = NULL
+ );
+
+private:
+ BYTE* m_pbPE;
+ int m_iSize;
+
+ PIMAGE_NT_HEADERS m_ntHeaders;
+
+ DWORD m_dwResourceSectionIndex;
+ DWORD m_dwResourceSectionVA;
+
+ CResourceDirectory* m_cResDir;
+
+ CResourceDirectory* ScanDirectory(PRESOURCE_DIRECTORY rdRoot, PRESOURCE_DIRECTORY rdToScan);
+
+ void WriteRsrcSec(BYTE* pbRsrcSec);
+ void SetOffsets(CResourceDirectory* resDir, DWORD newResDirAt);
+
+ DWORD AdjustVA(DWORD dwVirtualAddress, DWORD dwAdjustment);
+ DWORD AlignVA(DWORD dwVirtualAddress);
+};
+
+class CResourceDirectory {
+public:
+ CResourceDirectory(PIMAGE_RESOURCE_DIRECTORY prd);
+ virtual ~CResourceDirectory();
+
+ IMAGE_RESOURCE_DIRECTORY GetInfo();
+
+ CResourceDirectoryEntry* GetEntry(unsigned int i);
+ void AddEntry(CResourceDirectoryEntry* entry);
+ void RemoveEntry(int i);
+ int CountEntries();
+ int Find(WCHAR* szName);
+ int Find(WORD wId);
+
+ DWORD GetSize();
+
+ void Destroy();
+
+ DWORD m_dwWrittenAt;
+
+private:
+ IMAGE_RESOURCE_DIRECTORY m_rdDir;
+ std::vector<CResourceDirectoryEntry*> m_vEntries;
+};
+
+class CResourceDirectoryEntry {
+public:
+ CResourceDirectoryEntry(WCHAR* szName, CResourceDirectory* rdSubDir);
+ CResourceDirectoryEntry(WCHAR* szName, CResourceDataEntry* rdeData);
+ virtual ~CResourceDirectoryEntry();
+
+ bool HasName();
+ WCHAR* GetName();
+ int GetNameLength();
+
+ WORD GetId();
+
+ bool IsDataDirectory();
+ CResourceDirectory* GetSubDirectory();
+
+ CResourceDataEntry* GetDataEntry();
+
+ DWORD m_dwWrittenAt;
+
+private:
+ bool m_bHasName;
+ WCHAR* m_szName;
+ WORD m_wId;
+
+ bool m_bIsDataDirectory;
+ union {
+ CResourceDirectory* m_rdSubDir;
+ CResourceDataEntry* m_rdeData;
+ };
+};
+
+class CResourceDataEntry {
+public:
+ CResourceDataEntry(BYTE* pbData, DWORD dwSize, DWORD dwCodePage = 0, DWORD dwOffset = DWORD(-1));
+ ~CResourceDataEntry();
+
+ BYTE* GetData();
+
+ void SetData(BYTE* pbData, DWORD dwSize);
+ void SetData(BYTE* pbData, DWORD dwSize, DWORD dwCodePage);
+
+ DWORD GetSize();
+ DWORD GetCodePage();
+ DWORD GetOffset();
+
+ DWORD m_dwWrittenAt;
+
+private:
+ BYTE* m_pbData;
+ DWORD m_dwSize;
+ DWORD m_dwCodePage;
+ DWORD m_dwOffset;
+};
+
+#endif // !defined(AFX_RESOURCEEDITOR_H__683BF710_E805_4093_975B_D5729186A89A__INCLUDED_)
diff --git a/Source/ResourceVersionInfo.cpp b/Source/ResourceVersionInfo.cpp
index b292459..5fac171 100755
--- a/Source/ResourceVersionInfo.cpp
+++ b/Source/ResourceVersionInfo.cpp
@@ -1,318 +1,318 @@
-/*
- * ResourceVersionInfo.cpp: implementation of the CResourceVersionInfo class.
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "ResourceVersionInfo.h"
-
-#include "Platform.h"
-#include "util.h"
-#include "winchar.h"
-
-#ifdef NSIS_SUPPORT_VERSION_INFO
-
-#ifndef VOS__WINDOWS32
-# define VOS__WINDOWS32 4
-#endif
-#ifndef VFT_APP
-# define VFT_APP 1
-#endif
-
-#ifndef _WIN32
-# include <iconv.h>
-#endif
-
-struct version_string_list
-{
- int codepage;
- LANGID lang_id;
- int name;
- DefineList *pChildStrings;
-};
-
-CVersionStrigList::~CVersionStrigList()
-{
- struct version_string_list *itr = (struct version_string_list *) gr.get();
- int i = gr.getlen() / sizeof(struct version_string_list);
-
- while (i--)
- {
- delete itr[i].pChildStrings;
- }
-}
-
-int CVersionStrigList::add(LANGID langid, int codepage)
-{
- char Buff[10];
- sprintf(Buff, "%04x", langid);
- int pos = SortedStringListND<struct version_string_list>::add(Buff);
- if (pos == -1) return false;
- ((struct version_string_list*)gr.get())[pos].pChildStrings = new DefineList;
- ((struct version_string_list*)gr.get())[pos].codepage = codepage;
- ((struct version_string_list*)gr.get())[pos].lang_id = langid;
- return pos;
-}
-
-LANGID CVersionStrigList::get_lang(int idx)
-{
- version_string_list *data=(version_string_list *)gr.get();
- return data[idx].lang_id;
-}
-
-int CVersionStrigList::get_codepage(int idx)
-{
- version_string_list *data=(version_string_list *)gr.get();
- return data[idx].codepage;
-}
-
-DefineList* CVersionStrigList::get_strings(int idx)
-{
- version_string_list *data=(version_string_list *)gr.get();
- return data[idx].pChildStrings;
-}
-
-int CVersionStrigList::find(LANGID lang_id, int codepage)
-{
- char Buff[10];
- sprintf(Buff, "%04x", lang_id);
- return SortedStringListND<struct version_string_list>::find(Buff);
-}
-
-int CVersionStrigList::getlen()
-{
- return strings.getlen();
-}
-
-int CVersionStrigList::getnum()
-{
- return gr.getlen()/sizeof(struct version_string_list);
-}
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-CResourceVersionInfo::CResourceVersionInfo()
-{
- memset(&m_FixedInfo, 0, sizeof(VS_FIXEDFILEINFO));
- m_FixedInfo.dwSignature = 0xFEEF04BD;
- m_FixedInfo.dwFileOS = VOS__WINDOWS32;
- m_FixedInfo.dwFileType = VFT_APP;
-}
-
-CResourceVersionInfo::~CResourceVersionInfo()
-{
-
-}
-
-void CResourceVersionInfo::SetFileFlags(int Value)
-{
- m_FixedInfo.dwFileFlags = (m_FixedInfo.dwFileFlags & ~(m_FixedInfo.dwFileFlagsMask)) || Value;
-}
-
-void CResourceVersionInfo::SetFileVersion(int HighPart, int LowPart)
-{
- m_FixedInfo.dwFileVersionLS = LowPart;
- m_FixedInfo.dwFileVersionMS = HighPart;
-}
-
-void CResourceVersionInfo::SetProductVersion(int HighPart, int LowPart)
-{
- m_FixedInfo.dwProductVersionLS = LowPart;
- m_FixedInfo.dwProductVersionMS = HighPart;
-}
-
-int GetVersionHeader (LPSTR &p, WORD &wLength, WORD &wValueLength, WORD &wType)
-{
- WCHAR *szKey;
- char * baseP;
-
- baseP = p;
- wLength = *(WORD*)p;
- p += sizeof(WORD);
- wValueLength = *(WORD*)p;
- p += sizeof(WORD);
- wType = *(WORD*)p;
- p += sizeof(WORD);
- szKey = (WCHAR*)p;
- p += (winchar_strlen(szKey) + 1) * sizeof (WCHAR);
- while ( ((long)p % 4) != 0 )
- p++;
- return p - baseP;
-}
-
-DWORD ZEROS = 0;
-
-void PadStream (GrowBuf &strm)
-{
- if ( (strm.getlen() % 4) != 0 )
- strm.add (&ZEROS, 4 - (strm.getlen() % 4));
-}
-
-void SaveVersionHeader (GrowBuf &strm, WORD wLength, WORD wValueLength, WORD wType, const WCHAR *key, void *value)
-{
- WORD valueLen;
- WORD keyLen;
-
- strm.add (&wLength, sizeof (wLength));
-
- strm.add (&wValueLength, sizeof (wValueLength));
- strm.add (&wType, sizeof (wType));
- keyLen = WORD((winchar_strlen(key) + 1) * sizeof (WCHAR));
- strm.add ((void*)key, keyLen);
-
- PadStream(strm);
-
- if ( wValueLength > 0 )
- {
- valueLen = wValueLength;
- if ( wType == 1 )
- valueLen = valueLen * WORD(sizeof (WCHAR));
- strm.add (value, valueLen);
- }
-}
-
-void CResourceVersionInfo::ExportToStream(GrowBuf &strm, int Index)
-{
- DWORD v;
- WORD wSize;
- int p, p1;
- WCHAR *KeyName, *KeyValue;
-
- strm.resize(0);
- KeyName = winchar_fromansi("VS_VERSION_INFO");
- SaveVersionHeader (strm, 0, sizeof (VS_FIXEDFILEINFO), 0, KeyName, &m_FixedInfo);
- delete [] KeyName;
-
- DefineList *pChildStrings = m_ChildStringLists.get_strings(Index);
- if ( pChildStrings->getnum() > 0 )
- {
- GrowBuf stringInfoStream;
- int codepage = m_ChildStringLists.get_codepage(Index);
- LANGID langid = m_ChildStringLists.get_lang(Index);
- char Buff[16];
- sprintf(Buff, "%04x%04x", langid, codepage);
- KeyName = winchar_fromansi(Buff, CP_ACP);
- SaveVersionHeader (stringInfoStream, 0, 0, 0, KeyName, &ZEROS);
- delete [] KeyName;
-
- for ( int i = 0; i < pChildStrings->getnum(); i++ )
- {
- PadStream (stringInfoStream);
-
- p = stringInfoStream.getlen();
- KeyName = winchar_fromansi(pChildStrings->getname(i), codepage);
- KeyValue = winchar_fromansi(pChildStrings->getvalue(i), codepage);
- SaveVersionHeader (stringInfoStream, 0, WORD(winchar_strlen(KeyValue) + 1), 1, KeyName, (void*)KeyValue);
- delete [] KeyName;
- delete [] KeyValue;
- wSize = WORD(stringInfoStream.getlen() - p);
-
- *(WORD*)((PBYTE)stringInfoStream.get()+p)=wSize;
- }
-
- wSize = WORD(stringInfoStream.getlen());
- *(WORD*)((PBYTE)stringInfoStream.get())=wSize;
-
- PadStream (strm);
- p = strm.getlen();
- KeyName = winchar_fromansi("StringFileInfo", CP_ACP);
- SaveVersionHeader (strm, 0, 0, 0, KeyName, &ZEROS);
- delete [] KeyName;
- strm.add (stringInfoStream.get(), stringInfoStream.getlen());
- wSize = WORD(strm.getlen() - p);
-
- *(WORD*)((PBYTE)strm.get()+p)=wSize;
- }
-
- // Show all languages avaiable using Var-Translations
- if ( m_ChildStringLists.getnum() > 0 )
- {
- PadStream (strm);
- p = strm.getlen();
- KeyName = winchar_fromansi("VarFileInfo", CP_ACP);
- SaveVersionHeader (strm, 0, 0, 0, KeyName, &ZEROS);
- delete [] KeyName;
- PadStream (strm);
-
- p1 = strm.getlen();
- KeyName = winchar_fromansi("Translation", CP_ACP);
- SaveVersionHeader (strm, 0, 0, 0, KeyName, &ZEROS);
- delete [] KeyName;
-
- // First add selected code language translation
- v = MAKELONG(m_ChildStringLists.get_lang(Index), m_ChildStringLists.get_codepage(Index));
- strm.add (&v, sizeof (v));
-
- for ( int k =0; k < m_ChildStringLists.getnum(); k++ )
- {
- if ( k != Index )
- {
- v = MAKELONG(m_ChildStringLists.get_lang(k), m_ChildStringLists.get_codepage(k));
- strm.add (&v, sizeof (v));
- }
- }
-
- wSize = WORD(strm.getlen() - p1);
- *(WORD*)((PBYTE)strm.get()+p1)=wSize;
- wSize = WORD(sizeof (int) * m_ChildStringLists.getnum());
- p1+=sizeof(WORD);
- *(WORD*)((PBYTE)strm.get()+p1)=wSize;
-
- wSize = WORD(strm.getlen() - p);
- *(WORD*)((PBYTE)strm.get()+p)=wSize;
- }
-
- wSize = WORD(strm.getlen());
- *(WORD*)((PBYTE)strm.get())=wSize;
-}
-
-// Returns 0 if success, 1 if already defined
-int CResourceVersionInfo::SetKeyValue(LANGID lang_id, int codepage, char* AKeyName, char* AValue)
-{
- int pos = m_ChildStringLists.find(lang_id, codepage);
- if ( pos == -1 )
- {
- pos = m_ChildStringLists.add(lang_id, codepage);
- }
- DefineList *pStrings = m_ChildStringLists.get_strings(pos);
- return pStrings->add(AKeyName, AValue);
-}
-
-int CResourceVersionInfo::GetStringTablesCount()
-{
- return m_ChildStringLists.getnum();
-}
-
-LANGID CResourceVersionInfo::GetLangID(int Index)
-{
- return m_ChildStringLists.get_lang(Index);
-}
-
-int CResourceVersionInfo::GetCodePage(int Index)
-{
- return m_ChildStringLists.get_codepage(Index);
-}
-
-char *CResourceVersionInfo::FindKey(LANGID LangID, int codepage, char *pKeyName)
-{
- int pos = m_ChildStringLists.find(LangID, codepage);
- if ( pos == -1 )
- {
- return NULL;
- }
- DefineList *pStrings = m_ChildStringLists.get_strings(pos);
- return pStrings->find(pKeyName);
-}
-
-#endif
+/*
+ * ResourceVersionInfo.cpp: implementation of the CResourceVersionInfo class.
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "ResourceVersionInfo.h"
+
+#include "Platform.h"
+#include "util.h"
+#include "winchar.h"
+
+#ifdef NSIS_SUPPORT_VERSION_INFO
+
+#ifndef VOS__WINDOWS32
+# define VOS__WINDOWS32 4
+#endif
+#ifndef VFT_APP
+# define VFT_APP 1
+#endif
+
+#ifndef _WIN32
+# include <iconv.h>
+#endif
+
+struct version_string_list
+{
+ int codepage;
+ LANGID lang_id;
+ int name;
+ DefineList *pChildStrings;
+};
+
+CVersionStrigList::~CVersionStrigList()
+{
+ struct version_string_list *itr = (struct version_string_list *) gr.get();
+ int i = gr.getlen() / sizeof(struct version_string_list);
+
+ while (i--)
+ {
+ delete itr[i].pChildStrings;
+ }
+}
+
+int CVersionStrigList::add(LANGID langid, int codepage)
+{
+ char Buff[10];
+ sprintf(Buff, "%04x", langid);
+ int pos = SortedStringListND<struct version_string_list>::add(Buff);
+ if (pos == -1) return false;
+ ((struct version_string_list*)gr.get())[pos].pChildStrings = new DefineList;
+ ((struct version_string_list*)gr.get())[pos].codepage = codepage;
+ ((struct version_string_list*)gr.get())[pos].lang_id = langid;
+ return pos;
+}
+
+LANGID CVersionStrigList::get_lang(int idx)
+{
+ version_string_list *data=(version_string_list *)gr.get();
+ return data[idx].lang_id;
+}
+
+int CVersionStrigList::get_codepage(int idx)
+{
+ version_string_list *data=(version_string_list *)gr.get();
+ return data[idx].codepage;
+}
+
+DefineList* CVersionStrigList::get_strings(int idx)
+{
+ version_string_list *data=(version_string_list *)gr.get();
+ return data[idx].pChildStrings;
+}
+
+int CVersionStrigList::find(LANGID lang_id, int codepage)
+{
+ char Buff[10];
+ sprintf(Buff, "%04x", lang_id);
+ return SortedStringListND<struct version_string_list>::find(Buff);
+}
+
+int CVersionStrigList::getlen()
+{
+ return strings.getlen();
+}
+
+int CVersionStrigList::getnum()
+{
+ return gr.getlen()/sizeof(struct version_string_list);
+}
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CResourceVersionInfo::CResourceVersionInfo()
+{
+ memset(&m_FixedInfo, 0, sizeof(VS_FIXEDFILEINFO));
+ m_FixedInfo.dwSignature = 0xFEEF04BD;
+ m_FixedInfo.dwFileOS = VOS__WINDOWS32;
+ m_FixedInfo.dwFileType = VFT_APP;
+}
+
+CResourceVersionInfo::~CResourceVersionInfo()
+{
+
+}
+
+void CResourceVersionInfo::SetFileFlags(int Value)
+{
+ m_FixedInfo.dwFileFlags = (m_FixedInfo.dwFileFlags & ~(m_FixedInfo.dwFileFlagsMask)) || Value;
+}
+
+void CResourceVersionInfo::SetFileVersion(int HighPart, int LowPart)
+{
+ m_FixedInfo.dwFileVersionLS = LowPart;
+ m_FixedInfo.dwFileVersionMS = HighPart;
+}
+
+void CResourceVersionInfo::SetProductVersion(int HighPart, int LowPart)
+{
+ m_FixedInfo.dwProductVersionLS = LowPart;
+ m_FixedInfo.dwProductVersionMS = HighPart;
+}
+
+int GetVersionHeader (LPSTR &p, WORD &wLength, WORD &wValueLength, WORD &wType)
+{
+ WCHAR *szKey;
+ char * baseP;
+
+ baseP = p;
+ wLength = *(WORD*)p;
+ p += sizeof(WORD);
+ wValueLength = *(WORD*)p;
+ p += sizeof(WORD);
+ wType = *(WORD*)p;
+ p += sizeof(WORD);
+ szKey = (WCHAR*)p;
+ p += (winchar_strlen(szKey) + 1) * sizeof (WCHAR);
+ while ( ((long)p % 4) != 0 )
+ p++;
+ return p - baseP;
+}
+
+DWORD ZEROS = 0;
+
+void PadStream (GrowBuf &strm)
+{
+ if ( (strm.getlen() % 4) != 0 )
+ strm.add (&ZEROS, 4 - (strm.getlen() % 4));
+}
+
+void SaveVersionHeader (GrowBuf &strm, WORD wLength, WORD wValueLength, WORD wType, const WCHAR *key, void *value)
+{
+ WORD valueLen;
+ WORD keyLen;
+
+ strm.add (&wLength, sizeof (wLength));
+
+ strm.add (&wValueLength, sizeof (wValueLength));
+ strm.add (&wType, sizeof (wType));
+ keyLen = WORD((winchar_strlen(key) + 1) * sizeof (WCHAR));
+ strm.add ((void*)key, keyLen);
+
+ PadStream(strm);
+
+ if ( wValueLength > 0 )
+ {
+ valueLen = wValueLength;
+ if ( wType == 1 )
+ valueLen = valueLen * WORD(sizeof (WCHAR));
+ strm.add (value, valueLen);
+ }
+}
+
+void CResourceVersionInfo::ExportToStream(GrowBuf &strm, int Index)
+{
+ DWORD v;
+ WORD wSize;
+ int p, p1;
+ WCHAR *KeyName, *KeyValue;
+
+ strm.resize(0);
+ KeyName = winchar_fromansi("VS_VERSION_INFO");
+ SaveVersionHeader (strm, 0, sizeof (VS_FIXEDFILEINFO), 0, KeyName, &m_FixedInfo);
+ delete [] KeyName;
+
+ DefineList *pChildStrings = m_ChildStringLists.get_strings(Index);
+ if ( pChildStrings->getnum() > 0 )
+ {
+ GrowBuf stringInfoStream;
+ int codepage = m_ChildStringLists.get_codepage(Index);
+ LANGID langid = m_ChildStringLists.get_lang(Index);
+ char Buff[16];
+ sprintf(Buff, "%04x%04x", langid, codepage);
+ KeyName = winchar_fromansi(Buff, CP_ACP);
+ SaveVersionHeader (stringInfoStream, 0, 0, 0, KeyName, &ZEROS);
+ delete [] KeyName;
+
+ for ( int i = 0; i < pChildStrings->getnum(); i++ )
+ {
+ PadStream (stringInfoStream);
+
+ p = stringInfoStream.getlen();
+ KeyName = winchar_fromansi(pChildStrings->getname(i), codepage);
+ KeyValue = winchar_fromansi(pChildStrings->getvalue(i), codepage);
+ SaveVersionHeader (stringInfoStream, 0, WORD(winchar_strlen(KeyValue) + 1), 1, KeyName, (void*)KeyValue);
+ delete [] KeyName;
+ delete [] KeyValue;
+ wSize = WORD(stringInfoStream.getlen() - p);
+
+ *(WORD*)((PBYTE)stringInfoStream.get()+p)=wSize;
+ }
+
+ wSize = WORD(stringInfoStream.getlen());
+ *(WORD*)((PBYTE)stringInfoStream.get())=wSize;
+
+ PadStream (strm);
+ p = strm.getlen();
+ KeyName = winchar_fromansi("StringFileInfo", CP_ACP);
+ SaveVersionHeader (strm, 0, 0, 0, KeyName, &ZEROS);
+ delete [] KeyName;
+ strm.add (stringInfoStream.get(), stringInfoStream.getlen());
+ wSize = WORD(strm.getlen() - p);
+
+ *(WORD*)((PBYTE)strm.get()+p)=wSize;
+ }
+
+ // Show all languages avaiable using Var-Translations
+ if ( m_ChildStringLists.getnum() > 0 )
+ {
+ PadStream (strm);
+ p = strm.getlen();
+ KeyName = winchar_fromansi("VarFileInfo", CP_ACP);
+ SaveVersionHeader (strm, 0, 0, 0, KeyName, &ZEROS);
+ delete [] KeyName;
+ PadStream (strm);
+
+ p1 = strm.getlen();
+ KeyName = winchar_fromansi("Translation", CP_ACP);
+ SaveVersionHeader (strm, 0, 0, 0, KeyName, &ZEROS);
+ delete [] KeyName;
+
+ // First add selected code language translation
+ v = MAKELONG(m_ChildStringLists.get_lang(Index), m_ChildStringLists.get_codepage(Index));
+ strm.add (&v, sizeof (v));
+
+ for ( int k =0; k < m_ChildStringLists.getnum(); k++ )
+ {
+ if ( k != Index )
+ {
+ v = MAKELONG(m_ChildStringLists.get_lang(k), m_ChildStringLists.get_codepage(k));
+ strm.add (&v, sizeof (v));
+ }
+ }
+
+ wSize = WORD(strm.getlen() - p1);
+ *(WORD*)((PBYTE)strm.get()+p1)=wSize;
+ wSize = WORD(sizeof (int) * m_ChildStringLists.getnum());
+ p1+=sizeof(WORD);
+ *(WORD*)((PBYTE)strm.get()+p1)=wSize;
+
+ wSize = WORD(strm.getlen() - p);
+ *(WORD*)((PBYTE)strm.get()+p)=wSize;
+ }
+
+ wSize = WORD(strm.getlen());
+ *(WORD*)((PBYTE)strm.get())=wSize;
+}
+
+// Returns 0 if success, 1 if already defined
+int CResourceVersionInfo::SetKeyValue(LANGID lang_id, int codepage, char* AKeyName, char* AValue)
+{
+ int pos = m_ChildStringLists.find(lang_id, codepage);
+ if ( pos == -1 )
+ {
+ pos = m_ChildStringLists.add(lang_id, codepage);
+ }
+ DefineList *pStrings = m_ChildStringLists.get_strings(pos);
+ return pStrings->add(AKeyName, AValue);
+}
+
+int CResourceVersionInfo::GetStringTablesCount()
+{
+ return m_ChildStringLists.getnum();
+}
+
+LANGID CResourceVersionInfo::GetLangID(int Index)
+{
+ return m_ChildStringLists.get_lang(Index);
+}
+
+int CResourceVersionInfo::GetCodePage(int Index)
+{
+ return m_ChildStringLists.get_codepage(Index);
+}
+
+char *CResourceVersionInfo::FindKey(LANGID LangID, int codepage, char *pKeyName)
+{
+ int pos = m_ChildStringLists.find(LangID, codepage);
+ if ( pos == -1 )
+ {
+ return NULL;
+ }
+ DefineList *pStrings = m_ChildStringLists.get_strings(pos);
+ return pStrings->find(pKeyName);
+}
+
+#endif
diff --git a/Source/ResourceVersionInfo.h b/Source/ResourceVersionInfo.h
index 264ee3f..1f1c5ec 100755
--- a/Source/ResourceVersionInfo.h
+++ b/Source/ResourceVersionInfo.h
@@ -1,67 +1,67 @@
-/*
- * ResourceVersionInfo.h: interface for the CResourceVersionInfo class.
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#if !defined(AFX_RESOURCEVERSIONINFO_H__80439ADA_49DA_4623_8DA9_1663FF356E76__INCLUDED_)
-#define AFX_RESOURCEVERSIONINFO_H__80439ADA_49DA_4623_8DA9_1663FF356E76__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include "exehead/config.h"
-#ifdef NSIS_SUPPORT_VERSION_INFO
-
-#include "Platform.h"
-#include "strlist.h"
-
-struct version_string_list;
-
-class CVersionStrigList : public SortedStringListND<struct version_string_list>
-{
-public:
- ~CVersionStrigList();
- int add(LANGID langid, int codepage);
- LANGID get_lang(int idx);
- int get_codepage(int idx);
- DefineList* get_strings(int idx);
- int find(LANGID lang_id, int codepage);
- int getlen();
- int getnum();
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////////
-class CResourceVersionInfo
-{
- VS_FIXEDFILEINFO m_FixedInfo;
- CVersionStrigList m_ChildStringLists;
-
-public:
- CResourceVersionInfo();
- virtual ~CResourceVersionInfo();
- int SetKeyValue(LANGID lang_id, int codepage, char* AKeyName, char* AValue);
- void SetFileFlags(int Value);
- void SetFileVersion(int HighPart, int LowPart);
- void SetProductVersion(int HighPart, int LowPart);
- void ExportToStream(GrowBuf &strm, int Index);
- int GetStringTablesCount();
- LANGID GetLangID(int Index);
- int GetCodePage(int Index);
- char *FindKey(LANGID LangID, int codepage, char *pKeyName);
-};
-
-#endif
-
-#endif // !defined(AFX_RESOURCEVERSIONINFO_H__80439ADA_49DA_4623_8DA9_1663FF356E76__INCLUDED_)
+/*
+ * ResourceVersionInfo.h: interface for the CResourceVersionInfo class.
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#if !defined(AFX_RESOURCEVERSIONINFO_H__80439ADA_49DA_4623_8DA9_1663FF356E76__INCLUDED_)
+#define AFX_RESOURCEVERSIONINFO_H__80439ADA_49DA_4623_8DA9_1663FF356E76__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "exehead/config.h"
+#ifdef NSIS_SUPPORT_VERSION_INFO
+
+#include "Platform.h"
+#include "strlist.h"
+
+struct version_string_list;
+
+class CVersionStrigList : public SortedStringListND<struct version_string_list>
+{
+public:
+ ~CVersionStrigList();
+ int add(LANGID langid, int codepage);
+ LANGID get_lang(int idx);
+ int get_codepage(int idx);
+ DefineList* get_strings(int idx);
+ int find(LANGID lang_id, int codepage);
+ int getlen();
+ int getnum();
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+class CResourceVersionInfo
+{
+ VS_FIXEDFILEINFO m_FixedInfo;
+ CVersionStrigList m_ChildStringLists;
+
+public:
+ CResourceVersionInfo();
+ virtual ~CResourceVersionInfo();
+ int SetKeyValue(LANGID lang_id, int codepage, char* AKeyName, char* AValue);
+ void SetFileFlags(int Value);
+ void SetFileVersion(int HighPart, int LowPart);
+ void SetProductVersion(int HighPart, int LowPart);
+ void ExportToStream(GrowBuf &strm, int Index);
+ int GetStringTablesCount();
+ LANGID GetLangID(int Index);
+ int GetCodePage(int Index);
+ char *FindKey(LANGID LangID, int codepage, char *pKeyName);
+};
+
+#endif
+
+#endif // !defined(AFX_RESOURCEVERSIONINFO_H__80439ADA_49DA_4623_8DA9_1663FF356E76__INCLUDED_)
diff --git a/Source/SConscript b/Source/SConscript
index 5215c89..505e438 100755
--- a/Source/SConscript
+++ b/Source/SConscript
@@ -1,93 +1,94 @@
-target = 'makensis'
-
-pch = 'Platform.h'
-
-makensis_files = Split("""
- build.cpp
- clzma.cpp
- crc32.c
- DialogTemplate.cpp
- dirreader.cpp
- fileform.cpp
- growbuf.cpp
- lang.cpp
- lineparse.cpp
- makenssi.cpp
- manifest.cpp
- mmap.cpp
- Plugins.cpp
- ResourceEditor.cpp
- ResourceVersionInfo.cpp
- script.cpp
- ShConstants.cpp
- strlist.cpp
- tokens.cpp
- util.cpp
- winchar.cpp
- writer.cpp
-""")
-
-bzip2_files = Split("""
- bzip2/blocksort.c
- bzip2/bzlib.c
- bzip2/compress.c
- bzip2/huffman.c
-""")
-
-lzma_files = Split("""
- 7zip/7zGuids.cpp
- 7zip/7zip/Common/OutBuffer.cpp
- 7zip/7zip/Common/StreamUtils.cpp
- 7zip/7zip/Compress/LZ/LZInWindow.cpp
- 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
- 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp
- 7zip/Common/Alloc.cpp
- 7zip/Common/CRC.cpp
-""")
-
-zlib_files = Split("""
- zlib/deflate.c
- zlib/trees.c
-""")
-
-libs = Split("""
- gdi32
- user32
- pthread
- iconv
-""")
-
-Import('env AddAvailableLibs')
-
-##### Use available libraries
-
-if env['PLATFORM'] == 'win32':
- # XXX will cause problems if makensis is cross compiled
- # on freebsd, libversion.a exists and gives trouble if linked
- libs += ['version']
-
-AddAvailableLibs(env, libs)
-
-##### Defines
-
-env.Append(CPPDEFINES = ['_WIN32_IE=0x0500'])
-
-##### Set PCH
-
-# XXX doesn't work
-#env['PCH'] = env.PCH(pch)[0]
-#env['PCHSTOP'] = pch
-
-##### LZMA specific defines
-
-lzma_env = env.Clone()
-lzma_env.Append(CPPDEFINES = ['COMPRESS_MF_BT'])
-lzma_files = lzma_env.Object(lzma_files)
-
-##### Compile makensis
-
-files = makensis_files + bzip2_files + lzma_files + zlib_files
-
-makensis = env.Program(target, files)
-
-Return('makensis')
+target = 'makensis'
+
+pch = 'Platform.h'
+
+makensis_files = Split("""
+ build.cpp
+ clzma.cpp
+ crc32.c
+ DialogTemplate.cpp
+ dirreader.cpp
+ fileform.cpp
+ growbuf.cpp
+ icon.cpp
+ lang.cpp
+ lineparse.cpp
+ makenssi.cpp
+ manifest.cpp
+ mmap.cpp
+ Plugins.cpp
+ ResourceEditor.cpp
+ ResourceVersionInfo.cpp
+ script.cpp
+ ShConstants.cpp
+ strlist.cpp
+ tokens.cpp
+ util.cpp
+ winchar.cpp
+ writer.cpp
+""")
+
+bzip2_files = Split("""
+ bzip2/blocksort.c
+ bzip2/bzlib.c
+ bzip2/compress.c
+ bzip2/huffman.c
+""")
+
+lzma_files = Split("""
+ 7zip/7zGuids.cpp
+ 7zip/7zip/Common/OutBuffer.cpp
+ 7zip/7zip/Common/StreamUtils.cpp
+ 7zip/7zip/Compress/LZ/LZInWindow.cpp
+ 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
+ 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp
+ 7zip/Common/Alloc.cpp
+ 7zip/Common/CRC.cpp
+""")
+
+zlib_files = Split("""
+ zlib/deflate.c
+ zlib/trees.c
+""")
+
+libs = Split("""
+ gdi32
+ user32
+ pthread
+ iconv
+""")
+
+Import('env AddAvailableLibs')
+
+##### Use available libraries
+
+if env['PLATFORM'] == 'win32':
+ # XXX will cause problems if makensis is cross compiled
+ # on freebsd, libversion.a exists and gives trouble if linked
+ libs += ['version']
+
+AddAvailableLibs(env, libs)
+
+##### Defines
+
+env.Append(CPPDEFINES = ['_WIN32_IE=0x0500'])
+
+##### Set PCH
+
+# XXX doesn't work
+#env['PCH'] = env.PCH(pch)[0]
+#env['PCHSTOP'] = pch
+
+##### LZMA specific defines
+
+lzma_env = env.Clone()
+lzma_env.Append(CPPDEFINES = ['COMPRESS_MF_BT'])
+lzma_files = lzma_env.Object(lzma_files)
+
+##### Compile makensis
+
+files = makensis_files + bzip2_files + lzma_files + zlib_files
+
+makensis = env.Program(target, files)
+
+Return('makensis')
diff --git a/Source/ShConstants.cpp b/Source/ShConstants.cpp
index 66f2a27..b3aa0fd 100755
--- a/Source/ShConstants.cpp
+++ b/Source/ShConstants.cpp
@@ -1,85 +1,85 @@
-/*
- * ShConstants.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "ShConstants.h"
-
-ConstantsStringList::ConstantsStringList()
-{
- index = 0;
-}
-
-int ConstantsStringList::add(const char *name, int value1, int value2)
-{
- int pos=SortedStringListND<struct constantstring>::add(name);
- if (pos == -1) return -1;
-
- ((struct constantstring*)gr.get())[pos].index = index;
- ((struct constantstring*)gr.get())[pos].pos = pos;
- ((struct constantstring*)gr.get())[pos].value1 = value1;
- ((struct constantstring*)gr.get())[pos].value2 = value2;
-
- int temp = index;
- index++;
-
- return temp;
-}
-
-int ConstantsStringList::get(char *name, int n_chars /*= -1*/)
-{
- int v=SortedStringListND<struct constantstring>::find(name, n_chars);
- if (v==-1) return -1;
- return (((struct constantstring*)gr.get())[v].index);
-}
-
-int ConstantsStringList::getnum()
-{
- return index;
-}
-
-int ConstantsStringList::get_value1(int idx)
-{
- int pos=get_internal_idx(idx);
- if (pos==-1) return -1;
- return (((struct constantstring*)gr.get())[pos].value1);
-}
-
-int ConstantsStringList::get_value2(int idx)
-{
- int pos=get_internal_idx(idx);
- if (pos==-1) return -1;
- return (((struct constantstring*)gr.get())[pos].value2);
-}
-
-char* ConstantsStringList::idx2name(int idx)
-{
- int pos=get_internal_idx(idx);
- if (pos==-1) return NULL;
- struct constantstring *data=(struct constantstring *)gr.get();
- return ((char*)strings.get() + data[pos].name);
-}
-
-int ConstantsStringList::get_internal_idx(int idx)
-{
- struct constantstring *data=(struct constantstring *)gr.get();
- for (int i = 0; i < index; i++)
- {
- if (data[i].index == idx)
- {
- return i;
- }
- }
- return -1;
-}
+/*
+ * ShConstants.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "ShConstants.h"
+
+ConstantsStringList::ConstantsStringList()
+{
+ index = 0;
+}
+
+int ConstantsStringList::add(const char *name, int value1, int value2)
+{
+ int pos=SortedStringListND<struct constantstring>::add(name);
+ if (pos == -1) return -1;
+
+ ((struct constantstring*)gr.get())[pos].index = index;
+ ((struct constantstring*)gr.get())[pos].pos = pos;
+ ((struct constantstring*)gr.get())[pos].value1 = value1;
+ ((struct constantstring*)gr.get())[pos].value2 = value2;
+
+ int temp = index;
+ index++;
+
+ return temp;
+}
+
+int ConstantsStringList::get(char *name, int n_chars /*= -1*/)
+{
+ int v=SortedStringListND<struct constantstring>::find(name, n_chars);
+ if (v==-1) return -1;
+ return (((struct constantstring*)gr.get())[v].index);
+}
+
+int ConstantsStringList::getnum()
+{
+ return index;
+}
+
+int ConstantsStringList::get_value1(int idx)
+{
+ int pos=get_internal_idx(idx);
+ if (pos==-1) return -1;
+ return (((struct constantstring*)gr.get())[pos].value1);
+}
+
+int ConstantsStringList::get_value2(int idx)
+{
+ int pos=get_internal_idx(idx);
+ if (pos==-1) return -1;
+ return (((struct constantstring*)gr.get())[pos].value2);
+}
+
+char* ConstantsStringList::idx2name(int idx)
+{
+ int pos=get_internal_idx(idx);
+ if (pos==-1) return NULL;
+ struct constantstring *data=(struct constantstring *)gr.get();
+ return ((char*)strings.get() + data[pos].name);
+}
+
+int ConstantsStringList::get_internal_idx(int idx)
+{
+ struct constantstring *data=(struct constantstring *)gr.get();
+ for (int i = 0; i < index; i++)
+ {
+ if (data[i].index == idx)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
diff --git a/Source/ShConstants.h b/Source/ShConstants.h
index 9875b51..2b2f2f3 100755
--- a/Source/ShConstants.h
+++ b/Source/ShConstants.h
@@ -1,47 +1,47 @@
-/*
- * ShConstants.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 2003 Ramon
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef ___CONSTANTS___H_____
-#define ___CONSTANTS___H_____
-
-#include "strlist.h"
-
-struct constantstring {
- int name;
- int index;
- int pos;
- int value1;
- int value2;
-};
-
-class ConstantsStringList : public SortedStringListND<struct constantstring>
-{
- public:
- ConstantsStringList();
-
- int add(const char *name, int value1, int value2);
- int get(char *name, int n_chars = -1);
- int getnum();
- int get_value1(int idx);
- int get_value2(int idx);
- char *idx2name(int idx);
-
- private:
- int index;
- int get_internal_idx(int idx);
-};
-
-#endif
+/*
+ * ShConstants.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 2003 Ramon
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef ___CONSTANTS___H_____
+#define ___CONSTANTS___H_____
+
+#include "strlist.h"
+
+struct constantstring {
+ int name;
+ int index;
+ int pos;
+ int value1;
+ int value2;
+};
+
+class ConstantsStringList : public SortedStringListND<struct constantstring>
+{
+ public:
+ ConstantsStringList();
+
+ int add(const char *name, int value1, int value2);
+ int get(char *name, int n_chars = -1);
+ int getnum();
+ int get_value1(int idx);
+ int get_value2(int idx);
+ char *idx2name(int idx);
+
+ private:
+ int index;
+ int get_internal_idx(int idx);
+};
+
+#endif
diff --git a/Source/Tests/DialogTemplate.cpp b/Source/Tests/DialogTemplate.cpp
index 5719943..6a0c1b3 100755
--- a/Source/Tests/DialogTemplate.cpp
+++ b/Source/Tests/DialogTemplate.cpp
@@ -1,47 +1,47 @@
-#include <cppunit/extensions/HelperMacros.h>
-#include "../DialogTemplate.h"
-
-#include <stdlib.h>
-
-class CDialogTemplateTest : public CppUnit::TestFixture {
-
- CPPUNIT_TEST_SUITE( CDialogTemplateTest );
- CPPUNIT_TEST( testCorrectness );
- CPPUNIT_TEST_SUITE_END();
-
-public:
- void testCorrectness() {
- unsigned char original_dialog[184] = {
- 1, 0, 255, 255, 0, 0, 0, 0, 0, 0,
- 0, 0, 72, 4, 0, 64, 3, 0, 0, 0, 0,
- 0, 10, 1, 130, 0, 0, 0, 0, 0, 0, 0,
- 8, 0, 0, 0, 0, 1, 77, 0, 83, 0, 32,
- 0, 83, 0, 104, 0, 101, 0, 108, 0, 108, 0,
- 32, 0, 68, 0, 108, 0, 103, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 80,
- 0, 0, 0, 0, 22, 0, 20, 0, 7, 4, 0,
- 0, 255, 255, 130, 0, 255, 255, 103, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 2, 80, 25, 0, 0, 0, 241, 0, 23, 0,
- 238, 3, 0, 0, 255, 255, 130, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8,
- 161, 80, 0, 0, 24, 0, 10, 1, 105, 0, 232,
- 3, 0, 0, 82, 0, 105, 0, 99, 0, 104, 0,
- 69, 0, 100, 0, 105, 0, 116, 0, 50, 0, 48,
- 0, 65, 0, 0, 0, 0, 0, 0, 0
- };
-
- CDialogTemplate dt(original_dialog, 1252);
-
- DWORD dwSize;
- unsigned char *saved_dialog = dt.Save(dwSize);
-
- CPPUNIT_ASSERT_EQUAL( (DWORD) sizeof(original_dialog), dwSize );
- CPPUNIT_ASSERT_EQUAL( 0, memcmp(saved_dialog, original_dialog, dwSize) );
-
- delete [] saved_dialog;
- }
-
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION( CDialogTemplateTest );
+#include <cppunit/extensions/HelperMacros.h>
+#include "../DialogTemplate.h"
+
+#include <stdlib.h>
+
+class CDialogTemplateTest : public CppUnit::TestFixture {
+
+ CPPUNIT_TEST_SUITE( CDialogTemplateTest );
+ CPPUNIT_TEST( testCorrectness );
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testCorrectness() {
+ unsigned char original_dialog[184] = {
+ 1, 0, 255, 255, 0, 0, 0, 0, 0, 0,
+ 0, 0, 72, 4, 0, 64, 3, 0, 0, 0, 0,
+ 0, 10, 1, 130, 0, 0, 0, 0, 0, 0, 0,
+ 8, 0, 0, 0, 0, 1, 77, 0, 83, 0, 32,
+ 0, 83, 0, 104, 0, 101, 0, 108, 0, 108, 0,
+ 32, 0, 68, 0, 108, 0, 103, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 80,
+ 0, 0, 0, 0, 22, 0, 20, 0, 7, 4, 0,
+ 0, 255, 255, 130, 0, 255, 255, 103, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2, 80, 25, 0, 0, 0, 241, 0, 23, 0,
+ 238, 3, 0, 0, 255, 255, 130, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8,
+ 161, 80, 0, 0, 24, 0, 10, 1, 105, 0, 232,
+ 3, 0, 0, 82, 0, 105, 0, 99, 0, 104, 0,
+ 69, 0, 100, 0, 105, 0, 116, 0, 50, 0, 48,
+ 0, 65, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ CDialogTemplate dt(original_dialog, 1252);
+
+ DWORD dwSize;
+ unsigned char *saved_dialog = dt.Save(dwSize);
+
+ CPPUNIT_ASSERT_EQUAL( (DWORD) sizeof(original_dialog), dwSize );
+ CPPUNIT_ASSERT_EQUAL( 0, memcmp(saved_dialog, original_dialog, dwSize) );
+
+ delete [] saved_dialog;
+ }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( CDialogTemplateTest );
diff --git a/Source/Tests/ResourceEditor.cpp b/Source/Tests/ResourceEditor.cpp
index 179f8b9..8bf5739 100755
--- a/Source/Tests/ResourceEditor.cpp
+++ b/Source/Tests/ResourceEditor.cpp
@@ -1,832 +1,832 @@
-#include <cppunit/extensions/HelperMacros.h>
-#include "../ResourceEditor.h"
-
-#include <stdlib.h>
-
-class CResourceEditorTest : public CppUnit::TestFixture {
-
- CPPUNIT_TEST_SUITE( CResourceEditorTest );
- CPPUNIT_TEST( testCorrectness );
- CPPUNIT_TEST_SUITE_END();
-
-public:
- void testCorrectness() {
- extern unsigned char original_pe[8704];
-
- CResourceEditor re(original_pe, sizeof(original_pe));
-
- DWORD size;
-
- // get size
- size = re.Save(NULL, size);
- unsigned char *saved_pe = new unsigned char[size];
-
- // save
- int rc = re.Save(saved_pe, size);
- CPPUNIT_ASSERT_EQUAL( rc, 0 );
-
- // compare
- CPPUNIT_ASSERT_EQUAL( (DWORD) sizeof(original_pe), size );
- CPPUNIT_ASSERT_EQUAL( 0, memcmp(saved_pe, original_pe, size) );
-
- delete [] saved_pe;
- }
-
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION( CResourceEditorTest );
-
-unsigned char original_pe[8704] = {
- 77, 90, 144, 0, 3, 0, 0, 0, 4, 0,
- 0, 0, 255, 255, 0, 0, 184, 0, 0, 0, 0,
- 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 14,
- 31, 186, 14, 0, 180, 9, 205, 33, 184, 1, 76,
- 205, 33, 84, 104, 105, 115, 32, 112, 114, 111, 103,
- 114, 97, 109, 32, 99, 97, 110, 110, 111, 116, 32,
- 98, 101, 32, 114, 117, 110, 32, 105, 110, 32, 68,
- 79, 83, 32, 109, 111, 100, 101, 46, 13, 13, 10,
- 36, 0, 0, 0, 0, 0, 0, 0, 252, 249, 48,
- 199, 184, 152, 94, 148, 184, 152, 94, 148, 184, 152,
- 94, 148, 184, 152, 95, 148, 168, 152, 94, 148, 59,
- 144, 3, 148, 189, 152, 94, 148, 236, 187, 111, 148,
- 185, 152, 94, 148, 127, 158, 88, 148, 185, 152, 94,
- 148, 82, 105, 99, 104, 184, 152, 94, 148, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 80, 69, 0, 0, 76, 1, 4, 0,
- 86, 34, 23, 68, 0, 0, 0, 0, 0, 0, 0,
- 0, 224, 0, 15, 1, 11, 1, 6, 0, 0, 4,
- 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 126,
- 18, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0,
- 0, 0, 64, 0, 0, 16, 0, 0, 0, 2, 0,
- 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0,
- 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0,
- 4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
- 0, 0, 16, 0, 0, 16, 0, 0, 0, 0, 16,
- 0, 0, 16, 0, 0, 0, 0, 0, 0, 16, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,
- 32, 0, 0, 60, 0, 0, 0, 0, 80, 0, 0,
- 168, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 32, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 116,
- 101, 120, 116, 0, 0, 0, 160, 2, 0, 0, 0,
- 16, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 32, 0, 0, 96, 46, 114, 100, 97, 116, 97,
- 0, 0, 240, 1, 0, 0, 0, 32, 0, 0, 0,
- 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0,
- 64, 46, 100, 97, 116, 97, 0, 0, 0, 100, 18,
- 0, 0, 0, 48, 0, 0, 0, 20, 0, 0, 0,
- 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 64, 0, 0, 192, 46, 114, 115,
- 114, 99, 0, 0, 0, 168, 3, 0, 0, 0, 80,
- 0, 0, 0, 4, 0, 0, 0, 30, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 64, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 139, 68, 36, 8, 129, 236, 12, 2, 0,
- 0, 45, 16, 1, 0, 0, 83, 85, 86, 87, 15,
- 132, 234, 1, 0, 0, 72, 15, 133, 79, 2, 0,
- 0, 139, 132, 36, 40, 2, 0, 0, 102, 61, 2,
- 0, 117, 28, 51, 219, 83, 255, 180, 36, 36, 2,
- 0, 0, 255, 21, 60, 32, 64, 0, 83, 255, 21,
- 56, 32, 64, 0, 233, 38, 2, 0, 0, 139, 200,
- 193, 233, 16, 102, 131, 249, 1, 15, 133, 178, 0,
- 0, 0, 51, 219, 190, 71, 1, 0, 0, 83, 83,
- 189, 234, 3, 0, 0, 86, 85, 255, 180, 36, 48,
- 2, 0, 0, 255, 21, 52, 32, 64, 0, 131, 248,
- 255, 15, 132, 241, 1, 0, 0, 83, 83, 191, 233,
- 3, 0, 0, 86, 87, 255, 180, 36, 48, 2, 0,
- 0, 255, 21, 52, 32, 64, 0, 131, 248, 255, 15,
- 132, 210, 1, 0, 0, 83, 83, 86, 87, 255, 180,
- 36, 48, 2, 0, 0, 139, 61, 52, 32, 64, 0,
- 255, 215, 15, 183, 4, 197, 104, 50, 64, 0, 83,
- 83, 86, 85, 255, 180, 36, 48, 2, 0, 0, 193,
- 224, 10, 137, 68, 36, 36, 255, 215, 15, 183, 4,
- 197, 0, 48, 64, 0, 139, 76, 36, 16, 11, 200,
- 141, 68, 36, 28, 81, 104, 84, 66, 64, 0, 80,
- 255, 21, 48, 32, 64, 0, 131, 196, 12, 141, 68,
- 36, 28, 80, 104, 235, 3, 0, 0, 255, 180, 36,
- 40, 2, 0, 0, 255, 21, 44, 32, 64, 0, 233,
- 101, 1, 0, 0, 102, 61, 1, 0, 15, 133, 91,
- 1, 0, 0, 51, 219, 190, 71, 1, 0, 0, 83,
- 83, 189, 234, 3, 0, 0, 86, 85, 255, 180, 36,
- 48, 2, 0, 0, 255, 21, 52, 32, 64, 0, 131,
- 248, 255, 15, 132, 53, 1, 0, 0, 83, 83, 191,
- 233, 3, 0, 0, 86, 87, 255, 180, 36, 48, 2,
- 0, 0, 255, 21, 52, 32, 64, 0, 131, 248, 255,
- 15, 132, 22, 1, 0, 0, 106, 16, 106, 2, 255,
- 21, 4, 32, 64, 0, 59, 195, 137, 68, 36, 16,
- 15, 132, 0, 1, 0, 0, 80, 255, 21, 0, 32,
- 64, 0, 83, 83, 86, 87, 255, 180, 36, 48, 2,
- 0, 0, 139, 61, 52, 32, 64, 0, 137, 68, 36,
- 44, 255, 215, 15, 183, 4, 197, 104, 50, 64, 0,
- 83, 83, 86, 85, 255, 180, 36, 48, 2, 0, 0,
- 193, 224, 10, 137, 68, 36, 40, 255, 215, 15, 183,
- 4, 197, 0, 48, 64, 0, 139, 76, 36, 20, 11,
- 200, 81, 104, 80, 66, 64, 0, 255, 116, 36, 32,
- 255, 21, 48, 32, 64, 0, 131, 196, 12, 255, 116,
- 36, 16, 255, 21, 16, 32, 64, 0, 255, 180, 36,
- 32, 2, 0, 0, 255, 21, 40, 32, 64, 0, 133,
- 192, 15, 132, 134, 0, 0, 0, 255, 21, 36, 32,
- 64, 0, 255, 116, 36, 16, 106, 1, 255, 21, 32,
- 32, 64, 0, 255, 21, 28, 32, 64, 0, 235, 108,
- 51, 219, 83, 83, 104, 128, 0, 0, 0, 255, 180,
- 36, 44, 2, 0, 0, 255, 21, 24, 32, 64, 0,
- 139, 53, 52, 32, 64, 0, 51, 255, 189, 234, 3,
- 0, 0, 255, 183, 4, 48, 64, 0, 83, 104, 67,
- 1, 0, 0, 85, 255, 180, 36, 48, 2, 0, 0,
- 255, 214, 131, 199, 8, 129, 255, 104, 2, 0, 0,
- 114, 223, 51, 237, 191, 233, 3, 0, 0, 255, 181,
- 108, 50, 64, 0, 83, 104, 67, 1, 0, 0, 87,
- 255, 180, 36, 48, 2, 0, 0, 255, 214, 131, 197,
- 8, 129, 253, 224, 2, 0, 0, 114, 223, 95, 94,
- 93, 51, 192, 91, 129, 196, 12, 2, 0, 0, 194,
- 16, 0, 106, 0, 104, 0, 16, 64, 0, 106, 0,
- 106, 101, 106, 0, 255, 21, 12, 32, 64, 0, 80,
- 255, 21, 64, 32, 64, 0, 106, 0, 255, 21, 8,
- 32, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 220, 32, 0, 0, 234, 32, 0, 0,
- 248, 32, 0, 0, 6, 33, 0, 0, 204, 32, 0,
- 0, 0, 0, 0, 0, 40, 33, 0, 0, 56, 33,
- 0, 0, 74, 33, 0, 0, 94, 33, 0, 0, 112,
- 33, 0, 0, 128, 33, 0, 0, 146, 33, 0, 0,
- 158, 33, 0, 0, 180, 33, 0, 0, 198, 33, 0,
- 0, 210, 33, 0, 0, 0, 0, 0, 0, 132, 32,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26,
- 33, 0, 0, 0, 32, 0, 0, 156, 32, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 228, 33, 0,
- 0, 24, 32, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 220, 32, 0, 0, 234, 32, 0, 0,
- 248, 32, 0, 0, 6, 33, 0, 0, 204, 32, 0,
- 0, 0, 0, 0, 0, 40, 33, 0, 0, 56, 33,
- 0, 0, 74, 33, 0, 0, 94, 33, 0, 0, 112,
- 33, 0, 0, 128, 33, 0, 0, 146, 33, 0, 0,
- 158, 33, 0, 0, 180, 33, 0, 0, 198, 33, 0,
- 0, 210, 33, 0, 0, 0, 0, 0, 0, 0, 2,
- 71, 108, 111, 98, 97, 108, 85, 110, 108, 111, 99,
- 107, 0, 0, 249, 1, 71, 108, 111, 98, 97, 108,
- 76, 111, 99, 107, 0, 0, 238, 1, 71, 108, 111,
- 98, 97, 108, 65, 108, 108, 111, 99, 0, 175, 0,
- 69, 120, 105, 116, 80, 114, 111, 99, 101, 115, 115,
- 0, 119, 1, 71, 101, 116, 77, 111, 100, 117, 108,
- 101, 72, 97, 110, 100, 108, 101, 65, 0, 0, 75,
- 69, 82, 78, 69, 76, 51, 50, 46, 100, 108, 108,
- 0, 0, 58, 2, 83, 101, 110, 100, 77, 101, 115,
- 115, 97, 103, 101, 65, 0, 0, 66, 0, 67, 108,
- 111, 115, 101, 67, 108, 105, 112, 98, 111, 97, 114,
- 100, 0, 0, 73, 2, 83, 101, 116, 67, 108, 105,
- 112, 98, 111, 97, 114, 100, 68, 97, 116, 97, 0,
- 0, 193, 0, 69, 109, 112, 116, 121, 67, 108, 105,
- 112, 98, 111, 97, 114, 100, 0, 0, 245, 1, 79,
- 112, 101, 110, 67, 108, 105, 112, 98, 111, 97, 114,
- 100, 0, 82, 2, 83, 101, 116, 68, 108, 103, 73,
- 116, 101, 109, 84, 101, 120, 116, 65, 0, 213, 2,
- 119, 115, 112, 114, 105, 110, 116, 102, 65, 0, 53,
- 2, 83, 101, 110, 100, 68, 108, 103, 73, 116, 101,
- 109, 77, 101, 115, 115, 97, 103, 101, 65, 0, 3,
- 2, 80, 111, 115, 116, 81, 117, 105, 116, 77, 101,
- 115, 115, 97, 103, 101, 0, 198, 0, 69, 110, 100,
- 68, 105, 97, 108, 111, 103, 0, 158, 0, 68, 105,
- 97, 108, 111, 103, 66, 111, 120, 80, 97, 114, 97,
- 109, 65, 0, 85, 83, 69, 82, 51, 50, 46, 100,
- 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 64, 66, 64, 0, 127, 0, 0, 0, 48,
- 66, 64, 0, 54, 0, 0, 0, 32, 66, 64, 0,
- 28, 0, 0, 0, 16, 66, 64, 0, 1, 0, 0,
- 0, 4, 66, 64, 0, 43, 0, 0, 0, 244, 65,
- 64, 0, 77, 0, 0, 0, 228, 65, 64, 0, 44,
- 0, 0, 0, 216, 65, 64, 0, 45, 0, 0, 0,
- 204, 65, 64, 0, 35, 0, 0, 0, 188, 65, 64,
- 0, 69, 0, 0, 0, 172, 65, 64, 0, 2, 0,
- 0, 0, 156, 65, 64, 0, 3, 0, 0, 0, 140,
- 65, 64, 0, 4, 0, 0, 0, 124, 65, 64, 0,
- 26, 0, 0, 0, 108, 65, 64, 0, 5, 0, 0,
- 0, 96, 65, 64, 0, 6, 0, 0, 0, 84, 65,
- 64, 0, 101, 0, 0, 0, 72, 65, 64, 0, 19,
- 0, 0, 0, 60, 65, 64, 0, 9, 0, 0, 0,
- 44, 65, 64, 0, 37, 0, 0, 0, 28, 65, 64,
- 0, 56, 0, 0, 0, 12, 65, 64, 0, 41, 0,
- 0, 0, 0, 65, 64, 0, 11, 0, 0, 0, 240,
- 64, 64, 0, 12, 0, 0, 0, 228, 64, 64, 0,
- 86, 0, 0, 0, 212, 64, 64, 0, 55, 0, 0,
- 0, 196, 64, 64, 0, 7, 0, 0, 0, 184, 64,
- 64, 0, 8, 0, 0, 0, 172, 64, 64, 0, 71,
- 0, 0, 0, 156, 64, 64, 0, 13, 0, 0, 0,
- 144, 64, 64, 0, 57, 0, 0, 0, 132, 64, 64,
- 0, 14, 0, 0, 0, 116, 64, 64, 0, 15, 0,
- 0, 0, 100, 64, 64, 0, 33, 0, 0, 0, 84,
- 64, 64, 0, 16, 0, 0, 0, 68, 64, 64, 0,
- 17, 0, 0, 0, 52, 64, 64, 0, 75, 0, 0,
- 0, 36, 64, 64, 0, 96, 0, 0, 0, 20, 64,
- 64, 0, 63, 0, 0, 0, 8, 64, 64, 0, 87,
- 0, 0, 0, 248, 63, 64, 0, 18, 0, 0, 0,
- 236, 63, 64, 0, 64, 0, 0, 0, 224, 63, 64,
- 0, 38, 0, 0, 0, 208, 63, 64, 0, 39, 0,
- 0, 0, 192, 63, 64, 0, 47, 0, 0, 0, 176,
- 63, 64, 0, 62, 0, 0, 0, 164, 63, 64, 0,
- 76, 0, 0, 0, 148, 63, 64, 0, 88, 0, 0,
- 0, 132, 63, 64, 0, 78, 0, 0, 0, 116, 63,
- 64, 0, 80, 0, 0, 0, 100, 63, 64, 0, 97,
- 0, 0, 0, 88, 63, 64, 0, 20, 0, 0, 0,
- 72, 63, 64, 0, 72, 0, 0, 0, 60, 63, 64,
- 0, 21, 0, 0, 0, 48, 63, 64, 0, 22, 0,
- 0, 0, 32, 63, 64, 0, 70, 0, 0, 0, 16,
- 63, 64, 0, 24, 0, 0, 0, 0, 63, 64, 0,
- 25, 0, 0, 0, 240, 62, 64, 0, 79, 0, 0,
- 0, 224, 62, 64, 0, 26, 0, 0, 0, 208, 62,
- 64, 0, 89, 0, 0, 0, 196, 62, 64, 0, 27,
- 0, 0, 0, 184, 62, 64, 0, 36, 0, 0, 0,
- 168, 62, 64, 0, 10, 0, 0, 0, 152, 62, 64,
- 0, 65, 0, 0, 0, 136, 62, 64, 0, 29, 0,
- 0, 0, 120, 62, 64, 0, 90, 0, 0, 0, 108,
- 62, 64, 0, 73, 0, 0, 0, 96, 62, 64, 0,
- 68, 0, 0, 0, 84, 62, 64, 0, 74, 0, 0,
- 0, 72, 62, 64, 0, 30, 0, 0, 0, 60, 62,
- 64, 0, 31, 0, 0, 0, 44, 62, 64, 0, 34,
- 0, 0, 0, 28, 62, 64, 0, 32, 0, 0, 0,
- 16, 62, 64, 0, 67, 0, 0, 0, 4, 62, 64,
- 0, 42, 0, 0, 0, 244, 61, 64, 0, 0, 0,
- 0, 0, 228, 61, 64, 0, 1, 0, 0, 0, 212,
- 61, 64, 0, 2, 0, 0, 0, 192, 61, 64, 0,
- 1, 0, 0, 0, 164, 61, 64, 0, 2, 0, 0,
- 0, 144, 61, 64, 0, 3, 0, 0, 0, 120, 61,
- 64, 0, 4, 0, 0, 0, 96, 61, 64, 0, 5,
- 0, 0, 0, 72, 61, 64, 0, 6, 0, 0, 0,
- 48, 61, 64, 0, 7, 0, 0, 0, 24, 61, 64,
- 0, 8, 0, 0, 0, 4, 61, 64, 0, 9, 0,
- 0, 0, 236, 60, 64, 0, 10, 0, 0, 0, 212,
- 60, 64, 0, 11, 0, 0, 0, 188, 60, 64, 0,
- 12, 0, 0, 0, 164, 60, 64, 0, 13, 0, 0,
- 0, 140, 60, 64, 0, 14, 0, 0, 0, 120, 60,
- 64, 0, 15, 0, 0, 0, 96, 60, 64, 0, 16,
- 0, 0, 0, 72, 60, 64, 0, 1, 0, 0, 0,
- 52, 60, 64, 0, 2, 0, 0, 0, 28, 60, 64,
- 0, 1, 0, 0, 0, 0, 60, 64, 0, 2, 0,
- 0, 0, 228, 59, 64, 0, 3, 0, 0, 0, 200,
- 59, 64, 0, 4, 0, 0, 0, 172, 59, 64, 0,
- 5, 0, 0, 0, 148, 59, 64, 0, 1, 0, 0,
- 0, 132, 59, 64, 0, 2, 0, 0, 0, 108, 59,
- 64, 0, 1, 0, 0, 0, 88, 59, 64, 0, 2,
- 0, 0, 0, 68, 59, 64, 0, 3, 0, 0, 0,
- 48, 59, 64, 0, 4, 0, 0, 0, 28, 59, 64,
- 0, 5, 0, 0, 0, 8, 59, 64, 0, 6, 0,
- 0, 0, 240, 58, 64, 0, 7, 0, 0, 0, 208,
- 58, 64, 0, 8, 0, 0, 0, 184, 58, 64, 0,
- 9, 0, 0, 0, 156, 58, 64, 0, 10, 0, 0,
- 0, 132, 58, 64, 0, 11, 0, 0, 0, 104, 58,
- 64, 0, 12, 0, 0, 0, 76, 58, 64, 0, 13,
- 0, 0, 0, 48, 58, 64, 0, 1, 0, 0, 0,
- 32, 58, 64, 0, 2, 0, 0, 0, 8, 58, 64,
- 0, 3, 0, 0, 0, 240, 57, 64, 0, 4, 0,
- 0, 0, 216, 57, 64, 0, 5, 0, 0, 0, 188,
- 57, 64, 0, 6, 0, 0, 0, 164, 57, 64, 0,
- 1, 0, 0, 0, 148, 57, 64, 0, 2, 0, 0,
- 0, 124, 57, 64, 0, 3, 0, 0, 0, 100, 57,
- 64, 0, 4, 0, 0, 0, 72, 57, 64, 0, 5,
- 0, 0, 0, 40, 57, 64, 0, 1, 0, 0, 0,
- 24, 57, 64, 0, 2, 0, 0, 0, 0, 57, 64,
- 0, 2, 0, 0, 0, 232, 56, 64, 0, 1, 0,
- 0, 0, 216, 56, 64, 0, 1, 0, 0, 0, 196,
- 56, 64, 0, 1, 0, 0, 0, 172, 56, 64, 0,
- 2, 0, 0, 0, 140, 56, 64, 0, 2, 0, 0,
- 0, 116, 56, 64, 0, 1, 0, 0, 0, 88, 56,
- 64, 0, 2, 0, 0, 0, 60, 56, 64, 0, 2,
- 0, 0, 0, 40, 56, 64, 0, 1, 0, 0, 0,
- 8, 56, 64, 0, 2, 0, 0, 0, 240, 55, 64,
- 0, 3, 0, 0, 0, 212, 55, 64, 0, 1, 0,
- 0, 0, 196, 55, 64, 0, 2, 0, 0, 0, 172,
- 55, 64, 0, 3, 0, 0, 0, 148, 55, 64, 0,
- 4, 0, 0, 0, 120, 55, 64, 0, 5, 0, 0,
- 0, 92, 55, 64, 0, 6, 0, 0, 0, 68, 55,
- 64, 0, 7, 0, 0, 0, 32, 55, 64, 0, 8,
- 0, 0, 0, 4, 55, 64, 0, 9, 0, 0, 0,
- 232, 54, 64, 0, 10, 0, 0, 0, 208, 54, 64,
- 0, 11, 0, 0, 0, 180, 54, 64, 0, 12, 0,
- 0, 0, 156, 54, 64, 0, 13, 0, 0, 0, 132,
- 54, 64, 0, 14, 0, 0, 0, 108, 54, 64, 0,
- 15, 0, 0, 0, 80, 54, 64, 0, 16, 0, 0,
- 0, 56, 54, 64, 0, 17, 0, 0, 0, 28, 54,
- 64, 0, 18, 0, 0, 0, 0, 54, 64, 0, 19,
- 0, 0, 0, 228, 53, 64, 0, 20, 0, 0, 0,
- 200, 53, 64, 0, 1, 0, 0, 0, 184, 53, 64,
- 0, 2, 0, 0, 0, 160, 53, 64, 0, 1, 0,
- 0, 0, 136, 53, 64, 0, 2, 0, 0, 0, 116,
- 53, 64, 0, 1, 0, 0, 0, 96, 53, 64, 0,
- 2, 0, 0, 0, 72, 53, 64, 0, 83, 85, 66,
- 76, 65, 78, 71, 95, 85, 90, 66, 69, 75, 95,
- 67, 89, 82, 73, 76, 76, 73, 67, 0, 0, 83,
- 85, 66, 76, 65, 78, 71, 95, 85, 90, 66, 69,
- 75, 95, 76, 65, 84, 73, 78, 0, 83, 85, 66,
- 76, 65, 78, 71, 95, 85, 82, 68, 85, 95, 73,
- 78, 68, 73, 65, 0, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 85, 82, 68, 85, 95, 80, 65, 75,
- 73, 83, 84, 65, 78, 0, 0, 0, 83, 85, 66,
- 76, 65, 78, 71, 95, 83, 87, 69, 68, 73, 83,
- 72, 95, 70, 73, 78, 76, 65, 78, 68, 0, 83,
- 85, 66, 76, 65, 78, 71, 95, 83, 87, 69, 68,
- 73, 83, 72, 0, 83, 85, 66, 76, 65, 78, 71,
- 95, 83, 80, 65, 78, 73, 83, 72, 95, 80, 85,
- 69, 82, 84, 79, 95, 82, 73, 67, 79, 0, 83,
- 85, 66, 76, 65, 78, 71, 95, 83, 80, 65, 78,
- 73, 83, 72, 95, 78, 73, 67, 65, 82, 65, 71,
- 85, 65, 0, 0, 0, 83, 85, 66, 76, 65, 78,
- 71, 95, 83, 80, 65, 78, 73, 83, 72, 95, 72,
- 79, 78, 68, 85, 82, 65, 83, 0, 0, 0, 0,
- 83, 85, 66, 76, 65, 78, 71, 95, 83, 80, 65,
- 78, 73, 83, 72, 95, 69, 76, 95, 83, 65, 76,
- 86, 65, 68, 79, 82, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 83, 80, 65, 78, 73, 83, 72, 95,
- 66, 79, 76, 73, 86, 73, 65, 0, 83, 85, 66,
- 76, 65, 78, 71, 95, 83, 80, 65, 78, 73, 83,
- 72, 95, 80, 65, 82, 65, 71, 85, 65, 89, 0,
- 0, 0, 0, 83, 85, 66, 76, 65, 78, 71, 95,
- 83, 80, 65, 78, 73, 83, 72, 95, 85, 82, 85,
- 71, 85, 65, 89, 0, 83, 85, 66, 76, 65, 78,
- 71, 95, 83, 80, 65, 78, 73, 83, 72, 95, 67,
- 72, 73, 76, 69, 0, 0, 0, 83, 85, 66, 76,
- 65, 78, 71, 95, 83, 80, 65, 78, 73, 83, 72,
- 95, 69, 67, 85, 65, 68, 79, 82, 0, 83, 85,
- 66, 76, 65, 78, 71, 95, 83, 80, 65, 78, 73,
- 83, 72, 95, 65, 82, 71, 69, 78, 84, 73, 78,
- 65, 0, 0, 0, 83, 85, 66, 76, 65, 78, 71,
- 95, 83, 80, 65, 78, 73, 83, 72, 95, 80, 69,
- 82, 85, 0, 0, 0, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 83, 80, 65, 78, 73, 83, 72, 95,
- 67, 79, 76, 79, 77, 66, 73, 65, 0, 0, 0,
- 0, 83, 85, 66, 76, 65, 78, 71, 95, 83, 80,
- 65, 78, 73, 83, 72, 95, 86, 69, 78, 69, 90,
- 85, 69, 76, 65, 0, 0, 0, 83, 85, 66, 76,
- 65, 78, 71, 95, 83, 80, 65, 78, 73, 83, 72,
- 95, 68, 79, 77, 73, 78, 73, 67, 65, 78, 95,
- 82, 69, 80, 85, 66, 76, 73, 67, 0, 0, 83,
- 85, 66, 76, 65, 78, 71, 95, 83, 80, 65, 78,
- 73, 83, 72, 95, 80, 65, 78, 65, 77, 65, 0,
- 0, 83, 85, 66, 76, 65, 78, 71, 95, 83, 80,
- 65, 78, 73, 83, 72, 95, 67, 79, 83, 84, 65,
- 95, 82, 73, 67, 65, 0, 0, 83, 85, 66, 76,
- 65, 78, 71, 95, 83, 80, 65, 78, 73, 83, 72,
- 95, 71, 85, 65, 84, 69, 77, 65, 76, 65, 0,
- 0, 0, 83, 85, 66, 76, 65, 78, 71, 95, 83,
- 80, 65, 78, 73, 83, 72, 95, 77, 79, 68, 69,
- 82, 78, 0, 0, 83, 85, 66, 76, 65, 78, 71,
- 95, 83, 80, 65, 78, 73, 83, 72, 95, 77, 69,
- 88, 73, 67, 65, 78, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 83, 80, 65, 78, 73, 83, 72, 0,
- 83, 85, 66, 76, 65, 78, 71, 95, 83, 69, 82,
- 66, 73, 65, 78, 95, 67, 89, 82, 73, 76, 76,
- 73, 67, 0, 0, 0, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 83, 69, 82, 66, 73, 65, 78, 95,
- 76, 65, 84, 73, 78, 0, 0, 0, 83, 85, 66,
- 76, 65, 78, 71, 95, 80, 79, 82, 84, 85, 71,
- 85, 69, 83, 69, 95, 66, 82, 65, 90, 73, 76,
- 73, 65, 78, 0, 0, 0, 0, 83, 85, 66, 76,
- 65, 78, 71, 95, 80, 79, 82, 84, 85, 71, 85,
- 69, 83, 69, 0, 0, 83, 85, 66, 76, 65, 78,
- 71, 95, 78, 79, 82, 87, 69, 71, 73, 65, 78,
- 95, 78, 89, 78, 79, 82, 83, 75, 0, 0, 0,
- 83, 85, 66, 76, 65, 78, 71, 95, 78, 79, 82,
- 87, 69, 71, 73, 65, 78, 95, 66, 79, 75, 77,
- 65, 76, 0, 0, 0, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 78, 69, 80, 65, 76, 73, 95, 73,
- 78, 68, 73, 65, 0, 0, 0, 0, 83, 85, 66,
- 76, 65, 78, 71, 95, 77, 65, 76, 65, 89, 95,
- 66, 82, 85, 78, 69, 73, 95, 68, 65, 82, 85,
- 83, 83, 65, 76, 65, 77, 0, 83, 85, 66, 76,
- 65, 78, 71, 95, 77, 65, 76, 65, 89, 95, 77,
- 65, 76, 65, 89, 83, 73, 65, 0, 0, 83, 85,
- 66, 76, 65, 78, 71, 95, 76, 73, 84, 72, 85,
- 65, 78, 73, 65, 78, 0, 0, 83, 85, 66, 76,
- 65, 78, 71, 95, 75, 79, 82, 69, 65, 78, 0,
- 0, 83, 85, 66, 76, 65, 78, 71, 95, 75, 65,
- 83, 72, 77, 73, 82, 73, 95, 73, 78, 68, 73,
- 65, 0, 0, 83, 85, 66, 76, 65, 78, 71, 95,
- 73, 84, 65, 76, 73, 65, 78, 95, 83, 87, 73,
- 83, 83, 0, 0, 0, 83, 85, 66, 76, 65, 78,
- 71, 95, 73, 84, 65, 76, 73, 65, 78, 0, 83,
- 85, 66, 76, 65, 78, 71, 95, 71, 69, 82, 77,
- 65, 78, 95, 76, 73, 69, 67, 72, 84, 69, 78,
- 83, 84, 69, 73, 78, 0, 0, 0, 0, 83, 85,
- 66, 76, 65, 78, 71, 95, 71, 69, 82, 77, 65,
- 78, 95, 76, 85, 88, 69, 77, 66, 79, 85, 82,
- 71, 0, 0, 0, 83, 85, 66, 76, 65, 78, 71,
- 95, 71, 69, 82, 77, 65, 78, 95, 65, 85, 83,
- 84, 82, 73, 65, 78, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 71, 69, 82, 77, 65, 78, 95, 83,
- 87, 73, 83, 83, 0, 0, 0, 0, 83, 85, 66,
- 76, 65, 78, 71, 95, 71, 69, 82, 77, 65, 78,
- 0, 0, 83, 85, 66, 76, 65, 78, 71, 95, 70,
- 82, 69, 78, 67, 72, 95, 77, 79, 78, 65, 67,
- 79, 0, 0, 0, 83, 85, 66, 76, 65, 78, 71,
- 95, 70, 82, 69, 78, 67, 72, 95, 76, 85, 88,
- 69, 77, 66, 79, 85, 82, 71, 0, 0, 0, 83,
- 85, 66, 76, 65, 78, 71, 95, 70, 82, 69, 78,
- 67, 72, 95, 83, 87, 73, 83, 83, 0, 0, 0,
- 0, 83, 85, 66, 76, 65, 78, 71, 95, 70, 82,
- 69, 78, 67, 72, 95, 67, 65, 78, 65, 68, 73,
- 65, 78, 0, 83, 85, 66, 76, 65, 78, 71, 95,
- 70, 82, 69, 78, 67, 72, 95, 66, 69, 76, 71,
- 73, 65, 78, 0, 0, 83, 85, 66, 76, 65, 78,
- 71, 95, 70, 82, 69, 78, 67, 72, 0, 0, 83,
- 85, 66, 76, 65, 78, 71, 95, 69, 78, 71, 76,
- 73, 83, 72, 95, 80, 72, 73, 76, 73, 80, 80,
- 73, 78, 69, 83, 0, 83, 85, 66, 76, 65, 78,
- 71, 95, 69, 78, 71, 76, 73, 83, 72, 95, 90,
- 73, 77, 66, 65, 66, 87, 69, 0, 0, 0, 0,
- 83, 85, 66, 76, 65, 78, 71, 95, 69, 78, 71,
- 76, 73, 83, 72, 95, 84, 82, 73, 78, 73, 68,
- 65, 68, 0, 0, 0, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 69, 78, 71, 76, 73, 83, 72, 95,
- 66, 69, 76, 73, 90, 69, 0, 0, 83, 85, 66,
- 76, 65, 78, 71, 95, 69, 78, 71, 76, 73, 83,
- 72, 95, 67, 65, 82, 73, 66, 66, 69, 65, 78,
- 0, 0, 0, 83, 85, 66, 76, 65, 78, 71, 95,
- 69, 78, 71, 76, 73, 83, 72, 95, 74, 65, 77,
- 65, 73, 67, 65, 0, 83, 85, 66, 76, 65, 78,
- 71, 95, 69, 78, 71, 76, 73, 83, 72, 95, 83,
- 79, 85, 84, 72, 95, 65, 70, 82, 73, 67, 65,
- 0, 0, 0, 0, 83, 85, 66, 76, 65, 78, 71,
- 95, 69, 78, 71, 76, 73, 83, 72, 95, 69, 73,
- 82, 69, 0, 0, 0, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 69, 78, 71, 76, 73, 83, 72, 95,
- 78, 90, 0, 0, 83, 85, 66, 76, 65, 78, 71,
- 95, 69, 78, 71, 76, 73, 83, 72, 95, 67, 65,
- 78, 0, 83, 85, 66, 76, 65, 78, 71, 95, 69,
- 78, 71, 76, 73, 83, 72, 95, 65, 85, 83, 0,
- 83, 85, 66, 76, 65, 78, 71, 95, 69, 78, 71,
- 76, 73, 83, 72, 95, 85, 75, 0, 0, 83, 85,
- 66, 76, 65, 78, 71, 95, 69, 78, 71, 76, 73,
- 83, 72, 95, 85, 83, 0, 0, 83, 85, 66, 76,
- 65, 78, 71, 95, 68, 85, 84, 67, 72, 95, 66,
- 69, 76, 71, 73, 65, 78, 0, 0, 0, 83, 85,
- 66, 76, 65, 78, 71, 95, 68, 85, 84, 67, 72,
- 0, 0, 0, 83, 85, 66, 76, 65, 78, 71, 95,
- 67, 72, 73, 78, 69, 83, 69, 95, 77, 65, 67,
- 65, 85, 0, 0, 0, 83, 85, 66, 76, 65, 78,
- 71, 95, 67, 72, 73, 78, 69, 83, 69, 95, 83,
- 73, 78, 71, 65, 80, 79, 82, 69, 0, 0, 0,
- 83, 85, 66, 76, 65, 78, 71, 95, 67, 72, 73,
- 78, 69, 83, 69, 95, 72, 79, 78, 71, 75, 79,
- 78, 71, 0, 0, 0, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 67, 72, 73, 78, 69, 83, 69, 95,
- 83, 73, 77, 80, 76, 73, 70, 73, 69, 68, 0,
- 0, 83, 85, 66, 76, 65, 78, 71, 95, 67, 72,
- 73, 78, 69, 83, 69, 95, 84, 82, 65, 68, 73,
- 84, 73, 79, 78, 65, 76, 0, 83, 85, 66, 76,
- 65, 78, 71, 95, 65, 90, 69, 82, 73, 95, 67,
- 89, 82, 73, 76, 76, 73, 67, 0, 0, 83, 85,
- 66, 76, 65, 78, 71, 95, 65, 90, 69, 82, 73,
- 95, 76, 65, 84, 73, 78, 0, 83, 85, 66, 76,
- 65, 78, 71, 95, 65, 82, 65, 66, 73, 67, 95,
- 81, 65, 84, 65, 82, 0, 0, 0, 0, 83, 85,
- 66, 76, 65, 78, 71, 95, 65, 82, 65, 66, 73,
- 67, 95, 66, 65, 72, 82, 65, 73, 78, 0, 0,
- 83, 85, 66, 76, 65, 78, 71, 95, 65, 82, 65,
- 66, 73, 67, 95, 85, 65, 69, 0, 0, 83, 85,
- 66, 76, 65, 78, 71, 95, 65, 82, 65, 66, 73,
- 67, 95, 75, 85, 87, 65, 73, 84, 0, 0, 0,
- 83, 85, 66, 76, 65, 78, 71, 95, 65, 82, 65,
- 66, 73, 67, 95, 76, 69, 66, 65, 78, 79, 78,
- 0, 0, 83, 85, 66, 76, 65, 78, 71, 95, 65,
- 82, 65, 66, 73, 67, 95, 74, 79, 82, 68, 65,
- 78, 0, 0, 0, 83, 85, 66, 76, 65, 78, 71,
- 95, 65, 82, 65, 66, 73, 67, 95, 83, 89, 82,
- 73, 65, 0, 0, 0, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 65, 82, 65, 66, 73, 67, 95, 89,
- 69, 77, 69, 78, 0, 0, 0, 0, 83, 85, 66,
- 76, 65, 78, 71, 95, 65, 82, 65, 66, 73, 67,
- 95, 79, 77, 65, 78, 0, 83, 85, 66, 76, 65,
- 78, 71, 95, 65, 82, 65, 66, 73, 67, 95, 84,
- 85, 78, 73, 83, 73, 65, 0, 0, 83, 85, 66,
- 76, 65, 78, 71, 95, 65, 82, 65, 66, 73, 67,
- 95, 77, 79, 82, 79, 67, 67, 79, 0, 0, 83,
- 85, 66, 76, 65, 78, 71, 95, 65, 82, 65, 66,
- 73, 67, 95, 65, 76, 71, 69, 82, 73, 65, 0,
- 0, 83, 85, 66, 76, 65, 78, 71, 95, 65, 82,
- 65, 66, 73, 67, 95, 76, 73, 66, 89, 65, 0,
- 0, 0, 0, 83, 85, 66, 76, 65, 78, 71, 95,
- 65, 82, 65, 66, 73, 67, 95, 69, 71, 89, 80,
- 84, 0, 0, 0, 0, 83, 85, 66, 76, 65, 78,
- 71, 95, 65, 82, 65, 66, 73, 67, 95, 73, 82,
- 65, 81, 0, 83, 85, 66, 76, 65, 78, 71, 95,
- 65, 82, 65, 66, 73, 67, 95, 83, 65, 85, 68,
- 73, 95, 65, 82, 65, 66, 73, 65, 0, 83, 85,
- 66, 76, 65, 78, 71, 95, 83, 89, 83, 95, 68,
- 69, 70, 65, 85, 76, 84, 0, 83, 85, 66, 76,
- 65, 78, 71, 95, 68, 69, 70, 65, 85, 76, 84,
- 0, 83, 85, 66, 76, 65, 78, 71, 95, 78, 69,
- 85, 84, 82, 65, 76, 0, 76, 65, 78, 71, 95,
- 86, 73, 69, 84, 78, 65, 77, 69, 83, 69, 0,
- 76, 65, 78, 71, 95, 85, 90, 66, 69, 75, 0,
- 0, 76, 65, 78, 71, 95, 85, 82, 68, 85, 0,
- 0, 0, 76, 65, 78, 71, 95, 85, 75, 82, 65,
- 73, 78, 73, 65, 78, 0, 0, 76, 65, 78, 71,
- 95, 84, 85, 82, 75, 73, 83, 72, 0, 0, 0,
- 0, 76, 65, 78, 71, 95, 84, 72, 65, 73, 0,
- 0, 0, 76, 65, 78, 71, 95, 84, 69, 76, 85,
- 71, 85, 0, 76, 65, 78, 71, 95, 84, 65, 84,
- 65, 82, 0, 0, 76, 65, 78, 71, 95, 84, 65,
- 77, 73, 76, 0, 0, 76, 65, 78, 71, 95, 83,
- 89, 82, 73, 65, 67, 0, 76, 65, 78, 71, 95,
- 83, 87, 69, 68, 73, 83, 72, 0, 0, 0, 0,
- 76, 65, 78, 71, 95, 83, 87, 65, 72, 73, 76,
- 73, 0, 0, 0, 0, 76, 65, 78, 71, 95, 83,
- 80, 65, 78, 73, 83, 72, 0, 0, 0, 0, 76,
- 65, 78, 71, 95, 83, 76, 79, 86, 69, 78, 73,
- 65, 78, 0, 0, 76, 65, 78, 71, 95, 83, 76,
- 79, 86, 65, 75, 0, 76, 65, 78, 71, 95, 83,
- 73, 78, 68, 72, 73, 0, 76, 65, 78, 71, 95,
- 83, 69, 82, 66, 73, 65, 78, 0, 0, 0, 0,
- 76, 65, 78, 71, 95, 83, 65, 78, 83, 75, 82,
- 73, 84, 0, 0, 0, 76, 65, 78, 71, 95, 82,
- 85, 83, 83, 73, 65, 78, 0, 0, 0, 0, 76,
- 65, 78, 71, 95, 82, 79, 77, 65, 78, 73, 65,
- 78, 0, 0, 0, 76, 65, 78, 71, 95, 80, 85,
- 78, 74, 65, 66, 73, 0, 0, 0, 0, 76, 65,
- 78, 71, 95, 80, 79, 82, 84, 85, 71, 85, 69,
- 83, 69, 0, 76, 65, 78, 71, 95, 80, 79, 76,
- 73, 83, 72, 0, 76, 65, 78, 71, 95, 79, 82,
- 73, 89, 65, 0, 0, 76, 65, 78, 71, 95, 78,
- 79, 82, 87, 69, 71, 73, 65, 78, 0, 0, 76,
- 65, 78, 71, 95, 78, 69, 80, 65, 76, 73, 0,
- 76, 65, 78, 71, 95, 77, 79, 78, 71, 79, 76,
- 73, 65, 78, 0, 0, 76, 65, 78, 71, 95, 77,
- 65, 82, 65, 84, 72, 73, 0, 0, 0, 0, 76,
- 65, 78, 71, 95, 77, 65, 78, 73, 80, 85, 82,
- 73, 0, 0, 0, 76, 65, 78, 71, 95, 77, 65,
- 76, 65, 89, 65, 76, 65, 77, 0, 0, 76, 65,
- 78, 71, 95, 77, 65, 76, 65, 89, 0, 0, 76,
- 65, 78, 71, 95, 77, 65, 67, 69, 68, 79, 78,
- 73, 65, 78, 0, 76, 65, 78, 71, 95, 76, 73,
- 84, 72, 85, 65, 78, 73, 65, 78, 0, 76, 65,
- 78, 71, 95, 76, 65, 84, 86, 73, 65, 78, 0,
- 0, 0, 0, 76, 65, 78, 71, 95, 75, 89, 82,
- 71, 89, 90, 0, 76, 65, 78, 71, 95, 75, 79,
- 82, 69, 65, 78, 0, 76, 65, 78, 71, 95, 75,
- 79, 78, 75, 65, 78, 73, 0, 0, 0, 0, 76,
- 65, 78, 71, 95, 75, 65, 90, 65, 75, 0, 0,
- 76, 65, 78, 71, 95, 75, 65, 83, 72, 77, 73,
- 82, 73, 0, 0, 0, 76, 65, 78, 71, 95, 75,
- 65, 78, 78, 65, 68, 65, 0, 0, 0, 0, 76,
- 65, 78, 71, 95, 74, 65, 80, 65, 78, 69, 83,
- 69, 0, 0, 0, 76, 65, 78, 71, 95, 73, 84,
- 65, 76, 73, 65, 78, 0, 0, 0, 0, 76, 65,
- 78, 71, 95, 73, 78, 68, 79, 78, 69, 83, 73,
- 65, 78, 0, 76, 65, 78, 71, 95, 73, 67, 69,
- 76, 65, 78, 68, 73, 67, 0, 0, 76, 65, 78,
- 71, 95, 72, 85, 78, 71, 65, 82, 73, 65, 78,
- 0, 0, 76, 65, 78, 71, 95, 72, 73, 78, 68,
- 73, 0, 0, 76, 65, 78, 71, 95, 72, 69, 66,
- 82, 69, 87, 0, 76, 65, 78, 71, 95, 71, 85,
- 74, 65, 82, 65, 84, 73, 0, 0, 0, 76, 65,
- 78, 71, 95, 71, 82, 69, 69, 75, 0, 0, 76,
- 65, 78, 71, 95, 71, 69, 82, 77, 65, 78, 0,
- 76, 65, 78, 71, 95, 71, 69, 79, 82, 71, 73,
- 65, 78, 0, 0, 0, 76, 65, 78, 71, 95, 71,
- 65, 76, 73, 67, 73, 65, 78, 0, 0, 0, 76,
- 65, 78, 71, 95, 70, 82, 69, 78, 67, 72, 0,
- 76, 65, 78, 71, 95, 70, 73, 78, 78, 73, 83,
- 72, 0, 0, 0, 0, 76, 65, 78, 71, 95, 70,
- 65, 82, 83, 73, 0, 0, 76, 65, 78, 71, 95,
- 70, 65, 69, 82, 79, 69, 83, 69, 0, 0, 0,
- 76, 65, 78, 71, 95, 69, 83, 84, 79, 78, 73,
- 65, 78, 0, 0, 0, 76, 65, 78, 71, 95, 69,
- 78, 71, 76, 73, 83, 72, 0, 0, 0, 0, 76,
- 65, 78, 71, 95, 68, 85, 84, 67, 72, 0, 0,
- 76, 65, 78, 71, 95, 68, 73, 86, 69, 72, 73,
- 0, 76, 65, 78, 71, 95, 68, 65, 78, 73, 83,
- 72, 0, 76, 65, 78, 71, 95, 67, 90, 69, 67,
- 72, 0, 0, 76, 65, 78, 71, 95, 67, 82, 79,
- 65, 84, 73, 65, 78, 0, 0, 0, 76, 65, 78,
- 71, 95, 67, 72, 73, 78, 69, 83, 69, 0, 0,
- 0, 0, 76, 65, 78, 71, 95, 67, 65, 84, 65,
- 76, 65, 78, 0, 0, 0, 0, 76, 65, 78, 71,
- 95, 66, 85, 76, 71, 65, 82, 73, 65, 78, 0,
- 0, 76, 65, 78, 71, 95, 66, 69, 78, 71, 65,
- 76, 73, 0, 0, 0, 0, 76, 65, 78, 71, 95,
- 66, 69, 76, 65, 82, 85, 83, 73, 65, 78, 0,
- 76, 65, 78, 71, 95, 66, 65, 83, 81, 85, 69,
- 0, 76, 65, 78, 71, 95, 65, 90, 69, 82, 73,
- 0, 0, 76, 65, 78, 71, 95, 65, 83, 83, 65,
- 77, 69, 83, 69, 0, 0, 0, 76, 65, 78, 71,
- 95, 65, 82, 77, 69, 78, 73, 65, 78, 0, 0,
- 0, 76, 65, 78, 71, 95, 65, 82, 65, 66, 73,
- 67, 0, 76, 65, 78, 71, 95, 65, 76, 66, 65,
- 78, 73, 65, 78, 0, 0, 0, 76, 65, 78, 71,
- 95, 65, 70, 82, 73, 75, 65, 65, 78, 83, 0,
- 0, 76, 65, 78, 71, 95, 73, 78, 86, 65, 82,
- 73, 65, 78, 84, 0, 0, 76, 65, 78, 71, 95,
- 78, 69, 85, 84, 82, 65, 76, 0, 0, 0, 0,
- 37, 117, 0, 0, 76, 97, 110, 103, 117, 97, 103,
- 101, 32, 73, 68, 58, 32, 37, 100, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 2, 0, 5, 0, 0,
- 0, 32, 0, 0, 128, 24, 0, 0, 0, 56, 0,
- 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1, 0, 101, 0, 0, 0,
- 80, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
- 0, 0, 104, 0, 0, 128, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 9, 4, 0, 0, 128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 9, 4, 0, 0, 144, 0, 0, 0, 160,
- 80, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 136, 81, 0, 0, 25, 2, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 8,
- 200, 128, 0, 0, 0, 0, 5, 0, 0, 0, 0,
- 0, 135, 0, 75, 0, 0, 0, 0, 0, 77, 0,
- 97, 0, 107, 0, 101, 0, 76, 0, 97, 0, 110,
- 0, 103, 0, 73, 0, 68, 0, 0, 0, 8, 0,
- 77, 0, 83, 0, 32, 0, 83, 0, 97, 0, 110,
- 0, 115, 0, 32, 0, 83, 0, 101, 0, 114, 0,
- 105, 0, 102, 0, 0, 0, 0, 0, 3, 0, 33,
- 80, 0, 0, 0, 0, 7, 0, 7, 0, 121, 0,
- 100, 0, 234, 3, 255, 255, 133, 0, 0, 0, 0,
- 0, 0, 0, 3, 0, 33, 80, 0, 0, 0, 0,
- 7, 0, 24, 0, 121, 0, 100, 0, 233, 3, 255,
- 255, 133, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 1, 80, 0, 0, 0, 0, 78, 0, 54, 0, 50,
- 0, 14, 0, 1, 0, 255, 255, 128, 0, 67, 0,
- 111, 0, 112, 0, 121, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 1, 80, 0, 0, 0, 0, 7, 0,
- 54, 0, 50, 0, 14, 0, 2, 0, 255, 255, 128,
- 0, 69, 0, 120, 0, 105, 0, 116, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 2, 80, 0, 0, 0,
- 0, 7, 0, 41, 0, 121, 0, 8, 0, 235, 3,
- 255, 255, 130, 0, 0, 0, 0, 0, 0, 0, 60,
- 63, 120, 109, 108, 32, 118, 101, 114, 115, 105, 111,
- 110, 61, 34, 49, 46, 48, 34, 32, 101, 110, 99,
- 111, 100, 105, 110, 103, 61, 34, 85, 84, 70, 45,
- 56, 34, 32, 115, 116, 97, 110, 100, 97, 108, 111,
- 110, 101, 61, 34, 121, 101, 115, 34, 63, 62, 13,
- 10, 60, 97, 115, 115, 101, 109, 98, 108, 121, 32,
- 120, 109, 108, 110, 115, 61, 34, 117, 114, 110, 58,
- 115, 99, 104, 101, 109, 97, 115, 45, 109, 105, 99,
- 114, 111, 115, 111, 102, 116, 45, 99, 111, 109, 58,
- 97, 115, 109, 46, 118, 49, 34, 32, 109, 97, 110,
- 105, 102, 101, 115, 116, 86, 101, 114, 115, 105, 111,
- 110, 61, 34, 49, 46, 48, 34, 62, 13, 10, 60,
- 97, 115, 115, 101, 109, 98, 108, 121, 73, 100, 101,
- 110, 116, 105, 116, 121, 32, 118, 101, 114, 115, 105,
- 111, 110, 61, 34, 49, 46, 48, 46, 48, 46, 48,
- 34, 32, 112, 114, 111, 99, 101, 115, 115, 111, 114,
- 65, 114, 99, 104, 105, 116, 101, 99, 116, 117, 114,
- 101, 61, 34, 88, 56, 54, 34, 32, 110, 97, 109,
- 101, 61, 34, 78, 117, 108, 108, 115, 111, 102, 116,
- 46, 78, 83, 73, 83, 46, 77, 97, 107, 101, 76,
- 97, 110, 103, 73, 100, 34, 32, 116, 121, 112, 101,
- 61, 34, 119, 105, 110, 51, 50, 34, 47, 62, 13,
- 10, 60, 100, 101, 115, 99, 114, 105, 112, 116, 105,
- 111, 110, 62, 77, 97, 107, 101, 76, 97, 110, 103,
- 73, 100, 60, 47, 100, 101, 115, 99, 114, 105, 112,
- 116, 105, 111, 110, 62, 13, 10, 60, 100, 101, 112,
- 101, 110, 100, 101, 110, 99, 121, 62, 13, 10, 60,
- 100, 101, 112, 101, 110, 100, 101, 110, 116, 65, 115,
- 115, 101, 109, 98, 108, 121, 62, 13, 10, 60, 97,
- 115, 115, 101, 109, 98, 108, 121, 73, 100, 101, 110,
- 116, 105, 116, 121, 32, 116, 121, 112, 101, 61, 34,
- 119, 105, 110, 51, 50, 34, 32, 110, 97, 109, 101,
- 61, 34, 77, 105, 99, 114, 111, 115, 111, 102, 116,
- 46, 87, 105, 110, 100, 111, 119, 115, 46, 67, 111,
- 109, 109, 111, 110, 45, 67, 111, 110, 116, 114, 111,
- 108, 115, 34, 32, 118, 101, 114, 115, 105, 111, 110,
- 61, 34, 54, 46, 48, 46, 48, 46, 48, 34, 32,
- 112, 114, 111, 99, 101, 115, 115, 111, 114, 65, 114,
- 99, 104, 105, 116, 101, 99, 116, 117, 114, 101, 61,
- 34, 88, 56, 54, 34, 32, 112, 117, 98, 108, 105,
- 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 34,
- 54, 53, 57, 53, 98, 54, 52, 49, 52, 52, 99,
- 99, 102, 49, 100, 102, 34, 32, 108, 97, 110, 103,
- 117, 97, 103, 101, 61, 34, 42, 34, 32, 47, 62,
- 13, 10, 60, 47, 100, 101, 112, 101, 110, 100, 101,
- 110, 116, 65, 115, 115, 101, 109, 98, 108, 121, 62,
- 13, 10, 60, 47, 100, 101, 112, 101, 110, 100, 101,
- 110, 99, 121, 62, 13, 10, 60, 47, 97, 115, 115,
- 101, 109, 98, 108, 121, 62, 13, 10, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0
-};
+#include <cppunit/extensions/HelperMacros.h>
+#include "../ResourceEditor.h"
+
+#include <stdlib.h>
+
+class CResourceEditorTest : public CppUnit::TestFixture {
+
+ CPPUNIT_TEST_SUITE( CResourceEditorTest );
+ CPPUNIT_TEST( testCorrectness );
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testCorrectness() {
+ extern unsigned char original_pe[8704];
+
+ CResourceEditor re(original_pe, sizeof(original_pe));
+
+ DWORD size;
+
+ // get size
+ size = re.Save(NULL, size);
+ unsigned char *saved_pe = new unsigned char[size];
+
+ // save
+ int rc = re.Save(saved_pe, size);
+ CPPUNIT_ASSERT_EQUAL( rc, 0 );
+
+ // compare
+ CPPUNIT_ASSERT_EQUAL( (DWORD) sizeof(original_pe), size );
+ CPPUNIT_ASSERT_EQUAL( 0, memcmp(saved_pe, original_pe, size) );
+
+ delete [] saved_pe;
+ }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( CResourceEditorTest );
+
+unsigned char original_pe[8704] = {
+ 77, 90, 144, 0, 3, 0, 0, 0, 4, 0,
+ 0, 0, 255, 255, 0, 0, 184, 0, 0, 0, 0,
+ 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 14,
+ 31, 186, 14, 0, 180, 9, 205, 33, 184, 1, 76,
+ 205, 33, 84, 104, 105, 115, 32, 112, 114, 111, 103,
+ 114, 97, 109, 32, 99, 97, 110, 110, 111, 116, 32,
+ 98, 101, 32, 114, 117, 110, 32, 105, 110, 32, 68,
+ 79, 83, 32, 109, 111, 100, 101, 46, 13, 13, 10,
+ 36, 0, 0, 0, 0, 0, 0, 0, 252, 249, 48,
+ 199, 184, 152, 94, 148, 184, 152, 94, 148, 184, 152,
+ 94, 148, 184, 152, 95, 148, 168, 152, 94, 148, 59,
+ 144, 3, 148, 189, 152, 94, 148, 236, 187, 111, 148,
+ 185, 152, 94, 148, 127, 158, 88, 148, 185, 152, 94,
+ 148, 82, 105, 99, 104, 184, 152, 94, 148, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 80, 69, 0, 0, 76, 1, 4, 0,
+ 86, 34, 23, 68, 0, 0, 0, 0, 0, 0, 0,
+ 0, 224, 0, 15, 1, 11, 1, 6, 0, 0, 4,
+ 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 126,
+ 18, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0,
+ 0, 0, 64, 0, 0, 16, 0, 0, 0, 2, 0,
+ 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0,
+ 4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 16, 0, 0, 16, 0, 0, 0, 0, 16,
+ 0, 0, 16, 0, 0, 0, 0, 0, 0, 16, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72,
+ 32, 0, 0, 60, 0, 0, 0, 0, 80, 0, 0,
+ 168, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 32, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 116,
+ 101, 120, 116, 0, 0, 0, 160, 2, 0, 0, 0,
+ 16, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 32, 0, 0, 96, 46, 114, 100, 97, 116, 97,
+ 0, 0, 240, 1, 0, 0, 0, 32, 0, 0, 0,
+ 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0,
+ 64, 46, 100, 97, 116, 97, 0, 0, 0, 100, 18,
+ 0, 0, 0, 48, 0, 0, 0, 20, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 64, 0, 0, 192, 46, 114, 115,
+ 114, 99, 0, 0, 0, 168, 3, 0, 0, 0, 80,
+ 0, 0, 0, 4, 0, 0, 0, 30, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 64, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 139, 68, 36, 8, 129, 236, 12, 2, 0,
+ 0, 45, 16, 1, 0, 0, 83, 85, 86, 87, 15,
+ 132, 234, 1, 0, 0, 72, 15, 133, 79, 2, 0,
+ 0, 139, 132, 36, 40, 2, 0, 0, 102, 61, 2,
+ 0, 117, 28, 51, 219, 83, 255, 180, 36, 36, 2,
+ 0, 0, 255, 21, 60, 32, 64, 0, 83, 255, 21,
+ 56, 32, 64, 0, 233, 38, 2, 0, 0, 139, 200,
+ 193, 233, 16, 102, 131, 249, 1, 15, 133, 178, 0,
+ 0, 0, 51, 219, 190, 71, 1, 0, 0, 83, 83,
+ 189, 234, 3, 0, 0, 86, 85, 255, 180, 36, 48,
+ 2, 0, 0, 255, 21, 52, 32, 64, 0, 131, 248,
+ 255, 15, 132, 241, 1, 0, 0, 83, 83, 191, 233,
+ 3, 0, 0, 86, 87, 255, 180, 36, 48, 2, 0,
+ 0, 255, 21, 52, 32, 64, 0, 131, 248, 255, 15,
+ 132, 210, 1, 0, 0, 83, 83, 86, 87, 255, 180,
+ 36, 48, 2, 0, 0, 139, 61, 52, 32, 64, 0,
+ 255, 215, 15, 183, 4, 197, 104, 50, 64, 0, 83,
+ 83, 86, 85, 255, 180, 36, 48, 2, 0, 0, 193,
+ 224, 10, 137, 68, 36, 36, 255, 215, 15, 183, 4,
+ 197, 0, 48, 64, 0, 139, 76, 36, 16, 11, 200,
+ 141, 68, 36, 28, 81, 104, 84, 66, 64, 0, 80,
+ 255, 21, 48, 32, 64, 0, 131, 196, 12, 141, 68,
+ 36, 28, 80, 104, 235, 3, 0, 0, 255, 180, 36,
+ 40, 2, 0, 0, 255, 21, 44, 32, 64, 0, 233,
+ 101, 1, 0, 0, 102, 61, 1, 0, 15, 133, 91,
+ 1, 0, 0, 51, 219, 190, 71, 1, 0, 0, 83,
+ 83, 189, 234, 3, 0, 0, 86, 85, 255, 180, 36,
+ 48, 2, 0, 0, 255, 21, 52, 32, 64, 0, 131,
+ 248, 255, 15, 132, 53, 1, 0, 0, 83, 83, 191,
+ 233, 3, 0, 0, 86, 87, 255, 180, 36, 48, 2,
+ 0, 0, 255, 21, 52, 32, 64, 0, 131, 248, 255,
+ 15, 132, 22, 1, 0, 0, 106, 16, 106, 2, 255,
+ 21, 4, 32, 64, 0, 59, 195, 137, 68, 36, 16,
+ 15, 132, 0, 1, 0, 0, 80, 255, 21, 0, 32,
+ 64, 0, 83, 83, 86, 87, 255, 180, 36, 48, 2,
+ 0, 0, 139, 61, 52, 32, 64, 0, 137, 68, 36,
+ 44, 255, 215, 15, 183, 4, 197, 104, 50, 64, 0,
+ 83, 83, 86, 85, 255, 180, 36, 48, 2, 0, 0,
+ 193, 224, 10, 137, 68, 36, 40, 255, 215, 15, 183,
+ 4, 197, 0, 48, 64, 0, 139, 76, 36, 20, 11,
+ 200, 81, 104, 80, 66, 64, 0, 255, 116, 36, 32,
+ 255, 21, 48, 32, 64, 0, 131, 196, 12, 255, 116,
+ 36, 16, 255, 21, 16, 32, 64, 0, 255, 180, 36,
+ 32, 2, 0, 0, 255, 21, 40, 32, 64, 0, 133,
+ 192, 15, 132, 134, 0, 0, 0, 255, 21, 36, 32,
+ 64, 0, 255, 116, 36, 16, 106, 1, 255, 21, 32,
+ 32, 64, 0, 255, 21, 28, 32, 64, 0, 235, 108,
+ 51, 219, 83, 83, 104, 128, 0, 0, 0, 255, 180,
+ 36, 44, 2, 0, 0, 255, 21, 24, 32, 64, 0,
+ 139, 53, 52, 32, 64, 0, 51, 255, 189, 234, 3,
+ 0, 0, 255, 183, 4, 48, 64, 0, 83, 104, 67,
+ 1, 0, 0, 85, 255, 180, 36, 48, 2, 0, 0,
+ 255, 214, 131, 199, 8, 129, 255, 104, 2, 0, 0,
+ 114, 223, 51, 237, 191, 233, 3, 0, 0, 255, 181,
+ 108, 50, 64, 0, 83, 104, 67, 1, 0, 0, 87,
+ 255, 180, 36, 48, 2, 0, 0, 255, 214, 131, 197,
+ 8, 129, 253, 224, 2, 0, 0, 114, 223, 95, 94,
+ 93, 51, 192, 91, 129, 196, 12, 2, 0, 0, 194,
+ 16, 0, 106, 0, 104, 0, 16, 64, 0, 106, 0,
+ 106, 101, 106, 0, 255, 21, 12, 32, 64, 0, 80,
+ 255, 21, 64, 32, 64, 0, 106, 0, 255, 21, 8,
+ 32, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 220, 32, 0, 0, 234, 32, 0, 0,
+ 248, 32, 0, 0, 6, 33, 0, 0, 204, 32, 0,
+ 0, 0, 0, 0, 0, 40, 33, 0, 0, 56, 33,
+ 0, 0, 74, 33, 0, 0, 94, 33, 0, 0, 112,
+ 33, 0, 0, 128, 33, 0, 0, 146, 33, 0, 0,
+ 158, 33, 0, 0, 180, 33, 0, 0, 198, 33, 0,
+ 0, 210, 33, 0, 0, 0, 0, 0, 0, 132, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26,
+ 33, 0, 0, 0, 32, 0, 0, 156, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 228, 33, 0,
+ 0, 24, 32, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 220, 32, 0, 0, 234, 32, 0, 0,
+ 248, 32, 0, 0, 6, 33, 0, 0, 204, 32, 0,
+ 0, 0, 0, 0, 0, 40, 33, 0, 0, 56, 33,
+ 0, 0, 74, 33, 0, 0, 94, 33, 0, 0, 112,
+ 33, 0, 0, 128, 33, 0, 0, 146, 33, 0, 0,
+ 158, 33, 0, 0, 180, 33, 0, 0, 198, 33, 0,
+ 0, 210, 33, 0, 0, 0, 0, 0, 0, 0, 2,
+ 71, 108, 111, 98, 97, 108, 85, 110, 108, 111, 99,
+ 107, 0, 0, 249, 1, 71, 108, 111, 98, 97, 108,
+ 76, 111, 99, 107, 0, 0, 238, 1, 71, 108, 111,
+ 98, 97, 108, 65, 108, 108, 111, 99, 0, 175, 0,
+ 69, 120, 105, 116, 80, 114, 111, 99, 101, 115, 115,
+ 0, 119, 1, 71, 101, 116, 77, 111, 100, 117, 108,
+ 101, 72, 97, 110, 100, 108, 101, 65, 0, 0, 75,
+ 69, 82, 78, 69, 76, 51, 50, 46, 100, 108, 108,
+ 0, 0, 58, 2, 83, 101, 110, 100, 77, 101, 115,
+ 115, 97, 103, 101, 65, 0, 0, 66, 0, 67, 108,
+ 111, 115, 101, 67, 108, 105, 112, 98, 111, 97, 114,
+ 100, 0, 0, 73, 2, 83, 101, 116, 67, 108, 105,
+ 112, 98, 111, 97, 114, 100, 68, 97, 116, 97, 0,
+ 0, 193, 0, 69, 109, 112, 116, 121, 67, 108, 105,
+ 112, 98, 111, 97, 114, 100, 0, 0, 245, 1, 79,
+ 112, 101, 110, 67, 108, 105, 112, 98, 111, 97, 114,
+ 100, 0, 82, 2, 83, 101, 116, 68, 108, 103, 73,
+ 116, 101, 109, 84, 101, 120, 116, 65, 0, 213, 2,
+ 119, 115, 112, 114, 105, 110, 116, 102, 65, 0, 53,
+ 2, 83, 101, 110, 100, 68, 108, 103, 73, 116, 101,
+ 109, 77, 101, 115, 115, 97, 103, 101, 65, 0, 3,
+ 2, 80, 111, 115, 116, 81, 117, 105, 116, 77, 101,
+ 115, 115, 97, 103, 101, 0, 198, 0, 69, 110, 100,
+ 68, 105, 97, 108, 111, 103, 0, 158, 0, 68, 105,
+ 97, 108, 111, 103, 66, 111, 120, 80, 97, 114, 97,
+ 109, 65, 0, 85, 83, 69, 82, 51, 50, 46, 100,
+ 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 64, 66, 64, 0, 127, 0, 0, 0, 48,
+ 66, 64, 0, 54, 0, 0, 0, 32, 66, 64, 0,
+ 28, 0, 0, 0, 16, 66, 64, 0, 1, 0, 0,
+ 0, 4, 66, 64, 0, 43, 0, 0, 0, 244, 65,
+ 64, 0, 77, 0, 0, 0, 228, 65, 64, 0, 44,
+ 0, 0, 0, 216, 65, 64, 0, 45, 0, 0, 0,
+ 204, 65, 64, 0, 35, 0, 0, 0, 188, 65, 64,
+ 0, 69, 0, 0, 0, 172, 65, 64, 0, 2, 0,
+ 0, 0, 156, 65, 64, 0, 3, 0, 0, 0, 140,
+ 65, 64, 0, 4, 0, 0, 0, 124, 65, 64, 0,
+ 26, 0, 0, 0, 108, 65, 64, 0, 5, 0, 0,
+ 0, 96, 65, 64, 0, 6, 0, 0, 0, 84, 65,
+ 64, 0, 101, 0, 0, 0, 72, 65, 64, 0, 19,
+ 0, 0, 0, 60, 65, 64, 0, 9, 0, 0, 0,
+ 44, 65, 64, 0, 37, 0, 0, 0, 28, 65, 64,
+ 0, 56, 0, 0, 0, 12, 65, 64, 0, 41, 0,
+ 0, 0, 0, 65, 64, 0, 11, 0, 0, 0, 240,
+ 64, 64, 0, 12, 0, 0, 0, 228, 64, 64, 0,
+ 86, 0, 0, 0, 212, 64, 64, 0, 55, 0, 0,
+ 0, 196, 64, 64, 0, 7, 0, 0, 0, 184, 64,
+ 64, 0, 8, 0, 0, 0, 172, 64, 64, 0, 71,
+ 0, 0, 0, 156, 64, 64, 0, 13, 0, 0, 0,
+ 144, 64, 64, 0, 57, 0, 0, 0, 132, 64, 64,
+ 0, 14, 0, 0, 0, 116, 64, 64, 0, 15, 0,
+ 0, 0, 100, 64, 64, 0, 33, 0, 0, 0, 84,
+ 64, 64, 0, 16, 0, 0, 0, 68, 64, 64, 0,
+ 17, 0, 0, 0, 52, 64, 64, 0, 75, 0, 0,
+ 0, 36, 64, 64, 0, 96, 0, 0, 0, 20, 64,
+ 64, 0, 63, 0, 0, 0, 8, 64, 64, 0, 87,
+ 0, 0, 0, 248, 63, 64, 0, 18, 0, 0, 0,
+ 236, 63, 64, 0, 64, 0, 0, 0, 224, 63, 64,
+ 0, 38, 0, 0, 0, 208, 63, 64, 0, 39, 0,
+ 0, 0, 192, 63, 64, 0, 47, 0, 0, 0, 176,
+ 63, 64, 0, 62, 0, 0, 0, 164, 63, 64, 0,
+ 76, 0, 0, 0, 148, 63, 64, 0, 88, 0, 0,
+ 0, 132, 63, 64, 0, 78, 0, 0, 0, 116, 63,
+ 64, 0, 80, 0, 0, 0, 100, 63, 64, 0, 97,
+ 0, 0, 0, 88, 63, 64, 0, 20, 0, 0, 0,
+ 72, 63, 64, 0, 72, 0, 0, 0, 60, 63, 64,
+ 0, 21, 0, 0, 0, 48, 63, 64, 0, 22, 0,
+ 0, 0, 32, 63, 64, 0, 70, 0, 0, 0, 16,
+ 63, 64, 0, 24, 0, 0, 0, 0, 63, 64, 0,
+ 25, 0, 0, 0, 240, 62, 64, 0, 79, 0, 0,
+ 0, 224, 62, 64, 0, 26, 0, 0, 0, 208, 62,
+ 64, 0, 89, 0, 0, 0, 196, 62, 64, 0, 27,
+ 0, 0, 0, 184, 62, 64, 0, 36, 0, 0, 0,
+ 168, 62, 64, 0, 10, 0, 0, 0, 152, 62, 64,
+ 0, 65, 0, 0, 0, 136, 62, 64, 0, 29, 0,
+ 0, 0, 120, 62, 64, 0, 90, 0, 0, 0, 108,
+ 62, 64, 0, 73, 0, 0, 0, 96, 62, 64, 0,
+ 68, 0, 0, 0, 84, 62, 64, 0, 74, 0, 0,
+ 0, 72, 62, 64, 0, 30, 0, 0, 0, 60, 62,
+ 64, 0, 31, 0, 0, 0, 44, 62, 64, 0, 34,
+ 0, 0, 0, 28, 62, 64, 0, 32, 0, 0, 0,
+ 16, 62, 64, 0, 67, 0, 0, 0, 4, 62, 64,
+ 0, 42, 0, 0, 0, 244, 61, 64, 0, 0, 0,
+ 0, 0, 228, 61, 64, 0, 1, 0, 0, 0, 212,
+ 61, 64, 0, 2, 0, 0, 0, 192, 61, 64, 0,
+ 1, 0, 0, 0, 164, 61, 64, 0, 2, 0, 0,
+ 0, 144, 61, 64, 0, 3, 0, 0, 0, 120, 61,
+ 64, 0, 4, 0, 0, 0, 96, 61, 64, 0, 5,
+ 0, 0, 0, 72, 61, 64, 0, 6, 0, 0, 0,
+ 48, 61, 64, 0, 7, 0, 0, 0, 24, 61, 64,
+ 0, 8, 0, 0, 0, 4, 61, 64, 0, 9, 0,
+ 0, 0, 236, 60, 64, 0, 10, 0, 0, 0, 212,
+ 60, 64, 0, 11, 0, 0, 0, 188, 60, 64, 0,
+ 12, 0, 0, 0, 164, 60, 64, 0, 13, 0, 0,
+ 0, 140, 60, 64, 0, 14, 0, 0, 0, 120, 60,
+ 64, 0, 15, 0, 0, 0, 96, 60, 64, 0, 16,
+ 0, 0, 0, 72, 60, 64, 0, 1, 0, 0, 0,
+ 52, 60, 64, 0, 2, 0, 0, 0, 28, 60, 64,
+ 0, 1, 0, 0, 0, 0, 60, 64, 0, 2, 0,
+ 0, 0, 228, 59, 64, 0, 3, 0, 0, 0, 200,
+ 59, 64, 0, 4, 0, 0, 0, 172, 59, 64, 0,
+ 5, 0, 0, 0, 148, 59, 64, 0, 1, 0, 0,
+ 0, 132, 59, 64, 0, 2, 0, 0, 0, 108, 59,
+ 64, 0, 1, 0, 0, 0, 88, 59, 64, 0, 2,
+ 0, 0, 0, 68, 59, 64, 0, 3, 0, 0, 0,
+ 48, 59, 64, 0, 4, 0, 0, 0, 28, 59, 64,
+ 0, 5, 0, 0, 0, 8, 59, 64, 0, 6, 0,
+ 0, 0, 240, 58, 64, 0, 7, 0, 0, 0, 208,
+ 58, 64, 0, 8, 0, 0, 0, 184, 58, 64, 0,
+ 9, 0, 0, 0, 156, 58, 64, 0, 10, 0, 0,
+ 0, 132, 58, 64, 0, 11, 0, 0, 0, 104, 58,
+ 64, 0, 12, 0, 0, 0, 76, 58, 64, 0, 13,
+ 0, 0, 0, 48, 58, 64, 0, 1, 0, 0, 0,
+ 32, 58, 64, 0, 2, 0, 0, 0, 8, 58, 64,
+ 0, 3, 0, 0, 0, 240, 57, 64, 0, 4, 0,
+ 0, 0, 216, 57, 64, 0, 5, 0, 0, 0, 188,
+ 57, 64, 0, 6, 0, 0, 0, 164, 57, 64, 0,
+ 1, 0, 0, 0, 148, 57, 64, 0, 2, 0, 0,
+ 0, 124, 57, 64, 0, 3, 0, 0, 0, 100, 57,
+ 64, 0, 4, 0, 0, 0, 72, 57, 64, 0, 5,
+ 0, 0, 0, 40, 57, 64, 0, 1, 0, 0, 0,
+ 24, 57, 64, 0, 2, 0, 0, 0, 0, 57, 64,
+ 0, 2, 0, 0, 0, 232, 56, 64, 0, 1, 0,
+ 0, 0, 216, 56, 64, 0, 1, 0, 0, 0, 196,
+ 56, 64, 0, 1, 0, 0, 0, 172, 56, 64, 0,
+ 2, 0, 0, 0, 140, 56, 64, 0, 2, 0, 0,
+ 0, 116, 56, 64, 0, 1, 0, 0, 0, 88, 56,
+ 64, 0, 2, 0, 0, 0, 60, 56, 64, 0, 2,
+ 0, 0, 0, 40, 56, 64, 0, 1, 0, 0, 0,
+ 8, 56, 64, 0, 2, 0, 0, 0, 240, 55, 64,
+ 0, 3, 0, 0, 0, 212, 55, 64, 0, 1, 0,
+ 0, 0, 196, 55, 64, 0, 2, 0, 0, 0, 172,
+ 55, 64, 0, 3, 0, 0, 0, 148, 55, 64, 0,
+ 4, 0, 0, 0, 120, 55, 64, 0, 5, 0, 0,
+ 0, 92, 55, 64, 0, 6, 0, 0, 0, 68, 55,
+ 64, 0, 7, 0, 0, 0, 32, 55, 64, 0, 8,
+ 0, 0, 0, 4, 55, 64, 0, 9, 0, 0, 0,
+ 232, 54, 64, 0, 10, 0, 0, 0, 208, 54, 64,
+ 0, 11, 0, 0, 0, 180, 54, 64, 0, 12, 0,
+ 0, 0, 156, 54, 64, 0, 13, 0, 0, 0, 132,
+ 54, 64, 0, 14, 0, 0, 0, 108, 54, 64, 0,
+ 15, 0, 0, 0, 80, 54, 64, 0, 16, 0, 0,
+ 0, 56, 54, 64, 0, 17, 0, 0, 0, 28, 54,
+ 64, 0, 18, 0, 0, 0, 0, 54, 64, 0, 19,
+ 0, 0, 0, 228, 53, 64, 0, 20, 0, 0, 0,
+ 200, 53, 64, 0, 1, 0, 0, 0, 184, 53, 64,
+ 0, 2, 0, 0, 0, 160, 53, 64, 0, 1, 0,
+ 0, 0, 136, 53, 64, 0, 2, 0, 0, 0, 116,
+ 53, 64, 0, 1, 0, 0, 0, 96, 53, 64, 0,
+ 2, 0, 0, 0, 72, 53, 64, 0, 83, 85, 66,
+ 76, 65, 78, 71, 95, 85, 90, 66, 69, 75, 95,
+ 67, 89, 82, 73, 76, 76, 73, 67, 0, 0, 83,
+ 85, 66, 76, 65, 78, 71, 95, 85, 90, 66, 69,
+ 75, 95, 76, 65, 84, 73, 78, 0, 83, 85, 66,
+ 76, 65, 78, 71, 95, 85, 82, 68, 85, 95, 73,
+ 78, 68, 73, 65, 0, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 85, 82, 68, 85, 95, 80, 65, 75,
+ 73, 83, 84, 65, 78, 0, 0, 0, 83, 85, 66,
+ 76, 65, 78, 71, 95, 83, 87, 69, 68, 73, 83,
+ 72, 95, 70, 73, 78, 76, 65, 78, 68, 0, 83,
+ 85, 66, 76, 65, 78, 71, 95, 83, 87, 69, 68,
+ 73, 83, 72, 0, 83, 85, 66, 76, 65, 78, 71,
+ 95, 83, 80, 65, 78, 73, 83, 72, 95, 80, 85,
+ 69, 82, 84, 79, 95, 82, 73, 67, 79, 0, 83,
+ 85, 66, 76, 65, 78, 71, 95, 83, 80, 65, 78,
+ 73, 83, 72, 95, 78, 73, 67, 65, 82, 65, 71,
+ 85, 65, 0, 0, 0, 83, 85, 66, 76, 65, 78,
+ 71, 95, 83, 80, 65, 78, 73, 83, 72, 95, 72,
+ 79, 78, 68, 85, 82, 65, 83, 0, 0, 0, 0,
+ 83, 85, 66, 76, 65, 78, 71, 95, 83, 80, 65,
+ 78, 73, 83, 72, 95, 69, 76, 95, 83, 65, 76,
+ 86, 65, 68, 79, 82, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 83, 80, 65, 78, 73, 83, 72, 95,
+ 66, 79, 76, 73, 86, 73, 65, 0, 83, 85, 66,
+ 76, 65, 78, 71, 95, 83, 80, 65, 78, 73, 83,
+ 72, 95, 80, 65, 82, 65, 71, 85, 65, 89, 0,
+ 0, 0, 0, 83, 85, 66, 76, 65, 78, 71, 95,
+ 83, 80, 65, 78, 73, 83, 72, 95, 85, 82, 85,
+ 71, 85, 65, 89, 0, 83, 85, 66, 76, 65, 78,
+ 71, 95, 83, 80, 65, 78, 73, 83, 72, 95, 67,
+ 72, 73, 76, 69, 0, 0, 0, 83, 85, 66, 76,
+ 65, 78, 71, 95, 83, 80, 65, 78, 73, 83, 72,
+ 95, 69, 67, 85, 65, 68, 79, 82, 0, 83, 85,
+ 66, 76, 65, 78, 71, 95, 83, 80, 65, 78, 73,
+ 83, 72, 95, 65, 82, 71, 69, 78, 84, 73, 78,
+ 65, 0, 0, 0, 83, 85, 66, 76, 65, 78, 71,
+ 95, 83, 80, 65, 78, 73, 83, 72, 95, 80, 69,
+ 82, 85, 0, 0, 0, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 83, 80, 65, 78, 73, 83, 72, 95,
+ 67, 79, 76, 79, 77, 66, 73, 65, 0, 0, 0,
+ 0, 83, 85, 66, 76, 65, 78, 71, 95, 83, 80,
+ 65, 78, 73, 83, 72, 95, 86, 69, 78, 69, 90,
+ 85, 69, 76, 65, 0, 0, 0, 83, 85, 66, 76,
+ 65, 78, 71, 95, 83, 80, 65, 78, 73, 83, 72,
+ 95, 68, 79, 77, 73, 78, 73, 67, 65, 78, 95,
+ 82, 69, 80, 85, 66, 76, 73, 67, 0, 0, 83,
+ 85, 66, 76, 65, 78, 71, 95, 83, 80, 65, 78,
+ 73, 83, 72, 95, 80, 65, 78, 65, 77, 65, 0,
+ 0, 83, 85, 66, 76, 65, 78, 71, 95, 83, 80,
+ 65, 78, 73, 83, 72, 95, 67, 79, 83, 84, 65,
+ 95, 82, 73, 67, 65, 0, 0, 83, 85, 66, 76,
+ 65, 78, 71, 95, 83, 80, 65, 78, 73, 83, 72,
+ 95, 71, 85, 65, 84, 69, 77, 65, 76, 65, 0,
+ 0, 0, 83, 85, 66, 76, 65, 78, 71, 95, 83,
+ 80, 65, 78, 73, 83, 72, 95, 77, 79, 68, 69,
+ 82, 78, 0, 0, 83, 85, 66, 76, 65, 78, 71,
+ 95, 83, 80, 65, 78, 73, 83, 72, 95, 77, 69,
+ 88, 73, 67, 65, 78, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 83, 80, 65, 78, 73, 83, 72, 0,
+ 83, 85, 66, 76, 65, 78, 71, 95, 83, 69, 82,
+ 66, 73, 65, 78, 95, 67, 89, 82, 73, 76, 76,
+ 73, 67, 0, 0, 0, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 83, 69, 82, 66, 73, 65, 78, 95,
+ 76, 65, 84, 73, 78, 0, 0, 0, 83, 85, 66,
+ 76, 65, 78, 71, 95, 80, 79, 82, 84, 85, 71,
+ 85, 69, 83, 69, 95, 66, 82, 65, 90, 73, 76,
+ 73, 65, 78, 0, 0, 0, 0, 83, 85, 66, 76,
+ 65, 78, 71, 95, 80, 79, 82, 84, 85, 71, 85,
+ 69, 83, 69, 0, 0, 83, 85, 66, 76, 65, 78,
+ 71, 95, 78, 79, 82, 87, 69, 71, 73, 65, 78,
+ 95, 78, 89, 78, 79, 82, 83, 75, 0, 0, 0,
+ 83, 85, 66, 76, 65, 78, 71, 95, 78, 79, 82,
+ 87, 69, 71, 73, 65, 78, 95, 66, 79, 75, 77,
+ 65, 76, 0, 0, 0, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 78, 69, 80, 65, 76, 73, 95, 73,
+ 78, 68, 73, 65, 0, 0, 0, 0, 83, 85, 66,
+ 76, 65, 78, 71, 95, 77, 65, 76, 65, 89, 95,
+ 66, 82, 85, 78, 69, 73, 95, 68, 65, 82, 85,
+ 83, 83, 65, 76, 65, 77, 0, 83, 85, 66, 76,
+ 65, 78, 71, 95, 77, 65, 76, 65, 89, 95, 77,
+ 65, 76, 65, 89, 83, 73, 65, 0, 0, 83, 85,
+ 66, 76, 65, 78, 71, 95, 76, 73, 84, 72, 85,
+ 65, 78, 73, 65, 78, 0, 0, 83, 85, 66, 76,
+ 65, 78, 71, 95, 75, 79, 82, 69, 65, 78, 0,
+ 0, 83, 85, 66, 76, 65, 78, 71, 95, 75, 65,
+ 83, 72, 77, 73, 82, 73, 95, 73, 78, 68, 73,
+ 65, 0, 0, 83, 85, 66, 76, 65, 78, 71, 95,
+ 73, 84, 65, 76, 73, 65, 78, 95, 83, 87, 73,
+ 83, 83, 0, 0, 0, 83, 85, 66, 76, 65, 78,
+ 71, 95, 73, 84, 65, 76, 73, 65, 78, 0, 83,
+ 85, 66, 76, 65, 78, 71, 95, 71, 69, 82, 77,
+ 65, 78, 95, 76, 73, 69, 67, 72, 84, 69, 78,
+ 83, 84, 69, 73, 78, 0, 0, 0, 0, 83, 85,
+ 66, 76, 65, 78, 71, 95, 71, 69, 82, 77, 65,
+ 78, 95, 76, 85, 88, 69, 77, 66, 79, 85, 82,
+ 71, 0, 0, 0, 83, 85, 66, 76, 65, 78, 71,
+ 95, 71, 69, 82, 77, 65, 78, 95, 65, 85, 83,
+ 84, 82, 73, 65, 78, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 71, 69, 82, 77, 65, 78, 95, 83,
+ 87, 73, 83, 83, 0, 0, 0, 0, 83, 85, 66,
+ 76, 65, 78, 71, 95, 71, 69, 82, 77, 65, 78,
+ 0, 0, 83, 85, 66, 76, 65, 78, 71, 95, 70,
+ 82, 69, 78, 67, 72, 95, 77, 79, 78, 65, 67,
+ 79, 0, 0, 0, 83, 85, 66, 76, 65, 78, 71,
+ 95, 70, 82, 69, 78, 67, 72, 95, 76, 85, 88,
+ 69, 77, 66, 79, 85, 82, 71, 0, 0, 0, 83,
+ 85, 66, 76, 65, 78, 71, 95, 70, 82, 69, 78,
+ 67, 72, 95, 83, 87, 73, 83, 83, 0, 0, 0,
+ 0, 83, 85, 66, 76, 65, 78, 71, 95, 70, 82,
+ 69, 78, 67, 72, 95, 67, 65, 78, 65, 68, 73,
+ 65, 78, 0, 83, 85, 66, 76, 65, 78, 71, 95,
+ 70, 82, 69, 78, 67, 72, 95, 66, 69, 76, 71,
+ 73, 65, 78, 0, 0, 83, 85, 66, 76, 65, 78,
+ 71, 95, 70, 82, 69, 78, 67, 72, 0, 0, 83,
+ 85, 66, 76, 65, 78, 71, 95, 69, 78, 71, 76,
+ 73, 83, 72, 95, 80, 72, 73, 76, 73, 80, 80,
+ 73, 78, 69, 83, 0, 83, 85, 66, 76, 65, 78,
+ 71, 95, 69, 78, 71, 76, 73, 83, 72, 95, 90,
+ 73, 77, 66, 65, 66, 87, 69, 0, 0, 0, 0,
+ 83, 85, 66, 76, 65, 78, 71, 95, 69, 78, 71,
+ 76, 73, 83, 72, 95, 84, 82, 73, 78, 73, 68,
+ 65, 68, 0, 0, 0, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 69, 78, 71, 76, 73, 83, 72, 95,
+ 66, 69, 76, 73, 90, 69, 0, 0, 83, 85, 66,
+ 76, 65, 78, 71, 95, 69, 78, 71, 76, 73, 83,
+ 72, 95, 67, 65, 82, 73, 66, 66, 69, 65, 78,
+ 0, 0, 0, 83, 85, 66, 76, 65, 78, 71, 95,
+ 69, 78, 71, 76, 73, 83, 72, 95, 74, 65, 77,
+ 65, 73, 67, 65, 0, 83, 85, 66, 76, 65, 78,
+ 71, 95, 69, 78, 71, 76, 73, 83, 72, 95, 83,
+ 79, 85, 84, 72, 95, 65, 70, 82, 73, 67, 65,
+ 0, 0, 0, 0, 83, 85, 66, 76, 65, 78, 71,
+ 95, 69, 78, 71, 76, 73, 83, 72, 95, 69, 73,
+ 82, 69, 0, 0, 0, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 69, 78, 71, 76, 73, 83, 72, 95,
+ 78, 90, 0, 0, 83, 85, 66, 76, 65, 78, 71,
+ 95, 69, 78, 71, 76, 73, 83, 72, 95, 67, 65,
+ 78, 0, 83, 85, 66, 76, 65, 78, 71, 95, 69,
+ 78, 71, 76, 73, 83, 72, 95, 65, 85, 83, 0,
+ 83, 85, 66, 76, 65, 78, 71, 95, 69, 78, 71,
+ 76, 73, 83, 72, 95, 85, 75, 0, 0, 83, 85,
+ 66, 76, 65, 78, 71, 95, 69, 78, 71, 76, 73,
+ 83, 72, 95, 85, 83, 0, 0, 83, 85, 66, 76,
+ 65, 78, 71, 95, 68, 85, 84, 67, 72, 95, 66,
+ 69, 76, 71, 73, 65, 78, 0, 0, 0, 83, 85,
+ 66, 76, 65, 78, 71, 95, 68, 85, 84, 67, 72,
+ 0, 0, 0, 83, 85, 66, 76, 65, 78, 71, 95,
+ 67, 72, 73, 78, 69, 83, 69, 95, 77, 65, 67,
+ 65, 85, 0, 0, 0, 83, 85, 66, 76, 65, 78,
+ 71, 95, 67, 72, 73, 78, 69, 83, 69, 95, 83,
+ 73, 78, 71, 65, 80, 79, 82, 69, 0, 0, 0,
+ 83, 85, 66, 76, 65, 78, 71, 95, 67, 72, 73,
+ 78, 69, 83, 69, 95, 72, 79, 78, 71, 75, 79,
+ 78, 71, 0, 0, 0, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 67, 72, 73, 78, 69, 83, 69, 95,
+ 83, 73, 77, 80, 76, 73, 70, 73, 69, 68, 0,
+ 0, 83, 85, 66, 76, 65, 78, 71, 95, 67, 72,
+ 73, 78, 69, 83, 69, 95, 84, 82, 65, 68, 73,
+ 84, 73, 79, 78, 65, 76, 0, 83, 85, 66, 76,
+ 65, 78, 71, 95, 65, 90, 69, 82, 73, 95, 67,
+ 89, 82, 73, 76, 76, 73, 67, 0, 0, 83, 85,
+ 66, 76, 65, 78, 71, 95, 65, 90, 69, 82, 73,
+ 95, 76, 65, 84, 73, 78, 0, 83, 85, 66, 76,
+ 65, 78, 71, 95, 65, 82, 65, 66, 73, 67, 95,
+ 81, 65, 84, 65, 82, 0, 0, 0, 0, 83, 85,
+ 66, 76, 65, 78, 71, 95, 65, 82, 65, 66, 73,
+ 67, 95, 66, 65, 72, 82, 65, 73, 78, 0, 0,
+ 83, 85, 66, 76, 65, 78, 71, 95, 65, 82, 65,
+ 66, 73, 67, 95, 85, 65, 69, 0, 0, 83, 85,
+ 66, 76, 65, 78, 71, 95, 65, 82, 65, 66, 73,
+ 67, 95, 75, 85, 87, 65, 73, 84, 0, 0, 0,
+ 83, 85, 66, 76, 65, 78, 71, 95, 65, 82, 65,
+ 66, 73, 67, 95, 76, 69, 66, 65, 78, 79, 78,
+ 0, 0, 83, 85, 66, 76, 65, 78, 71, 95, 65,
+ 82, 65, 66, 73, 67, 95, 74, 79, 82, 68, 65,
+ 78, 0, 0, 0, 83, 85, 66, 76, 65, 78, 71,
+ 95, 65, 82, 65, 66, 73, 67, 95, 83, 89, 82,
+ 73, 65, 0, 0, 0, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 65, 82, 65, 66, 73, 67, 95, 89,
+ 69, 77, 69, 78, 0, 0, 0, 0, 83, 85, 66,
+ 76, 65, 78, 71, 95, 65, 82, 65, 66, 73, 67,
+ 95, 79, 77, 65, 78, 0, 83, 85, 66, 76, 65,
+ 78, 71, 95, 65, 82, 65, 66, 73, 67, 95, 84,
+ 85, 78, 73, 83, 73, 65, 0, 0, 83, 85, 66,
+ 76, 65, 78, 71, 95, 65, 82, 65, 66, 73, 67,
+ 95, 77, 79, 82, 79, 67, 67, 79, 0, 0, 83,
+ 85, 66, 76, 65, 78, 71, 95, 65, 82, 65, 66,
+ 73, 67, 95, 65, 76, 71, 69, 82, 73, 65, 0,
+ 0, 83, 85, 66, 76, 65, 78, 71, 95, 65, 82,
+ 65, 66, 73, 67, 95, 76, 73, 66, 89, 65, 0,
+ 0, 0, 0, 83, 85, 66, 76, 65, 78, 71, 95,
+ 65, 82, 65, 66, 73, 67, 95, 69, 71, 89, 80,
+ 84, 0, 0, 0, 0, 83, 85, 66, 76, 65, 78,
+ 71, 95, 65, 82, 65, 66, 73, 67, 95, 73, 82,
+ 65, 81, 0, 83, 85, 66, 76, 65, 78, 71, 95,
+ 65, 82, 65, 66, 73, 67, 95, 83, 65, 85, 68,
+ 73, 95, 65, 82, 65, 66, 73, 65, 0, 83, 85,
+ 66, 76, 65, 78, 71, 95, 83, 89, 83, 95, 68,
+ 69, 70, 65, 85, 76, 84, 0, 83, 85, 66, 76,
+ 65, 78, 71, 95, 68, 69, 70, 65, 85, 76, 84,
+ 0, 83, 85, 66, 76, 65, 78, 71, 95, 78, 69,
+ 85, 84, 82, 65, 76, 0, 76, 65, 78, 71, 95,
+ 86, 73, 69, 84, 78, 65, 77, 69, 83, 69, 0,
+ 76, 65, 78, 71, 95, 85, 90, 66, 69, 75, 0,
+ 0, 76, 65, 78, 71, 95, 85, 82, 68, 85, 0,
+ 0, 0, 76, 65, 78, 71, 95, 85, 75, 82, 65,
+ 73, 78, 73, 65, 78, 0, 0, 76, 65, 78, 71,
+ 95, 84, 85, 82, 75, 73, 83, 72, 0, 0, 0,
+ 0, 76, 65, 78, 71, 95, 84, 72, 65, 73, 0,
+ 0, 0, 76, 65, 78, 71, 95, 84, 69, 76, 85,
+ 71, 85, 0, 76, 65, 78, 71, 95, 84, 65, 84,
+ 65, 82, 0, 0, 76, 65, 78, 71, 95, 84, 65,
+ 77, 73, 76, 0, 0, 76, 65, 78, 71, 95, 83,
+ 89, 82, 73, 65, 67, 0, 76, 65, 78, 71, 95,
+ 83, 87, 69, 68, 73, 83, 72, 0, 0, 0, 0,
+ 76, 65, 78, 71, 95, 83, 87, 65, 72, 73, 76,
+ 73, 0, 0, 0, 0, 76, 65, 78, 71, 95, 83,
+ 80, 65, 78, 73, 83, 72, 0, 0, 0, 0, 76,
+ 65, 78, 71, 95, 83, 76, 79, 86, 69, 78, 73,
+ 65, 78, 0, 0, 76, 65, 78, 71, 95, 83, 76,
+ 79, 86, 65, 75, 0, 76, 65, 78, 71, 95, 83,
+ 73, 78, 68, 72, 73, 0, 76, 65, 78, 71, 95,
+ 83, 69, 82, 66, 73, 65, 78, 0, 0, 0, 0,
+ 76, 65, 78, 71, 95, 83, 65, 78, 83, 75, 82,
+ 73, 84, 0, 0, 0, 76, 65, 78, 71, 95, 82,
+ 85, 83, 83, 73, 65, 78, 0, 0, 0, 0, 76,
+ 65, 78, 71, 95, 82, 79, 77, 65, 78, 73, 65,
+ 78, 0, 0, 0, 76, 65, 78, 71, 95, 80, 85,
+ 78, 74, 65, 66, 73, 0, 0, 0, 0, 76, 65,
+ 78, 71, 95, 80, 79, 82, 84, 85, 71, 85, 69,
+ 83, 69, 0, 76, 65, 78, 71, 95, 80, 79, 76,
+ 73, 83, 72, 0, 76, 65, 78, 71, 95, 79, 82,
+ 73, 89, 65, 0, 0, 76, 65, 78, 71, 95, 78,
+ 79, 82, 87, 69, 71, 73, 65, 78, 0, 0, 76,
+ 65, 78, 71, 95, 78, 69, 80, 65, 76, 73, 0,
+ 76, 65, 78, 71, 95, 77, 79, 78, 71, 79, 76,
+ 73, 65, 78, 0, 0, 76, 65, 78, 71, 95, 77,
+ 65, 82, 65, 84, 72, 73, 0, 0, 0, 0, 76,
+ 65, 78, 71, 95, 77, 65, 78, 73, 80, 85, 82,
+ 73, 0, 0, 0, 76, 65, 78, 71, 95, 77, 65,
+ 76, 65, 89, 65, 76, 65, 77, 0, 0, 76, 65,
+ 78, 71, 95, 77, 65, 76, 65, 89, 0, 0, 76,
+ 65, 78, 71, 95, 77, 65, 67, 69, 68, 79, 78,
+ 73, 65, 78, 0, 76, 65, 78, 71, 95, 76, 73,
+ 84, 72, 85, 65, 78, 73, 65, 78, 0, 76, 65,
+ 78, 71, 95, 76, 65, 84, 86, 73, 65, 78, 0,
+ 0, 0, 0, 76, 65, 78, 71, 95, 75, 89, 82,
+ 71, 89, 90, 0, 76, 65, 78, 71, 95, 75, 79,
+ 82, 69, 65, 78, 0, 76, 65, 78, 71, 95, 75,
+ 79, 78, 75, 65, 78, 73, 0, 0, 0, 0, 76,
+ 65, 78, 71, 95, 75, 65, 90, 65, 75, 0, 0,
+ 76, 65, 78, 71, 95, 75, 65, 83, 72, 77, 73,
+ 82, 73, 0, 0, 0, 76, 65, 78, 71, 95, 75,
+ 65, 78, 78, 65, 68, 65, 0, 0, 0, 0, 76,
+ 65, 78, 71, 95, 74, 65, 80, 65, 78, 69, 83,
+ 69, 0, 0, 0, 76, 65, 78, 71, 95, 73, 84,
+ 65, 76, 73, 65, 78, 0, 0, 0, 0, 76, 65,
+ 78, 71, 95, 73, 78, 68, 79, 78, 69, 83, 73,
+ 65, 78, 0, 76, 65, 78, 71, 95, 73, 67, 69,
+ 76, 65, 78, 68, 73, 67, 0, 0, 76, 65, 78,
+ 71, 95, 72, 85, 78, 71, 65, 82, 73, 65, 78,
+ 0, 0, 76, 65, 78, 71, 95, 72, 73, 78, 68,
+ 73, 0, 0, 76, 65, 78, 71, 95, 72, 69, 66,
+ 82, 69, 87, 0, 76, 65, 78, 71, 95, 71, 85,
+ 74, 65, 82, 65, 84, 73, 0, 0, 0, 76, 65,
+ 78, 71, 95, 71, 82, 69, 69, 75, 0, 0, 76,
+ 65, 78, 71, 95, 71, 69, 82, 77, 65, 78, 0,
+ 76, 65, 78, 71, 95, 71, 69, 79, 82, 71, 73,
+ 65, 78, 0, 0, 0, 76, 65, 78, 71, 95, 71,
+ 65, 76, 73, 67, 73, 65, 78, 0, 0, 0, 76,
+ 65, 78, 71, 95, 70, 82, 69, 78, 67, 72, 0,
+ 76, 65, 78, 71, 95, 70, 73, 78, 78, 73, 83,
+ 72, 0, 0, 0, 0, 76, 65, 78, 71, 95, 70,
+ 65, 82, 83, 73, 0, 0, 76, 65, 78, 71, 95,
+ 70, 65, 69, 82, 79, 69, 83, 69, 0, 0, 0,
+ 76, 65, 78, 71, 95, 69, 83, 84, 79, 78, 73,
+ 65, 78, 0, 0, 0, 76, 65, 78, 71, 95, 69,
+ 78, 71, 76, 73, 83, 72, 0, 0, 0, 0, 76,
+ 65, 78, 71, 95, 68, 85, 84, 67, 72, 0, 0,
+ 76, 65, 78, 71, 95, 68, 73, 86, 69, 72, 73,
+ 0, 76, 65, 78, 71, 95, 68, 65, 78, 73, 83,
+ 72, 0, 76, 65, 78, 71, 95, 67, 90, 69, 67,
+ 72, 0, 0, 76, 65, 78, 71, 95, 67, 82, 79,
+ 65, 84, 73, 65, 78, 0, 0, 0, 76, 65, 78,
+ 71, 95, 67, 72, 73, 78, 69, 83, 69, 0, 0,
+ 0, 0, 76, 65, 78, 71, 95, 67, 65, 84, 65,
+ 76, 65, 78, 0, 0, 0, 0, 76, 65, 78, 71,
+ 95, 66, 85, 76, 71, 65, 82, 73, 65, 78, 0,
+ 0, 76, 65, 78, 71, 95, 66, 69, 78, 71, 65,
+ 76, 73, 0, 0, 0, 0, 76, 65, 78, 71, 95,
+ 66, 69, 76, 65, 82, 85, 83, 73, 65, 78, 0,
+ 76, 65, 78, 71, 95, 66, 65, 83, 81, 85, 69,
+ 0, 76, 65, 78, 71, 95, 65, 90, 69, 82, 73,
+ 0, 0, 76, 65, 78, 71, 95, 65, 83, 83, 65,
+ 77, 69, 83, 69, 0, 0, 0, 76, 65, 78, 71,
+ 95, 65, 82, 77, 69, 78, 73, 65, 78, 0, 0,
+ 0, 76, 65, 78, 71, 95, 65, 82, 65, 66, 73,
+ 67, 0, 76, 65, 78, 71, 95, 65, 76, 66, 65,
+ 78, 73, 65, 78, 0, 0, 0, 76, 65, 78, 71,
+ 95, 65, 70, 82, 73, 75, 65, 65, 78, 83, 0,
+ 0, 76, 65, 78, 71, 95, 73, 78, 86, 65, 82,
+ 73, 65, 78, 84, 0, 0, 76, 65, 78, 71, 95,
+ 78, 69, 85, 84, 82, 65, 76, 0, 0, 0, 0,
+ 37, 117, 0, 0, 76, 97, 110, 103, 117, 97, 103,
+ 101, 32, 73, 68, 58, 32, 37, 100, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2, 0, 5, 0, 0,
+ 0, 32, 0, 0, 128, 24, 0, 0, 0, 56, 0,
+ 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 101, 0, 0, 0,
+ 80, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
+ 0, 0, 104, 0, 0, 128, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 9, 4, 0, 0, 128, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 9, 4, 0, 0, 144, 0, 0, 0, 160,
+ 80, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 136, 81, 0, 0, 25, 2, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 8,
+ 200, 128, 0, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 135, 0, 75, 0, 0, 0, 0, 0, 77, 0,
+ 97, 0, 107, 0, 101, 0, 76, 0, 97, 0, 110,
+ 0, 103, 0, 73, 0, 68, 0, 0, 0, 8, 0,
+ 77, 0, 83, 0, 32, 0, 83, 0, 97, 0, 110,
+ 0, 115, 0, 32, 0, 83, 0, 101, 0, 114, 0,
+ 105, 0, 102, 0, 0, 0, 0, 0, 3, 0, 33,
+ 80, 0, 0, 0, 0, 7, 0, 7, 0, 121, 0,
+ 100, 0, 234, 3, 255, 255, 133, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 33, 80, 0, 0, 0, 0,
+ 7, 0, 24, 0, 121, 0, 100, 0, 233, 3, 255,
+ 255, 133, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 1, 80, 0, 0, 0, 0, 78, 0, 54, 0, 50,
+ 0, 14, 0, 1, 0, 255, 255, 128, 0, 67, 0,
+ 111, 0, 112, 0, 121, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 80, 0, 0, 0, 0, 7, 0,
+ 54, 0, 50, 0, 14, 0, 2, 0, 255, 255, 128,
+ 0, 69, 0, 120, 0, 105, 0, 116, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2, 80, 0, 0, 0,
+ 0, 7, 0, 41, 0, 121, 0, 8, 0, 235, 3,
+ 255, 255, 130, 0, 0, 0, 0, 0, 0, 0, 60,
+ 63, 120, 109, 108, 32, 118, 101, 114, 115, 105, 111,
+ 110, 61, 34, 49, 46, 48, 34, 32, 101, 110, 99,
+ 111, 100, 105, 110, 103, 61, 34, 85, 84, 70, 45,
+ 56, 34, 32, 115, 116, 97, 110, 100, 97, 108, 111,
+ 110, 101, 61, 34, 121, 101, 115, 34, 63, 62, 13,
+ 10, 60, 97, 115, 115, 101, 109, 98, 108, 121, 32,
+ 120, 109, 108, 110, 115, 61, 34, 117, 114, 110, 58,
+ 115, 99, 104, 101, 109, 97, 115, 45, 109, 105, 99,
+ 114, 111, 115, 111, 102, 116, 45, 99, 111, 109, 58,
+ 97, 115, 109, 46, 118, 49, 34, 32, 109, 97, 110,
+ 105, 102, 101, 115, 116, 86, 101, 114, 115, 105, 111,
+ 110, 61, 34, 49, 46, 48, 34, 62, 13, 10, 60,
+ 97, 115, 115, 101, 109, 98, 108, 121, 73, 100, 101,
+ 110, 116, 105, 116, 121, 32, 118, 101, 114, 115, 105,
+ 111, 110, 61, 34, 49, 46, 48, 46, 48, 46, 48,
+ 34, 32, 112, 114, 111, 99, 101, 115, 115, 111, 114,
+ 65, 114, 99, 104, 105, 116, 101, 99, 116, 117, 114,
+ 101, 61, 34, 88, 56, 54, 34, 32, 110, 97, 109,
+ 101, 61, 34, 78, 117, 108, 108, 115, 111, 102, 116,
+ 46, 78, 83, 73, 83, 46, 77, 97, 107, 101, 76,
+ 97, 110, 103, 73, 100, 34, 32, 116, 121, 112, 101,
+ 61, 34, 119, 105, 110, 51, 50, 34, 47, 62, 13,
+ 10, 60, 100, 101, 115, 99, 114, 105, 112, 116, 105,
+ 111, 110, 62, 77, 97, 107, 101, 76, 97, 110, 103,
+ 73, 100, 60, 47, 100, 101, 115, 99, 114, 105, 112,
+ 116, 105, 111, 110, 62, 13, 10, 60, 100, 101, 112,
+ 101, 110, 100, 101, 110, 99, 121, 62, 13, 10, 60,
+ 100, 101, 112, 101, 110, 100, 101, 110, 116, 65, 115,
+ 115, 101, 109, 98, 108, 121, 62, 13, 10, 60, 97,
+ 115, 115, 101, 109, 98, 108, 121, 73, 100, 101, 110,
+ 116, 105, 116, 121, 32, 116, 121, 112, 101, 61, 34,
+ 119, 105, 110, 51, 50, 34, 32, 110, 97, 109, 101,
+ 61, 34, 77, 105, 99, 114, 111, 115, 111, 102, 116,
+ 46, 87, 105, 110, 100, 111, 119, 115, 46, 67, 111,
+ 109, 109, 111, 110, 45, 67, 111, 110, 116, 114, 111,
+ 108, 115, 34, 32, 118, 101, 114, 115, 105, 111, 110,
+ 61, 34, 54, 46, 48, 46, 48, 46, 48, 34, 32,
+ 112, 114, 111, 99, 101, 115, 115, 111, 114, 65, 114,
+ 99, 104, 105, 116, 101, 99, 116, 117, 114, 101, 61,
+ 34, 88, 56, 54, 34, 32, 112, 117, 98, 108, 105,
+ 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 34,
+ 54, 53, 57, 53, 98, 54, 52, 49, 52, 52, 99,
+ 99, 102, 49, 100, 102, 34, 32, 108, 97, 110, 103,
+ 117, 97, 103, 101, 61, 34, 42, 34, 32, 47, 62,
+ 13, 10, 60, 47, 100, 101, 112, 101, 110, 100, 101,
+ 110, 116, 65, 115, 115, 101, 109, 98, 108, 121, 62,
+ 13, 10, 60, 47, 100, 101, 112, 101, 110, 100, 101,
+ 110, 99, 121, 62, 13, 10, 60, 47, 97, 115, 115,
+ 101, 109, 98, 108, 121, 62, 13, 10, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
diff --git a/Source/Tests/SConscript b/Source/Tests/SConscript
index 49cdc41..b6c510b 100755
--- a/Source/Tests/SConscript
+++ b/Source/Tests/SConscript
@@ -1,161 +1,161 @@
-target = 'test'
-
-tests = Split("""
- compression.cpp
- decompress.cpp
- DialogTemplate.cpp
- endian.cpp
- mmap.cpp
- ResourceEditor.cpp
- specmatch.cpp
- textrunner.cpp
- winchar.cpp
-""")
-
-required = Split("""
- DialogTemplate.cpp
- dirreader.cpp
- growbuf.cpp
- mmap.cpp
- ResourceEditor.cpp
- util.cpp
- winchar.cpp
-""")
-
-required_exehead = Split("""
- Tests/memcpy.c
-""")
-
-lzma_files = Split("""
- clzma.cpp
- 7zip/7zGuids.cpp
- 7zip/7zip/Common/OutBuffer.cpp
- 7zip/7zip/Common/StreamUtils.cpp
- 7zip/7zip/Compress/LZ/LZInWindow.cpp
- 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
- 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp
- 7zip/Common/Alloc.cpp
- 7zip/Common/CRC.cpp
- 7zip/LZMADecode.c
-""")
-
-required += lzma_files
-
-bzip2_files = Split("""
- bzip2/blocksort.c
- bzip2/bzlib.c
- bzip2/compress.c
- bzip2/huffman.c
-""")
-
-bzip2_exehead_files = Split("""
- bzip2/bzlib.c
- bzip2/decompress.c
-""")
-
-required += bzip2_files
-required_exehead += bzip2_exehead_files
-
-zlib_files = Split("""
- zlib/deflate.c
- zlib/trees.c
-""")
-
-zlib_exehead_files = Split("""
- zlib/INFBLOCK.C
-""")
-
-required += zlib_files
-required_exehead += zlib_exehead_files
-
-cppunitlibs = Split("""
- cppunit
-""")
-
-extralibs = Split("""
- dl
- gdi32
- iconv
- pthread
- user32
-""")
-
-scripts = Split("""
- preprocessor.nsi
-""")
-
-Import('env AddAvailableLibs')
-
-# Test scripts
-env.TestScript(scripts)
-
-# Use available libraries
-if env['PLATFORM'] == 'win32':
- # XXX will cause problems if tests are cross compiled
- # on freebsd, libversion.a exists and gives trouble if linked
- extralibs += ['version']
-
-AddAvailableLibs(env, extralibs)
-
-# compile using msvcrt (that's how cppunit.lib is built)
-if 'msvc' in env['TOOLS'] or 'mstoolkit' in env['TOOLS']:
- env.Append(CCFLAGS = ['/MD'])
-
-# uses exceptions
-env.Append(CCFLAGS = ['$EXCEPTION_FLAG'])
-
-# for lzma
-env.Append(CPPDEFINES = ['COMPRESS_MF_BT'])
-
-# test for CppUnit
-conf = env.Configure()
-cppunit = conf.CheckLibWithHeader(cppunitlibs, 'cppunit/extensions/HelperMacros.h', 'C++')
-conf.Finish()
-
-if cppunit:
-
- # compile files from parent directory
- required_obj = []
-
- for i in required:
- b = 'required/%s' % i.split('.')[0]
- s = '#Source/%s' % i
- o = env.Object(b, s)
-
- required_obj.append(o)
-
- # exehead files special treatment
- exehead_env = env.Clone()
- exehead_env.Append(CCFLAGS = ['$C_FLAG'])
- exehead_env.Append(
- CPPDEFINES = [
- 'EXEHEAD',
- 'NSIS_COMPRESS_USE_ZLIB' # just so config.h won't complain
- ]
- )
-
- for i in required_exehead:
- b = 'required/exehead/%s' % i.split('.')[0]
- s = '#Source/%s' % i
- o = exehead_env.Object(b, s)
-
- required_obj.append(o)
-
- # build test program
- tests = env.Program(target, tests + required_obj)
-
- # alias running the test to 'test'
- test = env.Alias('test-code', [tests], tests[0].abspath)
-
- # always test when asked to
- AlwaysBuild(test)
-
-else:
-
- # no CppUnit
- def err(target, source, env):
- print '*** error: CppUnit must be installed for testing!'
- return 1
-
- cmd = env.Command(target, [tests], Action(err, ''))
- env.Alias('test-code', cmd)
+target = 'test'
+
+tests = Split("""
+ compression.cpp
+ decompress.cpp
+ DialogTemplate.cpp
+ endian.cpp
+ mmap.cpp
+ ResourceEditor.cpp
+ specmatch.cpp
+ textrunner.cpp
+ winchar.cpp
+""")
+
+required = Split("""
+ DialogTemplate.cpp
+ dirreader.cpp
+ growbuf.cpp
+ mmap.cpp
+ ResourceEditor.cpp
+ util.cpp
+ winchar.cpp
+""")
+
+required_exehead = Split("""
+ Tests/memcpy.c
+""")
+
+lzma_files = Split("""
+ clzma.cpp
+ 7zip/7zGuids.cpp
+ 7zip/7zip/Common/OutBuffer.cpp
+ 7zip/7zip/Common/StreamUtils.cpp
+ 7zip/7zip/Compress/LZ/LZInWindow.cpp
+ 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp
+ 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp
+ 7zip/Common/Alloc.cpp
+ 7zip/Common/CRC.cpp
+ 7zip/LZMADecode.c
+""")
+
+required += lzma_files
+
+bzip2_files = Split("""
+ bzip2/blocksort.c
+ bzip2/bzlib.c
+ bzip2/compress.c
+ bzip2/huffman.c
+""")
+
+bzip2_exehead_files = Split("""
+ bzip2/bzlib.c
+ bzip2/decompress.c
+""")
+
+required += bzip2_files
+required_exehead += bzip2_exehead_files
+
+zlib_files = Split("""
+ zlib/deflate.c
+ zlib/trees.c
+""")
+
+zlib_exehead_files = Split("""
+ zlib/INFBLOCK.C
+""")
+
+required += zlib_files
+required_exehead += zlib_exehead_files
+
+cppunitlibs = Split("""
+ cppunit
+""")
+
+extralibs = Split("""
+ dl
+ gdi32
+ iconv
+ pthread
+ user32
+""")
+
+scripts = Split("""
+ preprocessor.nsi
+""")
+
+Import('env AddAvailableLibs')
+
+# Test scripts
+env.TestScript(scripts)
+
+# Use available libraries
+if env['PLATFORM'] == 'win32':
+ # XXX will cause problems if tests are cross compiled
+ # on freebsd, libversion.a exists and gives trouble if linked
+ extralibs += ['version']
+
+AddAvailableLibs(env, extralibs)
+
+# compile using msvcrt (that's how cppunit.lib is built)
+if 'msvc' in env['TOOLS'] or 'mstoolkit' in env['TOOLS']:
+ env.Append(CCFLAGS = ['/MD'])
+
+# uses exceptions
+env.Append(CCFLAGS = ['$EXCEPTION_FLAG'])
+
+# for lzma
+env.Append(CPPDEFINES = ['COMPRESS_MF_BT'])
+
+# test for CppUnit
+conf = env.Configure()
+cppunit = conf.CheckLibWithHeader(cppunitlibs, 'cppunit/extensions/HelperMacros.h', 'C++')
+conf.Finish()
+
+if cppunit:
+
+ # compile files from parent directory
+ required_obj = []
+
+ for i in required:
+ b = 'required/%s' % i.split('.')[0]
+ s = '#Source/%s' % i
+ o = env.Object(b, s)
+
+ required_obj.append(o)
+
+ # exehead files special treatment
+ exehead_env = env.Clone()
+ exehead_env.Append(CCFLAGS = ['$C_FLAG'])
+ exehead_env.Append(
+ CPPDEFINES = [
+ 'EXEHEAD',
+ 'NSIS_COMPRESS_USE_ZLIB' # just so config.h won't complain
+ ]
+ )
+
+ for i in required_exehead:
+ b = 'required/exehead/%s' % i.split('.')[0]
+ s = '#Source/%s' % i
+ o = exehead_env.Object(b, s)
+
+ required_obj.append(o)
+
+ # build test program
+ tests = env.Program(target, tests + required_obj)
+
+ # alias running the test to 'test'
+ test = env.Alias('test-code', [tests], tests[0].abspath)
+
+ # always test when asked to
+ AlwaysBuild(test)
+
+else:
+
+ # no CppUnit
+ def err(target, source, env):
+ print '*** error: CppUnit must be installed for testing!'
+ return 1
+
+ cmd = env.Command(target, [tests], Action(err, ''))
+ env.Alias('test-code', cmd)
diff --git a/Source/Tests/compression.cpp b/Source/Tests/compression.cpp
index 09f7987..746a7d9 100755
--- a/Source/Tests/compression.cpp
+++ b/Source/Tests/compression.cpp
@@ -1,154 +1,154 @@
-#include <cppunit/extensions/HelperMacros.h>
-#include "../Platform.h"
-#include "../growbuf.h"
-
-#include <stdlib.h>
-#include <time.h>
-
-#include "decompress.h"
-
-#include "../cbzip2.h"
-#include "../clzma.h"
-#include "../czlib.h"
-
-class CompressionTest : public CppUnit::TestFixture {
-
-public:
- void randData(IGrowBuf &buf, int kb) {
- srand(time(0));
-
- for (int i = 0; i < kb; i++) {
- int r = rand();
- for (size_t j = 0; j < 1024/sizeof(int); j++) {
- buf.add(&r, sizeof(int));
- }
- }
- }
-
- // compressor must be initialized!
- void compress(ICompressor &compressor, IGrowBuf& in, IGrowBuf& out) {
- compressor.SetNextIn((char *) in.get(), in.getlen());
-
- int ret;
-
- do {
- char outbuf[1024];
- compressor.SetNextOut(outbuf, sizeof(outbuf));
-
- ret = compressor.Compress(C_FINISH);
-
- CPPUNIT_ASSERT_MESSAGE( compressor.GetErrStr(ret) , ret >= 0 );
-
- out.add(outbuf, sizeof(outbuf) - compressor.GetAvailOut());
- } while (ret == 0);
- }
-
- typedef void (*decompressInitPtr)(void *);
- typedef int (*decompressWorkPtr)(void *);
-
- void decompress(IDecompressor& decompressor, IGrowBuf& in, IGrowBuf& out) {
- decompressor.init();
- decompressor.setNextIn(in.get(), in.getlen());
-
- int ret;
-
- do {
- char outbuf[1024];
- decompressor.setNextOut(outbuf, sizeof(outbuf));
-
- ret = decompressor.decompress();
-
- CPPUNIT_ASSERT( ret >= 0 );
-
- out.add(outbuf, sizeof(outbuf) - decompressor.getAvailOut());
-
- } while (ret == 0);
-
- }
-
- // compressor must be initialized!
- void testCompressDecompress(int size_kb, ICompressor &compressor, IDecompressor& decompressor) {
- GrowBuf data;
- GrowBuf compressed;
- GrowBuf decompressed;
-
- randData(data, size_kb);
-
- compress(compressor, data, compressed);
- decompress(decompressor, compressed, decompressed);
-
- CPPUNIT_ASSERT_MESSAGE( "decompressed data is smaller", data.getlen() <= decompressed.getlen() );
- CPPUNIT_ASSERT_MESSAGE( "decompressed data is larger", data.getlen() >= decompressed.getlen() );
- CPPUNIT_ASSERT_MESSAGE( "decompressed data is different", !memcmp(data.get(), decompressed.get(), data.getlen()) );
- }
-
- void testCompressDecompress(ICompressor &compressor, IDecompressor& decompressor) {
- CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK );
- testCompressDecompress(1, compressor, decompressor);
-
- CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK );
- testCompressDecompress(1024, compressor, decompressor);
-
- CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK );
- testCompressDecompress(8*1024, compressor, decompressor);
-
- CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK );
- testCompressDecompress(32*1024, compressor, decompressor);
- }
-
-};
-
-class bzip2CompressionTest : public CompressionTest {
-
- CPPUNIT_TEST_SUITE( bzip2CompressionTest );
- CPPUNIT_TEST( test );
- CPPUNIT_TEST_SUITE_END();
-
-public:
-
- void test() {
- CBzip2 compressor;
- bzip2Decompressor decompressor;
-
- testCompressDecompress(compressor, decompressor);
- }
-
-};
-
-class lzmaCompressionTest : public CompressionTest {
-
- CPPUNIT_TEST_SUITE( lzmaCompressionTest );
- CPPUNIT_TEST( test );
- CPPUNIT_TEST_SUITE_END();
-
-public:
-
- void test() {
- CLZMA compressor;
- lzmaDecompressor decompressor;
-
- testCompressDecompress(compressor, decompressor);
- }
-
-};
-
-class zlibCompressionTest : public CompressionTest {
-
- CPPUNIT_TEST_SUITE( zlibCompressionTest );
- CPPUNIT_TEST( test );
- CPPUNIT_TEST_SUITE_END();
-
-public:
-
- void test() {
- CZlib compressor;
- zlibDecompressor decompressor;
-
- testCompressDecompress(compressor, decompressor);
- }
-
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION( bzip2CompressionTest );
-CPPUNIT_TEST_SUITE_REGISTRATION( lzmaCompressionTest );
-CPPUNIT_TEST_SUITE_REGISTRATION( zlibCompressionTest );
+#include <cppunit/extensions/HelperMacros.h>
+#include "../Platform.h"
+#include "../growbuf.h"
+
+#include <stdlib.h>
+#include <time.h>
+
+#include "decompress.h"
+
+#include "../cbzip2.h"
+#include "../clzma.h"
+#include "../czlib.h"
+
+class CompressionTest : public CppUnit::TestFixture {
+
+public:
+ void randData(IGrowBuf &buf, int kb) {
+ srand(time(0));
+
+ for (int i = 0; i < kb; i++) {
+ int r = rand();
+ for (size_t j = 0; j < 1024/sizeof(int); j++) {
+ buf.add(&r, sizeof(int));
+ }
+ }
+ }
+
+ // compressor must be initialized!
+ void compress(ICompressor &compressor, IGrowBuf& in, IGrowBuf& out) {
+ compressor.SetNextIn((char *) in.get(), in.getlen());
+
+ int ret;
+
+ do {
+ char outbuf[1024];
+ compressor.SetNextOut(outbuf, sizeof(outbuf));
+
+ ret = compressor.Compress(C_FINISH);
+
+ CPPUNIT_ASSERT_MESSAGE( compressor.GetErrStr(ret) , ret >= 0 );
+
+ out.add(outbuf, sizeof(outbuf) - compressor.GetAvailOut());
+ } while (ret == 0);
+ }
+
+ typedef void (*decompressInitPtr)(void *);
+ typedef int (*decompressWorkPtr)(void *);
+
+ void decompress(IDecompressor& decompressor, IGrowBuf& in, IGrowBuf& out) {
+ decompressor.init();
+ decompressor.setNextIn(in.get(), in.getlen());
+
+ int ret;
+
+ do {
+ char outbuf[1024];
+ decompressor.setNextOut(outbuf, sizeof(outbuf));
+
+ ret = decompressor.decompress();
+
+ CPPUNIT_ASSERT( ret >= 0 );
+
+ out.add(outbuf, sizeof(outbuf) - decompressor.getAvailOut());
+
+ } while (ret == 0);
+
+ }
+
+ // compressor must be initialized!
+ void testCompressDecompress(int size_kb, ICompressor &compressor, IDecompressor& decompressor) {
+ GrowBuf data;
+ GrowBuf compressed;
+ GrowBuf decompressed;
+
+ randData(data, size_kb);
+
+ compress(compressor, data, compressed);
+ decompress(decompressor, compressed, decompressed);
+
+ CPPUNIT_ASSERT_MESSAGE( "decompressed data is smaller", data.getlen() <= decompressed.getlen() );
+ CPPUNIT_ASSERT_MESSAGE( "decompressed data is larger", data.getlen() >= decompressed.getlen() );
+ CPPUNIT_ASSERT_MESSAGE( "decompressed data is different", !memcmp(data.get(), decompressed.get(), data.getlen()) );
+ }
+
+ void testCompressDecompress(ICompressor &compressor, IDecompressor& decompressor) {
+ CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK );
+ testCompressDecompress(1, compressor, decompressor);
+
+ CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK );
+ testCompressDecompress(1024, compressor, decompressor);
+
+ CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK );
+ testCompressDecompress(8*1024, compressor, decompressor);
+
+ CPPUNIT_ASSERT( compressor.Init(9, 1 << 23) == C_OK );
+ testCompressDecompress(32*1024, compressor, decompressor);
+ }
+
+};
+
+class bzip2CompressionTest : public CompressionTest {
+
+ CPPUNIT_TEST_SUITE( bzip2CompressionTest );
+ CPPUNIT_TEST( test );
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+
+ void test() {
+ CBzip2 compressor;
+ bzip2Decompressor decompressor;
+
+ testCompressDecompress(compressor, decompressor);
+ }
+
+};
+
+class lzmaCompressionTest : public CompressionTest {
+
+ CPPUNIT_TEST_SUITE( lzmaCompressionTest );
+ CPPUNIT_TEST( test );
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+
+ void test() {
+ CLZMA compressor;
+ lzmaDecompressor decompressor;
+
+ testCompressDecompress(compressor, decompressor);
+ }
+
+};
+
+class zlibCompressionTest : public CompressionTest {
+
+ CPPUNIT_TEST_SUITE( zlibCompressionTest );
+ CPPUNIT_TEST( test );
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+
+ void test() {
+ CZlib compressor;
+ zlibDecompressor decompressor;
+
+ testCompressDecompress(compressor, decompressor);
+ }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( bzip2CompressionTest );
+CPPUNIT_TEST_SUITE_REGISTRATION( lzmaCompressionTest );
+CPPUNIT_TEST_SUITE_REGISTRATION( zlibCompressionTest );
diff --git a/Source/Tests/decompress.cpp b/Source/Tests/decompress.cpp
index 8f27f7b..45c570b 100755
--- a/Source/Tests/decompress.cpp
+++ b/Source/Tests/decompress.cpp
@@ -1,62 +1,62 @@
-#include "decompress.h"
-
-#include <string.h> // for memset
-
-#define EXEHEAD
-#define NSIS_CONFIG_COMPRESSION_SUPPORT
-
-extern "C" {
-#define NSIS_COMPRESS_USE_BZIP2
-#include "../bzip2/bzlib.h"
-#undef NSIS_COMPRESS_USE_BZIP2
-
-#define NSIS_COMPRESS_USE_LZMA
-#include "../7zip/LZMADecode.h"
-#undef NSIS_COMPRESS_USE_LZMA
-
-#define NSIS_COMPRESS_USE_ZLIB
-#include "../zlib/ZLIB.H"
-#undef NSIS_COMPRESS_USE_ZLIB
-}
-
-#define DECOMPRESSOR(name, type, initf, dec, u) \
- name::name() { \
- vs = new type; \
- memset(vs, 0, sizeof(type)); \
- } \
- \
- name::~name() { \
- delete (type *) vs; \
- vs = 0; \
- } \
- \
- void name::setNextIn(void *buffer, int size) { \
- type *s = (type *) vs; \
- s->next_in = (u *) buffer; \
- s->avail_in = size; \
- } \
- \
- void name::setNextOut(void *buffer, int size) { \
- type *s = (type *) vs; \
- s->next_out = (u *) buffer; \
- s->avail_out = size; \
- } \
- \
- int name::getAvailOut() { \
- type *s = (type *) vs; \
- return s->avail_out; \
- } \
- \
- void name::init() { \
- type *s = (type *) vs; \
- initf(s); \
- } \
- \
- int name::decompress() { \
- type *s = (type *) vs; \
- return dec(s); \
- }
-
-DECOMPRESSOR(lzmaDecompressor, lzma_stream, lzmaInit, lzmaDecode, unsigned char);
-DECOMPRESSOR(bzip2Decompressor, DState, BZ2_bzDecompressInit, BZ2_bzDecompress, char);
-DECOMPRESSOR(zlibDecompressor, z_stream, inflateReset, inflate, unsigned char);
+#include "decompress.h"
+
+#include <string.h> // for memset
+
+#define EXEHEAD
+#define NSIS_CONFIG_COMPRESSION_SUPPORT
+
+extern "C" {
+#define NSIS_COMPRESS_USE_BZIP2
+#include "../bzip2/bzlib.h"
+#undef NSIS_COMPRESS_USE_BZIP2
+
+#define NSIS_COMPRESS_USE_LZMA
+#include "../7zip/LZMADecode.h"
+#undef NSIS_COMPRESS_USE_LZMA
+
+#define NSIS_COMPRESS_USE_ZLIB
+#include "../zlib/ZLIB.H"
+#undef NSIS_COMPRESS_USE_ZLIB
+}
+
+#define DECOMPRESSOR(name, type, initf, dec, u) \
+ name::name() { \
+ vs = new type; \
+ memset(vs, 0, sizeof(type)); \
+ } \
+ \
+ name::~name() { \
+ delete (type *) vs; \
+ vs = 0; \
+ } \
+ \
+ void name::setNextIn(void *buffer, int size) { \
+ type *s = (type *) vs; \
+ s->next_in = (u *) buffer; \
+ s->avail_in = size; \
+ } \
+ \
+ void name::setNextOut(void *buffer, int size) { \
+ type *s = (type *) vs; \
+ s->next_out = (u *) buffer; \
+ s->avail_out = size; \
+ } \
+ \
+ int name::getAvailOut() { \
+ type *s = (type *) vs; \
+ return s->avail_out; \
+ } \
+ \
+ void name::init() { \
+ type *s = (type *) vs; \
+ initf(s); \
+ } \
+ \
+ int name::decompress() { \
+ type *s = (type *) vs; \
+ return dec(s); \
+ }
+
+DECOMPRESSOR(lzmaDecompressor, lzma_stream, lzmaInit, lzmaDecode, unsigned char);
+DECOMPRESSOR(bzip2Decompressor, DState, BZ2_bzDecompressInit, BZ2_bzDecompress, char);
+DECOMPRESSOR(zlibDecompressor, z_stream, inflateReset, inflate, unsigned char);
diff --git a/Source/Tests/decompress.h b/Source/Tests/decompress.h
index 4f0e492..6fb2a76 100755
--- a/Source/Tests/decompress.h
+++ b/Source/Tests/decompress.h
@@ -1,66 +1,66 @@
-class IDecompressor {
-public:
-
- virtual ~IDecompressor() {};
-
- virtual void init() = 0;
- virtual void setNextIn(void *buffer, int size) = 0;
- virtual void setNextOut(void *buffer, int size) = 0;
- virtual int getAvailOut() = 0;
- virtual int decompress() = 0;
-
-};
-
-class lzmaDecompressor : public IDecompressor {
-public:
-
- lzmaDecompressor();
- virtual ~lzmaDecompressor();
-
- virtual void init();
- virtual void setNextIn(void *buffer, int size);
- virtual void setNextOut(void *buffer, int size);
- virtual int getAvailOut();
- virtual int decompress();
-
-private:
-
- void *vs;
-
-};
-
-class bzip2Decompressor : public IDecompressor {
-public:
-
- bzip2Decompressor();
- virtual ~bzip2Decompressor();
-
- virtual void init();
- virtual void setNextIn(void *buffer, int size);
- virtual void setNextOut(void *buffer, int size);
- virtual int getAvailOut();
- virtual int decompress();
-
-private:
-
- void *vs;
-
-};
-
-class zlibDecompressor : public IDecompressor {
-public:
-
- zlibDecompressor();
- virtual ~zlibDecompressor();
-
- virtual void init();
- virtual void setNextIn(void *buffer, int size);
- virtual void setNextOut(void *buffer, int size);
- virtual int getAvailOut();
- virtual int decompress();
-
-private:
-
- void *vs;
-
-};
+class IDecompressor {
+public:
+
+ virtual ~IDecompressor() {};
+
+ virtual void init() = 0;
+ virtual void setNextIn(void *buffer, int size) = 0;
+ virtual void setNextOut(void *buffer, int size) = 0;
+ virtual int getAvailOut() = 0;
+ virtual int decompress() = 0;
+
+};
+
+class lzmaDecompressor : public IDecompressor {
+public:
+
+ lzmaDecompressor();
+ virtual ~lzmaDecompressor();
+
+ virtual void init();
+ virtual void setNextIn(void *buffer, int size);
+ virtual void setNextOut(void *buffer, int size);
+ virtual int getAvailOut();
+ virtual int decompress();
+
+private:
+
+ void *vs;
+
+};
+
+class bzip2Decompressor : public IDecompressor {
+public:
+
+ bzip2Decompressor();
+ virtual ~bzip2Decompressor();
+
+ virtual void init();
+ virtual void setNextIn(void *buffer, int size);
+ virtual void setNextOut(void *buffer, int size);
+ virtual int getAvailOut();
+ virtual int decompress();
+
+private:
+
+ void *vs;
+
+};
+
+class zlibDecompressor : public IDecompressor {
+public:
+
+ zlibDecompressor();
+ virtual ~zlibDecompressor();
+
+ virtual void init();
+ virtual void setNextIn(void *buffer, int size);
+ virtual void setNextOut(void *buffer, int size);
+ virtual int getAvailOut();
+ virtual int decompress();
+
+private:
+
+ void *vs;
+
+};
diff --git a/Source/Tests/endian.cpp b/Source/Tests/endian.cpp
index ed9b2e2..c1912d5 100755
--- a/Source/Tests/endian.cpp
+++ b/Source/Tests/endian.cpp
@@ -1,56 +1,56 @@
-#include <cppunit/extensions/HelperMacros.h>
-#include "../Platform.h"
-
-class EndianTest : public CppUnit::TestFixture {
-
- CPPUNIT_TEST_SUITE( EndianTest );
- CPPUNIT_TEST( testSwapEndian );
- CPPUNIT_TEST( testFixEndian16 );
- CPPUNIT_TEST( testFixEndian32 );
- CPPUNIT_TEST_SUITE_END();
-
-public:
- void testSwapEndian() {
- CPPUNIT_ASSERT_EQUAL( (int)0x78563412, (int)SWAP_ENDIAN_INT32(0x12345678) );
- CPPUNIT_ASSERT_EQUAL( (int)0xFFFFFFFF, (int)SWAP_ENDIAN_INT32(0xFFFFFFFF) );
- CPPUNIT_ASSERT_EQUAL( (int)0, (int)SWAP_ENDIAN_INT32(0) );
- CPPUNIT_ASSERT_EQUAL( (int)0x3412, (int)SWAP_ENDIAN_INT16(0x1234) );
- CPPUNIT_ASSERT_EQUAL( (int)0xFFFF, (int)SWAP_ENDIAN_INT16(0xFFFF) );
- CPPUNIT_ASSERT_EQUAL( (int)0, (int)SWAP_ENDIAN_INT16(0) );
- }
-
- void testFixEndian32() {
- int i=1;
- int actual = 0x12345678;
- FIX_ENDIAN_INT32_INPLACE(actual);
- int expected;
- if (((char*)&i)[0] == 1) {
- // little endian
- expected = 0x12345678;
- }
- else {
- // big endian
- expected = 0x78563412;
- }
- CPPUNIT_ASSERT_EQUAL(expected, actual);
- }
-
- void testFixEndian16() {
- int i=1;
- int actual = 0x1234;
- FIX_ENDIAN_INT16_INPLACE(actual);
- int expected;
- if (((char*)&i)[0] == 1) {
- // little endian
- expected = 0x1234;
- }
- else {
- // big endian
- expected = 0x3412;
- }
- CPPUNIT_ASSERT_EQUAL(expected, actual);
- }
-
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION( EndianTest );
+#include <cppunit/extensions/HelperMacros.h>
+#include "../Platform.h"
+
+class EndianTest : public CppUnit::TestFixture {
+
+ CPPUNIT_TEST_SUITE( EndianTest );
+ CPPUNIT_TEST( testSwapEndian );
+ CPPUNIT_TEST( testFixEndian16 );
+ CPPUNIT_TEST( testFixEndian32 );
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testSwapEndian() {
+ CPPUNIT_ASSERT_EQUAL( (int)0x78563412, (int)SWAP_ENDIAN_INT32(0x12345678) );
+ CPPUNIT_ASSERT_EQUAL( (int)0xFFFFFFFF, (int)SWAP_ENDIAN_INT32(0xFFFFFFFF) );
+ CPPUNIT_ASSERT_EQUAL( (int)0, (int)SWAP_ENDIAN_INT32(0) );
+ CPPUNIT_ASSERT_EQUAL( (int)0x3412, (int)SWAP_ENDIAN_INT16(0x1234) );
+ CPPUNIT_ASSERT_EQUAL( (int)0xFFFF, (int)SWAP_ENDIAN_INT16(0xFFFF) );
+ CPPUNIT_ASSERT_EQUAL( (int)0, (int)SWAP_ENDIAN_INT16(0) );
+ }
+
+ void testFixEndian32() {
+ int i=1;
+ int actual = 0x12345678;
+ FIX_ENDIAN_INT32_INPLACE(actual);
+ int expected;
+ if (((char*)&i)[0] == 1) {
+ // little endian
+ expected = 0x12345678;
+ }
+ else {
+ // big endian
+ expected = 0x78563412;
+ }
+ CPPUNIT_ASSERT_EQUAL(expected, actual);
+ }
+
+ void testFixEndian16() {
+ int i=1;
+ int actual = 0x1234;
+ FIX_ENDIAN_INT16_INPLACE(actual);
+ int expected;
+ if (((char*)&i)[0] == 1) {
+ // little endian
+ expected = 0x1234;
+ }
+ else {
+ // big endian
+ expected = 0x3412;
+ }
+ CPPUNIT_ASSERT_EQUAL(expected, actual);
+ }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( EndianTest );
diff --git a/Source/Tests/memcpy.c b/Source/Tests/memcpy.c
index f2828e8..0c590e8 100755
--- a/Source/Tests/memcpy.c
+++ b/Source/Tests/memcpy.c
@@ -1,11 +1,11 @@
-#include "../Platform.h"
-
-void NSISCALL mini_memcpy(void *out, const void *in, int len)
-{
- char *c_out=(char*)out;
- char *c_in=(char *)in;
- while (len-- > 0)
- {
- *c_out++=*c_in++;
- }
-}
+#include "../Platform.h"
+
+void NSISCALL mini_memcpy(void *out, const void *in, int len)
+{
+ char *c_out=(char*)out;
+ char *c_in=(char *)in;
+ while (len-- > 0)
+ {
+ *c_out++=*c_in++;
+ }
+}
diff --git a/Source/Tests/mmap.cpp b/Source/Tests/mmap.cpp
index b1088f4..c2d267b 100755
--- a/Source/Tests/mmap.cpp
+++ b/Source/Tests/mmap.cpp
@@ -1,74 +1,74 @@
-#include <cppunit/extensions/HelperMacros.h>
-#include "../mmap.h"
-
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-using namespace std; // for std::min
-
-int g_display_errors = 1;
-FILE *g_output = stderr;
-
-void quit() {
- fprintf(g_output, "MMap quit\n");
-}
-
-class MMapTest : public CppUnit::TestFixture {
-
- CPPUNIT_TEST_SUITE( MMapTest );
- CPPUNIT_TEST( testMMapFile );
- CPPUNIT_TEST_SUITE_END();
-
-public:
- void testMMapFile() {
- size_t i;
- const int BUF_SIZE = 50000; // 50MB
-
- // resize
-
- MMapFile mmap;
- mmap.resize(BUF_SIZE);
- CPPUNIT_ASSERT_EQUAL( BUF_SIZE, mmap.getsize() );
-
- // set content
-
- char *buf = (char *) mmap.get(0, BUF_SIZE);
-
- for (i = 0; i < BUF_SIZE; i++) {
- buf[i] = i % 256;
- }
-
- mmap.release();
-
- // test content and get(), getmore()
-
- srand(time(NULL));
-
- for (i = 0; i < 100; i++) {
- int offset1 = rand() % BUF_SIZE;
- int size1 = rand() % (BUF_SIZE - offset1);
- char *p1 = (char *) mmap.get(offset1, size1);
-
- int offset2 = rand() % BUF_SIZE;
- int size2 = rand() % (BUF_SIZE - offset2);
- char *p2 = (char *) mmap.getmore(offset2, size2);
-
- int j;
-
- for (j = 0; j < size1; j++) {
- CPPUNIT_ASSERT_EQUAL( p1[j], char((offset1 + j) % 256) );
- }
-
- for (j = 0; j < size2; j++) {
- CPPUNIT_ASSERT_EQUAL( p2[j], char((offset2 + j) % 256) );
- }
-
- mmap.release();
- mmap.release(p2, size2);
- }
- }
-
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION( MMapTest );
+#include <cppunit/extensions/HelperMacros.h>
+#include "../mmap.h"
+
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+using namespace std; // for std::min
+
+int g_display_errors = 1;
+FILE *g_output = stderr;
+
+void quit() {
+ fprintf(g_output, "MMap quit\n");
+}
+
+class MMapTest : public CppUnit::TestFixture {
+
+ CPPUNIT_TEST_SUITE( MMapTest );
+ CPPUNIT_TEST( testMMapFile );
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testMMapFile() {
+ size_t i;
+ const int BUF_SIZE = 50000; // 50MB
+
+ // resize
+
+ MMapFile mmap;
+ mmap.resize(BUF_SIZE);
+ CPPUNIT_ASSERT_EQUAL( BUF_SIZE, mmap.getsize() );
+
+ // set content
+
+ char *buf = (char *) mmap.get(0, BUF_SIZE);
+
+ for (i = 0; i < BUF_SIZE; i++) {
+ buf[i] = i % 256;
+ }
+
+ mmap.release();
+
+ // test content and get(), getmore()
+
+ srand(time(NULL));
+
+ for (i = 0; i < 100; i++) {
+ int offset1 = rand() % BUF_SIZE;
+ int size1 = rand() % (BUF_SIZE - offset1);
+ char *p1 = (char *) mmap.get(offset1, size1);
+
+ int offset2 = rand() % BUF_SIZE;
+ int size2 = rand() % (BUF_SIZE - offset2);
+ char *p2 = (char *) mmap.getmore(offset2, size2);
+
+ int j;
+
+ for (j = 0; j < size1; j++) {
+ CPPUNIT_ASSERT_EQUAL( p1[j], char((offset1 + j) % 256) );
+ }
+
+ for (j = 0; j < size2; j++) {
+ CPPUNIT_ASSERT_EQUAL( p2[j], char((offset2 + j) % 256) );
+ }
+
+ mmap.release();
+ mmap.release(p2, size2);
+ }
+ }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( MMapTest );
diff --git a/Source/Tests/preprocessor.nsi b/Source/Tests/preprocessor.nsi
index 751fdce..9f25c9b 100755
--- a/Source/Tests/preprocessor.nsi
+++ b/Source/Tests/preprocessor.nsi
@@ -1,224 +1,224 @@
-!ifndef file_is_included
-!define file_is_included
-
-Name preprocessor
-OutFile preprocessor.exe
-
-!ifdef some_define_that_doesnt_exist
-this should not be executed, so no error should be raised
-/*
-code inside comments should not be executed
-!ifdef
-*/
-# invalid preprocessor should be ignored
-!hello
-!endif
-
-!ifdef d1
-!error "d1 is not defined!"
-!else ifdef d2
-!error "d2 is not defined!"
-!else
-# this should be compiled
-!endif
-
-!define d1
-
-!ifdef d1
-# this should be compiled
-!else ifdef d2
-!error "d2 is not defined!"
-!else
-!error "d1 is defined!"
-!endif
-
-!undef d1
-!define d2
-
-!ifdef d1
-!error "d1 is not defined!"
-!else ifdef d2
-# this should be compiled
-!else
-!error "d2 is defined!"
-!endif
-
-!ifdef some_define_that_doesnt_exist
-the next !endif should be part of this line\
-!endif
-!\
-e\
-n\
-d\
-i\
-f
-
-!if 0
-/*
-this shouldn't be compiled
-!endif
-*/
-!endif
-
-# tests for !if statement
-!if 'test' == 'test'
- !if 1 <= 2
- !if ! 100 < 99.99
- !if 2.2 > 1.12
- !if ! 23 >= 37
- !if 1 && 1
- !if ! 0 || 0
-
- # this should be compiled
-
- !else
- !error "!if ! 0 || 0 is true!"
- !endif
- !else
- !error "!if 1 && 1 is true!"
- !endif
- !else
- !error "!if ! 23 >= 37 is true!"
- !endif
- !else
- !error "!if 2.2 > 1.12 is true!"
- !endif
- !else
- !error "!if ! 100 < 99.99 is true!"
- !endif
- !else
- !error "!if 1 <= 2 is true!"
- !endif
-!else
- !error "!if 'test' == 'test' is true!"
-!endif
-
-; testing of two math functions and a macro hack :)
-!define increase "!insertmacro increase"
-!macro increase DEFINE
- !define /math ${DEFINE}_MACROTEMP ${${DEFINE}} + 1
- !undef ${DEFINE}
- !define ${DEFINE} ${${DEFINE}_MACROTEMP}
- !undef ${DEFINE}_MACROTEMP
-!macroend
-
-!define number1 1 # 1
-!define /math number2 2 + 3
-!define /math number3 ${number2} - ${number1}
-${increase} number3
-!define /math number4 2 * ${number3}
-!define /math number5 ${number4} % 3
-
-!if ${number1} != 1
- !error "number1 != 1"
-!endif
-
-!if ${number2} != 5
- !error "number2 != 5"
-!endif
-
-!if ${number3} != 5
- !error "number3 != 5"
-!endif
-
-!if ${number4} != 10
- !error "number4 != 10"
-!endif
-
-!if ${number5} != 1
- !error "number5 != 1"
-!endif
-
-; end math functions
-
-# this should just give a warning, not an error
-!include /NONFATAL file_that_doesnt_exist.nsh
-
-# this should include this file just one time.
-!include preprocessor.nsi
-
-Section
-Return
-WriteUninstaller uninst.exe # avoid warning
-SectionEnd
-
-# test scopes
-
-!macro TEST_SCOPE scope def should_exist
-
- !if ${should_exist} == y
- !ifndef ${def}
- !error "${def} not defined in ${scope} scope"
- !endif
- !else
- !ifdef ${def}
- !error "${def} defined in ${scope} scope"
- !endif
- !endif
-
-!macroend
-
-!macro TEST_SCOPES scope global section function pageex uninstall
-
- !insertmacro TEST_SCOPE "${scope}" __GLOBAL__ ${global}
- !insertmacro TEST_SCOPE "${scope}" __SECTION__ ${section}
- !insertmacro TEST_SCOPE "${scope}" __FUNCTION__ ${function}
- !insertmacro TEST_SCOPE "${scope}" __PAGEEX__ ${pageex}
- !insertmacro TEST_SCOPE "${scope}" __UNINSTALL__ ${uninstall}
-
-!macroend
-
-!insertmacro TEST_SCOPES "global" y n n n n
-
-Section test
-!insertmacro TEST_SCOPES "section" n y n n n
-!if ${__SECTION__} != test
- !error "invalid __SECTION__ value"
-!endif
-SectionEnd
-
-Section un.test
-!insertmacro TEST_SCOPES "uninstall section" n y n n y
-!if ${__SECTION__} != test
- !error "invalid __SECTION__ value"
-!endif
-SectionEnd
-
-Function test
-Call test # avoid warning
-!insertmacro TEST_SCOPES "function" n n y n n
-!if ${__FUNCTION__} != test
- !error "invalid __FUNCTION__ value"
-!endif
-FunctionEnd
-
-Function un.test
-Call un.test # avoid warning
-!insertmacro TEST_SCOPES "uninstall function" n n y n y
-!if ${__FUNCTION__} != test
- !error "invalid __FUNCTION__ value"
-!endif
-FunctionEnd
-
-PageEx instfiles
-!insertmacro TEST_SCOPES "pageex" n n n y n
-!if ${__PAGEEX__} != instfiles
- !error "invalid __PAGEEX__ value"
-!endif
-PageExEnd
-
-PageEx un.instfiles
-!insertmacro TEST_SCOPES "uninstall pageex" n n n y y
-!if ${__PAGEEX__} != instfiles
- !error "invalid __PAGEEX__ value"
-!endif
-PageExEnd
-
-!insertmacro TEST_SCOPES "global" y n n n n
-
-!else
-
-# this should just give a warning, not an error
-!include /NONFATAL another_file_that_doesnt_exist.nsh
-
-!endif
+!ifndef file_is_included
+!define file_is_included
+
+Name preprocessor
+OutFile preprocessor.exe
+
+!ifdef some_define_that_doesnt_exist
+this should not be executed, so no error should be raised
+/*
+code inside comments should not be executed
+!ifdef
+*/
+# invalid preprocessor should be ignored
+!hello
+!endif
+
+!ifdef d1
+!error "d1 is not defined!"
+!else ifdef d2
+!error "d2 is not defined!"
+!else
+# this should be compiled
+!endif
+
+!define d1
+
+!ifdef d1
+# this should be compiled
+!else ifdef d2
+!error "d2 is not defined!"
+!else
+!error "d1 is defined!"
+!endif
+
+!undef d1
+!define d2
+
+!ifdef d1
+!error "d1 is not defined!"
+!else ifdef d2
+# this should be compiled
+!else
+!error "d2 is defined!"
+!endif
+
+!ifdef some_define_that_doesnt_exist
+the next !endif should be part of this line\
+!endif
+!\
+e\
+n\
+d\
+i\
+f
+
+!if 0
+/*
+this shouldn't be compiled
+!endif
+*/
+!endif
+
+# tests for !if statement
+!if 'test' == 'test'
+ !if 1 <= 2
+ !if ! 100 < 99.99
+ !if 2.2 > 1.12
+ !if ! 23 >= 37
+ !if 1 && 1
+ !if ! 0 || 0
+
+ # this should be compiled
+
+ !else
+ !error "!if ! 0 || 0 is true!"
+ !endif
+ !else
+ !error "!if 1 && 1 is true!"
+ !endif
+ !else
+ !error "!if ! 23 >= 37 is true!"
+ !endif
+ !else
+ !error "!if 2.2 > 1.12 is true!"
+ !endif
+ !else
+ !error "!if ! 100 < 99.99 is true!"
+ !endif
+ !else
+ !error "!if 1 <= 2 is true!"
+ !endif
+!else
+ !error "!if 'test' == 'test' is true!"
+!endif
+
+; testing of two math functions and a macro hack :)
+!define increase "!insertmacro increase"
+!macro increase DEFINE
+ !define /math ${DEFINE}_MACROTEMP ${${DEFINE}} + 1
+ !undef ${DEFINE}
+ !define ${DEFINE} ${${DEFINE}_MACROTEMP}
+ !undef ${DEFINE}_MACROTEMP
+!macroend
+
+!define number1 1 # 1
+!define /math number2 2 + 3
+!define /math number3 ${number2} - ${number1}
+${increase} number3
+!define /math number4 2 * ${number3}
+!define /math number5 ${number4} % 3
+
+!if ${number1} != 1
+ !error "number1 != 1"
+!endif
+
+!if ${number2} != 5
+ !error "number2 != 5"
+!endif
+
+!if ${number3} != 5
+ !error "number3 != 5"
+!endif
+
+!if ${number4} != 10
+ !error "number4 != 10"
+!endif
+
+!if ${number5} != 1
+ !error "number5 != 1"
+!endif
+
+; end math functions
+
+# this should just give a warning, not an error
+!include /NONFATAL file_that_doesnt_exist.nsh
+
+# this should include this file just one time.
+!include preprocessor.nsi
+
+Section
+Return
+WriteUninstaller uninst.exe # avoid warning
+SectionEnd
+
+# test scopes
+
+!macro TEST_SCOPE scope def should_exist
+
+ !if ${should_exist} == y
+ !ifndef ${def}
+ !error "${def} not defined in ${scope} scope"
+ !endif
+ !else
+ !ifdef ${def}
+ !error "${def} defined in ${scope} scope"
+ !endif
+ !endif
+
+!macroend
+
+!macro TEST_SCOPES scope global section function pageex uninstall
+
+ !insertmacro TEST_SCOPE "${scope}" __GLOBAL__ ${global}
+ !insertmacro TEST_SCOPE "${scope}" __SECTION__ ${section}
+ !insertmacro TEST_SCOPE "${scope}" __FUNCTION__ ${function}
+ !insertmacro TEST_SCOPE "${scope}" __PAGEEX__ ${pageex}
+ !insertmacro TEST_SCOPE "${scope}" __UNINSTALL__ ${uninstall}
+
+!macroend
+
+!insertmacro TEST_SCOPES "global" y n n n n
+
+Section test
+!insertmacro TEST_SCOPES "section" n y n n n
+!if ${__SECTION__} != test
+ !error "invalid __SECTION__ value"
+!endif
+SectionEnd
+
+Section un.test
+!insertmacro TEST_SCOPES "uninstall section" n y n n y
+!if ${__SECTION__} != test
+ !error "invalid __SECTION__ value"
+!endif
+SectionEnd
+
+Function test
+Call test # avoid warning
+!insertmacro TEST_SCOPES "function" n n y n n
+!if ${__FUNCTION__} != test
+ !error "invalid __FUNCTION__ value"
+!endif
+FunctionEnd
+
+Function un.test
+Call un.test # avoid warning
+!insertmacro TEST_SCOPES "uninstall function" n n y n y
+!if ${__FUNCTION__} != test
+ !error "invalid __FUNCTION__ value"
+!endif
+FunctionEnd
+
+PageEx instfiles
+!insertmacro TEST_SCOPES "pageex" n n n y n
+!if ${__PAGEEX__} != instfiles
+ !error "invalid __PAGEEX__ value"
+!endif
+PageExEnd
+
+PageEx un.instfiles
+!insertmacro TEST_SCOPES "uninstall pageex" n n n y y
+!if ${__PAGEEX__} != instfiles
+ !error "invalid __PAGEEX__ value"
+!endif
+PageExEnd
+
+!insertmacro TEST_SCOPES "global" y n n n n
+
+!else
+
+# this should just give a warning, not an error
+!include /NONFATAL another_file_that_doesnt_exist.nsh
+
+!endif
diff --git a/Source/Tests/root.txt b/Source/Tests/root.txt
index e3629ef..3e09f16 100755
--- a/Source/Tests/root.txt
+++ b/Source/Tests/root.txt
@@ -1,6 +1,6 @@
-this is a list of bugs related to root directories, which can not yet be tested automatically
-
-* bug #1331292 - browsing for root network directory disables next button
-
-* root with space after it, without AllowRootDirInstall
- http://forums.winamp.com/showthread.php?threadid=222727
+this is a list of bugs related to root directories, which can not yet be tested automatically
+
+* bug #1331292 - browsing for root network directory disables next button
+
+* root with space after it, without AllowRootDirInstall
+ http://forums.winamp.com/showthread.php?threadid=222727
diff --git a/Source/Tests/specmatch.cpp b/Source/Tests/specmatch.cpp
index a68555c..56a79c7 100755
--- a/Source/Tests/specmatch.cpp
+++ b/Source/Tests/specmatch.cpp
@@ -1,45 +1,45 @@
-#include <cppunit/extensions/HelperMacros.h>
-#include "../dirreader.h"
-
-#include <string>
-
-using namespace std;
-
-class SpecTest : public CppUnit::TestFixture {
-
- CPPUNIT_TEST_SUITE( SpecTest );
- CPPUNIT_TEST( testMatches );
- CPPUNIT_TEST_SUITE_END();
-
-public:
- void testMatches() {
- testMatch("test.exe", "test.exe", true);
- testMatch("test", "test", true);
- testMatch("test.exe", "test.*", true);
- testMatch("test", "test.*", true);
- testMatch("test", "????", true);
- testMatch("test", "???", false);
- testMatch("test", "*.exe", false);
- testMatch("test.exe.bat", "*.exe", false);
- testMatch("test.exe.bat", "*.bat", true);
- testMatch("test.exe.bat", "*t", true);
- testMatch("test.exe.bat", "*", true);
- testMatch("test.exe.bat", "*x*", true);
- testMatch("test.exe.exe", "*.*", true);
- testMatch("test.exe.bat", "*.b*", true);
- testMatch("test.exe.bat", "tes?.*.bat", true);
- testMatch("test.exe.bat", "tes?.*bat", true);
- testMatch("test.exe.bat", "tes?.*bat***.", true);
- testMatch("test.exe", "????.*", true);
- testMatch("testing.exe", "????.*", false);
- }
-
-private:
-
- void testMatch(string name, string spec, bool result) {
- CPPUNIT_ASSERT_EQUAL( dir_reader::matches(name, spec), result );
- }
-
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION( SpecTest );
+#include <cppunit/extensions/HelperMacros.h>
+#include "../dirreader.h"
+
+#include <string>
+
+using namespace std;
+
+class SpecTest : public CppUnit::TestFixture {
+
+ CPPUNIT_TEST_SUITE( SpecTest );
+ CPPUNIT_TEST( testMatches );
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testMatches() {
+ testMatch("test.exe", "test.exe", true);
+ testMatch("test", "test", true);
+ testMatch("test.exe", "test.*", true);
+ testMatch("test", "test.*", true);
+ testMatch("test", "????", true);
+ testMatch("test", "???", false);
+ testMatch("test", "*.exe", false);
+ testMatch("test.exe.bat", "*.exe", false);
+ testMatch("test.exe.bat", "*.bat", true);
+ testMatch("test.exe.bat", "*t", true);
+ testMatch("test.exe.bat", "*", true);
+ testMatch("test.exe.bat", "*x*", true);
+ testMatch("test.exe.exe", "*.*", true);
+ testMatch("test.exe.bat", "*.b*", true);
+ testMatch("test.exe.bat", "tes?.*.bat", true);
+ testMatch("test.exe.bat", "tes?.*bat", true);
+ testMatch("test.exe.bat", "tes?.*bat***.", true);
+ testMatch("test.exe", "????.*", true);
+ testMatch("testing.exe", "????.*", false);
+ }
+
+private:
+
+ void testMatch(string name, string spec, bool result) {
+ CPPUNIT_ASSERT_EQUAL( dir_reader::matches(name, spec), result );
+ }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( SpecTest );
diff --git a/Source/Tests/textrunner.cpp b/Source/Tests/textrunner.cpp
index 4c5179f..171a578 100755
--- a/Source/Tests/textrunner.cpp
+++ b/Source/Tests/textrunner.cpp
@@ -1,22 +1,22 @@
-#include <cppunit/CompilerOutputter.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <cppunit/ui/text/TestRunner.h>
-
-int main(int argc, char* argv[])
-{
- // Get the top level suite from the registry
- CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
-
- // Adds the test to the list of test to run
- CppUnit::TextUi::TestRunner runner;
- runner.addTest( suite );
-
- // Change the default outputter to a compiler error format outputter
- runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
- std::cerr ) );
- // Run the tests.
- bool wasSucessful = runner.run();
-
- // Return error code 1 if the one of test failed.
- return wasSucessful ? 0 : 1;
-}
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+int main(int argc, char* argv[])
+{
+ // Get the top level suite from the registry
+ CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+
+ // Adds the test to the list of test to run
+ CppUnit::TextUi::TestRunner runner;
+ runner.addTest( suite );
+
+ // Change the default outputter to a compiler error format outputter
+ runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
+ std::cerr ) );
+ // Run the tests.
+ bool wasSucessful = runner.run();
+
+ // Return error code 1 if the one of test failed.
+ return wasSucessful ? 0 : 1;
+}
diff --git a/Source/Tests/winchar.cpp b/Source/Tests/winchar.cpp
index 99934a9..a7df1e4 100755
--- a/Source/Tests/winchar.cpp
+++ b/Source/Tests/winchar.cpp
@@ -1,129 +1,129 @@
-#include <cppunit/extensions/HelperMacros.h>
-#include "../winchar.h"
-
-#include <time.h>
-#include <stdlib.h>
-
-// macro for fixing endianity
-#define _x(x) FIX_ENDIAN_INT16(WCHAR(x))
-
-class WinCharTest : public CppUnit::TestFixture {
-
- CPPUNIT_TEST_SUITE( WinCharTest );
- CPPUNIT_TEST( testFromAnsi );
- CPPUNIT_TEST( testToAnsi );
- CPPUNIT_TEST( testStrCpy );
- CPPUNIT_TEST( testStrNCpy );
- CPPUNIT_TEST( testStrLen );
- CPPUNIT_TEST( testStrCmp );
- CPPUNIT_TEST( testStrDup );
- CPPUNIT_TEST( testStoi );
- CPPUNIT_TEST_SUITE_END();
-
-public:
- void testFromAnsi() {
- WCHAR test[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 };
- WCHAR *dyn = winchar_fromansi("test");
-
- CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, 5) );
-
- delete [] dyn;
- }
-
- void testToAnsi() {
- WCHAR test[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 };
- char *dyn = winchar_toansi(test);
-
- CPPUNIT_ASSERT_EQUAL( 0, strcmp("test", dyn) );
-
- delete [] dyn;
- }
-
- void testStrCpy() {
- WCHAR a[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 };
- WCHAR b[5];
-
- CPPUNIT_ASSERT_EQUAL( (WCHAR*) b, (WCHAR*) winchar_strcpy(b, a) );
- CPPUNIT_ASSERT_EQUAL( 0, memcmp(a, b, 5) );
- }
-
- void testStrNCpy() {
- WCHAR a1[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 };
- WCHAR b[5];
-
- CPPUNIT_ASSERT_EQUAL( (WCHAR*) b, (WCHAR*) winchar_strncpy(b, a1, 5) );
- CPPUNIT_ASSERT_EQUAL( 0, memcmp(a1, b, 5 * sizeof(WCHAR)) );
-
- WCHAR a2[] = { _x('t'), _x('e'), 0, 0, 0 };
-
- CPPUNIT_ASSERT_EQUAL( (WCHAR*) b, (WCHAR*) winchar_strncpy(b, a2, 5) );
- CPPUNIT_ASSERT_EQUAL( 0, memcmp(a2, b, 5 * sizeof(WCHAR)) );
-
- CPPUNIT_ASSERT_EQUAL( (WCHAR*) b, (WCHAR*) winchar_strncpy(b, a1, 2) );
- CPPUNIT_ASSERT_EQUAL( 0, memcmp(a2, b, 5 * sizeof(WCHAR)) );
- }
-
- void testStrLen() {
- WCHAR test[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 };
-
- CPPUNIT_ASSERT_EQUAL( (size_t) 4, winchar_strlen(test) );
- }
-
- static int simplifyNumber(int n) {
- if (n < 0)
- return -1;
- if (n > 0)
- return 1;
- return 0;
- }
-
- void testStrCmp() {
- char a[] = "a";
- WCHAR wa[] = { _x('a'), 0 };
- char b[] = "b";
- WCHAR wb[] = { _x('b'), 0 };
- char empty[] = "";
- WCHAR wempty[] = { 0 };
-
- #define TEST_STR_CMP(x, y) \
- CPPUNIT_ASSERT_EQUAL(\
- simplifyNumber(strcmp(x, y)), \
- simplifyNumber(winchar_strcmp(w##x, w##y)) \
- )
-
- TEST_STR_CMP(a, b);
- TEST_STR_CMP(b, a);
- TEST_STR_CMP(a, a);
- TEST_STR_CMP(b, b);
- TEST_STR_CMP(a, empty);
- TEST_STR_CMP(empty, b);
- TEST_STR_CMP(empty, empty);
- }
-
- void testStrDup() {
- WCHAR a[] = { _x('a'), _x('b'), _x('c'), 0 };
-
- WCHAR *b = winchar_strdup(a);
-
- CPPUNIT_ASSERT_EQUAL( 0, winchar_strcmp(a, b) );
-
- delete [] b;
- }
-
- void testStoi() {
- srand(time(0));
-
- for (int i = 0; i < 1000; i++)
- {
- int r = rand();
- char s[128];
- sprintf(s, "%d", r);
- WCHAR *ws = winchar_fromansi(s);
- CPPUNIT_ASSERT_EQUAL( r, winchar_stoi(ws) );
- delete [] ws;
- }
- }
-
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION( WinCharTest );
+#include <cppunit/extensions/HelperMacros.h>
+#include "../winchar.h"
+
+#include <time.h>
+#include <stdlib.h>
+
+// macro for fixing endianity
+#define _x(x) FIX_ENDIAN_INT16(WCHAR(x))
+
+class WinCharTest : public CppUnit::TestFixture {
+
+ CPPUNIT_TEST_SUITE( WinCharTest );
+ CPPUNIT_TEST( testFromAnsi );
+ CPPUNIT_TEST( testToAnsi );
+ CPPUNIT_TEST( testStrCpy );
+ CPPUNIT_TEST( testStrNCpy );
+ CPPUNIT_TEST( testStrLen );
+ CPPUNIT_TEST( testStrCmp );
+ CPPUNIT_TEST( testStrDup );
+ CPPUNIT_TEST( testStoi );
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testFromAnsi() {
+ WCHAR test[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 };
+ WCHAR *dyn = winchar_fromansi("test");
+
+ CPPUNIT_ASSERT_EQUAL( 0, memcmp(test, dyn, 5) );
+
+ delete [] dyn;
+ }
+
+ void testToAnsi() {
+ WCHAR test[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 };
+ char *dyn = winchar_toansi(test);
+
+ CPPUNIT_ASSERT_EQUAL( 0, strcmp("test", dyn) );
+
+ delete [] dyn;
+ }
+
+ void testStrCpy() {
+ WCHAR a[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 };
+ WCHAR b[5];
+
+ CPPUNIT_ASSERT_EQUAL( (WCHAR*) b, (WCHAR*) winchar_strcpy(b, a) );
+ CPPUNIT_ASSERT_EQUAL( 0, memcmp(a, b, 5) );
+ }
+
+ void testStrNCpy() {
+ WCHAR a1[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 };
+ WCHAR b[5];
+
+ CPPUNIT_ASSERT_EQUAL( (WCHAR*) b, (WCHAR*) winchar_strncpy(b, a1, 5) );
+ CPPUNIT_ASSERT_EQUAL( 0, memcmp(a1, b, 5 * sizeof(WCHAR)) );
+
+ WCHAR a2[] = { _x('t'), _x('e'), 0, 0, 0 };
+
+ CPPUNIT_ASSERT_EQUAL( (WCHAR*) b, (WCHAR*) winchar_strncpy(b, a2, 5) );
+ CPPUNIT_ASSERT_EQUAL( 0, memcmp(a2, b, 5 * sizeof(WCHAR)) );
+
+ CPPUNIT_ASSERT_EQUAL( (WCHAR*) b, (WCHAR*) winchar_strncpy(b, a1, 2) );
+ CPPUNIT_ASSERT_EQUAL( 0, memcmp(a2, b, 5 * sizeof(WCHAR)) );
+ }
+
+ void testStrLen() {
+ WCHAR test[] = { _x('t'), _x('e'), _x('s'), _x('t'), 0 };
+
+ CPPUNIT_ASSERT_EQUAL( (size_t) 4, winchar_strlen(test) );
+ }
+
+ static int simplifyNumber(int n) {
+ if (n < 0)
+ return -1;
+ if (n > 0)
+ return 1;
+ return 0;
+ }
+
+ void testStrCmp() {
+ char a[] = "a";
+ WCHAR wa[] = { _x('a'), 0 };
+ char b[] = "b";
+ WCHAR wb[] = { _x('b'), 0 };
+ char empty[] = "";
+ WCHAR wempty[] = { 0 };
+
+ #define TEST_STR_CMP(x, y) \
+ CPPUNIT_ASSERT_EQUAL(\
+ simplifyNumber(strcmp(x, y)), \
+ simplifyNumber(winchar_strcmp(w##x, w##y)) \
+ )
+
+ TEST_STR_CMP(a, b);
+ TEST_STR_CMP(b, a);
+ TEST_STR_CMP(a, a);
+ TEST_STR_CMP(b, b);
+ TEST_STR_CMP(a, empty);
+ TEST_STR_CMP(empty, b);
+ TEST_STR_CMP(empty, empty);
+ }
+
+ void testStrDup() {
+ WCHAR a[] = { _x('a'), _x('b'), _x('c'), 0 };
+
+ WCHAR *b = winchar_strdup(a);
+
+ CPPUNIT_ASSERT_EQUAL( 0, winchar_strcmp(a, b) );
+
+ delete [] b;
+ }
+
+ void testStoi() {
+ srand(time(0));
+
+ for (int i = 0; i < 1000; i++)
+ {
+ int r = rand();
+ char s[128];
+ sprintf(s, "%d", r);
+ WCHAR *ws = winchar_fromansi(s);
+ CPPUNIT_ASSERT_EQUAL( r, winchar_stoi(ws) );
+ delete [] ws;
+ }
+ }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( WinCharTest );
diff --git a/Source/afxres.h b/Source/afxres.h
index b9e682f..bf6fa63 100755
--- a/Source/afxres.h
+++ b/Source/afxres.h
@@ -1,21 +1,21 @@
-/*
- * afxres.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-
-#ifndef IDC_STATIC
-#define IDC_STATIC -1
-#endif
+/*
+ * afxres.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+
+#ifndef IDC_STATIC
+#define IDC_STATIC -1
+#endif
diff --git a/Source/boost/checked_delete.hpp b/Source/boost/checked_delete.hpp
index adf3991..d7f5212 100755
--- a/Source/boost/checked_delete.hpp
+++ b/Source/boost/checked_delete.hpp
@@ -1,71 +1,71 @@
-#ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
-#define BOOST_CHECKED_DELETE_HPP_INCLUDED
-
-// MS compatible compilers support #pragma once
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-//
-// boost/checked_delete.hpp
-//
-// Copyright (c) 1999, 2000, 2001, 2002 boost.org
-// Copyright (c) 2002, 2003 Peter Dimov
-// Copyright (c) 2003 Daniel Frey
-// Copyright (c) 2003 Howard Hinnant
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-// See http://www.boost.org/libs/utility/checked_delete.html for documentation.
-//
-
-namespace boost
-{
-
-// verify that types are complete for increased safety
-
-template<class T> inline void checked_delete(T * x)
-{
- // intentionally complex - simplification causes regressions
- typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
- (void) sizeof(type_must_be_complete);
- delete x;
-}
-
-template<class T> inline void checked_array_delete(T * x)
-{
- typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
- (void) sizeof(type_must_be_complete);
- delete [] x;
-}
-
-template<class T> struct checked_deleter
-{
- typedef void result_type;
- typedef T * argument_type;
-
- void operator()(T * x) const
- {
- // boost:: disables ADL
- boost::checked_delete(x);
- }
-};
-
-template<class T> struct checked_array_deleter
-{
- typedef void result_type;
- typedef T * argument_type;
-
- void operator()(T * x) const
- {
- boost::checked_array_delete(x);
- }
-};
-
-} // namespace boost
-
-#endif // #ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
+#ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
+#define BOOST_CHECKED_DELETE_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+// boost/checked_delete.hpp
+//
+// Copyright (c) 1999, 2000, 2001, 2002 boost.org
+// Copyright (c) 2002, 2003 Peter Dimov
+// Copyright (c) 2003 Daniel Frey
+// Copyright (c) 2003 Howard Hinnant
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+// See http://www.boost.org/libs/utility/checked_delete.html for documentation.
+//
+
+namespace boost
+{
+
+// verify that types are complete for increased safety
+
+template<class T> inline void checked_delete(T * x)
+{
+ // intentionally complex - simplification causes regressions
+ typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
+ (void) sizeof(type_must_be_complete);
+ delete x;
+}
+
+template<class T> inline void checked_array_delete(T * x)
+{
+ typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
+ (void) sizeof(type_must_be_complete);
+ delete [] x;
+}
+
+template<class T> struct checked_deleter
+{
+ typedef void result_type;
+ typedef T * argument_type;
+
+ void operator()(T * x) const
+ {
+ // boost:: disables ADL
+ boost::checked_delete(x);
+ }
+};
+
+template<class T> struct checked_array_deleter
+{
+ typedef void result_type;
+ typedef T * argument_type;
+
+ void operator()(T * x) const
+ {
+ boost::checked_array_delete(x);
+ }
+};
+
+} // namespace boost
+
+#endif // #ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
diff --git a/Source/boost/detail/workaround.hpp b/Source/boost/detail/workaround.hpp
index 3121928..0d5a2b2 100755
--- a/Source/boost/detail/workaround.hpp
+++ b/Source/boost/detail/workaround.hpp
@@ -1,74 +1,74 @@
-// Copyright David Abrahams 2002. Permission to copy, use,
-// modify, sell and distribute this software is granted provided this
-// copyright notice appears in all copies. This software is provided
-// "as is" without express or implied warranty, and with no claim as
-// to its suitability for any purpose.
-#ifndef WORKAROUND_DWA2002126_HPP
-# define WORKAROUND_DWA2002126_HPP
-
-// Compiler/library version workaround macro
-//
-// Usage:
-//
-// #if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
-// ... // workaround code here
-// #endif
-//
-// When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the
-// first argument must be undefined or expand to a numeric
-// value. The above expands to:
-//
-// (BOOST_MSVC) != 0 && (BOOST_MSVC) <= 1200
-//
-// When used for workarounds that apply to the latest known version
-// and all earlier versions of a compiler, the following convention
-// should be observed:
-//
-// #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301))
-//
-// The version number in this case corresponds to the last version in
-// which the workaround was known to have been required. When
-// BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro
-// BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates
-// the workaround for any version of the compiler. When
-// BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or
-// error will be issued if the compiler version exceeds the argument
-// to BOOST_TESTED_AT(). This can be used to locate workarounds which
-// may be obsoleted by newer versions.
-
-# ifndef BOOST_STRICT_CONFIG
-
-# define BOOST_WORKAROUND(symbol, test) \
- ((symbol != 0) && (1 % (( (symbol test) ) + 1)))
-// ^ ^ ^ ^
-// The extra level of parenthesis nesting above, along with the
-// BOOST_OPEN_PAREN indirection below, is required to satisfy the
-// broken preprocessor in MWCW 8.3 and earlier.
-//
-// The basic mechanism works as follows:
-// (symbol test) + 1 => if (symbol test) then 2 else 1
-// 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0
-//
-// The complication with % is for cooperation with BOOST_TESTED_AT().
-// When "test" is BOOST_TESTED_AT(x) and
-// BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined,
-//
-// symbol test => if (symbol <= x) then 1 else -1
-// (symbol test) + 1 => if (symbol <= x) then 2 else 0
-// 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero
-//
-
-# ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS
-# define BOOST_OPEN_PAREN (
-# define BOOST_TESTED_AT(value) > value) ?(-1): BOOST_OPEN_PAREN 1
-# else
-# define BOOST_TESTED_AT(value) != ((value)-(value))
-# endif
-
-# else
-
-# define BOOST_WORKAROUND(symbol, test) 0
-
-# endif
-
-#endif // WORKAROUND_DWA2002126_HPP
+// Copyright David Abrahams 2002. Permission to copy, use,
+// modify, sell and distribute this software is granted provided this
+// copyright notice appears in all copies. This software is provided
+// "as is" without express or implied warranty, and with no claim as
+// to its suitability for any purpose.
+#ifndef WORKAROUND_DWA2002126_HPP
+# define WORKAROUND_DWA2002126_HPP
+
+// Compiler/library version workaround macro
+//
+// Usage:
+//
+// #if BOOST_WORKAROUND(BOOST_MSVC, <= 1200)
+// ... // workaround code here
+// #endif
+//
+// When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the
+// first argument must be undefined or expand to a numeric
+// value. The above expands to:
+//
+// (BOOST_MSVC) != 0 && (BOOST_MSVC) <= 1200
+//
+// When used for workarounds that apply to the latest known version
+// and all earlier versions of a compiler, the following convention
+// should be observed:
+//
+// #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301))
+//
+// The version number in this case corresponds to the last version in
+// which the workaround was known to have been required. When
+// BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro
+// BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates
+// the workaround for any version of the compiler. When
+// BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or
+// error will be issued if the compiler version exceeds the argument
+// to BOOST_TESTED_AT(). This can be used to locate workarounds which
+// may be obsoleted by newer versions.
+
+# ifndef BOOST_STRICT_CONFIG
+
+# define BOOST_WORKAROUND(symbol, test) \
+ ((symbol != 0) && (1 % (( (symbol test) ) + 1)))
+// ^ ^ ^ ^
+// The extra level of parenthesis nesting above, along with the
+// BOOST_OPEN_PAREN indirection below, is required to satisfy the
+// broken preprocessor in MWCW 8.3 and earlier.
+//
+// The basic mechanism works as follows:
+// (symbol test) + 1 => if (symbol test) then 2 else 1
+// 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0
+//
+// The complication with % is for cooperation with BOOST_TESTED_AT().
+// When "test" is BOOST_TESTED_AT(x) and
+// BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined,
+//
+// symbol test => if (symbol <= x) then 1 else -1
+// (symbol test) + 1 => if (symbol <= x) then 2 else 0
+// 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero
+//
+
+# ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS
+# define BOOST_OPEN_PAREN (
+# define BOOST_TESTED_AT(value) > value) ?(-1): BOOST_OPEN_PAREN 1
+# else
+# define BOOST_TESTED_AT(value) != ((value)-(value))
+# endif
+
+# else
+
+# define BOOST_WORKAROUND(symbol, test) 0
+
+# endif
+
+#endif // WORKAROUND_DWA2002126_HPP
diff --git a/Source/boost/scoped_array.hpp b/Source/boost/scoped_array.hpp
index eb61ad7..e217bae 100755
--- a/Source/boost/scoped_array.hpp
+++ b/Source/boost/scoped_array.hpp
@@ -1,122 +1,122 @@
-#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
-#define BOOST_SCOPED_ARRAY_HPP_INCLUDED
-
-// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
-// Copyright (c) 2001, 2002 Peter Dimov
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-// http://www.boost.org/libs/smart_ptr/scoped_array.htm
-//
-
-
-// From Boost 1.31.0, http://www.boost.org
-// Modified by Ori Peleg for use in NSIS, to reduce the required Boost includes
-
-#include "checked_delete.hpp"
-#include "detail/workaround.hpp"
-
-#include <cstddef> // for std::ptrdiff_t
-
-namespace boost
-{
-
-// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
-// is guaranteed, either on destruction of the scoped_array or via an explicit
-// reset(). Use shared_array or std::vector if your needs are more complex.
-
-template<class T> class scoped_array // noncopyable
-{
-private:
-
- T * ptr;
-
- scoped_array(scoped_array const &);
- scoped_array & operator=(scoped_array const &);
-
- typedef scoped_array<T> this_type;
-
-public:
-
- typedef T element_type;
-
- explicit scoped_array(T * p = 0) : ptr(p) // never throws
- {
- }
-
- ~scoped_array() // never throws
- {
- boost::checked_array_delete(ptr);
- }
-
- void reset(T * p = 0) // never throws
- {
- assert(p == 0 || p != ptr); // catch self-reset errors
- this_type(p).swap(*this);
- }
-
- T & operator[](std::ptrdiff_t i) const // never throws
- {
- assert(ptr != 0);
- assert(i >= 0);
- return ptr[i];
- }
-
- T * get() const // never throws
- {
- return ptr;
- }
-
- // implicit conversion to "bool"
-
-#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
-
- operator bool () const
- {
- return ptr != 0;
- }
-
-#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
- typedef T * (this_type::*unspecified_bool_type)() const;
-
- operator unspecified_bool_type() const // never throws
- {
- return ptr == 0? 0: &this_type::get;
- }
-
-#else
-
- typedef T * this_type::*unspecified_bool_type;
-
- operator unspecified_bool_type() const // never throws
- {
- return ptr == 0? 0: &this_type::ptr;
- }
-
-#endif
-
- bool operator! () const // never throws
- {
- return ptr == 0;
- }
-
- void swap(scoped_array & b) // never throws
- {
- T * tmp = b.ptr;
- b.ptr = ptr;
- ptr = tmp;
- }
-
-};
-
-template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws
-{
- a.swap(b);
-}
-
-} // namespace boost
-
-#endif // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
+#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
+#define BOOST_SCOPED_ARRAY_HPP_INCLUDED
+
+// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
+// Copyright (c) 2001, 2002 Peter Dimov
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+// http://www.boost.org/libs/smart_ptr/scoped_array.htm
+//
+
+
+// From Boost 1.31.0, http://www.boost.org
+// Modified by Ori Peleg for use in NSIS, to reduce the required Boost includes
+
+#include "checked_delete.hpp"
+#include "detail/workaround.hpp"
+
+#include <cstddef> // for std::ptrdiff_t
+
+namespace boost
+{
+
+// scoped_array extends scoped_ptr to arrays. Deletion of the array pointed to
+// is guaranteed, either on destruction of the scoped_array or via an explicit
+// reset(). Use shared_array or std::vector if your needs are more complex.
+
+template<class T> class scoped_array // noncopyable
+{
+private:
+
+ T * ptr;
+
+ scoped_array(scoped_array const &);
+ scoped_array & operator=(scoped_array const &);
+
+ typedef scoped_array<T> this_type;
+
+public:
+
+ typedef T element_type;
+
+ explicit scoped_array(T * p = 0) : ptr(p) // never throws
+ {
+ }
+
+ ~scoped_array() // never throws
+ {
+ boost::checked_array_delete(ptr);
+ }
+
+ void reset(T * p = 0) // never throws
+ {
+ assert(p == 0 || p != ptr); // catch self-reset errors
+ this_type(p).swap(*this);
+ }
+
+ T & operator[](std::ptrdiff_t i) const // never throws
+ {
+ assert(ptr != 0);
+ assert(i >= 0);
+ return ptr[i];
+ }
+
+ T * get() const // never throws
+ {
+ return ptr;
+ }
+
+ // implicit conversion to "bool"
+
+#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
+
+ operator bool () const
+ {
+ return ptr != 0;
+ }
+
+#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
+ typedef T * (this_type::*unspecified_bool_type)() const;
+
+ operator unspecified_bool_type() const // never throws
+ {
+ return ptr == 0? 0: &this_type::get;
+ }
+
+#else
+
+ typedef T * this_type::*unspecified_bool_type;
+
+ operator unspecified_bool_type() const // never throws
+ {
+ return ptr == 0? 0: &this_type::ptr;
+ }
+
+#endif
+
+ bool operator! () const // never throws
+ {
+ return ptr == 0;
+ }
+
+ void swap(scoped_array & b) // never throws
+ {
+ T * tmp = b.ptr;
+ b.ptr = ptr;
+ ptr = tmp;
+ }
+
+};
+
+template<class T> inline void swap(scoped_array<T> & a, scoped_array<T> & b) // never throws
+{
+ a.swap(b);
+}
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
diff --git a/Source/boost/scoped_ptr.hpp b/Source/boost/scoped_ptr.hpp
index eb00c6b..836c197 100755
--- a/Source/boost/scoped_ptr.hpp
+++ b/Source/boost/scoped_ptr.hpp
@@ -1,137 +1,137 @@
-#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
-#define BOOST_SCOPED_PTR_HPP_INCLUDED
-
-// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
-// Copyright (c) 2001, 2002 Peter Dimov
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
-//
-
-// From Boost 1.31.0, http://www.boost.org
-// Modified by Ori Peleg for use in NSIS, to reduce the required Boost includes
-
-#include <cassert>
-#include "checked_delete.hpp"
-#include "detail/workaround.hpp"
-
-#include <memory> // for std::auto_ptr
-
-namespace boost
-{
-
-// scoped_ptr mimics a built-in pointer except that it guarantees deletion
-// of the object pointed to, either on destruction of the scoped_ptr or via
-// an explicit reset(). scoped_ptr is a simple solution for simple needs;
-// use shared_ptr or std::auto_ptr if your needs are more complex.
-
-template<class T> class scoped_ptr // noncopyable
-{
-private:
-
- T * ptr;
-
- scoped_ptr(scoped_ptr const &);
- scoped_ptr & operator=(scoped_ptr const &);
-
- typedef scoped_ptr<T> this_type;
-
-public:
-
- typedef T element_type;
-
- explicit scoped_ptr(T * p = 0): ptr(p) // never throws
- {
- }
-
- explicit scoped_ptr(std::auto_ptr<T> p): ptr(p.release()) // never throws
- {
- }
-
- ~scoped_ptr() // never throws
- {
- boost::checked_delete(ptr);
- }
-
- void reset(T * p = 0) // never throws
- {
- assert(p == 0 || p != ptr); // catch self-reset errors
- this_type(p).swap(*this);
- }
-
- T & operator*() const // never throws
- {
- assert(ptr != 0);
- return *ptr;
- }
-
- T * operator->() const // never throws
- {
- assert(ptr != 0);
- return ptr;
- }
-
- T * get() const // never throws
- {
- return ptr;
- }
-
- // implicit conversion to "bool"
-
-#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
-
- operator bool () const
- {
- return ptr != 0;
- }
-
-#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
- typedef T * (this_type::*unspecified_bool_type)() const;
-
- operator unspecified_bool_type() const // never throws
- {
- return ptr == 0? 0: &this_type::get;
- }
-
-#else
- typedef T * this_type::*unspecified_bool_type;
-
- operator unspecified_bool_type() const // never throws
- {
- return ptr == 0? 0: &this_type::ptr;
- }
-
-#endif
-
- bool operator! () const // never throws
- {
- return ptr == 0;
- }
-
- void swap(scoped_ptr & b) // never throws
- {
- T * tmp = b.ptr;
- b.ptr = ptr;
- ptr = tmp;
- }
-};
-
-template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) // never throws
-{
- a.swap(b);
-}
-
-// get_pointer(p) is a generic way to say p.get()
-
-template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
-{
- return p.get();
-}
-
-} // namespace boost
-
-#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
+#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
+#define BOOST_SCOPED_PTR_HPP_INCLUDED
+
+// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
+// Copyright (c) 2001, 2002 Peter Dimov
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+// http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
+//
+
+// From Boost 1.31.0, http://www.boost.org
+// Modified by Ori Peleg for use in NSIS, to reduce the required Boost includes
+
+#include <cassert>
+#include "checked_delete.hpp"
+#include "detail/workaround.hpp"
+
+#include <memory> // for std::auto_ptr
+
+namespace boost
+{
+
+// scoped_ptr mimics a built-in pointer except that it guarantees deletion
+// of the object pointed to, either on destruction of the scoped_ptr or via
+// an explicit reset(). scoped_ptr is a simple solution for simple needs;
+// use shared_ptr or std::auto_ptr if your needs are more complex.
+
+template<class T> class scoped_ptr // noncopyable
+{
+private:
+
+ T * ptr;
+
+ scoped_ptr(scoped_ptr const &);
+ scoped_ptr & operator=(scoped_ptr const &);
+
+ typedef scoped_ptr<T> this_type;
+
+public:
+
+ typedef T element_type;
+
+ explicit scoped_ptr(T * p = 0): ptr(p) // never throws
+ {
+ }
+
+ explicit scoped_ptr(std::auto_ptr<T> p): ptr(p.release()) // never throws
+ {
+ }
+
+ ~scoped_ptr() // never throws
+ {
+ boost::checked_delete(ptr);
+ }
+
+ void reset(T * p = 0) // never throws
+ {
+ assert(p == 0 || p != ptr); // catch self-reset errors
+ this_type(p).swap(*this);
+ }
+
+ T & operator*() const // never throws
+ {
+ assert(ptr != 0);
+ return *ptr;
+ }
+
+ T * operator->() const // never throws
+ {
+ assert(ptr != 0);
+ return ptr;
+ }
+
+ T * get() const // never throws
+ {
+ return ptr;
+ }
+
+ // implicit conversion to "bool"
+
+#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
+
+ operator bool () const
+ {
+ return ptr != 0;
+ }
+
+#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
+ typedef T * (this_type::*unspecified_bool_type)() const;
+
+ operator unspecified_bool_type() const // never throws
+ {
+ return ptr == 0? 0: &this_type::get;
+ }
+
+#else
+ typedef T * this_type::*unspecified_bool_type;
+
+ operator unspecified_bool_type() const // never throws
+ {
+ return ptr == 0? 0: &this_type::ptr;
+ }
+
+#endif
+
+ bool operator! () const // never throws
+ {
+ return ptr == 0;
+ }
+
+ void swap(scoped_ptr & b) // never throws
+ {
+ T * tmp = b.ptr;
+ b.ptr = ptr;
+ ptr = tmp;
+ }
+};
+
+template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) // never throws
+{
+ a.swap(b);
+}
+
+// get_pointer(p) is a generic way to say p.get()
+
+template<class T> inline T * get_pointer(scoped_ptr<T> const & p)
+{
+ return p.get();
+}
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
diff --git a/Source/build.cpp b/Source/build.cpp
index b9caba1..f512f65 100755
--- a/Source/build.cpp
+++ b/Source/build.cpp
@@ -1,3471 +1,3491 @@
-/*
- * build.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-#include <stdio.h>
-#include "exehead/config.h"
-
-#include "version.h"
-
-#include "build.h"
-#include "util.h"
-#include "fileform.h"
-#include "writer.h"
-#include "crc32.h"
-#include "manifest.h"
-
-#include <stdexcept>
-
-#include "exehead/resource.h"
-#include "ResourceEditor.h"
-#include "DialogTemplate.h"
-#include "ResourceVersionInfo.h"
-
-#ifndef _WIN32
-# include <locale.h>
-# include <unistd.h>
-# include <limits.h>
-# include <stdlib.h>
-# include <stdarg.h>
-#endif
-
-#include <cassert> // for assert
-
-#define RET_UNLESS_OK( function_rc ) do { \
- int rc = (function_rc); \
- if ( rc != PS_OK) \
- return rc; \
-} while (false)
-
-using namespace std;
-
-namespace { // begin anonymous namespace
-
-bool isSimpleChar(char ch)
-{
- return (ch == '.' ) || (ch == '_' ) || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
-}
-
-} // end of anonymous namespace
-
-void CEXEBuild::define(const char *p, const char *v)
-{
- definedlist.add(p,v);
-}
-
-CEXEBuild::~CEXEBuild()
-{
- free(m_unicon_data);
-
- delete [] m_exehead;
-
- int nlt = lang_tables.getlen() / sizeof(LanguageTable);
- LanguageTable *nla = (LanguageTable*)lang_tables.get();
-
- for (int i = 0; i < nlt; i++) {
- DeleteLangTable(nla+i);
- }
-}
-
-CEXEBuild::CEXEBuild() :
- m_exehead(0),
- m_exehead_size(0)
-{
- linecnt = 0;
- fp = 0;
- curfilename = 0;
-
- display_info=1;
- display_script=1;
- display_errors=1;
- display_warnings=1;
-
- cur_ifblock=NULL;
- last_line_had_slash=0;
- inside_comment=false;
- multiple_entries_instruction=0;
-
- build_include_depth=0;
-
- has_called_write_output=false;
-
- ns_func.add("",0); // make sure offset 0 is special on these (i.e. never used by a label)
- ns_label.add("",0);
-
- definedlist.add("NSIS_VERSION", NSIS_VERSION);
-
- // automatically generated header file containing all defines
-#include "defines.h"
-
- // no longer optional
- definedlist.add("NSIS_SUPPORT_STANDARD_PREDEFINES");
- definedlist.add("NSIS_SUPPORT_NAMED_USERVARS");
- definedlist.add("NSIS_SUPPORT_LANG_IN_STRINGS");
-
-#ifdef _WIN32
- definedlist.add("NSIS_WIN32_MAKENSIS");
-#endif
-
- db_opt_save=db_comp_save=db_full_size=db_opt_save_u=db_comp_save_u=db_full_size_u=0;
-
- // Added by Amir Szekely 31st July 2002
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- compressor = &zlib_compressor;
-#endif
- build_compressor_set = false;
- build_compressor_final = false;
-#ifdef NSIS_ZLIB_COMPRESS_WHOLE
- build_compress_whole = true;
-#else
- build_compress_whole = false;
-#endif
- build_compress=1;
- build_compress_level=9;
- build_compress_dict_size=1<<23;
-
- cur_entries=&build_entries;
- cur_instruction_entry_map=&build_instruction_entry_map;
- cur_datablock=&build_datablock;
- cur_datablock_cache=&build_datablock_cache;
- cur_functions=&build_functions;
- cur_labels=&build_labels;
- cur_sections=&build_sections;
- cur_header=&build_header;
- cur_strlist=&build_strlist;
- cur_langtables=&build_langtables;
- cur_ctlcolors=&build_ctlcolors;
- cur_pages=&build_pages;
- cur_page=0;
- cur_page_type=-1;
-
- build_filebuflen=32<<20; // 32mb
-
- sectiongroup_open_cnt=0;
- build_cursection_isfunc=0;
- build_cursection=NULL;
- // init public data.
- build_packname[0]=build_packcmd[0]=build_output_filename[0]=0;
-
- // Added by ramon 23 May 2003
- build_allowskipfiles=1;
-
- // Added by ramon 6 jun 2003
-#ifdef NSIS_SUPPORT_VERSION_INFO
- version_product_v[0]=0;
-#endif
-
- build_overwrite=build_last_overwrite=0;
- build_crcchk=1;
- build_datesave=1;
- build_optimize_datablock=1;
-
- memset(&build_header,-1,sizeof(build_header));
-
- build_header.install_reg_rootkey=0;
- build_header.flags=CH_FLAGS_NO_ROOT_DIR;
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- build_header.lb_bg=RGB(0,0,0);
- build_header.lb_fg=RGB(0,255,0);
-#endif
-#ifdef NSIS_CONFIG_LICENSEPAGE
- build_header.license_bg=-COLOR_BTNFACE;
-#endif
- build_header.install_directory_ptr=0;
- build_header.install_directory_auto_append=0;
- build_header.install_reg_key_ptr=0;
- build_header.install_reg_value_ptr=0;
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- memset(build_header.install_types,0,sizeof(build_header.install_types));
-#endif
- memset(&build_header.blocks,0,sizeof(build_header.blocks));
-
- uninstall_mode=0;
- uninstall_size_full=0;
- uninstall_size=-1;
-
- memset(&build_uninst,-1,sizeof(build_uninst));
-
- build_header.install_reg_rootkey=0;
- build_uninst.flags=0;
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- build_uninst.lb_bg=RGB(0,0,0);
- build_uninst.lb_fg=RGB(0,255,0);
-#endif
-#ifdef NSIS_CONFIG_LICENSEPAGE
- build_uninst.license_bg=-COLOR_BTNFACE;
-#endif
- build_uninst.install_directory_ptr=0;
- build_uninst.install_directory_auto_append=0;
- build_uninst.install_reg_key_ptr=0;
- build_uninst.install_reg_value_ptr=0;
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- memset(build_uninst.install_types,0,sizeof(build_uninst.install_types));
-#endif
- memset(&build_uninst.blocks,0,sizeof(build_uninst.blocks));
-
- uninstaller_writes_used=0;
-
- build_strlist.add("",0);
- ubuild_strlist.add("",0);
-
- build_langstring_num=0;
- ubuild_langstring_num=0;
-
- build_font[0]=0;
- build_font_size=0;
-
- m_unicon_data=NULL;
- m_unicon_size=0;
-
- branding_image_found=false;
-
- no_space_texts=false;
-
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
- build_plugin_unload=0;
- plugins_processed=0;
-#endif
-
- last_used_lang=NSIS_DEFAULT_LANG;
-
- res_editor=0;
-
- manifest_comctl = manifest::comctl_old;
- manifest_exec_level = manifest::exec_level_none;
-
- enable_last_page_cancel=0;
- uenable_last_page_cancel=0;
-
- license_res_id=IDD_LICENSE;
-
- disable_window_icon=0;
-
- notify_hwnd=0;
-
-#ifdef NSIS_SUPPORT_BGBG
- bg_default_font.lfHeight=40;
- bg_default_font.lfWidth=0;
- bg_default_font.lfEscapement=0;
- bg_default_font.lfOrientation=0;
- bg_default_font.lfWeight=FW_BOLD;
- bg_default_font.lfItalic=TRUE;
- bg_default_font.lfUnderline=FALSE;
- bg_default_font.lfStrikeOut=FALSE;
- bg_default_font.lfCharSet=DEFAULT_CHARSET;
- bg_default_font.lfOutPrecision=OUT_DEFAULT_PRECIS;
- bg_default_font.lfClipPrecision=CLIP_DEFAULT_PRECIS;
- bg_default_font.lfQuality=DEFAULT_QUALITY;
- bg_default_font.lfPitchAndFamily=DEFAULT_PITCH;
- strncpy(bg_default_font.lfFaceName,"Times New Roman",LF_FACESIZE);
- memcpy(&bg_font,&bg_default_font,sizeof(LOGFONT));
-#endif
-
- defcodepage_set=false;
- uDefCodePage=CP_ACP;
-
- InitLangTables();
-
- // Register static user variables $0, $1 and so on
- // with ONE of reference count, to avoid warning on this vars
- char Aux[3];
- int i;
- for (i = 0; i < 10; i++) // 0 - 9
- {
- sprintf(Aux, "%d", i);
- m_UserVarNames.add(Aux,1);
- }
- for (i = 0; i < 10; i++) // 10 - 19
- {
- sprintf(Aux, "R%d", i);
- m_UserVarNames.add(Aux,1);
- }
- m_UserVarNames.add("CMDLINE",1); // 20 everything before here doesn't have trailing slash removal
- m_UserVarNames.add("INSTDIR",1); // 21
- m_UserVarNames.add("OUTDIR",1); // 22
- m_UserVarNames.add("EXEDIR",1); // 23
- m_UserVarNames.add("LANGUAGE",1); // 24
- m_UserVarNames.add("TEMP",-1); // 25
- m_UserVarNames.add("PLUGINSDIR",-1); // 26
- m_UserVarNames.add("EXEPATH",-1); // 27
- m_UserVarNames.add("EXEFILE",-1); // 28
- m_UserVarNames.add("HWNDPARENT",-1); // 29
- m_UserVarNames.add("_CLICK",-1); // 30
- m_UserVarNames.add("_OUTDIR",1); // 31
-
- m_iBaseVarsNum = m_UserVarNames.getnum();
-
- m_ShellConstants.add("WINDIR",CSIDL_WINDOWS,CSIDL_WINDOWS);
- m_ShellConstants.add("SYSDIR",CSIDL_SYSTEM,CSIDL_SYSTEM);
- m_ShellConstants.add("SMPROGRAMS",CSIDL_PROGRAMS, CSIDL_COMMON_PROGRAMS);
- m_ShellConstants.add("SMSTARTUP",CSIDL_STARTUP, CSIDL_COMMON_STARTUP);
- m_ShellConstants.add("DESKTOP",CSIDL_DESKTOPDIRECTORY, CSIDL_COMMON_DESKTOPDIRECTORY);
- m_ShellConstants.add("STARTMENU",CSIDL_STARTMENU, CSIDL_COMMON_STARTMENU);
- m_ShellConstants.add("QUICKLAUNCH", CSIDL_APPDATA, CSIDL_APPDATA);
- m_ShellConstants.add("DOCUMENTS",CSIDL_PERSONAL, CSIDL_COMMON_DOCUMENTS);
- m_ShellConstants.add("SENDTO",CSIDL_SENDTO, CSIDL_SENDTO);
- m_ShellConstants.add("RECENT",CSIDL_RECENT, CSIDL_RECENT);
- m_ShellConstants.add("FAVORITES",CSIDL_FAVORITES, CSIDL_COMMON_FAVORITES);
- m_ShellConstants.add("MUSIC",CSIDL_MYMUSIC, CSIDL_COMMON_MUSIC);
- m_ShellConstants.add("PICTURES",CSIDL_MYPICTURES, CSIDL_COMMON_PICTURES);
- m_ShellConstants.add("VIDEOS",CSIDL_MYVIDEO, CSIDL_COMMON_VIDEO);
- m_ShellConstants.add("NETHOOD", CSIDL_NETHOOD, CSIDL_NETHOOD);
- m_ShellConstants.add("FONTS", CSIDL_FONTS, CSIDL_FONTS);
- m_ShellConstants.add("TEMPLATES", CSIDL_TEMPLATES, CSIDL_COMMON_TEMPLATES);
- m_ShellConstants.add("APPDATA", CSIDL_APPDATA, CSIDL_COMMON_APPDATA);
- m_ShellConstants.add("LOCALAPPDATA", CSIDL_LOCAL_APPDATA, CSIDL_LOCAL_APPDATA);
- m_ShellConstants.add("PRINTHOOD", CSIDL_PRINTHOOD, CSIDL_PRINTHOOD);
- //m_ShellConstants.add("ALTSTARTUP", CSIDL_ALTSTARTUP, CSIDL_COMMON_ALTSTARTUP);
- m_ShellConstants.add("INTERNET_CACHE", CSIDL_INTERNET_CACHE, CSIDL_INTERNET_CACHE);
- m_ShellConstants.add("COOKIES", CSIDL_COOKIES, CSIDL_COOKIES);
- m_ShellConstants.add("HISTORY", CSIDL_HISTORY, CSIDL_HISTORY);
- m_ShellConstants.add("PROFILE", CSIDL_PROFILE, CSIDL_PROFILE);
- m_ShellConstants.add("ADMINTOOLS", CSIDL_ADMINTOOLS, CSIDL_COMMON_ADMINTOOLS);
- m_ShellConstants.add("RESOURCES", CSIDL_RESOURCES, CSIDL_RESOURCES);
- m_ShellConstants.add("RESOURCES_LOCALIZED", CSIDL_RESOURCES_LOCALIZED, CSIDL_RESOURCES_LOCALIZED);
- m_ShellConstants.add("CDBURN_AREA", CSIDL_CDBURN_AREA, CSIDL_CDBURN_AREA);
-
- unsigned int program_files = add_string("ProgramFilesDir", 0);
- unsigned int program_files_def = add_string("C:\\Program Files");
-
- if ((program_files >= 0x40) || (program_files_def >= 0xFF))
- {
- // see Source\exehead\util.c for implementation details
- // basically, it knows it needs to get folders from the registry when the 0x80 is on
- ERROR_MSG("Internal compiler error: too many strings added to strings block before adding shell constants!\n");
- throw out_of_range("Internal compiler error: too many strings added to strings block before adding shell constants!");
- }
-
- m_ShellConstants.add("PROGRAMFILES", 0x80 | program_files, program_files_def);
- m_ShellConstants.add("PROGRAMFILES32", 0x80 | program_files, program_files_def);
- m_ShellConstants.add("PROGRAMFILES64", 0xC0 | program_files, program_files_def);
-
- unsigned int common_files = add_string("CommonFilesDir", 0);
- unsigned int common_files_def = add_string("$PROGRAMFILES\\Common Files");
-
- if ((common_files > 0x40) || (common_files_def > 0xFF))
- {
- ERROR_MSG("Internal compiler error: too many strings added to strings block before adding shell constants!\n");
- throw out_of_range("Internal compiler error: too many strings added to strings block before adding shell constants!");
- }
-
- m_ShellConstants.add("COMMONFILES", 0x80 | common_files, common_files_def);
- m_ShellConstants.add("COMMONFILES32", 0x80 | common_files, common_files_def);
- m_ShellConstants.add("COMMONFILES64", 0xC0 | common_files, common_files_def);
-
- set_uninstall_mode(1);
-
- unsigned int uprogram_files = add_string("ProgramFilesDir", 0);
- unsigned int uprogram_files_def = add_string("C:\\Program Files");
- unsigned int ucommon_files = add_string("CommonFilesDir", 0);
- unsigned int ucommon_files_def = add_string("$PROGRAMFILES\\Common Files");
-
- if (uprogram_files != program_files
- || uprogram_files_def != program_files_def
- || ucommon_files != common_files
- || ucommon_files_def != common_files_def)
- {
- ERROR_MSG("Internal compiler error: installer's shell constants are different than uninstallers!\n");
- throw out_of_range("Internal compiler error: installer's shell constants are different than uninstallers!");
- }
-
- set_uninstall_mode(0);
-
- set_code_type_predefines();
-}
-
-void CEXEBuild::initialize(const char *makensis_path)
-{
- string nsis_dir;
- const char *dir = getenv("NSISDIR");
- if (dir) nsis_dir = dir;
- else {
-#ifndef NSIS_CONFIG_CONST_DATA_PATH
- nsis_dir = get_executable_dir(makensis_path);
-#else
- nsis_dir = PREFIX_DATA;
-#endif
- }
- definedlist.add("NSISDIR", nsis_dir.c_str());
-
- string includes_dir = nsis_dir;
- includes_dir += PLATFORM_PATH_SEPARATOR_STR"Include";
- include_dirs.add(includes_dir.c_str(),0);
-
- stubs_dir = nsis_dir;
- stubs_dir += PLATFORM_PATH_SEPARATOR_STR"Stubs";
-
- if (set_compressor("zlib", false) != PS_OK)
- {
- throw runtime_error("error setting default stub");
- }
-
- string uninst = stubs_dir + PLATFORM_PATH_SEPARATOR_STR + "uninst";
- m_unicon_data = generate_uninstall_icon_data(uninst.c_str(), m_unicon_size);
- if (!m_unicon_data)
- {
- throw runtime_error("invalid default uninstall icon");
- }
-}
-
-
-int CEXEBuild::getcurdbsize() { return cur_datablock->getlen(); }
-
-// returns offset in stringblock
-int CEXEBuild::add_string(const char *string, int process/*=1*/, WORD codepage/*=CP_ACP*/)
-{
- if (!string || !*string) return 0;
-
- if (*string == '$' && *(string+1) == '(') {
- int idx = 0;
- char *cp = strdup(string+2);
- char *p = strchr(cp, ')');
- if (p && p[1] == '\0' ) { // if string is only a language str identifier
- *p = 0;
- idx = DefineLangString(cp, process);
- }
- free(cp);
- if (idx < 0) return idx;
- }
-
- if (!process) return cur_strlist->add(string,2);
-
- char buf[NSIS_MAX_STRLEN*4];
- preprocess_string(buf,string,codepage);
- return cur_strlist->add(buf,2);
-}
-
-int CEXEBuild::add_intstring(const int i) // returns offset in stringblock
-{
- char i_str[1024];
- wsprintf(i_str, "%d", i);
- return add_string(i_str);
-}
-
-// based on Dave Laundon's code
-int CEXEBuild::preprocess_string(char *out, const char *in, WORD codepage/*=CP_ACP*/)
-{
- const char *p=in;
- while (*p)
- {
- const char *np = CharNextExA(codepage, p, 0);
- if (np - p > 1) // multibyte char
- {
- int l = np - p;
- while (l--)
- {
- unsigned char i = (unsigned char)*p++;
- if (i >= NS_CODES_START) {
- *out++ = (char)NS_SKIP_CODE;
- }
- *out++=(char)i;
- }
- continue;
- }
-
- unsigned char i = (unsigned char)*p;
-
- p=np;
-
- // Test for characters extending into the variable codes
- if (i >= NS_CODES_START) {
- *out++ = (char)NS_SKIP_CODE;
- }
- else if (i == '$')
- {
- if (*p == '$')
- p++; // Can simply convert $$ to $ now
- else
- {
- {
- bool bProceced=false;
- if ( *p )
- {
- const char *pUserVarName = p;
- while (isSimpleChar(*pUserVarName))
- pUserVarName++;
-
- while (pUserVarName > p)
- {
- if (m_ShellConstants.get((char*)p, pUserVarName-p) >= 0)
- break; // Upps it's a shell constant
-
- int idxUserVar = m_UserVarNames.get((char*)p, pUserVarName-p);
- if (idxUserVar >= 0)
- {
- // Well, using variables inside string formating doens't mean
- // using the variable, beacuse it will be always an empty string
- // which is also memory wasting
- // So the line below must be commented !??
- //m_UserVarNames.inc_reference(idxUserVar);
- *out++ = (char) NS_VAR_CODE; // Named user variable;
- WORD w = FIX_ENDIAN_INT16(CODE_SHORT(idxUserVar));
- memcpy(out, &w, sizeof(WORD));
- out += sizeof(WORD);
- p += pUserVarName-p;
- bProceced = true;
- break;
- }
- pUserVarName--;
- }
- }
- if (!bProceced && *p)
- {
- const char *pShellConstName = p;
- while (isSimpleChar(*pShellConstName))
- pShellConstName++;
-
- while (pShellConstName > p)
- {
- int idxConst = m_ShellConstants.get((char*)p, pShellConstName - p);
- if (idxConst >= 0)
- {
- int CSIDL_Value_current = m_ShellConstants.get_value1(idxConst);
- int CSIDL_Value_all = m_ShellConstants.get_value2(idxConst);
- *out++=(char)NS_SHELL_CODE; // Constant code identifier
- *out++=(char)CSIDL_Value_current;
- *out++=(char)CSIDL_Value_all;
- p = pShellConstName;
- bProceced = true;
- break;
- }
- pShellConstName--;
- }
- }
- if ( !bProceced && *p == '(' )
- {
- int idx = -1;
- char *cp = strdup(p+1);
- char *pos = strchr(cp, ')');
- if (pos)
- {
- *pos = 0;
- idx = DefineLangString(cp);
- if (idx < 0)
- {
- *out++ = (char)NS_LANG_CODE; // Next word is lang-string Identifier
- WORD w = FIX_ENDIAN_INT16(CODE_SHORT(-idx-1));
- memcpy(out, &w, sizeof(WORD));
- out += sizeof(WORD);
- p += strlen(cp) + 2;
- bProceced = true;
- }
- }
- free(cp);
- }
- if ( bProceced )
- continue;
- else
- {
- char tbuf[64];
- char cBracket = '\0';
- bool bDoWarning = true;
-
- if ( *p == '[' )
- cBracket = ']';
- else if ( *p == '(' )
- cBracket = ')';
- else if ( *p == '{' )
- cBracket = '}';
-
- strncpy(tbuf,p,63);
- tbuf[63]=0;
-
- if ( cBracket != 0 )
- {
- if (strchr(tbuf,cBracket)) (strchr(tbuf,cBracket)+1)[0]=0;
- if ( tbuf[0] == '{' && tbuf[strlen(tbuf)-1] == '}' )
- {
- char *tstIfDefine = strdup(tbuf+1);
- tstIfDefine[strlen(tstIfDefine)-1] = '\0';
- bDoWarning = definedlist.find(tstIfDefine) == NULL;
- }
- }
- else
- {
- if (strstr(tbuf," ")) strstr(tbuf," ")[0]=0;
- }
- if ( bDoWarning )
- warning_fl("unknown variable/constant \"%s\" detected, ignoring",tbuf);
- i = '$';
- }
- }
- }
- }
- *out++=(char)i;
- }
- *out=0;
- return 0;
-}
-
-// what it does is, when you pass it the offset of the last item added, it will determine if
-// that data is already present in the datablock, and if so, reference it instead (and shorten
-// the datablock as necessary). Reduces overhead if you want to add files to a couple places.
-// Woo, an optimizing installer generator, now we're styling.
-
-int CEXEBuild::datablock_optimize(int start_offset, int first_int)
-{
- int this_len = cur_datablock->getlen() - start_offset;
-
- cached_db_size this_size = {first_int, start_offset};
- cur_datablock_cache->add(&this_size, sizeof(cached_db_size));
-
- if (!build_optimize_datablock || this_len < (int) sizeof(int))
- return start_offset;
-
- MMapBuf *db = (MMapBuf *) cur_datablock;
- db->setro(TRUE);
-
- cached_db_size *db_sizes = (cached_db_size *) cur_datablock_cache->get();
- int db_sizes_num = cur_datablock_cache->getlen() / sizeof(cached_db_size);
- db_sizes_num--; // don't compare with the one we just added
-
- for (int i = 0; i < db_sizes_num; i++)
- {
- if (db_sizes[i].first_int == first_int)
- {
- int pos = db_sizes[i].start_offset;
- int left = this_len;
- while (left > 0)
- {
- int l = min(left, build_filebuflen);
- void *newstuff = db->get(start_offset + this_len - left, l);
- void *oldstuff = db->getmore(pos + this_len - left, l);
-
- int res = memcmp(newstuff, oldstuff, l);
-
- db->release(oldstuff, l);
- db->release();
-
- if (res)
- {
- break;
- }
-
- left -= l;
- }
-
- if (!left)
- {
- db_opt_save += this_len;
- db->resize(max(start_offset, pos + this_len));
- db->setro(FALSE);
- cur_datablock_cache->resize(cur_datablock_cache->getlen() - sizeof(cached_db_size));
- return pos;
- }
- }
- }
-
- db->setro(FALSE);
-
- return start_offset;
-}
-
-int CEXEBuild::add_db_data(IMMap *mmap) // returns offset
-{
- build_compressor_set = true;
-
- int done = 0;
-
- if (!mmap)
- {
- ERROR_MSG("Error: add_db_data() called with invalid mapped file\n");
- return -1;
- }
-
- int length = mmap->getsize();
-
- if (length < 0)
- {
- ERROR_MSG("Error: add_db_data() called with length=%d\n", length);
- return -1;
- }
-
- MMapBuf *db = (MMapBuf *) cur_datablock;
-
- int st = db->getlen();
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- if (length && !build_compress_whole && build_compress)
- {
- // grow datablock so that there is room to compress into
- int bufferlen = length + 1024 + length / 4; // give a nice 25% extra space
- db->resize(st + bufferlen + sizeof(int));
-
- int n = compressor->Init(build_compress_level, build_compress_dict_size);
- if (n != C_OK)
- {
- ERROR_MSG("Internal compiler error #12345: deflateInit() failed(%s [%d]).\n", compressor->GetErrStr(n), n);
- extern void quit(); quit();
- }
-
- int avail_in = length;
- int avail_out = bufferlen;
- int ret;
- while (avail_in > 0)
- {
- int in_len = min(build_filebuflen, avail_in);
- int out_len = min(build_filebuflen, avail_out);
-
- compressor->SetNextIn((char *) mmap->get(length - avail_in, in_len), in_len);
- compressor->SetNextOut((char *) db->get(st + sizeof(int) + bufferlen - avail_out, out_len), out_len);
- if ((ret = compressor->Compress(0)) < 0)
- {
- ERROR_MSG("Error: add_db_data() - compress() failed(%s [%d])\n", compressor->GetErrStr(ret), ret);
- return -1;
- }
- mmap->release();
- db->flush(out_len);
- db->release();
- avail_in -= in_len - compressor->GetAvailIn();
- avail_out -= out_len - compressor->GetAvailOut();
-
- if (!avail_out)
- // not enough space in the output buffer - no compression is better
- break;
- }
-
- // if not enough space in the output buffer - no compression is better
- if (avail_out)
- {
- char *out;
-
- char a;
- compressor->SetNextIn(&a,0);
-
- do
- {
- int out_len = min(build_filebuflen, avail_out);
-
- out = (char *) db->get(st + sizeof(int) + bufferlen - avail_out, out_len);
-
- compressor->SetNextOut(out, out_len);
- if ((ret = compressor->Compress(C_FINISH)) < 0)
- {
- ERROR_MSG("Error: add_db_data() - compress() failed(%s [%d])\n", compressor->GetErrStr(ret), ret);
- return -1;
- }
-
- db->flush(out_len);
- db->release();
-
- avail_out -= out_len - compressor->GetAvailOut();
- }
- while (compressor->GetNextOut() - out > 0 && avail_out > 0);
-
- compressor->End();
-
- int used = bufferlen - avail_out;
-
- // never store compressed if output buffer is full (compression increased the size...)
- if (avail_out && (build_compress == 2 || used < length))
- {
- done=1;
- db->resize(st + used + sizeof(int));
-
- *(int*)db->get(st, sizeof(int)) = FIX_ENDIAN_INT32(used | 0x80000000);
- db->release();
-
- int nst = datablock_optimize(st, used | 0x80000000);
- if (nst == st) db_comp_save += length - used;
- else st = nst;
- }
- }
- else
- compressor->End();
- }
-#endif // NSIS_CONFIG_COMPRESSION_SUPPORT
-
- if (!done)
- {
- db->resize(st + length + sizeof(int));
- int *plen = (int *) db->get(st, sizeof(int));
- *plen = FIX_ENDIAN_INT32(length);
- db->release();
-
- int left = length;
- while (left > 0)
- {
- int l = min(build_filebuflen, left);
- int *p = (int *) db->get(st + sizeof(int) + length - left, l);
- memcpy(p, mmap->get(length - left, l), l);
- db->flush(l);
- db->release();
- mmap->release();
- left -= l;
- }
-
- st = datablock_optimize(st, length);
- }
-
- db_full_size += length + sizeof(int);
-
- return st;
-}
-
-int CEXEBuild::add_db_data(const char *data, int length) // returns offset
-{
- MMapFake fakemap;
- fakemap.set(data, length);
- return add_db_data(&fakemap);
-}
-
-int CEXEBuild::add_data(const char *data, int length, IGrowBuf *dblock) // returns offset
-{
- build_compressor_set=true;
-
- int done=0;
-
- if (length < 0)
- {
- ERROR_MSG("Error: add_data() called with length=%d\n",length);
- return -1;
- }
-
- int st=dblock->getlen();
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- if (!build_compress_whole && build_compress)
- {
- // grow datablock so that there is room to compress into
- int bufferlen=length+1024+length/4; // give a nice 25% extra space
- dblock->resize(st+bufferlen+sizeof(int));
-
- int n = compressor->Init(build_compress_level, build_compress_dict_size);
- if (n != C_OK)
- {
- ERROR_MSG("Internal compiler error #12345: deflateInit() failed(%s [%d]).\n", compressor->GetErrStr(n), n);
- extern void quit(); quit();
- }
-
- compressor->SetNextIn((char*)data, length);
- compressor->SetNextOut((char*)dblock->get() + st + sizeof(int), bufferlen);
-
- compressor->Compress(C_FINISH);
-
- int used=bufferlen-compressor->GetAvailOut();
-
- // never store compressed if output buffer is full
- if (compressor->GetAvailOut() && (build_compress == 2 || used < length))
- {
- done=1;
- dblock->resize(st+used+sizeof(int));
-
- *((int*)((char *)dblock->get()+st)) = FIX_ENDIAN_INT32(used|0x80000000);
- }
- compressor->End();
- }
-#endif // NSIS_CONFIG_COMPRESSION_SUPPORT
-
- if (!done)
- {
- dblock->resize(st);
- int rl = FIX_ENDIAN_INT32(length);
- dblock->add(&rl,sizeof(int));
- dblock->add(data,length);
- }
-
- return st;
-}
-
-int CEXEBuild::add_label(const char *name)
-{
- if (!build_cursection)
- {
- ERROR_MSG("Error: Label declaration not valid outside of function/section\n");
- return PS_ERROR;
- }
- if ((name[0] >= '0' && name[0] <= '9') || name[0] == '-' || name[0] == ' ' || name[0] == ':')
- {
- ERROR_MSG("Error: labels must not begin with 0-9, -, :, or a space.\n");
- return PS_ERROR;
- }
-
- int cs=build_cursection->code;
- int ce=cs+build_cursection->code_size;
-
- char *p=strdup(name);
- if (p[strlen(p)-1] == ':') p[strlen(p)-1]=0;
- int offs=ns_label.add(p,0);
- free(p);
-
- int n=cur_labels->getlen()/sizeof(section);
- if (n)
- {
- section *t=(section*)cur_labels->get();
- while (n--)
- {
- if ((*name == '.' || (t->code >= cs && t->code <= ce)) &&
- t->name_ptr==offs)
- {
- if (*name == '.') ERROR_MSG("Error: global label \"%s\" already declared\n",name);
- else
- {
- char *t = "section";
- if (build_cursection_isfunc)
- t = "function";
- ERROR_MSG("Error: label \"%s\" already declared in %s\n",name,t);
- }
- return PS_ERROR;
- }
- t++;
- }
- }
-
- section s={0};
- s.name_ptr = offs;
- s.code = ce;
- cur_labels->add(&s,sizeof(s));
-
- return PS_OK;
-}
-
-int CEXEBuild::add_function(const char *funname)
-{
- if (build_cursection_isfunc)
- {
- ERROR_MSG("Error: Function open when creating function (use FunctionEnd first)\n");
- return PS_ERROR;
- }
- if (build_cursection)
- {
- ERROR_MSG("Error: Section open when creating function (use SectionEnd first)\n");
- return PS_ERROR;
- }
- if (cur_page)
- {
- ERROR_MSG("Error: PageEx open when creating function (use PageExEnd first)\n");
- return PS_ERROR;
- }
- if (!funname[0])
- {
- ERROR_MSG("Error: Function must have a name\n");
- return PS_ERROR;
- }
-
- set_uninstall_mode(!strnicmp(funname,"un.",3));
-
- int addr=ns_func.add(funname,0);
- int x;
- int n=cur_functions->getlen()/sizeof(section);
- section *tmp=(section*)cur_functions->get();
- for (x = 0; x < n; x ++)
- {
- if (tmp[x].name_ptr == addr)
- {
- ERROR_MSG("Error: Function named \"%s\" already exists.\n",funname);
- return PS_ERROR;
- }
- }
-
- cur_functions->resize((n+1)*sizeof(section));
- build_cursection=((section*)cur_functions->get())+n;
- build_cursection_isfunc=1;
- build_cursection->name_ptr=addr;
- build_cursection->code=cur_entries->getlen()/sizeof(entry);
- build_cursection->code_size=0;
- build_cursection->install_types=0;
- build_cursection->flags=0;
- build_cursection->size_kb=0;
- memset(build_cursection->name,0,sizeof(build_cursection->name));
-
- if (uninstall_mode)
- set_code_type_predefines(funname+3);
- else
- set_code_type_predefines(funname);
-
- return PS_OK;
-}
-
-int CEXEBuild::function_end()
-{
- if (!build_cursection_isfunc)
- {
- ERROR_MSG("Error: No function open, FunctionEnd called\n");
- return PS_ERROR;
- }
- // add ret.
- add_entry_direct(EW_RET);
-
- build_cursection_isfunc=0;
- build_cursection=NULL;
-
- set_uninstall_mode(0);
-
- set_code_type_predefines();
- return PS_OK;
-}
-
-
-int CEXEBuild::section_add_flags(int flags)
-{
- if (!build_cursection || build_cursection_isfunc)
- {
- ERROR_MSG("Error: can't modify flags when no section is open\n");
- return PS_ERROR;
- }
- build_cursection->flags |= flags;
- return PS_OK;
-}
-
-int CEXEBuild::section_add_install_type(int inst_type)
-{
- if (!build_cursection || build_cursection_isfunc)
- {
- ERROR_MSG("Error: can't modify flags when no section is open\n");
- return PS_ERROR;
- }
- if (build_cursection->install_types == ~0)
- build_cursection->install_types = 0;
- build_cursection->install_types |= inst_type;
- return PS_OK;
-}
-
-void CEXEBuild::section_add_size_kb(int kb)
-{
- if (build_cursection)
- {
- build_cursection->size_kb+=kb;
- }
-}
-
-int CEXEBuild::section_end()
-{
- if (build_cursection_isfunc)
- {
- ERROR_MSG("Error: SectionEnd specified in function (not section)\n");
- return PS_ERROR;
- }
- if (!build_cursection)
- {
- ERROR_MSG("Error: SectionEnd specified and no sections open\n");
- return PS_ERROR;
- }
- add_entry_direct(EW_RET);
- build_cursection->code_size--;
- build_cursection=NULL;
- if (!sectiongroup_open_cnt)
- set_uninstall_mode(0);
-
- set_code_type_predefines();
- return PS_OK;
-}
-
-int CEXEBuild::add_section(const char *secname, const char *defname, int expand/*=0*/)
-{
- if (build_cursection_isfunc)
- {
- ERROR_MSG("Error: Section can't create section (already in function, use FunctionEnd first)\n");
- return PS_ERROR;
- }
- if (cur_page) {
- ERROR_MSG("Error: PageEx already open, call PageExEnd first\n");
- return PS_ERROR;
- }
- if (build_cursection)
- {
- ERROR_MSG("Error: Section already open, call SectionEnd first\n");
- return PS_ERROR;
- }
-
- section new_section;
- new_section.flags = SF_SELECTED;
- new_section.flags |= expand ? SF_EXPAND : 0;
- new_section.code_size = 0;
- new_section.size_kb = 0;
-
- char *name = (char*)secname;
-
- if (secname[0] == '-')
- {
- if (secname[1])
- {
- new_section.flags |= SF_SECGRP;
- name++;
- }
- else
- new_section.flags |= SF_SECGRPEND;
- }
-
- if (name[0] == '!')
- {
- name++;
- new_section.flags |= SF_BOLD;
- }
-
- int old_uninstall_mode = uninstall_mode;
-
- set_uninstall_mode(0);
-
- if (!strnicmp(name, "un.", 3))
- {
- set_uninstall_mode(1);
- name += 3;
- }
-
- if (!stricmp(name, "uninstall"))
- {
- set_uninstall_mode(1);
- }
-
- if ((new_section.flags & SF_SECGRPEND) && sectiongroup_open_cnt && old_uninstall_mode)
- {
- set_uninstall_mode(1);
- }
-
- if (sectiongroup_open_cnt)
- {
- if (uninstall_mode != old_uninstall_mode)
- {
- ERROR_MSG("Error: Can't create %s section in %s section group (use SectionGroupEnd first)\n", uninstall_mode ? "uninstaller" : "installer", old_uninstall_mode ? "uninstaller" : "installer");
- return PS_ERROR;
- }
- }
-
- new_section.code = cur_entries->getlen() / sizeof(entry);
-
- new_section.install_types = *name ? 0 : ~0;
- new_section.name_ptr = add_string(name);
- memset(&new_section.name,0,sizeof(new_section.name));
-
- cur_sections->add(&new_section, sizeof(section));
- build_cursection = (section *) cur_sections->get() + cur_header->blocks[NB_SECTIONS].num;
-
- if (defname[0])
- {
- char buf[1024];
- wsprintf(buf, "%d", cur_header->blocks[NB_SECTIONS].num);
- if (definedlist.add(defname, buf))
- {
- ERROR_MSG("Error: \"%s\" already defined, can't assign section index!\n", defname);
- return PS_ERROR;
- }
- }
-
- cur_header->blocks[NB_SECTIONS].num++;
-
- if (new_section.flags & (SF_SECGRP | SF_SECGRPEND))
- {
- add_entry_direct(EW_RET);
- build_cursection->code_size = 0;
-
- build_cursection = 0;
-
- if (new_section.flags & SF_SECGRPEND)
- {
- sectiongroup_open_cnt--;
- if (sectiongroup_open_cnt < 0)
- {
- ERROR_MSG("SectionGroupEnd: no SectionGroups are open\n");
- return PS_ERROR;
- }
- if (!sectiongroup_open_cnt)
- {
- set_uninstall_mode(0);
- }
- }
- else
- sectiongroup_open_cnt++;
- }
-
- set_code_type_predefines(name);
-
- return PS_OK;
-}
-
-int CEXEBuild::add_entry(const entry *ent)
-{
- if (!build_cursection && !uninstall_mode)
- {
- ERROR_MSG("Error: Can't add entry, no section or function is open!\n");
- return PS_ERROR;
- }
-
- cur_entries->add(ent,sizeof(entry));
- cur_instruction_entry_map->add(&multiple_entries_instruction,sizeof(int));
- build_cursection->code_size++;
- cur_header->blocks[NB_ENTRIES].num++;
-
- multiple_entries_instruction=1;
-
- return PS_OK;
-}
-
-int CEXEBuild::add_entry_direct(int which, int o0, int o1, int o2, int o3, int o4, int o5 /*o#=0*/)
-{
- entry ent;
- ent.which = which;
- ent.offsets[0] = o0;
- ent.offsets[1] = o1;
- ent.offsets[2] = o2;
- ent.offsets[3] = o3;
- ent.offsets[4] = o4;
- ent.offsets[5] = o5;
- return add_entry(&ent);
-}
-
-int CEXEBuild::resolve_jump_int(const char *fn, int *a, int offs, int start, int end)
-{
- if (*a > 0)
- {
- char *lname=(char*)ns_label.get()+*a;
- if (lname[0] == '-' || lname[0]=='+')
- {
- int jump = atoi(lname);
- int *skip_map = (int *) cur_instruction_entry_map->get();
- int maxoffs = cur_instruction_entry_map->getlen() / (int) sizeof(int);
-
- int direction = 1;
- if (jump < 0)
- direction = -1;
-
- for (; jump != 0; jump -= direction)
- {
- offs += direction;
- if (offs >= 0 && offs < maxoffs)
- {
- while (skip_map[offs])
- {
- offs += direction;
- }
- }
- }
-
- *a = offs + 1;
- }
- else
- {
- section *s = (section*)cur_labels->get();
- int n=cur_labels->getlen()/sizeof(section);
- while (n-->0)
- {
- if ((*lname == '.' || (s->code >= start && s->code <= end)) && s->name_ptr == *a)
- {
- *a = s->code+1; // jumps are to the absolute position, +1 (to differentiate between no jump, and jumping to offset 0)
- s->flags++;
- return 0;
- }
- s++;
- }
-
- ERROR_MSG("Error: could not resolve label \"%s\" in %s\n",lname,fn);
- return 1;
- }
- }
- else if (*a < 0) // to jump to a user variable target, -variable_index-1 is already stored.
- {
- }
- // otherwise, *a is 0, which means no jump and we also leave it intact
- return 0;
-}
-
-int CEXEBuild::resolve_call_int(const char *fn, const char *str, int fptr, int *ofs)
-{
- if (fptr < 0) return 0;
- int nf=cur_functions->getlen()/sizeof(section);
- section *sec=(section *)cur_functions->get();
- while (nf-- > 0)
- {
- if (sec->name_ptr>0 && sec->name_ptr == fptr)
- {
- ofs[0]=sec->code;
- sec->flags++;
- return 0;
- }
- sec++;
- }
- ERROR_MSG("Error: resolving %s function \"%s\" in %s\n",str,(char*)ns_func.get()+fptr,fn);
- ERROR_MSG("Note: uninstall functions must begin with \"un.\", and install functions must not\n");
- return 1;
-}
-
-int CEXEBuild::resolve_instruction(const char *fn, const char *str, entry *w, int offs, int start, int end)
-{
- if (w->which == EW_NOP)
- {
- if (resolve_jump_int(fn,&w->offsets[0],offs,start,end)) return 1;
- }
-#ifdef NSIS_SUPPORT_MESSAGEBOX
- else if (w->which == EW_MESSAGEBOX)
- {
- if (resolve_jump_int(fn,&w->offsets[3],offs,start,end)) return 1;
- if (resolve_jump_int(fn,&w->offsets[5],offs,start,end)) return 1;
- }
-#endif
- else if (w->which == EW_IFFILEEXISTS)
- {
- if (resolve_jump_int(fn,&w->offsets[1],offs,start,end)) return 1;
- if (resolve_jump_int(fn,&w->offsets[2],offs,start,end)) return 1;
- }
- else if (w->which == EW_IFFLAG)
- {
- if (resolve_jump_int(fn,&w->offsets[0],offs,start,end)) return 1;
- if (resolve_jump_int(fn,&w->offsets[1],offs,start,end)) return 1;
- }
-#ifdef NSIS_SUPPORT_STROPTS
- else if (w->which == EW_STRCMP)
- {
- if (resolve_jump_int(fn,&w->offsets[2],offs,start,end)) return 1;
- if (resolve_jump_int(fn,&w->offsets[3],offs,start,end)) return 1;
- }
-#endif
-#ifdef NSIS_SUPPORT_INTOPTS
- else if (w->which == EW_INTCMP)
- {
- if (resolve_jump_int(fn,&w->offsets[2],offs,start,end)) return 1;
- if (resolve_jump_int(fn,&w->offsets[3],offs,start,end)) return 1;
- if (resolve_jump_int(fn,&w->offsets[4],offs,start,end)) return 1;
- }
-#endif
-#ifdef NSIS_SUPPORT_HWNDS
- else if (w->which == EW_ISWINDOW)
- {
- if (resolve_jump_int(fn,&w->offsets[1],offs,start,end)) return 1;
- if (resolve_jump_int(fn,&w->offsets[2],offs,start,end)) return 1;
- }
-#endif
- else if (w->which == EW_CALL)
- {
- if (w->offsets[0] >= 0 && w->offsets[1]) // get as jump
- {
- if (resolve_jump_int(fn,&w->offsets[0],offs,start,end)) return 1;
- }
- else
- {
- if (w->offsets[0] >= 0 && resolve_call_int(fn,str,w->offsets[0],w->offsets)) return 1;
- // if w->offsets[0] >= 0, EW_CALL requires that it 1-based.
- // otherwise, if < 0, it needs an increment anyway (since it
- // was encoded with a -2 base, to prevent it looking like an
- // empty string "")
- w->offsets[0]++;
- }
- }
-#ifdef NSIS_SUPPORT_STROPTS
- else if (w->which == EW_GETFUNCTIONADDR)
- {
- if (w->offsets[1] < 0)
- {
- ERROR_MSG("Error: GetFunctionAddress requires a real function to get address of.\n");
- return 1;
- }
-
- if (resolve_call_int(fn,str,w->offsets[1],&w->offsets[1])) return 1;
-
- w->which=EW_ASSIGNVAR;
- w->offsets[1]=add_intstring(w->offsets[1]+1); // +1 here to make 1-based.
- }
- else if (w->which == EW_GETLABELADDR)
- {
- if (resolve_jump_int(fn,&w->offsets[1],offs,start,end)) return 1;
- w->which=EW_ASSIGNVAR;
- w->offsets[1]=add_intstring(w->offsets[1]);
- }
-#endif
- return 0;
-}
-
-int CEXEBuild::resolve_coderefs(const char *str)
-{
- // resolve jumps&calls
- {
- section *sec=(section *)cur_functions->get();
- int l=cur_functions->getlen()/sizeof(section);
- entry *w=(entry *)cur_entries->get();
- while (l-- > 0)
- {
- int x;
- for (x = sec->code; x < sec->code+sec->code_size; x ++)
- {
- char fname[1024];
- wsprintf(fname,"function \"%s\"",ns_func.get()+sec->name_ptr);
- if (resolve_instruction(fname,str,w+x,x,sec->code,sec->code+sec->code_size)) return 1;
- }
- sec++;
- }
-
- int cnt=0;
- sec=(section *)cur_sections->get();
- l=cur_sections->getlen()/sizeof(section);
- while (l-- > 0)
- {
- int x=sec->name_ptr;
- char fname[1024];
- const char *section_name;
- if (x < 0)
- {
- // lang string
- section_name = "$(lang string)";
- }
- else
- {
- // normal string
- section_name = cur_strlist->get() + x;
- }
- if (x) wsprintf(fname,"%s section \"%s\" (%d)",str,section_name,cnt);
- else wsprintf(fname,"unnamed %s section (%d)",str,cnt);
- for (x = sec->code; x < sec->code+sec->code_size; x ++)
- {
- if (resolve_instruction(fname,str,w+x,x,sec->code,sec->code+sec->code_size))
- return 1;
- }
- sec++;
- cnt++;
- }
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- if (cur_pages->getlen()) {
- page *p=(page *)cur_pages->get();
- int i = 0;
- while (i < cur_header->blocks[NB_PAGES].num) {
- char pagestr[1024];
- wsprintf(pagestr, "%s pages", str);
- if (resolve_call_int(pagestr,p->dlg_id?"pre-page":"create-page",p->prefunc,&p->prefunc)) return 1;
- if (resolve_call_int(pagestr,"show-page",p->showfunc,&p->showfunc)) return 1;
- if (resolve_call_int(pagestr,"leave-page",p->leavefunc,&p->leavefunc)) return 1;
- p++;
- i++;
- }
- }
-#endif
-#endif
- }
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- // resolve callbacks
- {
- struct {
- char *name;
- int *p;
- } callbacks[] = {
- {"%s.onInit", &cur_header->code_onInit},
- {"%s.on%sInstSuccess", &cur_header->code_onInstSuccess},
- {"%s.on%sInstFailed", &cur_header->code_onInstFailed},
- {"%s.onUserAbort", &cur_header->code_onUserAbort},
- {"%s.onVerifyInstDir", &cur_header->code_onVerifyInstDir},
-#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
- {"%s.onGUIInit", &cur_header->code_onGUIInit},
- {"%s.onGUIEnd", &cur_header->code_onGUIEnd},
- {"%s.onMouseOverSection", &cur_header->code_onMouseOverSection},
-#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- {"%s.onSelChange", &cur_header->code_onSelChange},
-#endif//NSIS_CONFIG_COMPONENTPAGE
-#ifdef NSIS_SUPPORT_REBOOT
- {"%s.onRebootFailed", &cur_header->code_onRebootFailed},
-#endif//NSIS_SUPPORT_REBOOT
- {0, 0}
- };
-
- for (int i = 0; callbacks[i].name; i++) {
- const char *un = uninstall_mode ? "un" : "";
- char fname[1024];
- wsprintf(fname, callbacks[i].name, un, un);
- char cbstr[1024];
- wsprintf(cbstr, "%s callback", str);
- char cbstr2[1024];
- wsprintf(cbstr2, "%s.callbacks", un);
-
- if (resolve_call_int(cbstr,cbstr2,ns_func.find(fname,0),callbacks[i].p))
- return PS_ERROR;
- }
- }
-#endif//NSIS_SUPPORT_CODECALLBACKS
-
- // optimize unused functions
- {
- section *sec=(section *)cur_functions->get();
- int l=cur_functions->getlen()/sizeof(section);
- entry *w=(entry*)cur_entries->get();
- while (l-- > 0)
- {
- if (sec->name_ptr)
- {
- if (!sec->flags)
- {
- if (sec->code_size>0)
- {
- warning("%s function \"%s\" not referenced - zeroing code (%d-%d) out\n",str,
- ns_func.get()+sec->name_ptr,
- sec->code,sec->code+sec->code_size);
- memset(w+sec->code,0,sec->code_size*sizeof(entry));
- }
- }
- }
- sec++;
- }
- }
-
- // give warnings on unused labels
- {
- section *t=(section*)cur_labels->get();
- int n=cur_labels->getlen()/sizeof(section);
- while (n-->0)
- {
- if (!t->flags)
- {
- char *n=(char*)ns_label.get()+t->name_ptr;
- if (*n == '.') warning("global label \"%s\" not used",n);
- else warning("label \"%s\" not used",n);
- }
- t++;
- }
- }
-
- return 0;
-}
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-int CEXEBuild::add_page(int type)
-{
- page pg = {
- 0,
- 0,
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- -1,
- -1,
- -1,
-#endif
- 0,
- };
-
-#ifndef NSIS_CONFIG_LICENSEPAGE
- if (type == PAGE_LICENSE)
- {
- ERROR_MSG("Error: can't add license page, NSIS_CONFIG_LICENSEPAGE not defined.\n");
- return PS_ERROR;
- }
-#endif
-#ifndef NSIS_CONFIG_COMPONENTPAGE
- if (type == PAGE_COMPONENTS)
- {
- ERROR_MSG("Error: can't add components page, NSIS_CONFIG_COMPONENTPAGE not defined.\n");
- return PS_ERROR;
- }
-#endif
-#ifndef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (type == PAGE_COMPONENTS)
- {
- ERROR_MSG("Error: can't add uninstConfirm page, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n");
- return PS_ERROR;
- }
-#endif
-
- struct {
- int wndproc_id;
- int dlg_id;
- char *name;
- } ids[] = {
- {PWP_CUSTOM, 0, "custom"}, // custom
-#ifdef NSIS_CONFIG_LICENSEPAGE
- {PWP_LICENSE, IDD_LICENSE, "license"}, // license
-#else
- {0, IDD_LICENSE, "license"}, // license
-#endif
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- {PWP_SELCOM, IDD_SELCOM, "components"}, // components
-#else
- {0, IDD_SELCOM, "components"}, // components
-#endif
- {PWP_DIR, IDD_DIR, "directory"}, // directory
- {PWP_INSTFILES, IDD_INSTFILES, "instfiles"}, // instfiles
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- {PWP_UNINST, IDD_UNINST, "uninstConfirm"}, // uninstConfirm
-#else
- {0, IDD_UNINST, "uninstConfirm"}, // uninstConfirm
-#endif
- {PWP_COMPLETED, -1, NULL} // completed
- };
-
- pg.wndproc_id = ids[type].wndproc_id;
- pg.dlg_id = ids[type].dlg_id;
-
- cur_pages->add(&pg,sizeof(page));
-
- cur_page = (page *)cur_pages->get() + cur_header->blocks[NB_PAGES].num++;
-
- cur_page_type = type;
-
- set_code_type_predefines(ids[type].name);
- return PS_OK;
-}
-
-int CEXEBuild::page_end()
-{
- cur_page = 0;
-
- set_code_type_predefines();
- return PS_OK;
-}
-#endif
-
-#ifdef NSIS_SUPPORT_VERSION_INFO
-int CEXEBuild::AddVersionInfo()
-{
- GrowBuf VerInfoStream;
-
- if ( rVersionInfo.GetStringTablesCount() > 0 )
- {
- if ( !version_product_v[0] )
- {
- ERROR_MSG("Error: VIProductVersion is required when other version information functions are used.\n");
- return PS_ERROR;
- }
- else
- {
- int imm, iml, ilm, ill;
- if ( sscanf(version_product_v, "%d.%d.%d.%d", &imm, &iml, &ilm, &ill) != 4 )
- {
- ERROR_MSG("Error: invalid VIProductVersion format, should be X.X.X.X\n");
- return PS_ERROR;
- }
- rVersionInfo.SetFileVersion(MAKELONG(iml, imm),MAKELONG(ill, ilm));
- rVersionInfo.SetProductVersion(MAKELONG(iml, imm),MAKELONG(ill, ilm));
-
- try
- {
- init_res_editor();
- for ( int i = 0; i < rVersionInfo.GetStringTablesCount(); i++ )
- {
- LANGID lang_id = rVersionInfo.GetLangID(i);
- int code_page = rVersionInfo.GetCodePage(i);
-
- char *lang_name = GetLangNameAndCP(lang_id);
-
- if ( !rVersionInfo.FindKey(lang_id, code_page, "FileVersion") )
- warning("Generating version information for language \"%04d-%s\" without standard key \"FileVersion\"", lang_id, lang_name);
- if ( !rVersionInfo.FindKey(lang_id, code_page, "FileDescription") )
- warning("Generating version information for language \"%04d-%s\" without standard key \"FileDescription\"", lang_id, lang_name);
- if ( !rVersionInfo.FindKey(lang_id, code_page, "LegalCopyright") )
- warning("Generating version information for language \"%04d-%s\" without standard key \"LegalCopyright\"", lang_id, lang_name);
-
- rVersionInfo.ExportToStream(VerInfoStream, i);
- res_editor->UpdateResourceA(RT_VERSION, 1, lang_id, (BYTE*)VerInfoStream.get(), VerInfoStream.getlen());
- }
- }
- catch (exception& err) {
- ERROR_MSG("Error adding version information: %s\n", err.what());
- return PS_ERROR;
- }
- }
- }
-
- return PS_OK;
-}
-#endif // NSIS_SUPPORT_VERSION_INFO
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-int CEXEBuild::ProcessPages()
-{
- SCRIPT_MSG("Processing pages... ");
-
- int license_normal=0;
- int license_fsrb=0;
- int license_fscb=0;
- int selcom=0;
- int dir=0, dir_used;
- int uninstconfirm=0;
- int instlog=0, instlog_used;
- int main=0;
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
-again:
-#endif
-
- dir_used = 0;
- instlog_used = 0;
-
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- if ((cur_header->flags & (CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) == 0)
-#endif
- {
- main++;
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
-#define LS(inst, uninst) (uninstall_mode ? uninst : inst)
-#else
-#define LS(inst, uninst) inst
-#endif
-
- DefineInnerLangString(NLF_BRANDING);
-
- if (!cur_pages->getlen()) {
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (uninstall_mode) {
- if (HasUserDefined(NLF_UNINST_TEXT)) {
- add_page(PAGE_UNINSTCONFIRM);
- page_end();
- }
- add_page(PAGE_INSTFILES);
- page_end();
- add_page(PAGE_COMPLETED);
- page_end();
- }
- else
-#endif
- {
-#ifdef NSIS_CONFIG_LICENSEPAGE
- if (HasUserDefined(NLF_LICENSE_TEXT) && HasUserDefined(NLF_LICENSE_DATA)) {
- add_page(PAGE_LICENSE);
- page_end();
- }
-#endif
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- if (HasUserDefined(NLF_COMP_TEXT)) {
- add_page(PAGE_COMPONENTS);
- page_end();
- }
-#endif
- if (HasUserDefined(NLF_DIR_TEXT)) {
- add_page(PAGE_DIRECTORY);
- page_end();
- }
- add_page(PAGE_INSTFILES);
- page_end();
- add_page(PAGE_COMPLETED);
- page_end();
- }
- }
- // start processing the pages
- {
- int i = 0;
- page *p = (page *) cur_pages->get();
-
- for (i = 0; i < cur_header->blocks[NB_PAGES].num; i++, p++) {
- page *pp = 0;
-
- if (i) {
- pp = p - 1;
-
- // set back button
- p->flags |= PF_BACK_SHOW;
- if (pp->wndproc_id != PWP_COMPLETED && p->wndproc_id != PWP_COMPLETED && p->wndproc_id != PWP_INSTFILES)
- p->flags |= PF_BACK_ENABLE;
- if (!p->back)
- p->back = DefineInnerLangString(NLF_BTN_BACK);
-
- // set previous page's next button
- if (!pp->next) {
- int str = 0;
-
-#ifdef NSIS_CONFIG_LICENSEPAGE
- if (pp->wndproc_id == PWP_LICENSE && (!(pp->flags & PF_LICENSE_FORCE_SELECTION) || HasUserDefined(NLF_BTN_LICENSE)))
- str = NLF_BTN_LICENSE;
- else
-#endif
- if (p->wndproc_id == PWP_INSTFILES)
- str = LS(NLF_BTN_INSTALL, NLF_BTN_UNINSTALL);
- else
- str = NLF_BTN_NEXT;
-
- pp->next = DefineInnerLangString(str);
- }
-
- // set previous page's click next text
- if (!pp->clicknext) {
- int str = 0;
-
- if (p->wndproc_id == PWP_INSTFILES)
- str = LS(NLF_CLICK_INSTALL, NLF_CLICK_UNINSTALL);
- else
- str = NLF_CLICK_NEXT;
-
- pp->clicknext = DefineInnerLangString(str);
- }
- }
-
- // enable next button
- if (p->wndproc_id != PWP_INSTFILES)
- p->flags |= PF_NEXT_ENABLE;
-
- // set cancel button
- if (!p->cancel)
- p->cancel = DefineInnerLangString(NLF_BTN_CANCEL);
- if (p->wndproc_id != PWP_INSTFILES && p->wndproc_id != PWP_COMPLETED)
- p->flags |= PF_CANCEL_ENABLE;
-
- // set caption
- struct {
- int caption;
- int ucaption;
- } captions[] = {
-#ifdef NSIS_CONFIG_LICENSEPAGE
- {NLF_SUBCAPTION_LICENSE, NLF_SUBCAPTION_LICENSE},
-#endif
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- {NLF_SUBCAPTION_OPTIONS, NLF_SUBCAPTION_OPTIONS},
-#endif
- {NLF_SUBCAPTION_DIR, NLF_SUBCAPTION_DIR},
- {NLF_SUBCAPTION_INSTFILES, NLF_USUBCAPTION_INSTFILES},
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- {NLF_USUBCAPTION_CONFIRM, NLF_USUBCAPTION_CONFIRM},
-#endif
- {NLF_SUBCAPTION_COMPLETED, NLF_USUBCAPTION_COMPLETED}
- };
-
- if (!p->caption && p->wndproc_id != PWP_CUSTOM) {
- p->caption = DefineInnerLangString(LS(captions[p->wndproc_id].caption, captions[p->wndproc_id].ucaption));
- }
-
- // set texts
- switch (p->dlg_id) {
-#ifdef NSIS_CONFIG_LICENSEPAGE
- case IDD_LICENSE:
- case IDD_LICENSE_FSRB:
- case IDD_LICENSE_FSCB:
- {
- if (!(p->flags & PF_PAGE_EX))
- p->dlg_id = license_res_id;
- if (!(p->flags & (PF_LICENSE_FORCE_SELECTION | PF_LICENSE_NO_FORCE_SELECTION)))
- p->dlg_id = license_res_id;
-
- p->flags |= PF_NO_NEXT_FOCUS;
-
- if (!p->parms[1])
- p->parms[1] = DefineInnerLangString(NLF_LICENSE_DATA, 0);
-
- if (p->dlg_id == IDD_LICENSE) {
- if (!p->parms[0])
- p->parms[0] = DefineInnerLangString(LS(NLF_LICENSE_TEXT, NLF_ULICENSE_TEXT));
-
- license_normal++;
- }
- else if (p->dlg_id == IDD_LICENSE_FSCB) {
- p->flags |= PF_LICENSE_FORCE_SELECTION;
-
- if (!p->parms[0])
- p->parms[0] = DefineInnerLangString(LS(NLF_LICENSE_TEXT_FSCB, NLF_ULICENSE_TEXT_FSCB));
- if (!p->parms[2])
- p->parms[2] = DefineInnerLangString(NLF_BTN_LICENSE_AGREE);
-
- license_fscb++;
- }
- else if (p->dlg_id == IDD_LICENSE_FSRB) {
- p->flags |= PF_LICENSE_FORCE_SELECTION;
-
- if (!p->parms[0])
- p->parms[0] = DefineInnerLangString(LS(NLF_LICENSE_TEXT_FSRB, NLF_ULICENSE_TEXT_FSRB));
- if (!p->parms[2])
- p->parms[2] = DefineInnerLangString(NLF_BTN_LICENSE_AGREE);
- if (!p->parms[3])
- p->parms[3] = DefineInnerLangString(NLF_BTN_LICENSE_DISAGREE);
-
- license_fsrb++;
- }
- break;
- }
-#endif
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- case IDD_SELCOM:
- {
- if (!p->parms[0])
- p->parms[0] = DefineInnerLangString(LS(NLF_COMP_TEXT, NLF_UCOMP_TEXT));
- if (!p->parms[1])
- p->parms[1] = DefineInnerLangString(LS(NLF_COMP_SUBTEXT1, NLF_UCOMP_SUBTEXT1));
- if (!p->parms[2])
- p->parms[2] = DefineInnerLangString(LS(NLF_COMP_SUBTEXT2, NLF_UCOMP_SUBTEXT2));
- if (!p->parms[3] && !uninstall_mode && HasUserDefined(NLF_COMP_SUBTEXT1))
- p->parms[3] = p->parms[1];
- if (!p->parms[4] && !uninstall_mode && HasUserDefined(NLF_COMP_SUBTEXT2))
- p->parms[4] = p->parms[2];
- else if (!p->parms[4])
- p->parms[4] = DefineInnerLangString(LS(NLF_COMP_SUBTEXT1_NO_INST_TYPES, NLF_UCOMP_SUBTEXT1_NO_INST_TYPES));
-
- DefineInnerLangString(NLF_SPACE_REQ);
- DefineInnerLangString(NLF_BYTE);
- DefineInnerLangString(NLF_KILO);
- DefineInnerLangString(NLF_MEGA);
- DefineInnerLangString(NLF_GIGA);
-
- selcom++;
- break;
- }
-#endif
- case IDD_DIR:
- {
- if (!p->parms[0])
- p->parms[0] = DefineInnerLangString(LS(NLF_DIR_TEXT, NLF_UDIR_TEXT));
- if (!p->parms[1])
- p->parms[1] = DefineInnerLangString(LS(NLF_DIR_SUBTEXT, NLF_UDIR_SUBTEXT));
- if (!p->parms[2])
- p->parms[2] = DefineInnerLangString(NLF_BTN_BROWSE);
- if (!p->parms[3])
- p->parms[3] = DefineInnerLangString(LS(NLF_DIR_BROWSETEXT, NLF_UDIR_BROWSETEXT));
- if (!p->parms[4])
- p->parms[4] = m_UserVarNames.get("INSTDIR");
- else
- p->parms[4]--;
-
- DefineInnerLangString(NLF_SPACE_AVAIL);
- DefineInnerLangString(NLF_SPACE_REQ);
- DefineInnerLangString(NLF_BYTE);
- DefineInnerLangString(NLF_KILO);
- DefineInnerLangString(NLF_MEGA);
- DefineInnerLangString(NLF_GIGA);
-#ifdef NSIS_CONFIG_LOG
- DefineInnerLangString(NLF_LOG_INSTALL_PROCESS);
-#endif
-
- dir++;
- break;
- }
- case IDD_INSTFILES:
- {
- if (!p->parms[1])
- p->parms[1] = DefineInnerLangString(NLF_BTN_DETAILS);
- if (!p->parms[2])
- p->parms[2] = DefineInnerLangString(NLF_COMPLETED);
-
- DefineInnerLangString(NLF_COPY_DETAILS);
-
- instlog++;
- instlog_used++;
- break;
- }
- case IDD_UNINST:
- {
- if (!p->parms[0])
- p->parms[0] = DefineInnerLangString(NLF_UNINST_TEXT);
- if (!p->parms[1])
- p->parms[1] = DefineInnerLangString(NLF_UNINST_SUBTEXT);
- if (!p->parms[4])
- p->parms[4] = m_UserVarNames.get("INSTDIR");
- else
- p->parms[4]--;
-
- uninstconfirm++;
- break;
- }
- }
-
- p->flags &= ~PF_PAGE_EX;
- }
-
- p--;
-
- if (!p->next)
- p->next = DefineInnerLangString(NLF_BTN_CLOSE);
- if (p->wndproc_id == PWP_COMPLETED)
- (p-1)->next = DefineInnerLangString(NLF_BTN_CLOSE);
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (uninstall_mode) {
- if (!uenable_last_page_cancel && instlog_used)
- p->flags &= ~PF_CANCEL_ENABLE;
- }
- else
-#endif
- {
- if (!enable_last_page_cancel && instlog_used)
- p->flags &= ~PF_CANCEL_ENABLE;
- }
-
- if (!instlog_used) {
- warning("%sage instfiles not used, no sections will be executed!", uninstall_mode ? "Uninstall p" : "P");
- }
- }
- }
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (!uninstall_mode) {
- set_uninstall_mode(1);
- goto again;
- }
- else
- set_uninstall_mode(0);
-#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
-
-
- SCRIPT_MSG("Done!\n");
-
-#define REMOVE_ICON(id) if (disable_window_icon) { \
- BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG); \
- if (dlg) { \
- CDialogTemplate dt(dlg,uDefCodePage); \
- res_editor->FreeResource(dlg); \
- if (dt.RemoveItem(IDC_ULICON)) { \
- DialogItemTemplate* text = dt.GetItem(IDC_INTROTEXT); \
- DialogItemTemplate* prog = dt.GetItem(IDC_PROGRESS); \
- if (text) { \
- text->sWidth += text->sX; \
- text->sX = 0; \
- } \
- if (prog) { \
- prog->sWidth += prog->sX; \
- prog->sX = 0; \
- } \
- \
- DWORD dwSize; \
- dlg = dt.Save(dwSize); \
- res_editor->UpdateResourceA(RT_DIALOG, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG, dlg, dwSize); \
- delete [] dlg; \
- } \
- } \
- }
-
- try {
- SCRIPT_MSG("Removing unused resources... ");
- init_res_editor();
-#ifdef NSIS_CONFIG_LICENSEPAGE
- if (!license_normal) {
- res_editor->UpdateResourceA(RT_DIALOG, IDD_LICENSE, NSIS_DEFAULT_LANG, 0, 0);
- }
- else REMOVE_ICON(IDD_LICENSE);
- if (!license_fsrb) {
- res_editor->UpdateResourceA(RT_DIALOG, IDD_LICENSE_FSRB, NSIS_DEFAULT_LANG, 0, 0);
- }
- else REMOVE_ICON(IDD_LICENSE_FSRB);
- if (!license_fscb) {
- res_editor->UpdateResourceA(RT_DIALOG, IDD_LICENSE_FSCB, NSIS_DEFAULT_LANG, 0, 0);
- }
- else REMOVE_ICON(IDD_LICENSE_FSCB);
-#endif // NSIS_CONFIG_LICENSEPAGE
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- if (!selcom) {
- res_editor->UpdateResourceA(RT_DIALOG, IDD_SELCOM, NSIS_DEFAULT_LANG, 0, 0);
- res_editor->UpdateResourceA(RT_BITMAP, IDB_BITMAP1, NSIS_DEFAULT_LANG, 0, 0);
- }
- else REMOVE_ICON(IDD_SELCOM);
-#endif // NSIS_CONFIG_COMPONENTPAGE
- if (!dir) {
- res_editor->UpdateResourceA(RT_DIALOG, IDD_DIR, NSIS_DEFAULT_LANG, 0, 0);
- }
- else REMOVE_ICON(IDD_DIR);
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (!uninstconfirm) {
- res_editor->UpdateResourceA(RT_DIALOG, IDD_UNINST, NSIS_DEFAULT_LANG, 0, 0);
- }
- else REMOVE_ICON(IDD_UNINST);
-#endif // NSIS_CONFIG_UNINSTALL_SUPPORT
- if (!instlog) {
- res_editor->UpdateResourceA(RT_DIALOG, IDD_INSTFILES, NSIS_DEFAULT_LANG, 0, 0);
- }
- else REMOVE_ICON(IDD_INSTFILES);
- if (!main) {
- res_editor->UpdateResourceA(RT_DIALOG, IDD_INST, NSIS_DEFAULT_LANG, 0, 0);
- if (!build_compress_whole && !build_crcchk)
- res_editor->UpdateResourceA(RT_DIALOG, IDD_VERIFY, NSIS_DEFAULT_LANG, 0, 0);
- }
-
- SCRIPT_MSG("Done!\n");
- }
- catch (exception& err) {
- ERROR_MSG("\nError: %s\n", err.what());
- return PS_ERROR;
- }
-
- return PS_OK;
-}
-#endif // NSIS_CONFIG_VISIBLE_SUPPORT
-
-#ifdef NSIS_CONFIG_COMPONENTPAGE
-void CEXEBuild::PrepareInstTypes()
-{
- if (!(cur_header->flags & CH_FLAGS_NO_CUSTOM))
- cur_header->install_types[NSIS_MAX_INST_TYPES] = DefineInnerLangString(NLF_COMP_CUSTOM);
-
- // set insttype list for RO sections that didn't use SectionIn
- int i = cur_header->blocks[NB_SECTIONS].num;
- section *sections = (section *) cur_sections->get();
-
- while (i--)
- {
- if (sections[i].flags & SF_RO && !sections[i].install_types)
- sections[i].install_types = ~0;
- }
-
- // set selection to first insttype
- if (cur_header->install_types[0])
- {
- int i = cur_header->blocks[NB_SECTIONS].num;
- section *sections = (section *) cur_sections->get();
-
- // if /o was used abort since the user did his manual choice
- while (i--)
- if ((sections[i].flags & SF_SELECTED) == 0)
- return;
-
- i = cur_header->blocks[NB_SECTIONS].num;
-
- while (i--)
- if ((sections[i].install_types & 1) == 0)
- sections[i].flags &= ~SF_SELECTED;
- }
-}
-#endif
-
-void CEXEBuild::AddStandardStrings()
-{
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (uninstall_mode)
- {
- cur_header->str_uninstchild = add_string("$TEMP\\$1u_.exe");
- cur_header->str_uninstcmd = add_string("\"$TEMP\\$1u_.exe\" $0 _?=$INSTDIR\\");
- }
-#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
- cur_header->str_wininit = add_string("$WINDIR\\wininit.ini");
-#endif//NSIS_SUPPORT_MOVEONREBOOT
-}
-
-void CEXEBuild::PrepareHeaders(IGrowBuf *hdrbuf)
-{
- GrowBuf blocks_buf;
- growbuf_writer_sink sink(&blocks_buf);
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- cur_header->blocks[NB_PAGES].offset = sizeof(header) + blocks_buf.getlen();
- page_writer::write_block(cur_pages, &sink);
-#endif
-
- cur_header->blocks[NB_SECTIONS].offset = sizeof(header) + blocks_buf.getlen();
- section_writer::write_block(cur_sections, &sink);
-
- cur_header->blocks[NB_ENTRIES].offset = sizeof(header) + blocks_buf.getlen();
- entry_writer::write_block(cur_entries, &sink);
-
- cur_header->blocks[NB_STRINGS].offset = sizeof(header) + blocks_buf.getlen();
- blocks_buf.add(cur_strlist->get(), cur_strlist->getlen());
-
- cur_header->blocks[NB_LANGTABLES].offset = sizeof(header) + blocks_buf.getlen();
- lang_table_writer::write_block(cur_langtables, &sink, cur_header->langtable_size);
-
- cur_header->blocks[NB_CTLCOLORS].offset = sizeof(header) + blocks_buf.getlen();
- ctlcolors_writer::write_block(cur_ctlcolors, &sink);
-
-#ifdef NSIS_SUPPORT_BGBG
- if (cur_header->bg_color1 != -1)
- {
- bg_font.lfFaceName[LF_FACESIZE-1] = 0;
-
- cur_header->blocks[NB_BGFONT].offset = sizeof(header) + blocks_buf.getlen();
-
- LOGFONT_writer w(&sink);
- w.write(&bg_font);
- }
-#endif
-
- growbuf_writer_sink sink2(hdrbuf);
- header_writer header(&sink2);
- header.write(cur_header);
-
- sink2.write_growbuf(&blocks_buf);
-}
-
-int CEXEBuild::SetVarsSection()
-{
- try {
- init_res_editor();
-
- VerifyDeclaredUserVarRefs(&m_UserVarNames);
- int MaxUserVars = m_UserVarNames.getnum();
- // -1 because the default size is 1
- if (!res_editor->AddExtraVirtualSize2PESection(NSIS_VARS_SECTION, (MaxUserVars - 1) * sizeof(NSIS_STRING)))
- {
- ERROR_MSG("Internal compiler error #12346: invalid exehead cannot find section \"%s\"!\n", NSIS_VARS_SECTION);
- return PS_ERROR;
- }
- }
- catch (exception& err) {
- ERROR_MSG("\nError: %s\n", err.what());
- return PS_ERROR;
- }
-
- return PS_OK;
-}
-
-int CEXEBuild::SetManifest()
-{
- try {
- init_res_editor();
-
- string manifest = manifest::generate(manifest_comctl, manifest_exec_level);
-
- if (manifest == "")
- return PS_OK;
-
- res_editor->UpdateResourceA(MAKEINTRESOURCE(24), MAKEINTRESOURCE(1), NSIS_DEFAULT_LANG, (LPBYTE) manifest.c_str(), manifest.length());
- }
- catch (exception& err) {
- ERROR_MSG("Error while setting manifest: %s\n", err.what());
- return PS_ERROR;
- }
-
- return PS_OK;
-}
-
-int CEXEBuild::check_write_output_errors() const
-{
- if (has_called_write_output)
- {
- ERROR_MSG("Error (write_output): write_output already called, can't continue\n");
- return PS_ERROR;
- }
-
- if (!build_output_filename[0])
- {
- ERROR_MSG("Error: invalid script: never had OutFile command\n");
- return PS_ERROR;
- }
-
- if (!build_sections.getlen())
- {
- ERROR_MSG("Error: invalid script: no sections specified\n");
- return PS_ERROR;
- }
-
- if (!build_entries.getlen())
- {
- ERROR_MSG("Error: invalid script: no entries specified\n");
- return PS_ERROR;
- }
-
- if (build_cursection)
- {
- ERROR_MSG("Error: Section left open at EOF\n");
- return PS_ERROR;
- }
-
- if (sectiongroup_open_cnt)
- {
- ERROR_MSG("Error: SectionGroup left open at EOF\n");
- return PS_ERROR;
- }
-
- if (cur_page)
- {
- ERROR_MSG("Error: PageEx left open at EOF\n");
- return PS_ERROR;
- }
-
- // deal with functions, for both install and uninstall modes.
- if (build_cursection_isfunc)
- {
- ERROR_MSG("Error: Function left open at EOF\n");
- return PS_ERROR;
- }
-
- return PS_OK;
-}
-
-int CEXEBuild::prepare_uninstaller() {
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (ubuild_entries.getlen())
- {
- if (!uninstaller_writes_used)
- {
- warning("Uninstaller script code found but WriteUninstaller never used - no uninstaller will be created.");
- return PS_OK;
- }
-
- build_uninst.flags|=build_header.flags&(CH_FLAGS_PROGRESS_COLORED|CH_FLAGS_NO_ROOT_DIR);
-
- set_uninstall_mode(1);
-
- DefineInnerLangString(NLF_UCAPTION);
-
- if (resolve_coderefs("uninstall"))
- return PS_ERROR;
-
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- // set sections to the first insttype
- PrepareInstTypes();
-#endif
-
- // Add standard strings to string table
- AddStandardStrings();
-
- set_uninstall_mode(0);
- }
- else if (uninstaller_writes_used)
- {
- ERROR_MSG("Error: no Uninstall section specified, but WriteUninstaller used %d time(s)\n",uninstaller_writes_used);
- return PS_ERROR;
- }
-#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
- return PS_OK;
-}
-
-int CEXEBuild::pack_exe_header()
-{
- if (!(build_packname[0] && build_packcmd[0])) {
- // header not asked to be packed
- return PS_OK;
- }
-
- // write out exe header, pack, read back in, and
- // update the header info
- FILE *tmpfile=FOPEN(build_packname,"wb");
- if (!tmpfile)
- {
- ERROR_MSG("Error: writing temporary file \"%s\" for pack\n",build_packname);
- return PS_ERROR;
- }
- fwrite(m_exehead,1,m_exehead_size,tmpfile);
- fclose(tmpfile);
- if (sane_system(build_packcmd) == -1)
- {
- remove(build_packname);
- ERROR_MSG("Error: calling packer on \"%s\"\n",build_packname);
- return PS_ERROR;
- }
-
- int result = update_exehead(build_packname);
- remove(build_packname);
-
- if (result != PS_OK)
- {
- ERROR_MSG("Error: reading temporary file \"%s\" after pack\n",build_packname);
- return result;
- }
-
- return PS_OK;
-}
-
-int CEXEBuild::write_output(void)
-{
-#ifndef NSIS_CONFIG_CRC_SUPPORT
- build_crcchk=0;
-#endif
-
- RET_UNLESS_OK( check_write_output_errors() );
-
- has_called_write_output=true;
-
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
- RET_UNLESS_OK( add_plugins_dir_initializer() );
-#endif //NSIS_CONFIG_PLUGIN_SUPPORT
-
-#ifdef NSIS_SUPPORT_VERSION_INFO
- RET_UNLESS_OK( AddVersionInfo() );
-#endif //NSIS_SUPPORT_VERSION_INFO
-
- RET_UNLESS_OK( prepare_uninstaller() );
-
- DefineInnerLangString(NLF_CAPTION);
- if (resolve_coderefs("install"))
- return PS_ERROR;
-
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- // set sections to the first insttype
- PrepareInstTypes();
-#endif
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- RET_UNLESS_OK( ProcessPages() );
-#endif //NSIS_CONFIG_VISIBLE_SUPPORT
-
- // Generate language tables
- RET_UNLESS_OK( GenerateLangTables() );
-
- // Setup user variables PE section
- RET_UNLESS_OK( SetVarsSection() );
-
- // Set XML manifest
- RET_UNLESS_OK( SetManifest() );
-
- // Add standard strings to string table
- AddStandardStrings();
-
- try {
- // Save all changes to the exe header
- close_res_editor();
- }
- catch (exception& err) {
- ERROR_MSG("\nError: %s\n", err.what());
- return PS_ERROR;
- }
-
- RET_UNLESS_OK( pack_exe_header() );
-
-
- build_optimize_datablock=0;
-
- int data_block_size_before_uninst = build_datablock.getlen();
-
- RET_UNLESS_OK( uninstall_generate() );
-
- crc32_t crc=0;
-
- {
- string full_path = get_full_path(build_output_filename);
- notify(MAKENSIS_NOTIFY_OUTPUT, full_path.c_str());
- INFO_MSG("\nOutput: \"%s\"\n", full_path.c_str());
- }
-
- FILE *fp = FOPEN(build_output_filename,"w+b");
- if (!fp)
- {
- ERROR_MSG("Can't open output file\n");
- return PS_ERROR;
- }
-
- if (fwrite(m_exehead,1,m_exehead_size,fp) != m_exehead_size)
- {
- ERROR_MSG("Error: can't write %d bytes to output\n",m_exehead_size);
- fclose(fp);
- return PS_ERROR;
- }
-
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- #ifdef NSIS_CONFIG_CRC_ANAL
- crc=CRC32(crc,m_exehead,m_exehead_size);
- #else
- crc=CRC32(crc,m_exehead+512,m_exehead_size-512);
- #endif
-#endif
-
- firstheader fh={0,};
- fh.nsinst[0]=FH_INT1;
- fh.nsinst[1]=FH_INT2;
- fh.nsinst[2]=FH_INT3;
-
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- fh.flags=(build_crcchk?(build_crcchk==2?FH_FLAGS_FORCE_CRC:0):FH_FLAGS_NO_CRC);
-#else
- fh.flags=0;
-#endif
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- if (build_header.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) fh.flags |= FH_FLAGS_SILENT;
-#endif
- fh.siginfo=FH_SIG;
-
- int installinfo_compressed;
- int fd_start = 0;
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- if (build_compress_whole)
- {
- int n = compressor->Init(build_compress_level, build_compress_dict_size);
- if (n != C_OK)
- {
- ERROR_MSG("Internal compiler error #12345: deflateInit() failed(%s [%d]).\n", compressor->GetErrStr(n), n);
- return PS_ERROR;
- }
- }
-#endif
-
- {
- GrowBuf ihd;
- {
- GrowBuf hdrcomp;
-
- PrepareHeaders(&hdrcomp);
-
- if (add_data((char*)hdrcomp.get(),hdrcomp.getlen(),&ihd) < 0)
- return PS_ERROR;
-
- fh.length_of_header=hdrcomp.getlen();
- installinfo_compressed=ihd.getlen();
- }
-
- if (!build_compress_whole)
- fh.length_of_all_following_data=ihd.getlen()+build_datablock.getlen()+(int)sizeof(firstheader)+(build_crcchk?sizeof(crc32_t):0);
- else
- fd_start=ftell(fp);
-
- try
- {
- file_writer_sink sink(fp);
- firstheader_writer w(&sink);
- w.write(&fh);
- }
- catch (...)
- {
- ERROR_MSG("Error: can't write %d bytes to output\n",sizeof(fh));
- fclose(fp);
- return PS_ERROR;
- }
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- if (build_compress_whole) {
- if (deflateToFile(fp,(char*)ihd.get(),ihd.getlen()))
- {
- fclose(fp);
- return PS_ERROR;
- }
- }
- else
-#endif
- {
- if (fwrite(ihd.get(),1,ihd.getlen(),fp) != (unsigned int)ihd.getlen())
- {
- ERROR_MSG("Error: can't write %d bytes to output\n",ihd.getlen());
- fclose(fp);
- return PS_ERROR;
- }
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- crc_writer_sink crc_sink((crc32_t *) &crc);
- firstheader_writer w(&crc_sink);
- w.write(&fh);
-
- crc=CRC32(crc,(unsigned char*)ihd.get(),ihd.getlen());
-#endif
- }
- }
-
- INFO_MSG("Install: ");
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- int np=build_header.blocks[NB_PAGES].num;
- INFO_MSG("%d page%s (%d bytes), ",np,np==1?"":"s",np*sizeof(page));
-#endif
- {
- int ns=build_sections.getlen()/sizeof(section);
- section *s=(section*)build_sections.get();
- int x;
- int req=0;
- for (x = 1; x < ns; x ++)
- {
- if (!s[x].name_ptr || s[x].flags & SF_RO) req++;
- }
- INFO_MSG("%d section%s",ns,ns==1?"":"s");
- if (req)
- {
- INFO_MSG(" (%d required)",req);
- }
- INFO_MSG(" (%d bytes), ", build_sections.getlen());
- }
- int ne=build_header.blocks[NB_ENTRIES].num;
- INFO_MSG("%d instruction%s (%d bytes), ",ne,ne==1?"":"s",ne*sizeof(entry));
- int ns=build_strlist.getnum();
- INFO_MSG("%d string%s (%d bytes), ",ns,ns==1?"":"s",build_strlist.getlen());
- int nlt=build_header.blocks[NB_LANGTABLES].num;
- INFO_MSG("%d language table%s (%d bytes).\n",nlt,nlt==1?"":"s",build_langtables.getlen());
- if (ubuild_entries.getlen())
- {
- INFO_MSG("Uninstall: ");
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- np=build_uninst.blocks[NB_PAGES].num;
- INFO_MSG("%d page%s (%d bytes), \n",np,np==1?"":"s",ubuild_pages.getlen());
-#endif
- {
- int ns=ubuild_sections.getlen()/sizeof(section);
- section *s=(section*)ubuild_sections.get();
- int x;
- int req=0;
- for (x = 1; x < ns; x ++)
- {
- if (!s[x].name_ptr || s[x].flags & SF_RO) req++;
- }
- INFO_MSG("%d section%s",ns,ns==1?"":"s");
- if (req)
- {
- INFO_MSG(" (%d required)",req);
- }
- INFO_MSG(" (%d bytes), ", ubuild_sections.getlen());
- }
- ne=build_uninst.blocks[NB_ENTRIES].num;
- INFO_MSG("%d instruction%s (%d bytes), ",ne,ne==1?"":"s",ubuild_entries.getlen());
- ns=ubuild_strlist.getnum();
- INFO_MSG("%d string%s (%d bytes), ",ns,ns==1?"":"s",ubuild_strlist.getlen());
- nlt=build_uninst.blocks[NB_LANGTABLES].num;
- INFO_MSG("%d language table%s (%d bytes).\n",nlt,nlt==1?"":"s",ubuild_langtables.getlen());
- }
-
-
- if (db_opt_save)
- {
- int total_out_size_estimate=
- m_exehead_size+sizeof(fh)+build_datablock.getlen()+(build_crcchk?sizeof(crc32_t):0);
- int pc=(int)(((INT64)db_opt_save*1000)/(db_opt_save+total_out_size_estimate));
- INFO_MSG("Datablock optimizer saved %d bytes (~%d.%d%%).\n",db_opt_save,
- pc/10,pc%10);
- }
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- INFO_MSG("\nUsing %s%s compression.\n\n", compressor->GetName(), build_compress_whole?" (compress whole)":"");
-#endif
-
- unsigned int total_usize=m_exehead_original_size;
-
- INFO_MSG("EXE header size: %10d / %d bytes\n",m_exehead_size,m_exehead_original_size);
-
- if (build_compress_whole) {
- INFO_MSG("Install code: (%d bytes)\n",
- sizeof(fh)+fh.length_of_header);
- }
- else {
- INFO_MSG("Install code: %10d / %d bytes\n",
- sizeof(fh)+installinfo_compressed,
- sizeof(fh)+fh.length_of_header);
- }
-
- total_usize+=sizeof(fh)+fh.length_of_header;
-
- {
- int dbsize, dbsizeu;
- dbsize = build_datablock.getlen();
- if (uninstall_size>0) dbsize-=uninstall_size;
-
- if (build_compress_whole) {
- dbsizeu=dbsize;
- INFO_MSG("Install data: (%d bytes)\n",dbsizeu);
- }
- else {
- dbsizeu = db_full_size - uninstall_size_full;
- INFO_MSG("Install data: %10d / %d bytes\n",dbsize,dbsizeu);
- }
- total_usize+=dbsizeu;
- }
-
- if (uninstall_size>=0)
- {
- if (build_compress_whole)
- INFO_MSG("Uninstall code+data: (%d bytes)\n",uninstall_size_full);
- else
- INFO_MSG("Uninstall code+data: %6d / %d bytes\n",uninstall_size,uninstall_size_full);
- total_usize+=uninstall_size_full;
- }
-
- if (build_compress_whole) {
- INFO_MSG("Compressed data: ");
- }
-
- if (build_datablock.getlen())
- {
- build_datablock.setro(TRUE);
- int dbl = build_datablock.getlen();
- int left = dbl;
- while (left > 0)
- {
- int l = min(build_filebuflen, left);
- char *dbptr = (char *) build_datablock.get(dbl - left, l);
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- if (build_compress_whole)
- {
- if (deflateToFile(fp,dbptr,l))
- {
- fclose(fp);
- return PS_ERROR;
- }
- }
- else
-#endif
- {
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- crc=CRC32(crc,(unsigned char *)dbptr,l);
-#endif
- if ((int)fwrite(dbptr,1,l,fp) != l)
- {
- ERROR_MSG("Error: can't write %d bytes to output\n",l);
- fclose(fp);
- return PS_ERROR;
- }
- fflush(fp);
- }
- build_datablock.release();
- left -= l;
- }
- build_datablock.setro(FALSE);
- build_datablock.clear();
- }
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- if (build_compress_whole)
- {
- if (deflateToFile(fp,NULL,0))
- {
- fclose(fp);
- return PS_ERROR;
- }
- compressor->End();
-
- unsigned fend = ftell(fp);
-
- fh.length_of_all_following_data=ftell(fp)-fd_start+(build_crcchk?sizeof(crc32_t):0);
- INFO_MSG(
- "%10d / %d bytes\n",
- ftell(fp) - fd_start,
- data_block_size_before_uninst + fh.length_of_header + sizeof(firstheader) + uninstall_size_full
- );
-
- fseek(fp,fd_start,SEEK_SET);
-
- try
- {
- file_writer_sink sink(fp);
- firstheader_writer w(&sink);
- w.write(&fh);
- }
- catch (...)
- {
- ERROR_MSG("Error: can't write %d bytes to output\n",sizeof(fh));
- fclose(fp);
- return PS_ERROR;
- }
-
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- if (build_crcchk)
- {
- // check rest of CRC
- fseek(fp,fd_start,SEEK_SET);
- for (;;)
- {
- char buf[32768];
- int l=fread(buf,1,sizeof(buf),fp);
- if (!l) break;
- crc=CRC32(crc,(unsigned char *)buf,l);
- }
- }
-#endif
- fseek(fp,fend,SEEK_SET); // reset eof flag
- }
-#endif
-
- if (build_crcchk)
- {
- total_usize+=sizeof(int);
- int rcrc = FIX_ENDIAN_INT32(crc);
- if (fwrite(&rcrc,1,sizeof(crc32_t),fp) != sizeof(crc32_t))
- {
- ERROR_MSG("Error: can't write %d bytes to output\n",sizeof(crc32_t));
- fclose(fp);
- return PS_ERROR;
- }
- INFO_MSG("CRC (0x%08X): 4 / 4 bytes\n",crc);
- }
- INFO_MSG("\n");
- {
- UINT pc=(UINT)(((UINT64)ftell(fp)*1000)/(total_usize));
- INFO_MSG("Total size: %10u / %u bytes (%u.%u%%)\n",
- ftell(fp),total_usize,pc/10,pc%10);
- }
- fclose(fp);
- print_warnings();
- return PS_OK;
-}
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
-int CEXEBuild::deflateToFile(FILE *fp, char *buf, int len) // len==0 to flush
-{
- build_compressor_set=true;
-
- char obuf[65536];
- bool flush=false;
- compressor->SetNextIn(buf,len);
- if (!buf||!len)
- {
- char a;
- compressor->SetNextIn(&a,0);
- flush=C_FINISH;
- }
- for (;;)
- {
- compressor->SetNextOut(obuf,sizeof(obuf));
- int ret=compressor->Compress(flush);
- if (ret<0 && (ret!=-1 || !flush))
- {
- ERROR_MSG("Error: deflateToFile: deflate() failed(%s [%d])\n", compressor->GetErrStr(ret), ret);
- return 1;
- }
- int l=compressor->GetNextOut()-obuf;
- if (l)
- {
- if (fwrite(obuf,1,l,fp) != (unsigned)l)
- {
- ERROR_MSG("Error: deflateToFile fwrite(%d) failed\n",l);
- return 1;
- }
- fflush(fp);
- }
- if (!compressor->GetAvailIn() && (!flush || !l)) break;
- }
- return 0;
-}
-#endif
-
-int CEXEBuild::uninstall_generate()
-{
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (ubuild_entries.getlen() && uninstaller_writes_used)
- {
- SCRIPT_MSG("Generating uninstaller... ");
-
- firstheader fh={0,};
-
- GrowBuf uhd;
- {
- GrowBuf udata;
-
- set_uninstall_mode(1);
-
- PrepareHeaders(&udata);
-
- fh.length_of_header=udata.getlen();
- int err=add_data((char*)udata.get(),udata.getlen(),&uhd);
- set_uninstall_mode(0);
- if (err < 0) return PS_ERROR;
- }
-
- crc32_t crc=0;
-
- // Get offsets of icons to replace for uninstall
- // Also makes sure that the icons are there and in the right size.
- if (generate_unicons_offsets(m_exehead, m_exehead_size, m_unicon_data) == 0)
- return PS_ERROR;
-
- entry *ent = (entry *) build_entries.get();
- if (!ent)
- return PS_ERROR;
- int ents = build_header.blocks[NB_ENTRIES].num;
- int uns = uninstaller_writes_used;
- int uninstdata_offset = build_datablock.getlen();
- while (ents--)
- {
- if (ent->which == EW_WRITEUNINSTALLER)
- {
- ent->offsets[1] = uninstdata_offset;
- ent->offsets[2] = m_unicon_size;
- uns--;
- if (!uns)
- break;
- }
- ent++;
- }
-
- if (add_db_data((char *)m_unicon_data,m_unicon_size) < 0)
- return PS_ERROR;
-
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- {
- // "create" the uninstaller
- LPBYTE uninst_header = (LPBYTE) malloc(m_exehead_size);
- if (!uninst_header)
- return PS_ERROR;
-
- memcpy(uninst_header, m_exehead, m_exehead_size);
-
- // patch the icons
- LPBYTE seeker = m_unicon_data;
- while (*seeker) {
- DWORD dwSize = FIX_ENDIAN_INT32(*(LPDWORD) seeker);
- seeker += sizeof(DWORD);
- DWORD dwOffset = FIX_ENDIAN_INT32(*(LPDWORD) seeker);
- seeker += sizeof(DWORD);
- memcpy(uninst_header + dwOffset, seeker, dwSize);
- seeker += dwSize;
- }
-
-#ifdef NSIS_CONFIG_CRC_ANAL
- crc=CRC32(crc, uninst_header, m_exehead_size);
-#else
- crc=CRC32(crc, uninst_header + 512, m_exehead_size - 512);
-#endif
-
- free(uninst_header);
- }
-#endif
- fh.nsinst[0]=FH_INT1;
- fh.nsinst[1]=FH_INT2;
- fh.nsinst[2]=FH_INT3;
- fh.flags=FH_FLAGS_UNINSTALL;
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- fh.flags|=(build_crcchk?(build_crcchk==2?FH_FLAGS_FORCE_CRC:0):FH_FLAGS_NO_CRC);
-#endif
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- if (build_uninst.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) fh.flags |= FH_FLAGS_SILENT;
-#endif
- fh.siginfo=FH_SIG;
- fh.length_of_all_following_data=
- uhd.getlen()+ubuild_datablock.getlen()+(int)sizeof(firstheader)+(build_crcchk?sizeof(crc32_t):0);
-
- MMapBuf udata;
-
- {
- growbuf_writer_sink sink(&udata);
- firstheader_writer w(&sink);
- w.write(&fh);
- }
-
- ubuild_datablock.setro(TRUE);
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- if (build_compress_whole) {
- // compress uninstaller too
- {
- char obuf[65536];
- int n = compressor->Init(build_compress_level, build_compress_dict_size);
- if (n != C_OK)
- {
- ERROR_MSG("Internal compiler error #12345: deflateInit() failed(%s [%d]).\n", compressor->GetErrStr(n), n);
- extern void quit(); quit();
- }
-
- compressor->SetNextIn((char*)uhd.get(), uhd.getlen());
- while (compressor->GetAvailIn())
- {
- compressor->SetNextOut(obuf, sizeof(obuf));
- compressor->Compress(0);
- if (compressor->GetNextOut() - obuf > 0)
- {
- udata.add(obuf, compressor->GetNextOut() - obuf);
- }
- }
-
- int avail_in = ubuild_datablock.getlen();
- int in_pos = 0;
- while (avail_in > 0) {
- int l = min(avail_in, build_filebuflen);
-
- char *p = (char*)ubuild_datablock.get(in_pos, l);
- compressor->SetNextIn(p, l);
-
- while (compressor->GetAvailIn())
- {
- compressor->SetNextOut(obuf, sizeof(obuf));
- compressor->Compress(0);
- if (compressor->GetNextOut() - obuf > 0)
- udata.add(obuf, compressor->GetNextOut() - obuf);
- }
-
- ubuild_datablock.release();
-
- avail_in -= l;
- in_pos += l;
- }
-
- for (;;)
- {
- compressor->SetNextOut(obuf, sizeof(obuf));
- compressor->Compress(C_FINISH);
- if (compressor->GetNextOut() - obuf > 0)
- udata.add(obuf, compressor->GetNextOut() - obuf);
- else break;
- }
- compressor->End();
- }
-
- firstheader *_fh=(firstheader *)udata.get(0, sizeof(firstheader));
- _fh->length_of_all_following_data=FIX_ENDIAN_INT32(udata.getlen()+(build_crcchk?sizeof(crc32_t):0));
- udata.release();
- }
- else
-#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
- {
- udata.add(uhd.get(), uhd.getlen());
-
- int st = udata.getlen();
- int length = ubuild_datablock.getlen();
- int left = length;
- udata.resize(st + left);
- while (left > 0)
- {
- int l = min(build_filebuflen, left);
- void *p = ubuild_datablock.get(length - left, l);
- memcpy(udata.get(st + length - left, l), p, l);
- udata.flush(l);
- udata.release();
- ubuild_datablock.release();
- left -= l;
- }
- }
-
- ubuild_datablock.clear();
-
- udata.setro(TRUE);
-
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- if (build_crcchk)
- {
- int pos = 0;
- int left = udata.getlen();
- while (left > 0)
- {
- int l = min(build_filebuflen, left);
- crc = CRC32(crc, (unsigned char *) udata.get(pos, l), l);
- udata.release();
- pos += l;
- left -= l;
- }
- udata.setro(FALSE);
- FIX_ENDIAN_INT32_INPLACE(crc);
- udata.add(&crc, sizeof(crc));
- udata.setro(TRUE);
- }
-#endif
-
- if (add_db_data(&udata) < 0)
- return PS_ERROR;
-
- udata.clear();
-
- //uninstall_size_full=fh.length_of_all_following_data + sizeof(int) + unicondata_size - 32 + sizeof(int);
- uninstall_size_full=fh.length_of_all_following_data+m_unicon_size;
-
- // compressed size
- uninstall_size=build_datablock.getlen()-uninstdata_offset;
-
- SCRIPT_MSG("Done!\n");
- }
-#endif
- return PS_OK;
-}
-
-#define SWAP(x,y,i) { i _ii; _ii=x; x=y; y=_ii; }
-
-void CEXEBuild::set_uninstall_mode(int un)
-{
- if (un != uninstall_mode)
- {
- uninstall_mode=un;
- if (un)
- {
- cur_datablock=&ubuild_datablock;
- cur_datablock_cache=&ubuild_datablock_cache;
- cur_entries=&ubuild_entries;
- cur_instruction_entry_map=&ubuild_instruction_entry_map;
- cur_functions=&ubuild_functions;
- cur_labels=&ubuild_labels;
- cur_pages=&ubuild_pages;
- cur_sections=&ubuild_sections;
- cur_header=&build_uninst;
- cur_strlist=&ubuild_strlist;
- cur_langtables=&ubuild_langtables;
- cur_ctlcolors=&ubuild_ctlcolors;
-
- definedlist.add("__UNINSTALL__");
- }
- else
- {
- cur_datablock=&build_datablock;
- cur_datablock_cache=&build_datablock_cache;
- cur_entries=&build_entries;
- cur_instruction_entry_map=&build_instruction_entry_map;
- cur_functions=&build_functions;
- cur_labels=&build_labels;
- cur_pages=&build_pages;
- cur_sections=&build_sections;
- cur_header=&build_header;
- cur_strlist=&build_strlist;
- cur_langtables=&build_langtables;
- cur_ctlcolors=&build_ctlcolors;
-
- definedlist.del("__UNINSTALL__");
- }
-
- SWAP(db_opt_save_u,db_opt_save,int);
- SWAP(db_comp_save_u,db_comp_save,int);
- SWAP(db_full_size_u,db_full_size,int);
- }
-}
-
-extern FILE *g_output;
-
-void CEXEBuild::warning(const char *s, ...)
-{
- char buf[NSIS_MAX_STRLEN*10];
- va_list val;
- va_start(val,s);
-#ifdef _WIN32
- vsprintf(buf,s,val);
-#else
- vsnprintf(buf,NSIS_MAX_STRLEN*10,s,val);
-#endif
- va_end(val);
- m_warnings.add(buf,0);
- notify(MAKENSIS_NOTIFY_WARNING,buf);
- if (display_warnings)
- {
- fprintf(g_output,"warning: %s\n",buf);
- fflush(g_output);
- }
-}
-
-void CEXEBuild::warning_fl(const char *s, ...)
-{
- char buf[NSIS_MAX_STRLEN*10];
- va_list val;
- va_start(val,s);
-#ifdef _WIN32
- vsprintf(buf,s,val);
-#else
- vsnprintf(buf,NSIS_MAX_STRLEN*10,s,val);
-#endif
- va_end(val);
- sprintf(buf+strlen(buf)," (%s:%d)",curfilename,linecnt);
- m_warnings.add(buf,0);
- notify(MAKENSIS_NOTIFY_WARNING,buf);
- if (display_warnings)
- {
- fprintf(g_output,"warning: %s\n",buf);
- fflush(g_output);
- }
-}
-
-void CEXEBuild::ERROR_MSG(const char *s, ...) const
-{
- if (display_errors || notify_hwnd)
- {
- char buf[NSIS_MAX_STRLEN*10];
- va_list val;
- va_start(val,s);
-#ifdef _WIN32
- vsprintf(buf,s,val);
-#else
- vsnprintf(buf,NSIS_MAX_STRLEN*10,s,val);
-#endif
- va_end(val);
- notify(MAKENSIS_NOTIFY_ERROR,buf);
- if (display_errors)
- {
- fprintf(g_output,"%s",buf);
- fflush(g_output);
- }
- }
-}
-
-void CEXEBuild::SCRIPT_MSG(const char *s, ...) const
-{
- if (display_script)
- {
- va_list val;
- va_start(val,s);
- vfprintf(g_output,s,val);
- va_end(val);
- fflush(g_output);
- }
-}
-
-void CEXEBuild::INFO_MSG(const char *s, ...) const
-{
- if (display_info)
- {
- va_list val;
- va_start(val,s);
- vfprintf(g_output,s,val);
- va_end(val);
- fflush(g_output);
- }
-}
-
-void CEXEBuild::print_warnings()
-{
- int nw=0,x=m_warnings.getlen();
- if (!x || !display_warnings) return;
- char *p=m_warnings.get();
- while (x>0) if (!p[--x]) nw++;
- fprintf(g_output,"\n%d warning%s:\n",nw,nw==1?"":"s");
- for (x = 0; x < nw; x ++)
- {
- fprintf(g_output," %s\n",p);
- p+=strlen(p)+1;
- }
- fflush(g_output);
-}
-
-void CEXEBuild::notify(notify_e code, const char *data) const
-{
-#ifdef _WIN32
- if (notify_hwnd)
- {
- COPYDATASTRUCT cds = {(DWORD)code, strlen(data)+1, (void *) data};
- SendMessage(notify_hwnd, WM_COPYDATA, 0, (LPARAM)&cds);
- }
-#endif
-}
-
-// Added by Ximon Eighteen 5th August 2002
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
-void CEXEBuild::build_plugin_table(void)
-{
- if (plugins_processed)
- return;
- plugins_processed=1;
-
- plugin_used = false;
- uninst_plugin_used = false;
- string searchPath = definedlist.find("NSISDIR");
- searchPath += PLATFORM_PATH_SEPARATOR_STR"Plugins";
- INFO_MSG("Processing plugin dlls: \"%s" PLATFORM_PATH_SEPARATOR_STR "*.dll\"\n",searchPath.c_str());
- m_plugins.FindCommands(searchPath, display_info?true:false);
- INFO_MSG("\n");
-}
-
-#define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags, flag)/sizeof(int))
-
-int CEXEBuild::add_plugins_dir_initializer(void)
-{
- if (!plugin_used && !uninst_plugin_used) return PS_OK;
-
- SCRIPT_MSG("Adding plug-ins initializing function... ");
-
- bool uninstall = !plugin_used;
-
- int ret;
- int zero_offset;
-
- int var_zero;
- var_zero=m_UserVarNames.get("0");
-
-again:
- // Function [un.]Initialize_____Plugins
- ret=add_function(uninstall?"un.Initialize_____Plugins":"Initialize_____Plugins");
- if (ret != PS_OK) return ret;
-
- // don't move this, depends on [un.]
- zero_offset=add_string("$0");
-
- // SetDetailsPrint none
- ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), add_intstring(6));
- if (ret != PS_OK) return ret;
-
- // StrCmp $PLUGINSDIR ""
- ret=add_entry_direct(EW_STRCMP, add_string("$PLUGINSDIR"), 0, 0, ns_label.add("Initialize_____Plugins_done",0));
- if (ret != PS_OK) return ret;
- // Push $0
- ret=add_entry_direct(EW_PUSHPOP, zero_offset);
- if (ret != PS_OK) return ret;
- // ClearErrors
- ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(exec_error));
- if (ret != PS_OK) return ret;
- // GetTempFileName $0
- ret=add_entry_direct(EW_GETTEMPFILENAME, var_zero, add_string("$TEMP"));
- if (ret != PS_OK) return ret;
- // Delete $0 [simple, nothing that could clash with special temp permissions]
- ret=add_entry_direct(EW_DELETEFILE, zero_offset, DEL_SIMPLE);
- if (ret != PS_OK) return ret;
- // CraeteDirectory $0 - a dir instead of that temp file
- ret=add_entry_direct(EW_CREATEDIR, zero_offset);
- if (ret != PS_OK) return ret;
- // IfErrors Initialize_____Plugins_error - detect errors
- ret=add_entry_direct(EW_IFFLAG, ns_label.add("Initialize_____Plugins_error",0), 0, FLAG_OFFSET(exec_error));
- if (ret != PS_OK) return ret;
- // Copy $0 to $PLUGINSDIR
- ret=add_entry_direct(EW_ASSIGNVAR, m_UserVarNames.get("PLUGINSDIR"), zero_offset);
- if (ret != PS_OK) return ret;
- // Pop $0
- ret=add_entry_direct(EW_PUSHPOP, var_zero, 1);
- if (ret != PS_OK) return ret;
-
- // done
- if (add_label("Initialize_____Plugins_done")) return PS_ERROR;
- // Return
- ret=add_entry_direct(EW_RET);
- if (ret != PS_OK) return ret;
-
- // error
- if (add_label("Initialize_____Plugins_error")) return PS_ERROR;
- // error message box
- ret=add_entry_direct(EW_MESSAGEBOX, MB_OK|MB_ICONSTOP|(IDOK<<21), add_string("Error! Can't initialize plug-ins directory. Please try again later."));
- if (ret != PS_OK) return ret;
- // Quit
- ret=add_entry_direct(EW_QUIT);
- if (ret != PS_OK) return ret;
-
- // FunctionEnd
- ret=function_end();
- if (ret != PS_OK) return ret;
-
- if (uninst_plugin_used && !uninstall) {
- uninstall = true;
- goto again;
- }
-
- SCRIPT_MSG("Done!\n");
-
- return PS_OK;
-}
-#endif // NSIS_CONFIG_PLUGIN_SUPPORT
-
-void CEXEBuild::init_res_editor()
-{
- build_compressor_set = true;
- if (!res_editor)
- res_editor = new CResourceEditor(m_exehead, m_exehead_size);
-}
-
-void CEXEBuild::close_res_editor()
-{
- if (!res_editor) return;
- DWORD newsize;
-
- // get size
- newsize = res_editor->Save(NULL, newsize);
- unsigned char *new_header = new unsigned char[newsize];
-
- // save
- int rc = res_editor->Save(new_header, newsize);
- assert(rc == 0);
-
- update_exehead(new_header, newsize);
-
- // TODO: resource-controlling class
- delete [] new_header;
-
- delete res_editor;
- res_editor=0;
-}
-
-int CEXEBuild::DeclaredUserVar(const char *szVarName)
-{
- if (m_ShellConstants.get((char*)szVarName) >= 0)
- {
- ERROR_MSG("Error: name \"%s\" in use by constant\n", szVarName);
- return PS_ERROR;
- }
-
- int idxUserVar = m_UserVarNames.get((char*)szVarName);
- if (idxUserVar >= 0)
- {
- ERROR_MSG("Error: variable \"%s\" already declared\n", szVarName);
- return PS_ERROR;
- }
- const char *pVarName = szVarName;
- int iVarLen = strlen(szVarName);
-
- if (iVarLen > 60)
- {
- ERROR_MSG("Error: variable name too long!\n");
- return PS_ERROR;
- }
- else if (!iVarLen)
- {
- ERROR_MSG("Error: variable with empty name!\n");
- return PS_ERROR;
- }
- else
- {
- while (*pVarName)
- {
- if (!isSimpleChar(*pVarName))
- {
- ERROR_MSG("Error: invalid characters in variable name \"%s\", use only characters [a-z][A-Z][0-9] and '_'\n", szVarName);
- return PS_ERROR;
- }
- pVarName++;
- }
- }
-
- m_UserVarNames.add(szVarName);
- if (m_UserVarNames.getnum() > MAX_CODED)
- {
- ERROR_MSG("Error: too many user variables declared. Maximum allowed is %u.\n", MAX_CODED - m_iBaseVarsNum);
- return PS_ERROR;
- }
- return PS_OK;
-}
-
-
-int CEXEBuild::GetUserVarIndex(LineParser &line, int token)
-{
- char *p = line.gettoken_str(token);
- if ( *p == '$' && *(p+1) )
- {
- int idxUserVar = m_UserVarNames.get((char *)p+1);
- if (idxUserVar >= 0 && m_UserVarNames.get_reference(idxUserVar) >= 0)
- {
- m_UserVarNames.inc_reference(idxUserVar);
- return idxUserVar;
- }
- else
- {
- int idxConst = m_ShellConstants.get((char *)p+1);
- if (idxConst >= 0)
- {
- ERROR_MSG("Error: cannot change constants : %s\n", p);
- }
- }
- }
- return -1;
-}
-
-void CEXEBuild::VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList)
-{
- for (int i = m_iBaseVarsNum; i < pVarsStringList->getnum(); i++)
- {
- if (!pVarsStringList->get_reference(i))
- {
- warning("Variable \"%s\" not referenced or never set, wasting memory!", pVarsStringList->idx2name(i));
- }
- }
-}
-
-int CEXEBuild::set_compressor(const string& compressor, const bool solid) {
- string stub = stubs_dir + PLATFORM_PATH_SEPARATOR_STR + compressor;
- if (solid)
- stub += "_solid";
-
- return update_exehead(stub, &m_exehead_original_size);
-}
-
-int CEXEBuild::update_exehead(const string& file, size_t *size/*=NULL*/) {
- FILE *tmpfile = fopen(file.c_str(), "rb");
- if (!tmpfile)
- {
- ERROR_MSG("Error: opening stub \"%s\"\n", file.c_str());
- return PS_ERROR;
- }
-
- fseek(tmpfile, 0, SEEK_END);
- size_t exehead_size = ftell(tmpfile);
-
- unsigned char *exehead = new unsigned char[exehead_size];
- fseek(tmpfile, 0, SEEK_SET);
- if (fread(exehead, 1, exehead_size, tmpfile) != exehead_size)
- {
- ERROR_MSG("Error: reading stub \"%s\"\n", file.c_str());
- fclose(tmpfile);
- delete [] exehead;
- return PS_ERROR;
- }
- fclose(tmpfile);
-
- update_exehead(exehead, exehead_size);
-
- if (size)
- *size = exehead_size;
-
- delete [] exehead;
-
- return PS_OK;
-}
-
-void CEXEBuild::update_exehead(const unsigned char *new_exehead, size_t new_size) {
- assert(m_exehead != new_exehead);
-
- // align exehead to 512
- m_exehead_size = align_to_512(new_size);
-
- delete [] m_exehead;
- m_exehead = new unsigned char[m_exehead_size];
-
- // copy exehead
- memcpy(m_exehead, new_exehead, new_size);
-
- // zero rest of exehead
- memset(m_exehead + new_size, 0, m_exehead_size - new_size);
-}
-
-void CEXEBuild::set_code_type_predefines(const char *value)
-{
- definedlist.del("__SECTION__");
- definedlist.del("__FUNCTION__");
- definedlist.del("__PAGEEX__");
- definedlist.del("__GLOBAL__");
-
- switch (GetCurrentTokenPlace())
- {
- case TP_SEC:
- definedlist.add("__SECTION__", value==NULL?"":value);
- break;
- case TP_FUNC:
- definedlist.add("__FUNCTION__", value==NULL?"":value);
- break;
- case TP_PAGEEX:
- definedlist.add("__PAGEEX__", value==NULL?"":value);
- break;
- default:
- definedlist.add("__GLOBAL__");
- }
-}
-
+/*
+ * build.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+#include <stdio.h>
+#include "exehead/config.h"
+
+#include "version.h"
+
+#include "build.h"
+#include "util.h"
+#include "fileform.h"
+#include "writer.h"
+#include "crc32.h"
+#include "manifest.h"
+#include "icon.h"
+
+#include <stdexcept>
+
+#include "exehead/resource.h"
+#include "ResourceEditor.h"
+#include "DialogTemplate.h"
+#include "ResourceVersionInfo.h"
+
+#ifndef _WIN32
+# include <locale.h>
+# include <unistd.h>
+# include <limits.h>
+# include <stdlib.h>
+# include <stdarg.h>
+#endif
+
+#include <cassert> // for assert
+
+#define RET_UNLESS_OK( function_rc ) do { \
+ int rc = (function_rc); \
+ if ( rc != PS_OK) \
+ return rc; \
+} while (false)
+
+using namespace std;
+
+namespace { // begin anonymous namespace
+
+bool isSimpleChar(char ch)
+{
+ return (ch == '.' ) || (ch == '_' ) || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
+}
+
+} // end of anonymous namespace
+
+void CEXEBuild::define(const char *p, const char *v)
+{
+ definedlist.add(p,v);
+}
+
+CEXEBuild::~CEXEBuild()
+{
+ free_loaded_icon(installer_icon);
+ free_loaded_icon(uninstaller_icon);
+
+ delete [] m_exehead;
+
+ int nlt = lang_tables.getlen() / sizeof(LanguageTable);
+ LanguageTable *nla = (LanguageTable*)lang_tables.get();
+
+ for (int i = 0; i < nlt; i++) {
+ DeleteLangTable(nla+i);
+ }
+}
+
+CEXEBuild::CEXEBuild() :
+ m_exehead(0),
+ m_exehead_size(0)
+{
+ linecnt = 0;
+ fp = 0;
+ curfilename = 0;
+
+ display_info=1;
+ display_script=1;
+ display_errors=1;
+ display_warnings=1;
+
+ cur_ifblock=NULL;
+ last_line_had_slash=0;
+ inside_comment=false;
+ multiple_entries_instruction=0;
+
+ build_include_depth=0;
+
+ has_called_write_output=false;
+
+ ns_func.add("",0); // make sure offset 0 is special on these (i.e. never used by a label)
+ ns_label.add("",0);
+
+ definedlist.add("NSIS_VERSION", NSIS_VERSION);
+
+ // automatically generated header file containing all defines
+#include "defines.h"
+
+ // no longer optional
+ definedlist.add("NSIS_SUPPORT_STANDARD_PREDEFINES");
+ definedlist.add("NSIS_SUPPORT_NAMED_USERVARS");
+ definedlist.add("NSIS_SUPPORT_LANG_IN_STRINGS");
+
+#ifdef _WIN32
+ definedlist.add("NSIS_WIN32_MAKENSIS");
+#endif
+
+ db_opt_save=db_comp_save=db_full_size=db_opt_save_u=db_comp_save_u=db_full_size_u=0;
+
+ // Added by Amir Szekely 31st July 2002
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ compressor = &zlib_compressor;
+#endif
+ build_compressor_set = false;
+ build_compressor_final = false;
+#ifdef NSIS_ZLIB_COMPRESS_WHOLE
+ build_compress_whole = true;
+#else
+ build_compress_whole = false;
+#endif
+ build_compress=1;
+ build_compress_level=9;
+ build_compress_dict_size=1<<23;
+
+ cur_entries=&build_entries;
+ cur_instruction_entry_map=&build_instruction_entry_map;
+ cur_datablock=&build_datablock;
+ cur_datablock_cache=&build_datablock_cache;
+ cur_functions=&build_functions;
+ cur_labels=&build_labels;
+ cur_sections=&build_sections;
+ cur_header=&build_header;
+ cur_strlist=&build_strlist;
+ cur_langtables=&build_langtables;
+ cur_ctlcolors=&build_ctlcolors;
+ cur_pages=&build_pages;
+ cur_page=0;
+ cur_page_type=-1;
+
+ build_filebuflen=32<<20; // 32mb
+
+ sectiongroup_open_cnt=0;
+ build_cursection_isfunc=0;
+ build_cursection=NULL;
+ // init public data.
+ build_packname[0]=build_packcmd[0]=build_output_filename[0]=0;
+
+ // Added by ramon 23 May 2003
+ build_allowskipfiles=1;
+
+ // Added by ramon 6 jun 2003
+#ifdef NSIS_SUPPORT_VERSION_INFO
+ version_product_v[0]=0;
+#endif
+
+ build_overwrite=build_last_overwrite=0;
+ build_crcchk=1;
+ build_datesave=1;
+ build_optimize_datablock=1;
+
+ memset(&build_header,-1,sizeof(build_header));
+
+ build_header.install_reg_rootkey=0;
+ build_header.flags=CH_FLAGS_NO_ROOT_DIR;
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ build_header.lb_bg=RGB(0,0,0);
+ build_header.lb_fg=RGB(0,255,0);
+#endif
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ build_header.license_bg=-COLOR_BTNFACE;
+#endif
+ build_header.install_directory_ptr=0;
+ build_header.install_directory_auto_append=0;
+ build_header.install_reg_key_ptr=0;
+ build_header.install_reg_value_ptr=0;
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ memset(build_header.install_types,0,sizeof(build_header.install_types));
+#endif
+ memset(&build_header.blocks,0,sizeof(build_header.blocks));
+
+ uninstall_mode=0;
+ uninstall_size_full=0;
+ uninstall_size=-1;
+
+ memset(&build_uninst,-1,sizeof(build_uninst));
+
+ build_header.install_reg_rootkey=0;
+ build_uninst.flags=0;
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ build_uninst.lb_bg=RGB(0,0,0);
+ build_uninst.lb_fg=RGB(0,255,0);
+#endif
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ build_uninst.license_bg=-COLOR_BTNFACE;
+#endif
+ build_uninst.install_directory_ptr=0;
+ build_uninst.install_directory_auto_append=0;
+ build_uninst.install_reg_key_ptr=0;
+ build_uninst.install_reg_value_ptr=0;
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ memset(build_uninst.install_types,0,sizeof(build_uninst.install_types));
+#endif
+ memset(&build_uninst.blocks,0,sizeof(build_uninst.blocks));
+
+ uninstaller_writes_used=0;
+
+ build_strlist.add("",0);
+ ubuild_strlist.add("",0);
+
+ build_langstring_num=0;
+ ubuild_langstring_num=0;
+
+ build_font[0]=0;
+ build_font_size=0;
+
+ m_unicon_size=0;
+
+ branding_image_found=false;
+
+ no_space_texts=false;
+
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+ build_plugin_unload=0;
+ plugins_processed=0;
+#endif
+
+ last_used_lang=NSIS_DEFAULT_LANG;
+
+ res_editor=0;
+
+ manifest_comctl = manifest::comctl_old;
+ manifest_exec_level = manifest::exec_level_none;
+
+ enable_last_page_cancel=0;
+ uenable_last_page_cancel=0;
+
+ license_res_id=IDD_LICENSE;
+
+ disable_window_icon=0;
+
+ notify_hwnd=0;
+
+#ifdef NSIS_SUPPORT_BGBG
+ bg_default_font.lfHeight=40;
+ bg_default_font.lfWidth=0;
+ bg_default_font.lfEscapement=0;
+ bg_default_font.lfOrientation=0;
+ bg_default_font.lfWeight=FW_BOLD;
+ bg_default_font.lfItalic=TRUE;
+ bg_default_font.lfUnderline=FALSE;
+ bg_default_font.lfStrikeOut=FALSE;
+ bg_default_font.lfCharSet=DEFAULT_CHARSET;
+ bg_default_font.lfOutPrecision=OUT_DEFAULT_PRECIS;
+ bg_default_font.lfClipPrecision=CLIP_DEFAULT_PRECIS;
+ bg_default_font.lfQuality=DEFAULT_QUALITY;
+ bg_default_font.lfPitchAndFamily=DEFAULT_PITCH;
+ strncpy(bg_default_font.lfFaceName,"Times New Roman",LF_FACESIZE);
+ memcpy(&bg_font,&bg_default_font,sizeof(LOGFONT));
+#endif
+
+ defcodepage_set=false;
+ uDefCodePage=CP_ACP;
+
+ InitLangTables();
+
+ // Register static user variables $0, $1 and so on
+ // with ONE of reference count, to avoid warning on this vars
+ char Aux[3];
+ int i;
+ for (i = 0; i < 10; i++) // 0 - 9
+ {
+ sprintf(Aux, "%d", i);
+ m_UserVarNames.add(Aux,1);
+ }
+ for (i = 0; i < 10; i++) // 10 - 19
+ {
+ sprintf(Aux, "R%d", i);
+ m_UserVarNames.add(Aux,1);
+ }
+ m_UserVarNames.add("CMDLINE",1); // 20 everything before here doesn't have trailing slash removal
+ m_UserVarNames.add("INSTDIR",1); // 21
+ m_UserVarNames.add("OUTDIR",1); // 22
+ m_UserVarNames.add("EXEDIR",1); // 23
+ m_UserVarNames.add("LANGUAGE",1); // 24
+ m_UserVarNames.add("TEMP",-1); // 25
+ m_UserVarNames.add("PLUGINSDIR",-1); // 26
+ m_UserVarNames.add("EXEPATH",-1); // 27
+ m_UserVarNames.add("EXEFILE",-1); // 28
+ m_UserVarNames.add("HWNDPARENT",-1); // 29
+ m_UserVarNames.add("_CLICK",-1); // 30
+ m_UserVarNames.add("_OUTDIR",1); // 31
+
+ m_iBaseVarsNum = m_UserVarNames.getnum();
+
+ m_ShellConstants.add("WINDIR",CSIDL_WINDOWS,CSIDL_WINDOWS);
+ m_ShellConstants.add("SYSDIR",CSIDL_SYSTEM,CSIDL_SYSTEM);
+ m_ShellConstants.add("SMPROGRAMS",CSIDL_PROGRAMS, CSIDL_COMMON_PROGRAMS);
+ m_ShellConstants.add("SMSTARTUP",CSIDL_STARTUP, CSIDL_COMMON_STARTUP);
+ m_ShellConstants.add("DESKTOP",CSIDL_DESKTOPDIRECTORY, CSIDL_COMMON_DESKTOPDIRECTORY);
+ m_ShellConstants.add("STARTMENU",CSIDL_STARTMENU, CSIDL_COMMON_STARTMENU);
+ m_ShellConstants.add("QUICKLAUNCH", CSIDL_APPDATA, CSIDL_APPDATA);
+ m_ShellConstants.add("DOCUMENTS",CSIDL_PERSONAL, CSIDL_COMMON_DOCUMENTS);
+ m_ShellConstants.add("SENDTO",CSIDL_SENDTO, CSIDL_SENDTO);
+ m_ShellConstants.add("RECENT",CSIDL_RECENT, CSIDL_RECENT);
+ m_ShellConstants.add("FAVORITES",CSIDL_FAVORITES, CSIDL_COMMON_FAVORITES);
+ m_ShellConstants.add("MUSIC",CSIDL_MYMUSIC, CSIDL_COMMON_MUSIC);
+ m_ShellConstants.add("PICTURES",CSIDL_MYPICTURES, CSIDL_COMMON_PICTURES);
+ m_ShellConstants.add("VIDEOS",CSIDL_MYVIDEO, CSIDL_COMMON_VIDEO);
+ m_ShellConstants.add("NETHOOD", CSIDL_NETHOOD, CSIDL_NETHOOD);
+ m_ShellConstants.add("FONTS", CSIDL_FONTS, CSIDL_FONTS);
+ m_ShellConstants.add("TEMPLATES", CSIDL_TEMPLATES, CSIDL_COMMON_TEMPLATES);
+ m_ShellConstants.add("APPDATA", CSIDL_APPDATA, CSIDL_COMMON_APPDATA);
+ m_ShellConstants.add("LOCALAPPDATA", CSIDL_LOCAL_APPDATA, CSIDL_LOCAL_APPDATA);
+ m_ShellConstants.add("PRINTHOOD", CSIDL_PRINTHOOD, CSIDL_PRINTHOOD);
+ //m_ShellConstants.add("ALTSTARTUP", CSIDL_ALTSTARTUP, CSIDL_COMMON_ALTSTARTUP);
+ m_ShellConstants.add("INTERNET_CACHE", CSIDL_INTERNET_CACHE, CSIDL_INTERNET_CACHE);
+ m_ShellConstants.add("COOKIES", CSIDL_COOKIES, CSIDL_COOKIES);
+ m_ShellConstants.add("HISTORY", CSIDL_HISTORY, CSIDL_HISTORY);
+ m_ShellConstants.add("PROFILE", CSIDL_PROFILE, CSIDL_PROFILE);
+ m_ShellConstants.add("ADMINTOOLS", CSIDL_ADMINTOOLS, CSIDL_COMMON_ADMINTOOLS);
+ m_ShellConstants.add("RESOURCES", CSIDL_RESOURCES, CSIDL_RESOURCES);
+ m_ShellConstants.add("RESOURCES_LOCALIZED", CSIDL_RESOURCES_LOCALIZED, CSIDL_RESOURCES_LOCALIZED);
+ m_ShellConstants.add("CDBURN_AREA", CSIDL_CDBURN_AREA, CSIDL_CDBURN_AREA);
+
+ unsigned int program_files = add_string("ProgramFilesDir", 0);
+ unsigned int program_files_def = add_string("C:\\Program Files");
+
+ if ((program_files >= 0x40) || (program_files_def >= 0xFF))
+ {
+ // see Source\exehead\util.c for implementation details
+ // basically, it knows it needs to get folders from the registry when the 0x80 is on
+ ERROR_MSG("Internal compiler error: too many strings added to strings block before adding shell constants!\n");
+ throw out_of_range("Internal compiler error: too many strings added to strings block before adding shell constants!");
+ }
+
+ m_ShellConstants.add("PROGRAMFILES", 0x80 | program_files, program_files_def);
+ m_ShellConstants.add("PROGRAMFILES32", 0x80 | program_files, program_files_def);
+ m_ShellConstants.add("PROGRAMFILES64", 0xC0 | program_files, program_files_def);
+
+ unsigned int common_files = add_string("CommonFilesDir", 0);
+ unsigned int common_files_def = add_string("$PROGRAMFILES\\Common Files");
+
+ if ((common_files > 0x40) || (common_files_def > 0xFF))
+ {
+ ERROR_MSG("Internal compiler error: too many strings added to strings block before adding shell constants!\n");
+ throw out_of_range("Internal compiler error: too many strings added to strings block before adding shell constants!");
+ }
+
+ m_ShellConstants.add("COMMONFILES", 0x80 | common_files, common_files_def);
+ m_ShellConstants.add("COMMONFILES32", 0x80 | common_files, common_files_def);
+ m_ShellConstants.add("COMMONFILES64", 0xC0 | common_files, common_files_def);
+
+ set_uninstall_mode(1);
+
+ unsigned int uprogram_files = add_string("ProgramFilesDir", 0);
+ unsigned int uprogram_files_def = add_string("C:\\Program Files");
+ unsigned int ucommon_files = add_string("CommonFilesDir", 0);
+ unsigned int ucommon_files_def = add_string("$PROGRAMFILES\\Common Files");
+
+ if (uprogram_files != program_files
+ || uprogram_files_def != program_files_def
+ || ucommon_files != common_files
+ || ucommon_files_def != common_files_def)
+ {
+ ERROR_MSG("Internal compiler error: installer's shell constants are different than uninstallers!\n");
+ throw out_of_range("Internal compiler error: installer's shell constants are different than uninstallers!");
+ }
+
+ set_uninstall_mode(0);
+
+ set_code_type_predefines();
+}
+
+void CEXEBuild::initialize(const char *makensis_path)
+{
+ string nsis_dir;
+ const char *dir = getenv("NSISDIR");
+ if (dir) nsis_dir = dir;
+ else {
+#ifndef NSIS_CONFIG_CONST_DATA_PATH
+ nsis_dir = get_executable_dir(makensis_path);
+#else
+ nsis_dir = PREFIX_DATA;
+#endif
+ }
+ definedlist.add("NSISDIR", nsis_dir.c_str());
+
+ string includes_dir = nsis_dir;
+ includes_dir += PLATFORM_PATH_SEPARATOR_STR"Include";
+ include_dirs.add(includes_dir.c_str(),0);
+
+ stubs_dir = nsis_dir;
+ stubs_dir += PLATFORM_PATH_SEPARATOR_STR"Stubs";
+
+ if (set_compressor("zlib", false) != PS_OK)
+ {
+ throw runtime_error("error setting default stub");
+ }
+
+ string uninst = stubs_dir + PLATFORM_PATH_SEPARATOR_STR + "uninst";
+ uninstaller_icon = load_icon_file(uninst.c_str());
+}
+
+
+int CEXEBuild::getcurdbsize() { return cur_datablock->getlen(); }
+
+// returns offset in stringblock
+int CEXEBuild::add_string(const char *string, int process/*=1*/, WORD codepage/*=CP_ACP*/)
+{
+ if (!string || !*string) return 0;
+
+ if (*string == '$' && *(string+1) == '(') {
+ int idx = 0;
+ char *cp = strdup(string+2);
+ char *p = strchr(cp, ')');
+ if (p && p[1] == '\0' ) { // if string is only a language str identifier
+ *p = 0;
+ idx = DefineLangString(cp, process);
+ }
+ free(cp);
+ if (idx < 0) return idx;
+ }
+
+ if (!process) return cur_strlist->add(string,2);
+
+ char buf[NSIS_MAX_STRLEN*4];
+ preprocess_string(buf,string,codepage);
+ return cur_strlist->add(buf,2);
+}
+
+int CEXEBuild::add_intstring(const int i) // returns offset in stringblock
+{
+ char i_str[1024];
+ wsprintf(i_str, "%d", i);
+ return add_string(i_str);
+}
+
+// based on Dave Laundon's code
+int CEXEBuild::preprocess_string(char *out, const char *in, WORD codepage/*=CP_ACP*/)
+{
+ const char *p=in;
+ while (*p)
+ {
+ const char *np = CharNextExA(codepage, p, 0);
+ if (np - p > 1) // multibyte char
+ {
+ int l = np - p;
+ while (l--)
+ {
+ unsigned char i = (unsigned char)*p++;
+ if (i >= NS_CODES_START) {
+ *out++ = (char)NS_SKIP_CODE;
+ }
+ *out++=(char)i;
+ }
+ continue;
+ }
+
+ unsigned char i = (unsigned char)*p;
+
+ p=np;
+
+ // Test for characters extending into the variable codes
+ if (i >= NS_CODES_START) {
+ *out++ = (char)NS_SKIP_CODE;
+ }
+ else if (i == '$')
+ {
+ if (*p == '$')
+ p++; // Can simply convert $$ to $ now
+ else
+ {
+ {
+ bool bProceced=false;
+ if ( *p )
+ {
+ const char *pUserVarName = p;
+ while (isSimpleChar(*pUserVarName))
+ pUserVarName++;
+
+ while (pUserVarName > p)
+ {
+ if (m_ShellConstants.get((char*)p, pUserVarName-p) >= 0)
+ break; // Upps it's a shell constant
+
+ int idxUserVar = m_UserVarNames.get((char*)p, pUserVarName-p);
+ if (idxUserVar >= 0)
+ {
+ // Well, using variables inside string formating doens't mean
+ // using the variable, beacuse it will be always an empty string
+ // which is also memory wasting
+ // So the line below must be commented !??
+ //m_UserVarNames.inc_reference(idxUserVar);
+ *out++ = (char) NS_VAR_CODE; // Named user variable;
+ WORD w = FIX_ENDIAN_INT16(CODE_SHORT(idxUserVar));
+ memcpy(out, &w, sizeof(WORD));
+ out += sizeof(WORD);
+ p += pUserVarName-p;
+ bProceced = true;
+ break;
+ }
+ pUserVarName--;
+ }
+ }
+ if (!bProceced && *p)
+ {
+ const char *pShellConstName = p;
+ while (isSimpleChar(*pShellConstName))
+ pShellConstName++;
+
+ while (pShellConstName > p)
+ {
+ int idxConst = m_ShellConstants.get((char*)p, pShellConstName - p);
+ if (idxConst >= 0)
+ {
+ int CSIDL_Value_current = m_ShellConstants.get_value1(idxConst);
+ int CSIDL_Value_all = m_ShellConstants.get_value2(idxConst);
+ *out++=(char)NS_SHELL_CODE; // Constant code identifier
+ *out++=(char)CSIDL_Value_current;
+ *out++=(char)CSIDL_Value_all;
+ p = pShellConstName;
+ bProceced = true;
+ break;
+ }
+ pShellConstName--;
+ }
+ }
+ if ( !bProceced && *p == '(' )
+ {
+ int idx = -1;
+ char *cp = strdup(p+1);
+ char *pos = strchr(cp, ')');
+ if (pos)
+ {
+ *pos = 0;
+ idx = DefineLangString(cp);
+ if (idx < 0)
+ {
+ *out++ = (char)NS_LANG_CODE; // Next word is lang-string Identifier
+ WORD w = FIX_ENDIAN_INT16(CODE_SHORT(-idx-1));
+ memcpy(out, &w, sizeof(WORD));
+ out += sizeof(WORD);
+ p += strlen(cp) + 2;
+ bProceced = true;
+ }
+ }
+ free(cp);
+ }
+ if ( bProceced )
+ continue;
+ else
+ {
+ char tbuf[64];
+ char cBracket = '\0';
+ bool bDoWarning = true;
+
+ if ( *p == '[' )
+ cBracket = ']';
+ else if ( *p == '(' )
+ cBracket = ')';
+ else if ( *p == '{' )
+ cBracket = '}';
+
+ strncpy(tbuf,p,63);
+ tbuf[63]=0;
+
+ if ( cBracket != 0 )
+ {
+ if (strchr(tbuf,cBracket)) (strchr(tbuf,cBracket)+1)[0]=0;
+ if ( tbuf[0] == '{' && tbuf[strlen(tbuf)-1] == '}' )
+ {
+ char *tstIfDefine = strdup(tbuf+1);
+ tstIfDefine[strlen(tstIfDefine)-1] = '\0';
+ bDoWarning = definedlist.find(tstIfDefine) == NULL;
+ }
+ }
+ else
+ {
+ if (strstr(tbuf," ")) strstr(tbuf," ")[0]=0;
+ }
+ if ( bDoWarning )
+ warning_fl("unknown variable/constant \"%s\" detected, ignoring",tbuf);
+ i = '$';
+ }
+ }
+ }
+ }
+ *out++=(char)i;
+ }
+ *out=0;
+ return 0;
+}
+
+// what it does is, when you pass it the offset of the last item added, it will determine if
+// that data is already present in the datablock, and if so, reference it instead (and shorten
+// the datablock as necessary). Reduces overhead if you want to add files to a couple places.
+// Woo, an optimizing installer generator, now we're styling.
+
+int CEXEBuild::datablock_optimize(int start_offset, int first_int)
+{
+ int this_len = cur_datablock->getlen() - start_offset;
+
+ cached_db_size this_size = {first_int, start_offset};
+ cur_datablock_cache->add(&this_size, sizeof(cached_db_size));
+
+ if (!build_optimize_datablock || this_len < (int) sizeof(int))
+ return start_offset;
+
+ MMapBuf *db = (MMapBuf *) cur_datablock;
+ db->setro(TRUE);
+
+ cached_db_size *db_sizes = (cached_db_size *) cur_datablock_cache->get();
+ int db_sizes_num = cur_datablock_cache->getlen() / sizeof(cached_db_size);
+ db_sizes_num--; // don't compare with the one we just added
+
+ for (int i = 0; i < db_sizes_num; i++)
+ {
+ if (db_sizes[i].first_int == first_int)
+ {
+ int pos = db_sizes[i].start_offset;
+ int left = this_len;
+ while (left > 0)
+ {
+ int l = min(left, build_filebuflen);
+ void *newstuff = db->get(start_offset + this_len - left, l);
+ void *oldstuff = db->getmore(pos + this_len - left, l);
+
+ int res = memcmp(newstuff, oldstuff, l);
+
+ db->release(oldstuff, l);
+ db->release();
+
+ if (res)
+ {
+ break;
+ }
+
+ left -= l;
+ }
+
+ if (!left)
+ {
+ db_opt_save += this_len;
+ db->resize(max(start_offset, pos + this_len));
+ db->setro(FALSE);
+ cur_datablock_cache->resize(cur_datablock_cache->getlen() - sizeof(cached_db_size));
+ return pos;
+ }
+ }
+ }
+
+ db->setro(FALSE);
+
+ return start_offset;
+}
+
+int CEXEBuild::add_db_data(IMMap *mmap) // returns offset
+{
+ build_compressor_set = true;
+
+ int done = 0;
+
+ if (!mmap)
+ {
+ ERROR_MSG("Error: add_db_data() called with invalid mapped file\n");
+ return -1;
+ }
+
+ int length = mmap->getsize();
+
+ if (length < 0)
+ {
+ ERROR_MSG("Error: add_db_data() called with length=%d\n", length);
+ return -1;
+ }
+
+ MMapBuf *db = (MMapBuf *) cur_datablock;
+
+ int st = db->getlen();
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ if (length && !build_compress_whole && build_compress)
+ {
+ // grow datablock so that there is room to compress into
+ int bufferlen = length + 1024 + length / 4; // give a nice 25% extra space
+ db->resize(st + bufferlen + sizeof(int));
+
+ int n = compressor->Init(build_compress_level, build_compress_dict_size);
+ if (n != C_OK)
+ {
+ ERROR_MSG("Internal compiler error #12345: deflateInit() failed(%s [%d]).\n", compressor->GetErrStr(n), n);
+ extern void quit(); quit();
+ }
+
+ int avail_in = length;
+ int avail_out = bufferlen;
+ int ret;
+ while (avail_in > 0)
+ {
+ int in_len = min(build_filebuflen, avail_in);
+ int out_len = min(build_filebuflen, avail_out);
+
+ compressor->SetNextIn((char *) mmap->get(length - avail_in, in_len), in_len);
+ compressor->SetNextOut((char *) db->get(st + sizeof(int) + bufferlen - avail_out, out_len), out_len);
+ if ((ret = compressor->Compress(0)) < 0)
+ {
+ ERROR_MSG("Error: add_db_data() - compress() failed(%s [%d])\n", compressor->GetErrStr(ret), ret);
+ return -1;
+ }
+ mmap->release();
+ db->flush(out_len);
+ db->release();
+ avail_in -= in_len - compressor->GetAvailIn();
+ avail_out -= out_len - compressor->GetAvailOut();
+
+ if (!avail_out)
+ // not enough space in the output buffer - no compression is better
+ break;
+ }
+
+ // if not enough space in the output buffer - no compression is better
+ if (avail_out)
+ {
+ char *out;
+
+ char a;
+ compressor->SetNextIn(&a,0);
+
+ do
+ {
+ int out_len = min(build_filebuflen, avail_out);
+
+ out = (char *) db->get(st + sizeof(int) + bufferlen - avail_out, out_len);
+
+ compressor->SetNextOut(out, out_len);
+ if ((ret = compressor->Compress(C_FINISH)) < 0)
+ {
+ ERROR_MSG("Error: add_db_data() - compress() failed(%s [%d])\n", compressor->GetErrStr(ret), ret);
+ return -1;
+ }
+
+ db->flush(out_len);
+ db->release();
+
+ avail_out -= out_len - compressor->GetAvailOut();
+ }
+ while (compressor->GetNextOut() - out > 0 && avail_out > 0);
+
+ compressor->End();
+
+ int used = bufferlen - avail_out;
+
+ // never store compressed if output buffer is full (compression increased the size...)
+ if (avail_out && (build_compress == 2 || used < length))
+ {
+ done=1;
+ db->resize(st + used + sizeof(int));
+
+ *(int*)db->get(st, sizeof(int)) = FIX_ENDIAN_INT32(used | 0x80000000);
+ db->release();
+
+ int nst = datablock_optimize(st, used | 0x80000000);
+ if (nst == st) db_comp_save += length - used;
+ else st = nst;
+ }
+ }
+ else
+ compressor->End();
+ }
+#endif // NSIS_CONFIG_COMPRESSION_SUPPORT
+
+ if (!done)
+ {
+ db->resize(st + length + sizeof(int));
+ int *plen = (int *) db->get(st, sizeof(int));
+ *plen = FIX_ENDIAN_INT32(length);
+ db->release();
+
+ int left = length;
+ while (left > 0)
+ {
+ int l = min(build_filebuflen, left);
+ int *p = (int *) db->get(st + sizeof(int) + length - left, l);
+ memcpy(p, mmap->get(length - left, l), l);
+ db->flush(l);
+ db->release();
+ mmap->release();
+ left -= l;
+ }
+
+ st = datablock_optimize(st, length);
+ }
+
+ db_full_size += length + sizeof(int);
+
+ return st;
+}
+
+int CEXEBuild::add_db_data(const char *data, int length) // returns offset
+{
+ MMapFake fakemap;
+ fakemap.set(data, length);
+ return add_db_data(&fakemap);
+}
+
+int CEXEBuild::add_data(const char *data, int length, IGrowBuf *dblock) // returns offset
+{
+ build_compressor_set=true;
+
+ int done=0;
+
+ if (length < 0)
+ {
+ ERROR_MSG("Error: add_data() called with length=%d\n",length);
+ return -1;
+ }
+
+ int st=dblock->getlen();
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ if (!build_compress_whole && build_compress)
+ {
+ // grow datablock so that there is room to compress into
+ int bufferlen=length+1024+length/4; // give a nice 25% extra space
+ dblock->resize(st+bufferlen+sizeof(int));
+
+ int n = compressor->Init(build_compress_level, build_compress_dict_size);
+ if (n != C_OK)
+ {
+ ERROR_MSG("Internal compiler error #12345: deflateInit() failed(%s [%d]).\n", compressor->GetErrStr(n), n);
+ extern void quit(); quit();
+ }
+
+ compressor->SetNextIn((char*)data, length);
+ compressor->SetNextOut((char*)dblock->get() + st + sizeof(int), bufferlen);
+
+ compressor->Compress(C_FINISH);
+
+ int used=bufferlen-compressor->GetAvailOut();
+
+ // never store compressed if output buffer is full
+ if (compressor->GetAvailOut() && (build_compress == 2 || used < length))
+ {
+ done=1;
+ dblock->resize(st+used+sizeof(int));
+
+ *((int*)((char *)dblock->get()+st)) = FIX_ENDIAN_INT32(used|0x80000000);
+ }
+ compressor->End();
+ }
+#endif // NSIS_CONFIG_COMPRESSION_SUPPORT
+
+ if (!done)
+ {
+ dblock->resize(st);
+ int rl = FIX_ENDIAN_INT32(length);
+ dblock->add(&rl,sizeof(int));
+ dblock->add(data,length);
+ }
+
+ return st;
+}
+
+int CEXEBuild::add_label(const char *name)
+{
+ if (!build_cursection)
+ {
+ ERROR_MSG("Error: Label declaration not valid outside of function/section\n");
+ return PS_ERROR;
+ }
+ if ((name[0] >= '0' && name[0] <= '9') || name[0] == '-' || name[0] == ' ' || name[0] == ':')
+ {
+ ERROR_MSG("Error: labels must not begin with 0-9, -, :, or a space.\n");
+ return PS_ERROR;
+ }
+
+ int cs=build_cursection->code;
+ int ce=cs+build_cursection->code_size;
+
+ char *p=strdup(name);
+ if (p[strlen(p)-1] == ':') p[strlen(p)-1]=0;
+ int offs=ns_label.add(p,0);
+ free(p);
+
+ int n=cur_labels->getlen()/sizeof(section);
+ if (n)
+ {
+ section *t=(section*)cur_labels->get();
+ while (n--)
+ {
+ if ((*name == '.' || (t->code >= cs && t->code <= ce)) &&
+ t->name_ptr==offs)
+ {
+ if (*name == '.') ERROR_MSG("Error: global label \"%s\" already declared\n",name);
+ else
+ {
+ char *t = "section";
+ if (build_cursection_isfunc)
+ t = "function";
+ ERROR_MSG("Error: label \"%s\" already declared in %s\n",name,t);
+ }
+ return PS_ERROR;
+ }
+ t++;
+ }
+ }
+
+ section s={0};
+ s.name_ptr = offs;
+ s.code = ce;
+ cur_labels->add(&s,sizeof(s));
+
+ return PS_OK;
+}
+
+int CEXEBuild::add_function(const char *funname)
+{
+ if (build_cursection_isfunc)
+ {
+ ERROR_MSG("Error: Function open when creating function (use FunctionEnd first)\n");
+ return PS_ERROR;
+ }
+ if (build_cursection)
+ {
+ ERROR_MSG("Error: Section open when creating function (use SectionEnd first)\n");
+ return PS_ERROR;
+ }
+ if (cur_page)
+ {
+ ERROR_MSG("Error: PageEx open when creating function (use PageExEnd first)\n");
+ return PS_ERROR;
+ }
+ if (!funname[0])
+ {
+ ERROR_MSG("Error: Function must have a name\n");
+ return PS_ERROR;
+ }
+
+ set_uninstall_mode(!strnicmp(funname,"un.",3));
+
+ int addr=ns_func.add(funname,0);
+ int x;
+ int n=cur_functions->getlen()/sizeof(section);
+ section *tmp=(section*)cur_functions->get();
+ for (x = 0; x < n; x ++)
+ {
+ if (tmp[x].name_ptr == addr)
+ {
+ ERROR_MSG("Error: Function named \"%s\" already exists.\n",funname);
+ return PS_ERROR;
+ }
+ }
+
+ cur_functions->resize((n+1)*sizeof(section));
+ build_cursection=((section*)cur_functions->get())+n;
+ build_cursection_isfunc=1;
+ build_cursection->name_ptr=addr;
+ build_cursection->code=cur_entries->getlen()/sizeof(entry);
+ build_cursection->code_size=0;
+ build_cursection->install_types=0;
+ build_cursection->flags=0;
+ build_cursection->size_kb=0;
+ memset(build_cursection->name,0,sizeof(build_cursection->name));
+
+ if (uninstall_mode)
+ set_code_type_predefines(funname+3);
+ else
+ set_code_type_predefines(funname);
+
+ return PS_OK;
+}
+
+int CEXEBuild::function_end()
+{
+ if (!build_cursection_isfunc)
+ {
+ ERROR_MSG("Error: No function open, FunctionEnd called\n");
+ return PS_ERROR;
+ }
+ // add ret.
+ add_entry_direct(EW_RET);
+
+ build_cursection_isfunc=0;
+ build_cursection=NULL;
+
+ set_uninstall_mode(0);
+
+ set_code_type_predefines();
+ return PS_OK;
+}
+
+
+int CEXEBuild::section_add_flags(int flags)
+{
+ if (!build_cursection || build_cursection_isfunc)
+ {
+ ERROR_MSG("Error: can't modify flags when no section is open\n");
+ return PS_ERROR;
+ }
+ build_cursection->flags |= flags;
+ return PS_OK;
+}
+
+int CEXEBuild::section_add_install_type(int inst_type)
+{
+ if (!build_cursection || build_cursection_isfunc)
+ {
+ ERROR_MSG("Error: can't modify flags when no section is open\n");
+ return PS_ERROR;
+ }
+ if (build_cursection->install_types == ~0)
+ build_cursection->install_types = 0;
+ build_cursection->install_types |= inst_type;
+ return PS_OK;
+}
+
+void CEXEBuild::section_add_size_kb(int kb)
+{
+ if (build_cursection)
+ {
+ build_cursection->size_kb+=kb;
+ }
+}
+
+int CEXEBuild::section_end()
+{
+ if (build_cursection_isfunc)
+ {
+ ERROR_MSG("Error: SectionEnd specified in function (not section)\n");
+ return PS_ERROR;
+ }
+ if (!build_cursection)
+ {
+ ERROR_MSG("Error: SectionEnd specified and no sections open\n");
+ return PS_ERROR;
+ }
+ add_entry_direct(EW_RET);
+ build_cursection->code_size--;
+ build_cursection=NULL;
+ if (!sectiongroup_open_cnt)
+ set_uninstall_mode(0);
+
+ set_code_type_predefines();
+ return PS_OK;
+}
+
+int CEXEBuild::add_section(const char *secname, const char *defname, int expand/*=0*/)
+{
+ if (build_cursection_isfunc)
+ {
+ ERROR_MSG("Error: Section can't create section (already in function, use FunctionEnd first)\n");
+ return PS_ERROR;
+ }
+ if (cur_page) {
+ ERROR_MSG("Error: PageEx already open, call PageExEnd first\n");
+ return PS_ERROR;
+ }
+ if (build_cursection)
+ {
+ ERROR_MSG("Error: Section already open, call SectionEnd first\n");
+ return PS_ERROR;
+ }
+
+ section new_section;
+ new_section.flags = SF_SELECTED;
+ new_section.flags |= expand ? SF_EXPAND : 0;
+ new_section.code_size = 0;
+ new_section.size_kb = 0;
+
+ char *name = (char*)secname;
+
+ if (secname[0] == '-')
+ {
+ if (secname[1])
+ {
+ new_section.flags |= SF_SECGRP;
+ name++;
+ }
+ else
+ new_section.flags |= SF_SECGRPEND;
+ }
+
+ if (name[0] == '!')
+ {
+ name++;
+ new_section.flags |= SF_BOLD;
+ }
+
+ int old_uninstall_mode = uninstall_mode;
+
+ set_uninstall_mode(0);
+
+ if (!strnicmp(name, "un.", 3))
+ {
+ set_uninstall_mode(1);
+ name += 3;
+ }
+
+ if (!stricmp(name, "uninstall"))
+ {
+ set_uninstall_mode(1);
+ }
+
+ if ((new_section.flags & SF_SECGRPEND) && sectiongroup_open_cnt && old_uninstall_mode)
+ {
+ set_uninstall_mode(1);
+ }
+
+ if (sectiongroup_open_cnt)
+ {
+ if (uninstall_mode != old_uninstall_mode)
+ {
+ ERROR_MSG("Error: Can't create %s section in %s section group (use SectionGroupEnd first)\n", uninstall_mode ? "uninstaller" : "installer", old_uninstall_mode ? "uninstaller" : "installer");
+ return PS_ERROR;
+ }
+ }
+
+ new_section.code = cur_entries->getlen() / sizeof(entry);
+
+ new_section.install_types = *name ? 0 : ~0;
+ new_section.name_ptr = add_string(name);
+ memset(&new_section.name,0,sizeof(new_section.name));
+
+ cur_sections->add(&new_section, sizeof(section));
+ build_cursection = (section *) cur_sections->get() + cur_header->blocks[NB_SECTIONS].num;
+
+ if (defname[0])
+ {
+ char buf[1024];
+ wsprintf(buf, "%d", cur_header->blocks[NB_SECTIONS].num);
+ if (definedlist.add(defname, buf))
+ {
+ ERROR_MSG("Error: \"%s\" already defined, can't assign section index!\n", defname);
+ return PS_ERROR;
+ }
+ }
+
+ cur_header->blocks[NB_SECTIONS].num++;
+
+ if (new_section.flags & (SF_SECGRP | SF_SECGRPEND))
+ {
+ add_entry_direct(EW_RET);
+ build_cursection->code_size = 0;
+
+ build_cursection = 0;
+
+ if (new_section.flags & SF_SECGRPEND)
+ {
+ sectiongroup_open_cnt--;
+ if (sectiongroup_open_cnt < 0)
+ {
+ ERROR_MSG("SectionGroupEnd: no SectionGroups are open\n");
+ return PS_ERROR;
+ }
+ if (!sectiongroup_open_cnt)
+ {
+ set_uninstall_mode(0);
+ }
+ }
+ else
+ sectiongroup_open_cnt++;
+ }
+
+ set_code_type_predefines(name);
+
+ return PS_OK;
+}
+
+int CEXEBuild::add_entry(const entry *ent)
+{
+ if (!build_cursection && !uninstall_mode)
+ {
+ ERROR_MSG("Error: Can't add entry, no section or function is open!\n");
+ return PS_ERROR;
+ }
+
+ cur_entries->add(ent,sizeof(entry));
+ cur_instruction_entry_map->add(&multiple_entries_instruction,sizeof(int));
+ build_cursection->code_size++;
+ cur_header->blocks[NB_ENTRIES].num++;
+
+ multiple_entries_instruction=1;
+
+ return PS_OK;
+}
+
+int CEXEBuild::add_entry_direct(int which, int o0, int o1, int o2, int o3, int o4, int o5 /*o#=0*/)
+{
+ entry ent;
+ ent.which = which;
+ ent.offsets[0] = o0;
+ ent.offsets[1] = o1;
+ ent.offsets[2] = o2;
+ ent.offsets[3] = o3;
+ ent.offsets[4] = o4;
+ ent.offsets[5] = o5;
+ return add_entry(&ent);
+}
+
+int CEXEBuild::resolve_jump_int(const char *fn, int *a, int offs, int start, int end)
+{
+ if (*a > 0)
+ {
+ char *lname=(char*)ns_label.get()+*a;
+ if (lname[0] == '-' || lname[0]=='+')
+ {
+ int jump = atoi(lname);
+ int *skip_map = (int *) cur_instruction_entry_map->get();
+ int maxoffs = cur_instruction_entry_map->getlen() / (int) sizeof(int);
+
+ int direction = 1;
+ if (jump < 0)
+ direction = -1;
+
+ for (; jump != 0; jump -= direction)
+ {
+ offs += direction;
+ if (offs >= 0 && offs < maxoffs)
+ {
+ while (skip_map[offs])
+ {
+ offs += direction;
+ }
+ }
+ }
+
+ *a = offs + 1;
+ }
+ else
+ {
+ section *s = (section*)cur_labels->get();
+ int n=cur_labels->getlen()/sizeof(section);
+ while (n-->0)
+ {
+ if ((*lname == '.' || (s->code >= start && s->code <= end)) && s->name_ptr == *a)
+ {
+ *a = s->code+1; // jumps are to the absolute position, +1 (to differentiate between no jump, and jumping to offset 0)
+ s->flags++;
+ return 0;
+ }
+ s++;
+ }
+
+ ERROR_MSG("Error: could not resolve label \"%s\" in %s\n",lname,fn);
+ return 1;
+ }
+ }
+ else if (*a < 0) // to jump to a user variable target, -variable_index-1 is already stored.
+ {
+ }
+ // otherwise, *a is 0, which means no jump and we also leave it intact
+ return 0;
+}
+
+int CEXEBuild::resolve_call_int(const char *fn, const char *str, int fptr, int *ofs)
+{
+ if (fptr < 0) return 0;
+ int nf=cur_functions->getlen()/sizeof(section);
+ section *sec=(section *)cur_functions->get();
+ while (nf-- > 0)
+ {
+ if (sec->name_ptr>0 && sec->name_ptr == fptr)
+ {
+ ofs[0]=sec->code;
+ sec->flags++;
+ return 0;
+ }
+ sec++;
+ }
+ ERROR_MSG("Error: resolving %s function \"%s\" in %s\n",str,(char*)ns_func.get()+fptr,fn);
+ ERROR_MSG("Note: uninstall functions must begin with \"un.\", and install functions must not\n");
+ return 1;
+}
+
+int CEXEBuild::resolve_instruction(const char *fn, const char *str, entry *w, int offs, int start, int end)
+{
+ if (w->which == EW_NOP)
+ {
+ if (resolve_jump_int(fn,&w->offsets[0],offs,start,end)) return 1;
+ }
+#ifdef NSIS_SUPPORT_MESSAGEBOX
+ else if (w->which == EW_MESSAGEBOX)
+ {
+ if (resolve_jump_int(fn,&w->offsets[3],offs,start,end)) return 1;
+ if (resolve_jump_int(fn,&w->offsets[5],offs,start,end)) return 1;
+ }
+#endif
+ else if (w->which == EW_IFFILEEXISTS)
+ {
+ if (resolve_jump_int(fn,&w->offsets[1],offs,start,end)) return 1;
+ if (resolve_jump_int(fn,&w->offsets[2],offs,start,end)) return 1;
+ }
+ else if (w->which == EW_IFFLAG)
+ {
+ if (resolve_jump_int(fn,&w->offsets[0],offs,start,end)) return 1;
+ if (resolve_jump_int(fn,&w->offsets[1],offs,start,end)) return 1;
+ }
+#ifdef NSIS_SUPPORT_STROPTS
+ else if (w->which == EW_STRCMP)
+ {
+ if (resolve_jump_int(fn,&w->offsets[2],offs,start,end)) return 1;
+ if (resolve_jump_int(fn,&w->offsets[3],offs,start,end)) return 1;
+ }
+#endif
+#ifdef NSIS_SUPPORT_INTOPTS
+ else if (w->which == EW_INTCMP)
+ {
+ if (resolve_jump_int(fn,&w->offsets[2],offs,start,end)) return 1;
+ if (resolve_jump_int(fn,&w->offsets[3],offs,start,end)) return 1;
+ if (resolve_jump_int(fn,&w->offsets[4],offs,start,end)) return 1;
+ }
+#endif
+#ifdef NSIS_SUPPORT_HWNDS
+ else if (w->which == EW_ISWINDOW)
+ {
+ if (resolve_jump_int(fn,&w->offsets[1],offs,start,end)) return 1;
+ if (resolve_jump_int(fn,&w->offsets[2],offs,start,end)) return 1;
+ }
+#endif
+ else if (w->which == EW_CALL)
+ {
+ if (w->offsets[0] >= 0 && w->offsets[1]) // get as jump
+ {
+ if (resolve_jump_int(fn,&w->offsets[0],offs,start,end)) return 1;
+ }
+ else
+ {
+ if (w->offsets[0] >= 0 && resolve_call_int(fn,str,w->offsets[0],w->offsets)) return 1;
+ // if w->offsets[0] >= 0, EW_CALL requires that it 1-based.
+ // otherwise, if < 0, it needs an increment anyway (since it
+ // was encoded with a -2 base, to prevent it looking like an
+ // empty string "")
+ w->offsets[0]++;
+ }
+ }
+#ifdef NSIS_SUPPORT_STROPTS
+ else if (w->which == EW_GETFUNCTIONADDR)
+ {
+ if (w->offsets[1] < 0)
+ {
+ ERROR_MSG("Error: GetFunctionAddress requires a real function to get address of.\n");
+ return 1;
+ }
+
+ if (resolve_call_int(fn,str,w->offsets[1],&w->offsets[1])) return 1;
+
+ w->which=EW_ASSIGNVAR;
+ w->offsets[1]=add_intstring(w->offsets[1]+1); // +1 here to make 1-based.
+ }
+ else if (w->which == EW_GETLABELADDR)
+ {
+ if (resolve_jump_int(fn,&w->offsets[1],offs,start,end)) return 1;
+ w->which=EW_ASSIGNVAR;
+ w->offsets[1]=add_intstring(w->offsets[1]);
+ }
+#endif
+ return 0;
+}
+
+int CEXEBuild::resolve_coderefs(const char *str)
+{
+ // resolve jumps&calls
+ {
+ section *sec=(section *)cur_functions->get();
+ int l=cur_functions->getlen()/sizeof(section);
+ entry *w=(entry *)cur_entries->get();
+ while (l-- > 0)
+ {
+ int x;
+ for (x = sec->code; x < sec->code+sec->code_size; x ++)
+ {
+ char fname[1024];
+ wsprintf(fname,"function \"%s\"",ns_func.get()+sec->name_ptr);
+ if (resolve_instruction(fname,str,w+x,x,sec->code,sec->code+sec->code_size)) return 1;
+ }
+ sec++;
+ }
+
+ int cnt=0;
+ sec=(section *)cur_sections->get();
+ l=cur_sections->getlen()/sizeof(section);
+ while (l-- > 0)
+ {
+ int x=sec->name_ptr;
+ char fname[1024];
+ const char *section_name;
+ if (x < 0)
+ {
+ // lang string
+ section_name = "$(lang string)";
+ }
+ else
+ {
+ // normal string
+ section_name = cur_strlist->get() + x;
+ }
+ if (x) wsprintf(fname,"%s section \"%s\" (%d)",str,section_name,cnt);
+ else wsprintf(fname,"unnamed %s section (%d)",str,cnt);
+ for (x = sec->code; x < sec->code+sec->code_size; x ++)
+ {
+ if (resolve_instruction(fname,str,w+x,x,sec->code,sec->code+sec->code_size))
+ return 1;
+ }
+ sec++;
+ cnt++;
+ }
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ if (cur_pages->getlen()) {
+ page *p=(page *)cur_pages->get();
+ int i = 0;
+ while (i < cur_header->blocks[NB_PAGES].num) {
+ char pagestr[1024];
+ wsprintf(pagestr, "%s pages", str);
+ if (resolve_call_int(pagestr,p->dlg_id?"pre-page":"create-page",p->prefunc,&p->prefunc)) return 1;
+ if (resolve_call_int(pagestr,"show-page",p->showfunc,&p->showfunc)) return 1;
+ if (resolve_call_int(pagestr,"leave-page",p->leavefunc,&p->leavefunc)) return 1;
+ p++;
+ i++;
+ }
+ }
+#endif
+#endif
+ }
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ // resolve callbacks
+ {
+ struct {
+ char *name;
+ int *p;
+ } callbacks[] = {
+ {"%s.onInit", &cur_header->code_onInit},
+ {"%s.on%sInstSuccess", &cur_header->code_onInstSuccess},
+ {"%s.on%sInstFailed", &cur_header->code_onInstFailed},
+ {"%s.onUserAbort", &cur_header->code_onUserAbort},
+ {"%s.onVerifyInstDir", &cur_header->code_onVerifyInstDir},
+#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ {"%s.onGUIInit", &cur_header->code_onGUIInit},
+ {"%s.onGUIEnd", &cur_header->code_onGUIEnd},
+ {"%s.onMouseOverSection", &cur_header->code_onMouseOverSection},
+#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ {"%s.onSelChange", &cur_header->code_onSelChange},
+#endif//NSIS_CONFIG_COMPONENTPAGE
+#ifdef NSIS_SUPPORT_REBOOT
+ {"%s.onRebootFailed", &cur_header->code_onRebootFailed},
+#endif//NSIS_SUPPORT_REBOOT
+ {0, 0}
+ };
+
+ for (int i = 0; callbacks[i].name; i++) {
+ const char *un = uninstall_mode ? "un" : "";
+ char fname[1024];
+ wsprintf(fname, callbacks[i].name, un, un);
+ char cbstr[1024];
+ wsprintf(cbstr, "%s callback", str);
+ char cbstr2[1024];
+ wsprintf(cbstr2, "%s.callbacks", un);
+
+ if (resolve_call_int(cbstr,cbstr2,ns_func.find(fname,0),callbacks[i].p))
+ return PS_ERROR;
+ }
+ }
+#endif//NSIS_SUPPORT_CODECALLBACKS
+
+ // optimize unused functions
+ {
+ section *sec=(section *)cur_functions->get();
+ int l=cur_functions->getlen()/sizeof(section);
+ entry *w=(entry*)cur_entries->get();
+ while (l-- > 0)
+ {
+ if (sec->name_ptr)
+ {
+ if (!sec->flags)
+ {
+ if (sec->code_size>0)
+ {
+ warning("%s function \"%s\" not referenced - zeroing code (%d-%d) out\n",str,
+ ns_func.get()+sec->name_ptr,
+ sec->code,sec->code+sec->code_size);
+ memset(w+sec->code,0,sec->code_size*sizeof(entry));
+ }
+ }
+ }
+ sec++;
+ }
+ }
+
+ // give warnings on unused labels
+ {
+ section *t=(section*)cur_labels->get();
+ int n=cur_labels->getlen()/sizeof(section);
+ while (n-->0)
+ {
+ if (!t->flags)
+ {
+ char *n=(char*)ns_label.get()+t->name_ptr;
+ if (*n == '.') warning("global label \"%s\" not used",n);
+ else warning("label \"%s\" not used",n);
+ }
+ t++;
+ }
+ }
+
+ return 0;
+}
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+int CEXEBuild::add_page(int type)
+{
+ page pg = {
+ 0,
+ 0,
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ -1,
+ -1,
+ -1,
+#endif
+ 0,
+ };
+
+#ifndef NSIS_CONFIG_LICENSEPAGE
+ if (type == PAGE_LICENSE)
+ {
+ ERROR_MSG("Error: can't add license page, NSIS_CONFIG_LICENSEPAGE not defined.\n");
+ return PS_ERROR;
+ }
+#endif
+#ifndef NSIS_CONFIG_COMPONENTPAGE
+ if (type == PAGE_COMPONENTS)
+ {
+ ERROR_MSG("Error: can't add components page, NSIS_CONFIG_COMPONENTPAGE not defined.\n");
+ return PS_ERROR;
+ }
+#endif
+#ifndef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (type == PAGE_COMPONENTS)
+ {
+ ERROR_MSG("Error: can't add uninstConfirm page, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n");
+ return PS_ERROR;
+ }
+#endif
+
+ struct {
+ int wndproc_id;
+ int dlg_id;
+ char *name;
+ } ids[] = {
+ {PWP_CUSTOM, 0, "custom"}, // custom
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ {PWP_LICENSE, IDD_LICENSE, "license"}, // license
+#else
+ {0, IDD_LICENSE, "license"}, // license
+#endif
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ {PWP_SELCOM, IDD_SELCOM, "components"}, // components
+#else
+ {0, IDD_SELCOM, "components"}, // components
+#endif
+ {PWP_DIR, IDD_DIR, "directory"}, // directory
+ {PWP_INSTFILES, IDD_INSTFILES, "instfiles"}, // instfiles
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ {PWP_UNINST, IDD_UNINST, "uninstConfirm"}, // uninstConfirm
+#else
+ {0, IDD_UNINST, "uninstConfirm"}, // uninstConfirm
+#endif
+ {PWP_COMPLETED, -1, NULL} // completed
+ };
+
+ pg.wndproc_id = ids[type].wndproc_id;
+ pg.dlg_id = ids[type].dlg_id;
+
+ cur_pages->add(&pg,sizeof(page));
+
+ cur_page = (page *)cur_pages->get() + cur_header->blocks[NB_PAGES].num++;
+
+ cur_page_type = type;
+
+ set_code_type_predefines(ids[type].name);
+ return PS_OK;
+}
+
+int CEXEBuild::page_end()
+{
+ cur_page = 0;
+
+ set_code_type_predefines();
+ return PS_OK;
+}
+#endif
+
+#ifdef NSIS_SUPPORT_VERSION_INFO
+int CEXEBuild::AddVersionInfo()
+{
+ GrowBuf VerInfoStream;
+
+ if ( rVersionInfo.GetStringTablesCount() > 0 )
+ {
+ if ( !version_product_v[0] )
+ {
+ ERROR_MSG("Error: VIProductVersion is required when other version information functions are used.\n");
+ return PS_ERROR;
+ }
+ else
+ {
+ int imm, iml, ilm, ill;
+ if ( sscanf(version_product_v, "%d.%d.%d.%d", &imm, &iml, &ilm, &ill) != 4 )
+ {
+ ERROR_MSG("Error: invalid VIProductVersion format, should be X.X.X.X\n");
+ return PS_ERROR;
+ }
+ rVersionInfo.SetFileVersion(MAKELONG(iml, imm),MAKELONG(ill, ilm));
+ rVersionInfo.SetProductVersion(MAKELONG(iml, imm),MAKELONG(ill, ilm));
+
+ try
+ {
+ init_res_editor();
+ for ( int i = 0; i < rVersionInfo.GetStringTablesCount(); i++ )
+ {
+ LANGID lang_id = rVersionInfo.GetLangID(i);
+ int code_page = rVersionInfo.GetCodePage(i);
+
+ char *lang_name = GetLangNameAndCP(lang_id);
+
+ if ( !rVersionInfo.FindKey(lang_id, code_page, "FileVersion") )
+ warning("Generating version information for language \"%04d-%s\" without standard key \"FileVersion\"", lang_id, lang_name);
+ if ( !rVersionInfo.FindKey(lang_id, code_page, "FileDescription") )
+ warning("Generating version information for language \"%04d-%s\" without standard key \"FileDescription\"", lang_id, lang_name);
+ if ( !rVersionInfo.FindKey(lang_id, code_page, "LegalCopyright") )
+ warning("Generating version information for language \"%04d-%s\" without standard key \"LegalCopyright\"", lang_id, lang_name);
+
+ rVersionInfo.ExportToStream(VerInfoStream, i);
+ res_editor->UpdateResourceA(RT_VERSION, 1, lang_id, (BYTE*)VerInfoStream.get(), VerInfoStream.getlen());
+ }
+ }
+ catch (exception& err) {
+ ERROR_MSG("Error adding version information: %s\n", err.what());
+ return PS_ERROR;
+ }
+ }
+ }
+
+ return PS_OK;
+}
+#endif // NSIS_SUPPORT_VERSION_INFO
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+int CEXEBuild::ProcessPages()
+{
+ SCRIPT_MSG("Processing pages... ");
+
+ int license_normal=0;
+ int license_fsrb=0;
+ int license_fscb=0;
+ int selcom=0;
+ int dir=0, dir_used;
+ int uninstconfirm=0;
+ int instlog=0, instlog_used;
+ int main=0;
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+again:
+#endif
+
+ dir_used = 0;
+ instlog_used = 0;
+
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ if ((cur_header->flags & (CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) == 0)
+#endif
+ {
+ main++;
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+#define LS(inst, uninst) (uninstall_mode ? uninst : inst)
+#else
+#define LS(inst, uninst) inst
+#endif
+
+ DefineInnerLangString(NLF_BRANDING);
+
+ if (!cur_pages->getlen()) {
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (uninstall_mode) {
+ if (HasUserDefined(NLF_UNINST_TEXT)) {
+ add_page(PAGE_UNINSTCONFIRM);
+ page_end();
+ }
+ add_page(PAGE_INSTFILES);
+ page_end();
+ add_page(PAGE_COMPLETED);
+ page_end();
+ }
+ else
+#endif
+ {
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ if (HasUserDefined(NLF_LICENSE_TEXT) && HasUserDefined(NLF_LICENSE_DATA)) {
+ add_page(PAGE_LICENSE);
+ page_end();
+ }
+#endif
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ if (HasUserDefined(NLF_COMP_TEXT)) {
+ add_page(PAGE_COMPONENTS);
+ page_end();
+ }
+#endif
+ if (HasUserDefined(NLF_DIR_TEXT)) {
+ add_page(PAGE_DIRECTORY);
+ page_end();
+ }
+ add_page(PAGE_INSTFILES);
+ page_end();
+ add_page(PAGE_COMPLETED);
+ page_end();
+ }
+ }
+ // start processing the pages
+ {
+ int i = 0;
+ page *p = (page *) cur_pages->get();
+
+ for (i = 0; i < cur_header->blocks[NB_PAGES].num; i++, p++) {
+ page *pp = 0;
+
+ if (i) {
+ pp = p - 1;
+
+ // set back button
+ p->flags |= PF_BACK_SHOW;
+ if (pp->wndproc_id != PWP_COMPLETED && p->wndproc_id != PWP_COMPLETED && p->wndproc_id != PWP_INSTFILES)
+ p->flags |= PF_BACK_ENABLE;
+ if (!p->back)
+ p->back = DefineInnerLangString(NLF_BTN_BACK);
+
+ // set previous page's next button
+ if (!pp->next) {
+ int str = 0;
+
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ if (pp->wndproc_id == PWP_LICENSE && (!(pp->flags & PF_LICENSE_FORCE_SELECTION) || HasUserDefined(NLF_BTN_LICENSE)))
+ str = NLF_BTN_LICENSE;
+ else
+#endif
+ if (p->wndproc_id == PWP_INSTFILES)
+ str = LS(NLF_BTN_INSTALL, NLF_BTN_UNINSTALL);
+ else
+ str = NLF_BTN_NEXT;
+
+ pp->next = DefineInnerLangString(str);
+ }
+
+ // set previous page's click next text
+ if (!pp->clicknext) {
+ int str = 0;
+
+ if (p->wndproc_id == PWP_INSTFILES)
+ str = LS(NLF_CLICK_INSTALL, NLF_CLICK_UNINSTALL);
+ else
+ str = NLF_CLICK_NEXT;
+
+ pp->clicknext = DefineInnerLangString(str);
+ }
+ }
+
+ // enable next button
+ if (p->wndproc_id != PWP_INSTFILES)
+ p->flags |= PF_NEXT_ENABLE;
+
+ // set cancel button
+ if (!p->cancel)
+ p->cancel = DefineInnerLangString(NLF_BTN_CANCEL);
+ if (p->wndproc_id != PWP_INSTFILES && p->wndproc_id != PWP_COMPLETED)
+ p->flags |= PF_CANCEL_ENABLE;
+
+ // set caption
+ struct {
+ int caption;
+ int ucaption;
+ } captions[] = {
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ {NLF_SUBCAPTION_LICENSE, NLF_SUBCAPTION_LICENSE},
+#endif
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ {NLF_SUBCAPTION_OPTIONS, NLF_SUBCAPTION_OPTIONS},
+#endif
+ {NLF_SUBCAPTION_DIR, NLF_SUBCAPTION_DIR},
+ {NLF_SUBCAPTION_INSTFILES, NLF_USUBCAPTION_INSTFILES},
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ {NLF_USUBCAPTION_CONFIRM, NLF_USUBCAPTION_CONFIRM},
+#endif
+ {NLF_SUBCAPTION_COMPLETED, NLF_USUBCAPTION_COMPLETED}
+ };
+
+ if (!p->caption && p->wndproc_id != PWP_CUSTOM) {
+ p->caption = DefineInnerLangString(LS(captions[p->wndproc_id].caption, captions[p->wndproc_id].ucaption));
+ }
+
+ // set texts
+ switch (p->dlg_id) {
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ case IDD_LICENSE:
+ case IDD_LICENSE_FSRB:
+ case IDD_LICENSE_FSCB:
+ {
+ if (!(p->flags & PF_PAGE_EX))
+ p->dlg_id = license_res_id;
+ if (!(p->flags & (PF_LICENSE_FORCE_SELECTION | PF_LICENSE_NO_FORCE_SELECTION)))
+ p->dlg_id = license_res_id;
+
+ p->flags |= PF_NO_NEXT_FOCUS;
+
+ if (!p->parms[1])
+ p->parms[1] = DefineInnerLangString(NLF_LICENSE_DATA, 0);
+
+ if (p->dlg_id == IDD_LICENSE) {
+ if (!p->parms[0])
+ p->parms[0] = DefineInnerLangString(LS(NLF_LICENSE_TEXT, NLF_ULICENSE_TEXT));
+
+ license_normal++;
+ }
+ else if (p->dlg_id == IDD_LICENSE_FSCB) {
+ p->flags |= PF_LICENSE_FORCE_SELECTION;
+
+ if (!p->parms[0])
+ p->parms[0] = DefineInnerLangString(LS(NLF_LICENSE_TEXT_FSCB, NLF_ULICENSE_TEXT_FSCB));
+ if (!p->parms[2])
+ p->parms[2] = DefineInnerLangString(NLF_BTN_LICENSE_AGREE);
+
+ license_fscb++;
+ }
+ else if (p->dlg_id == IDD_LICENSE_FSRB) {
+ p->flags |= PF_LICENSE_FORCE_SELECTION;
+
+ if (!p->parms[0])
+ p->parms[0] = DefineInnerLangString(LS(NLF_LICENSE_TEXT_FSRB, NLF_ULICENSE_TEXT_FSRB));
+ if (!p->parms[2])
+ p->parms[2] = DefineInnerLangString(NLF_BTN_LICENSE_AGREE);
+ if (!p->parms[3])
+ p->parms[3] = DefineInnerLangString(NLF_BTN_LICENSE_DISAGREE);
+
+ license_fsrb++;
+ }
+ break;
+ }
+#endif
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ case IDD_SELCOM:
+ {
+ if (!p->parms[0])
+ p->parms[0] = DefineInnerLangString(LS(NLF_COMP_TEXT, NLF_UCOMP_TEXT));
+ if (!p->parms[1])
+ p->parms[1] = DefineInnerLangString(LS(NLF_COMP_SUBTEXT1, NLF_UCOMP_SUBTEXT1));
+ if (!p->parms[2])
+ p->parms[2] = DefineInnerLangString(LS(NLF_COMP_SUBTEXT2, NLF_UCOMP_SUBTEXT2));
+ if (!p->parms[3] && !uninstall_mode && HasUserDefined(NLF_COMP_SUBTEXT1))
+ p->parms[3] = p->parms[1];
+ if (!p->parms[4] && !uninstall_mode && HasUserDefined(NLF_COMP_SUBTEXT2))
+ p->parms[4] = p->parms[2];
+ else if (!p->parms[4])
+ p->parms[4] = DefineInnerLangString(LS(NLF_COMP_SUBTEXT1_NO_INST_TYPES, NLF_UCOMP_SUBTEXT1_NO_INST_TYPES));
+
+ DefineInnerLangString(NLF_SPACE_REQ);
+ DefineInnerLangString(NLF_BYTE);
+ DefineInnerLangString(NLF_KILO);
+ DefineInnerLangString(NLF_MEGA);
+ DefineInnerLangString(NLF_GIGA);
+
+ selcom++;
+ break;
+ }
+#endif
+ case IDD_DIR:
+ {
+ if (!p->parms[0])
+ p->parms[0] = DefineInnerLangString(LS(NLF_DIR_TEXT, NLF_UDIR_TEXT));
+ if (!p->parms[1])
+ p->parms[1] = DefineInnerLangString(LS(NLF_DIR_SUBTEXT, NLF_UDIR_SUBTEXT));
+ if (!p->parms[2])
+ p->parms[2] = DefineInnerLangString(NLF_BTN_BROWSE);
+ if (!p->parms[3])
+ p->parms[3] = DefineInnerLangString(LS(NLF_DIR_BROWSETEXT, NLF_UDIR_BROWSETEXT));
+ if (!p->parms[4])
+ p->parms[4] = m_UserVarNames.get("INSTDIR");
+ else
+ p->parms[4]--;
+
+ DefineInnerLangString(NLF_SPACE_AVAIL);
+ DefineInnerLangString(NLF_SPACE_REQ);
+ DefineInnerLangString(NLF_BYTE);
+ DefineInnerLangString(NLF_KILO);
+ DefineInnerLangString(NLF_MEGA);
+ DefineInnerLangString(NLF_GIGA);
+#ifdef NSIS_CONFIG_LOG
+ DefineInnerLangString(NLF_LOG_INSTALL_PROCESS);
+#endif
+
+ dir++;
+ break;
+ }
+ case IDD_INSTFILES:
+ {
+ if (!p->parms[1])
+ p->parms[1] = DefineInnerLangString(NLF_BTN_DETAILS);
+ if (!p->parms[2])
+ p->parms[2] = DefineInnerLangString(NLF_COMPLETED);
+
+ DefineInnerLangString(NLF_COPY_DETAILS);
+
+ instlog++;
+ instlog_used++;
+ break;
+ }
+ case IDD_UNINST:
+ {
+ if (!p->parms[0])
+ p->parms[0] = DefineInnerLangString(NLF_UNINST_TEXT);
+ if (!p->parms[1])
+ p->parms[1] = DefineInnerLangString(NLF_UNINST_SUBTEXT);
+ if (!p->parms[4])
+ p->parms[4] = m_UserVarNames.get("INSTDIR");
+ else
+ p->parms[4]--;
+
+ uninstconfirm++;
+ break;
+ }
+ }
+
+ p->flags &= ~PF_PAGE_EX;
+ }
+
+ p--;
+
+ if (!p->next)
+ p->next = DefineInnerLangString(NLF_BTN_CLOSE);
+ if (p->wndproc_id == PWP_COMPLETED)
+ (p-1)->next = DefineInnerLangString(NLF_BTN_CLOSE);
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (uninstall_mode) {
+ if (!uenable_last_page_cancel && instlog_used)
+ p->flags &= ~PF_CANCEL_ENABLE;
+ }
+ else
+#endif
+ {
+ if (!enable_last_page_cancel && instlog_used)
+ p->flags &= ~PF_CANCEL_ENABLE;
+ }
+
+ if (!instlog_used) {
+ warning("%sage instfiles not used, no sections will be executed!", uninstall_mode ? "Uninstall p" : "P");
+ }
+ }
+ }
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (!uninstall_mode) {
+ set_uninstall_mode(1);
+ goto again;
+ }
+ else
+ set_uninstall_mode(0);
+#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
+
+
+ SCRIPT_MSG("Done!\n");
+
+#define REMOVE_ICON(id) if (disable_window_icon) { \
+ BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG); \
+ if (dlg) { \
+ CDialogTemplate dt(dlg,uDefCodePage); \
+ res_editor->FreeResource(dlg); \
+ if (dt.RemoveItem(IDC_ULICON)) { \
+ DialogItemTemplate* text = dt.GetItem(IDC_INTROTEXT); \
+ DialogItemTemplate* prog = dt.GetItem(IDC_PROGRESS); \
+ if (text) { \
+ text->sWidth += text->sX; \
+ text->sX = 0; \
+ } \
+ if (prog) { \
+ prog->sWidth += prog->sX; \
+ prog->sX = 0; \
+ } \
+ \
+ DWORD dwSize; \
+ dlg = dt.Save(dwSize); \
+ res_editor->UpdateResourceA(RT_DIALOG, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG, dlg, dwSize); \
+ delete [] dlg; \
+ } \
+ } \
+ }
+
+ try {
+ SCRIPT_MSG("Removing unused resources... ");
+ init_res_editor();
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ if (!license_normal) {
+ res_editor->UpdateResourceA(RT_DIALOG, IDD_LICENSE, NSIS_DEFAULT_LANG, 0, 0);
+ }
+ else REMOVE_ICON(IDD_LICENSE);
+ if (!license_fsrb) {
+ res_editor->UpdateResourceA(RT_DIALOG, IDD_LICENSE_FSRB, NSIS_DEFAULT_LANG, 0, 0);
+ }
+ else REMOVE_ICON(IDD_LICENSE_FSRB);
+ if (!license_fscb) {
+ res_editor->UpdateResourceA(RT_DIALOG, IDD_LICENSE_FSCB, NSIS_DEFAULT_LANG, 0, 0);
+ }
+ else REMOVE_ICON(IDD_LICENSE_FSCB);
+#endif // NSIS_CONFIG_LICENSEPAGE
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ if (!selcom) {
+ res_editor->UpdateResourceA(RT_DIALOG, IDD_SELCOM, NSIS_DEFAULT_LANG, 0, 0);
+ res_editor->UpdateResourceA(RT_BITMAP, IDB_BITMAP1, NSIS_DEFAULT_LANG, 0, 0);
+ }
+ else REMOVE_ICON(IDD_SELCOM);
+#endif // NSIS_CONFIG_COMPONENTPAGE
+ if (!dir) {
+ res_editor->UpdateResourceA(RT_DIALOG, IDD_DIR, NSIS_DEFAULT_LANG, 0, 0);
+ }
+ else REMOVE_ICON(IDD_DIR);
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (!uninstconfirm) {
+ res_editor->UpdateResourceA(RT_DIALOG, IDD_UNINST, NSIS_DEFAULT_LANG, 0, 0);
+ }
+ else REMOVE_ICON(IDD_UNINST);
+#endif // NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (!instlog) {
+ res_editor->UpdateResourceA(RT_DIALOG, IDD_INSTFILES, NSIS_DEFAULT_LANG, 0, 0);
+ }
+ else REMOVE_ICON(IDD_INSTFILES);
+ if (!main) {
+ res_editor->UpdateResourceA(RT_DIALOG, IDD_INST, NSIS_DEFAULT_LANG, 0, 0);
+ if (!build_compress_whole && !build_crcchk)
+ res_editor->UpdateResourceA(RT_DIALOG, IDD_VERIFY, NSIS_DEFAULT_LANG, 0, 0);
+ }
+
+ SCRIPT_MSG("Done!\n");
+ }
+ catch (exception& err) {
+ ERROR_MSG("\nError: %s\n", err.what());
+ return PS_ERROR;
+ }
+
+ return PS_OK;
+}
+#endif // NSIS_CONFIG_VISIBLE_SUPPORT
+
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+void CEXEBuild::PrepareInstTypes()
+{
+ if (!(cur_header->flags & CH_FLAGS_NO_CUSTOM))
+ cur_header->install_types[NSIS_MAX_INST_TYPES] = DefineInnerLangString(NLF_COMP_CUSTOM);
+
+ // set insttype list for RO sections that didn't use SectionIn
+ int i = cur_header->blocks[NB_SECTIONS].num;
+ section *sections = (section *) cur_sections->get();
+
+ while (i--)
+ {
+ if (sections[i].flags & SF_RO && !sections[i].install_types)
+ sections[i].install_types = ~0;
+ }
+
+ // set selection to first insttype
+ if (cur_header->install_types[0])
+ {
+ int i = cur_header->blocks[NB_SECTIONS].num;
+ section *sections = (section *) cur_sections->get();
+
+ // if /o was used abort since the user did his manual choice
+ while (i--)
+ if ((sections[i].flags & SF_SELECTED) == 0)
+ return;
+
+ i = cur_header->blocks[NB_SECTIONS].num;
+
+ while (i--)
+ if ((sections[i].install_types & 1) == 0)
+ sections[i].flags &= ~SF_SELECTED;
+ }
+}
+#endif
+
+void CEXEBuild::AddStandardStrings()
+{
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (uninstall_mode)
+ {
+ cur_header->str_uninstchild = add_string("$TEMP\\$1u_.exe");
+ cur_header->str_uninstcmd = add_string("\"$TEMP\\$1u_.exe\" $0 _?=$INSTDIR\\");
+ }
+#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+ cur_header->str_wininit = add_string("$WINDIR\\wininit.ini");
+#endif//NSIS_SUPPORT_MOVEONREBOOT
+}
+
+void CEXEBuild::PrepareHeaders(IGrowBuf *hdrbuf)
+{
+ GrowBuf blocks_buf;
+ growbuf_writer_sink sink(&blocks_buf);
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ cur_header->blocks[NB_PAGES].offset = sizeof(header) + blocks_buf.getlen();
+ page_writer::write_block(cur_pages, &sink);
+#endif
+
+ cur_header->blocks[NB_SECTIONS].offset = sizeof(header) + blocks_buf.getlen();
+ section_writer::write_block(cur_sections, &sink);
+
+ cur_header->blocks[NB_ENTRIES].offset = sizeof(header) + blocks_buf.getlen();
+ entry_writer::write_block(cur_entries, &sink);
+
+ cur_header->blocks[NB_STRINGS].offset = sizeof(header) + blocks_buf.getlen();
+ blocks_buf.add(cur_strlist->get(), cur_strlist->getlen());
+
+ cur_header->blocks[NB_LANGTABLES].offset = sizeof(header) + blocks_buf.getlen();
+ lang_table_writer::write_block(cur_langtables, &sink, cur_header->langtable_size);
+
+ cur_header->blocks[NB_CTLCOLORS].offset = sizeof(header) + blocks_buf.getlen();
+ ctlcolors_writer::write_block(cur_ctlcolors, &sink);
+
+#ifdef NSIS_SUPPORT_BGBG
+ if (cur_header->bg_color1 != -1)
+ {
+ bg_font.lfFaceName[LF_FACESIZE-1] = 0;
+
+ cur_header->blocks[NB_BGFONT].offset = sizeof(header) + blocks_buf.getlen();
+
+ LOGFONT_writer w(&sink);
+ w.write(&bg_font);
+ }
+#endif
+
+ growbuf_writer_sink sink2(hdrbuf);
+ header_writer header(&sink2);
+ header.write(cur_header);
+
+ sink2.write_growbuf(&blocks_buf);
+}
+
+int CEXEBuild::SetVarsSection()
+{
+ try {
+ init_res_editor();
+
+ VerifyDeclaredUserVarRefs(&m_UserVarNames);
+ int MaxUserVars = m_UserVarNames.getnum();
+ // -1 because the default size is 1
+ if (!res_editor->AddExtraVirtualSize2PESection(NSIS_VARS_SECTION, (MaxUserVars - 1) * sizeof(NSIS_STRING)))
+ {
+ ERROR_MSG("Internal compiler error #12346: invalid exehead cannot find section \"%s\"!\n", NSIS_VARS_SECTION);
+ return PS_ERROR;
+ }
+ }
+ catch (exception& err) {
+ ERROR_MSG("\nError: %s\n", err.what());
+ return PS_ERROR;
+ }
+
+ return PS_OK;
+}
+
+int CEXEBuild::SetManifest()
+{
+ try {
+ init_res_editor();
+
+ string manifest = manifest::generate(manifest_comctl, manifest_exec_level);
+
+ if (manifest == "")
+ return PS_OK;
+
+ res_editor->UpdateResourceA(MAKEINTRESOURCE(24), MAKEINTRESOURCE(1), NSIS_DEFAULT_LANG, (LPBYTE) manifest.c_str(), manifest.length());
+ }
+ catch (exception& err) {
+ ERROR_MSG("Error while setting manifest: %s\n", err.what());
+ return PS_ERROR;
+ }
+
+ return PS_OK;
+}
+
+int CEXEBuild::check_write_output_errors() const
+{
+ if (has_called_write_output)
+ {
+ ERROR_MSG("Error (write_output): write_output already called, can't continue\n");
+ return PS_ERROR;
+ }
+
+ if (!build_output_filename[0])
+ {
+ ERROR_MSG("Error: invalid script: never had OutFile command\n");
+ return PS_ERROR;
+ }
+
+ if (!build_sections.getlen())
+ {
+ ERROR_MSG("Error: invalid script: no sections specified\n");
+ return PS_ERROR;
+ }
+
+ if (!build_entries.getlen())
+ {
+ ERROR_MSG("Error: invalid script: no entries specified\n");
+ return PS_ERROR;
+ }
+
+ if (build_cursection)
+ {
+ ERROR_MSG("Error: Section left open at EOF\n");
+ return PS_ERROR;
+ }
+
+ if (sectiongroup_open_cnt)
+ {
+ ERROR_MSG("Error: SectionGroup left open at EOF\n");
+ return PS_ERROR;
+ }
+
+ if (cur_page)
+ {
+ ERROR_MSG("Error: PageEx left open at EOF\n");
+ return PS_ERROR;
+ }
+
+ // deal with functions, for both install and uninstall modes.
+ if (build_cursection_isfunc)
+ {
+ ERROR_MSG("Error: Function left open at EOF\n");
+ return PS_ERROR;
+ }
+
+ return PS_OK;
+}
+
+int CEXEBuild::prepare_uninstaller() {
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (ubuild_entries.getlen())
+ {
+ if (!uninstaller_writes_used)
+ {
+ warning("Uninstaller script code found but WriteUninstaller never used - no uninstaller will be created.");
+ return PS_OK;
+ }
+
+ build_uninst.flags|=build_header.flags&(CH_FLAGS_PROGRESS_COLORED|CH_FLAGS_NO_ROOT_DIR);
+
+ set_uninstall_mode(1);
+
+ DefineInnerLangString(NLF_UCAPTION);
+
+ if (resolve_coderefs("uninstall"))
+ return PS_ERROR;
+
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ // set sections to the first insttype
+ PrepareInstTypes();
+#endif
+
+ // Add standard strings to string table
+ AddStandardStrings();
+
+ set_uninstall_mode(0);
+ }
+ else if (uninstaller_writes_used)
+ {
+ ERROR_MSG("Error: no Uninstall section specified, but WriteUninstaller used %d time(s)\n",uninstaller_writes_used);
+ return PS_ERROR;
+ }
+#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
+ return PS_OK;
+}
+
+int CEXEBuild::pack_exe_header()
+{
+ if (!(build_packname[0] && build_packcmd[0])) {
+ // header not asked to be packed
+ return PS_OK;
+ }
+
+ // write out exe header, pack, read back in, and
+ // update the header info
+ FILE *tmpfile=FOPEN(build_packname,"wb");
+ if (!tmpfile)
+ {
+ ERROR_MSG("Error: writing temporary file \"%s\" for pack\n",build_packname);
+ return PS_ERROR;
+ }
+ fwrite(m_exehead,1,m_exehead_size,tmpfile);
+ fclose(tmpfile);
+ if (sane_system(build_packcmd) == -1)
+ {
+ remove(build_packname);
+ ERROR_MSG("Error: calling packer on \"%s\"\n",build_packname);
+ return PS_ERROR;
+ }
+
+ int result = update_exehead(build_packname);
+ remove(build_packname);
+
+ if (result != PS_OK)
+ {
+ ERROR_MSG("Error: reading temporary file \"%s\" after pack\n",build_packname);
+ return result;
+ }
+
+ return PS_OK;
+}
+
+int CEXEBuild::write_output(void)
+{
+#ifndef NSIS_CONFIG_CRC_SUPPORT
+ build_crcchk=0;
+#endif
+
+ RET_UNLESS_OK( check_write_output_errors() );
+
+ has_called_write_output=true;
+
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+ RET_UNLESS_OK( add_plugins_dir_initializer() );
+#endif //NSIS_CONFIG_PLUGIN_SUPPORT
+
+#ifdef NSIS_SUPPORT_VERSION_INFO
+ RET_UNLESS_OK( AddVersionInfo() );
+#endif //NSIS_SUPPORT_VERSION_INFO
+
+ RET_UNLESS_OK( prepare_uninstaller() );
+
+ DefineInnerLangString(NLF_CAPTION);
+ if (resolve_coderefs("install"))
+ return PS_ERROR;
+
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ // set sections to the first insttype
+ PrepareInstTypes();
+#endif
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ RET_UNLESS_OK( ProcessPages() );
+#endif //NSIS_CONFIG_VISIBLE_SUPPORT
+
+ // Generate language tables
+ RET_UNLESS_OK( GenerateLangTables() );
+
+ // Setup user variables PE section
+ RET_UNLESS_OK( SetVarsSection() );
+
+ // Set XML manifest
+ RET_UNLESS_OK( SetManifest() );
+
+ // Add standard strings to string table
+ AddStandardStrings();
+
+ try {
+ // Load icon from exe, if needed
+ if (installer_icon.empty())
+ {
+ init_res_editor();
+ installer_icon = load_icon_res(res_editor, IDI_ICON2);
+ }
+
+ // Set icon
+ set_icon(res_editor, IDI_ICON2, installer_icon, uninstaller_icon);
+
+ // Save all changes to the exe header
+ close_res_editor();
+ }
+ catch (exception& err) {
+ ERROR_MSG("\nError: %s\n", err.what());
+ return PS_ERROR;
+ }
+
+ RET_UNLESS_OK( pack_exe_header() );
+
+
+ build_optimize_datablock=0;
+
+ int data_block_size_before_uninst = build_datablock.getlen();
+
+ RET_UNLESS_OK( uninstall_generate() );
+
+ crc32_t crc=0;
+
+ {
+ string full_path = get_full_path(build_output_filename);
+ notify(MAKENSIS_NOTIFY_OUTPUT, full_path.c_str());
+ INFO_MSG("\nOutput: \"%s\"\n", full_path.c_str());
+ }
+
+ FILE *fp = FOPEN(build_output_filename,"w+b");
+ if (!fp)
+ {
+ ERROR_MSG("Can't open output file\n");
+ return PS_ERROR;
+ }
+
+ if (fwrite(m_exehead,1,m_exehead_size,fp) != m_exehead_size)
+ {
+ ERROR_MSG("Error: can't write %d bytes to output\n",m_exehead_size);
+ fclose(fp);
+ return PS_ERROR;
+ }
+
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ #ifdef NSIS_CONFIG_CRC_ANAL
+ crc=CRC32(crc,m_exehead,m_exehead_size);
+ #else
+ crc=CRC32(crc,m_exehead+512,m_exehead_size-512);
+ #endif
+#endif
+
+ firstheader fh={0,};
+ fh.nsinst[0]=FH_INT1;
+ fh.nsinst[1]=FH_INT2;
+ fh.nsinst[2]=FH_INT3;
+
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ fh.flags=(build_crcchk?(build_crcchk==2?FH_FLAGS_FORCE_CRC:0):FH_FLAGS_NO_CRC);
+#else
+ fh.flags=0;
+#endif
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ if (build_header.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) fh.flags |= FH_FLAGS_SILENT;
+#endif
+ fh.siginfo=FH_SIG;
+
+ int installinfo_compressed;
+ int fd_start = 0;
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ if (build_compress_whole)
+ {
+ int n = compressor->Init(build_compress_level, build_compress_dict_size);
+ if (n != C_OK)
+ {
+ ERROR_MSG("Internal compiler error #12345: deflateInit() failed(%s [%d]).\n", compressor->GetErrStr(n), n);
+ return PS_ERROR;
+ }
+ }
+#endif
+
+ {
+ GrowBuf ihd;
+ {
+ GrowBuf hdrcomp;
+
+ PrepareHeaders(&hdrcomp);
+
+ if (add_data((char*)hdrcomp.get(),hdrcomp.getlen(),&ihd) < 0)
+ return PS_ERROR;
+
+ fh.length_of_header=hdrcomp.getlen();
+ installinfo_compressed=ihd.getlen();
+ }
+
+ if (!build_compress_whole)
+ fh.length_of_all_following_data=ihd.getlen()+build_datablock.getlen()+(int)sizeof(firstheader)+(build_crcchk?sizeof(crc32_t):0);
+ else
+ fd_start=ftell(fp);
+
+ try
+ {
+ file_writer_sink sink(fp);
+ firstheader_writer w(&sink);
+ w.write(&fh);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Error: can't write %d bytes to output\n",sizeof(fh));
+ fclose(fp);
+ return PS_ERROR;
+ }
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ if (build_compress_whole) {
+ if (deflateToFile(fp,(char*)ihd.get(),ihd.getlen()))
+ {
+ fclose(fp);
+ return PS_ERROR;
+ }
+ }
+ else
+#endif
+ {
+ if (fwrite(ihd.get(),1,ihd.getlen(),fp) != (unsigned int)ihd.getlen())
+ {
+ ERROR_MSG("Error: can't write %d bytes to output\n",ihd.getlen());
+ fclose(fp);
+ return PS_ERROR;
+ }
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ crc_writer_sink crc_sink((crc32_t *) &crc);
+ firstheader_writer w(&crc_sink);
+ w.write(&fh);
+
+ crc=CRC32(crc,(unsigned char*)ihd.get(),ihd.getlen());
+#endif
+ }
+ }
+
+ INFO_MSG("Install: ");
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ int np=build_header.blocks[NB_PAGES].num;
+ INFO_MSG("%d page%s (%d bytes), ",np,np==1?"":"s",np*sizeof(page));
+#endif
+ {
+ int ns=build_sections.getlen()/sizeof(section);
+ section *s=(section*)build_sections.get();
+ int x;
+ int req=0;
+ for (x = 1; x < ns; x ++)
+ {
+ if (!s[x].name_ptr || s[x].flags & SF_RO) req++;
+ }
+ INFO_MSG("%d section%s",ns,ns==1?"":"s");
+ if (req)
+ {
+ INFO_MSG(" (%d required)",req);
+ }
+ INFO_MSG(" (%d bytes), ", build_sections.getlen());
+ }
+ int ne=build_header.blocks[NB_ENTRIES].num;
+ INFO_MSG("%d instruction%s (%d bytes), ",ne,ne==1?"":"s",ne*sizeof(entry));
+ int ns=build_strlist.getnum();
+ INFO_MSG("%d string%s (%d bytes), ",ns,ns==1?"":"s",build_strlist.getlen());
+ int nlt=build_header.blocks[NB_LANGTABLES].num;
+ INFO_MSG("%d language table%s (%d bytes).\n",nlt,nlt==1?"":"s",build_langtables.getlen());
+ if (ubuild_entries.getlen())
+ {
+ INFO_MSG("Uninstall: ");
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ np=build_uninst.blocks[NB_PAGES].num;
+ INFO_MSG("%d page%s (%d bytes), \n",np,np==1?"":"s",ubuild_pages.getlen());
+#endif
+ {
+ int ns=ubuild_sections.getlen()/sizeof(section);
+ section *s=(section*)ubuild_sections.get();
+ int x;
+ int req=0;
+ for (x = 1; x < ns; x ++)
+ {
+ if (!s[x].name_ptr || s[x].flags & SF_RO) req++;
+ }
+ INFO_MSG("%d section%s",ns,ns==1?"":"s");
+ if (req)
+ {
+ INFO_MSG(" (%d required)",req);
+ }
+ INFO_MSG(" (%d bytes), ", ubuild_sections.getlen());
+ }
+ ne=build_uninst.blocks[NB_ENTRIES].num;
+ INFO_MSG("%d instruction%s (%d bytes), ",ne,ne==1?"":"s",ubuild_entries.getlen());
+ ns=ubuild_strlist.getnum();
+ INFO_MSG("%d string%s (%d bytes), ",ns,ns==1?"":"s",ubuild_strlist.getlen());
+ nlt=build_uninst.blocks[NB_LANGTABLES].num;
+ INFO_MSG("%d language table%s (%d bytes).\n",nlt,nlt==1?"":"s",ubuild_langtables.getlen());
+ }
+
+
+ if (db_opt_save)
+ {
+ int total_out_size_estimate=
+ m_exehead_size+sizeof(fh)+build_datablock.getlen()+(build_crcchk?sizeof(crc32_t):0);
+ int pc=(int)(((INT64)db_opt_save*1000)/(db_opt_save+total_out_size_estimate));
+ INFO_MSG("Datablock optimizer saved %d bytes (~%d.%d%%).\n",db_opt_save,
+ pc/10,pc%10);
+ }
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ INFO_MSG("\nUsing %s%s compression.\n\n", compressor->GetName(), build_compress_whole?" (compress whole)":"");
+#endif
+
+ unsigned int total_usize=m_exehead_original_size;
+
+ INFO_MSG("EXE header size: %10d / %d bytes\n",m_exehead_size,m_exehead_original_size);
+
+ if (build_compress_whole) {
+ INFO_MSG("Install code: (%d bytes)\n",
+ sizeof(fh)+fh.length_of_header);
+ }
+ else {
+ INFO_MSG("Install code: %10d / %d bytes\n",
+ sizeof(fh)+installinfo_compressed,
+ sizeof(fh)+fh.length_of_header);
+ }
+
+ total_usize+=sizeof(fh)+fh.length_of_header;
+
+ {
+ int dbsize, dbsizeu;
+ dbsize = build_datablock.getlen();
+ if (uninstall_size>0) dbsize-=uninstall_size;
+
+ if (build_compress_whole) {
+ dbsizeu=dbsize;
+ INFO_MSG("Install data: (%d bytes)\n",dbsizeu);
+ }
+ else {
+ dbsizeu = db_full_size - uninstall_size_full;
+ INFO_MSG("Install data: %10d / %d bytes\n",dbsize,dbsizeu);
+ }
+ total_usize+=dbsizeu;
+ }
+
+ if (uninstall_size>=0)
+ {
+ if (build_compress_whole)
+ INFO_MSG("Uninstall code+data: (%d bytes)\n",uninstall_size_full);
+ else
+ INFO_MSG("Uninstall code+data: %6d / %d bytes\n",uninstall_size,uninstall_size_full);
+ total_usize+=uninstall_size_full;
+ }
+
+ if (build_compress_whole) {
+ INFO_MSG("Compressed data: ");
+ }
+
+ if (build_datablock.getlen())
+ {
+ build_datablock.setro(TRUE);
+ int dbl = build_datablock.getlen();
+ int left = dbl;
+ while (left > 0)
+ {
+ int l = min(build_filebuflen, left);
+ char *dbptr = (char *) build_datablock.get(dbl - left, l);
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ if (build_compress_whole)
+ {
+ if (deflateToFile(fp,dbptr,l))
+ {
+ fclose(fp);
+ return PS_ERROR;
+ }
+ }
+ else
+#endif
+ {
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ crc=CRC32(crc,(unsigned char *)dbptr,l);
+#endif
+ if ((int)fwrite(dbptr,1,l,fp) != l)
+ {
+ ERROR_MSG("Error: can't write %d bytes to output\n",l);
+ fclose(fp);
+ return PS_ERROR;
+ }
+ fflush(fp);
+ }
+ build_datablock.release();
+ left -= l;
+ }
+ build_datablock.setro(FALSE);
+ build_datablock.clear();
+ }
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ if (build_compress_whole)
+ {
+ if (deflateToFile(fp,NULL,0))
+ {
+ fclose(fp);
+ return PS_ERROR;
+ }
+ compressor->End();
+
+ unsigned fend = ftell(fp);
+
+ fh.length_of_all_following_data=ftell(fp)-fd_start+(build_crcchk?sizeof(crc32_t):0);
+ INFO_MSG(
+ "%10d / %d bytes\n",
+ ftell(fp) - fd_start,
+ data_block_size_before_uninst + fh.length_of_header + sizeof(firstheader) + uninstall_size_full
+ );
+
+ fseek(fp,fd_start,SEEK_SET);
+
+ try
+ {
+ file_writer_sink sink(fp);
+ firstheader_writer w(&sink);
+ w.write(&fh);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Error: can't write %d bytes to output\n",sizeof(fh));
+ fclose(fp);
+ return PS_ERROR;
+ }
+
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ if (build_crcchk)
+ {
+ // check rest of CRC
+ fseek(fp,fd_start,SEEK_SET);
+ for (;;)
+ {
+ char buf[32768];
+ int l=fread(buf,1,sizeof(buf),fp);
+ if (!l) break;
+ crc=CRC32(crc,(unsigned char *)buf,l);
+ }
+ }
+#endif
+ fseek(fp,fend,SEEK_SET); // reset eof flag
+ }
+#endif
+
+ if (build_crcchk)
+ {
+ total_usize+=sizeof(int);
+ int rcrc = FIX_ENDIAN_INT32(crc);
+ if (fwrite(&rcrc,1,sizeof(crc32_t),fp) != sizeof(crc32_t))
+ {
+ ERROR_MSG("Error: can't write %d bytes to output\n",sizeof(crc32_t));
+ fclose(fp);
+ return PS_ERROR;
+ }
+ INFO_MSG("CRC (0x%08X): 4 / 4 bytes\n",crc);
+ }
+ INFO_MSG("\n");
+ {
+ UINT pc=(UINT)(((UINT64)ftell(fp)*1000)/(total_usize));
+ INFO_MSG("Total size: %10u / %u bytes (%u.%u%%)\n",
+ ftell(fp),total_usize,pc/10,pc%10);
+ }
+ fclose(fp);
+ print_warnings();
+ return PS_OK;
+}
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+int CEXEBuild::deflateToFile(FILE *fp, char *buf, int len) // len==0 to flush
+{
+ build_compressor_set=true;
+
+ char obuf[65536];
+ bool flush=false;
+ compressor->SetNextIn(buf,len);
+ if (!buf||!len)
+ {
+ char a;
+ compressor->SetNextIn(&a,0);
+ flush=C_FINISH;
+ }
+ for (;;)
+ {
+ compressor->SetNextOut(obuf,sizeof(obuf));
+ int ret=compressor->Compress(flush);
+ if (ret<0 && (ret!=-1 || !flush))
+ {
+ ERROR_MSG("Error: deflateToFile: deflate() failed(%s [%d])\n", compressor->GetErrStr(ret), ret);
+ return 1;
+ }
+ int l=compressor->GetNextOut()-obuf;
+ if (l)
+ {
+ if (fwrite(obuf,1,l,fp) != (unsigned)l)
+ {
+ ERROR_MSG("Error: deflateToFile fwrite(%d) failed\n",l);
+ return 1;
+ }
+ fflush(fp);
+ }
+ if (!compressor->GetAvailIn() && (!flush || !l)) break;
+ }
+ return 0;
+}
+#endif
+
+int CEXEBuild::uninstall_generate()
+{
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (ubuild_entries.getlen() && uninstaller_writes_used)
+ {
+ SCRIPT_MSG("Generating uninstaller... ");
+
+ firstheader fh={0,};
+
+ GrowBuf uhd;
+ {
+ GrowBuf udata;
+
+ set_uninstall_mode(1);
+
+ PrepareHeaders(&udata);
+
+ fh.length_of_header=udata.getlen();
+ int err=add_data((char*)udata.get(),udata.getlen(),&uhd);
+ set_uninstall_mode(0);
+ if (err < 0) return PS_ERROR;
+ }
+
+ crc32_t crc=0;
+
+ // Get offsets of icons to replace for uninstall
+ // Also makes sure that the icons are there and in the right size.
+ LPBYTE unicon_data = generate_uninstall_icon_data(installer_icon, uninstaller_icon, m_unicon_size);
+ if (generate_unicons_offsets(m_exehead, m_exehead_size, unicon_data, IDI_ICON2) == 0)
+ {
+ delete [] unicon_data;
+ return PS_ERROR;
+ }
+
+ entry *ent = (entry *) build_entries.get();
+ if (!ent)
+ {
+ delete [] unicon_data;
+ return PS_ERROR;
+ }
+
+ int ents = build_header.blocks[NB_ENTRIES].num;
+ int uns = uninstaller_writes_used;
+ int uninstdata_offset = build_datablock.getlen();
+ while (ents--)
+ {
+ if (ent->which == EW_WRITEUNINSTALLER)
+ {
+ ent->offsets[1] = uninstdata_offset;
+ ent->offsets[2] = m_unicon_size;
+ uns--;
+ if (!uns)
+ break;
+ }
+ ent++;
+ }
+
+ if (add_db_data((char *)unicon_data,m_unicon_size) < 0)
+ {
+ delete [] unicon_data;
+ return PS_ERROR;
+ }
+
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ {
+ // "create" the uninstaller
+ LPBYTE uninst_header = (LPBYTE) malloc(m_exehead_size);
+ if (!uninst_header)
+ return PS_ERROR;
+
+ memcpy(uninst_header, m_exehead, m_exehead_size);
+
+ // patch the icons
+ LPBYTE seeker = unicon_data;
+ while (*seeker) {
+ DWORD dwSize = FIX_ENDIAN_INT32(*(LPDWORD) seeker);
+ seeker += sizeof(DWORD);
+ DWORD dwOffset = FIX_ENDIAN_INT32(*(LPDWORD) seeker);
+ seeker += sizeof(DWORD);
+ memcpy(uninst_header + dwOffset, seeker, dwSize);
+ seeker += dwSize;
+ }
+
+ delete [] unicon_data;
+
+#ifdef NSIS_CONFIG_CRC_ANAL
+ crc=CRC32(crc, uninst_header, m_exehead_size);
+#else
+ crc=CRC32(crc, uninst_header + 512, m_exehead_size - 512);
+#endif
+
+ free(uninst_header);
+ }
+#endif
+ fh.nsinst[0]=FH_INT1;
+ fh.nsinst[1]=FH_INT2;
+ fh.nsinst[2]=FH_INT3;
+ fh.flags=FH_FLAGS_UNINSTALL;
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ fh.flags|=(build_crcchk?(build_crcchk==2?FH_FLAGS_FORCE_CRC:0):FH_FLAGS_NO_CRC);
+#endif
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ if (build_uninst.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG)) fh.flags |= FH_FLAGS_SILENT;
+#endif
+ fh.siginfo=FH_SIG;
+ fh.length_of_all_following_data=
+ uhd.getlen()+ubuild_datablock.getlen()+(int)sizeof(firstheader)+(build_crcchk?sizeof(crc32_t):0);
+
+ MMapBuf udata;
+
+ {
+ growbuf_writer_sink sink(&udata);
+ firstheader_writer w(&sink);
+ w.write(&fh);
+ }
+
+ ubuild_datablock.setro(TRUE);
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ if (build_compress_whole) {
+ // compress uninstaller too
+ {
+ char obuf[65536];
+ int n = compressor->Init(build_compress_level, build_compress_dict_size);
+ if (n != C_OK)
+ {
+ ERROR_MSG("Internal compiler error #12345: deflateInit() failed(%s [%d]).\n", compressor->GetErrStr(n), n);
+ extern void quit(); quit();
+ }
+
+ compressor->SetNextIn((char*)uhd.get(), uhd.getlen());
+ while (compressor->GetAvailIn())
+ {
+ compressor->SetNextOut(obuf, sizeof(obuf));
+ compressor->Compress(0);
+ if (compressor->GetNextOut() - obuf > 0)
+ {
+ udata.add(obuf, compressor->GetNextOut() - obuf);
+ }
+ }
+
+ int avail_in = ubuild_datablock.getlen();
+ int in_pos = 0;
+ while (avail_in > 0) {
+ int l = min(avail_in, build_filebuflen);
+
+ char *p = (char*)ubuild_datablock.get(in_pos, l);
+ compressor->SetNextIn(p, l);
+
+ while (compressor->GetAvailIn())
+ {
+ compressor->SetNextOut(obuf, sizeof(obuf));
+ compressor->Compress(0);
+ if (compressor->GetNextOut() - obuf > 0)
+ udata.add(obuf, compressor->GetNextOut() - obuf);
+ }
+
+ ubuild_datablock.release();
+
+ avail_in -= l;
+ in_pos += l;
+ }
+
+ for (;;)
+ {
+ compressor->SetNextOut(obuf, sizeof(obuf));
+ compressor->Compress(C_FINISH);
+ if (compressor->GetNextOut() - obuf > 0)
+ udata.add(obuf, compressor->GetNextOut() - obuf);
+ else break;
+ }
+ compressor->End();
+ }
+
+ firstheader *_fh=(firstheader *)udata.get(0, sizeof(firstheader));
+ _fh->length_of_all_following_data=FIX_ENDIAN_INT32(udata.getlen()+(build_crcchk?sizeof(crc32_t):0));
+ udata.release();
+ }
+ else
+#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
+ {
+ udata.add(uhd.get(), uhd.getlen());
+
+ int st = udata.getlen();
+ int length = ubuild_datablock.getlen();
+ int left = length;
+ udata.resize(st + left);
+ while (left > 0)
+ {
+ int l = min(build_filebuflen, left);
+ void *p = ubuild_datablock.get(length - left, l);
+ memcpy(udata.get(st + length - left, l), p, l);
+ udata.flush(l);
+ udata.release();
+ ubuild_datablock.release();
+ left -= l;
+ }
+ }
+
+ ubuild_datablock.clear();
+
+ udata.setro(TRUE);
+
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ if (build_crcchk)
+ {
+ int pos = 0;
+ int left = udata.getlen();
+ while (left > 0)
+ {
+ int l = min(build_filebuflen, left);
+ crc = CRC32(crc, (unsigned char *) udata.get(pos, l), l);
+ udata.release();
+ pos += l;
+ left -= l;
+ }
+ udata.setro(FALSE);
+ FIX_ENDIAN_INT32_INPLACE(crc);
+ udata.add(&crc, sizeof(crc));
+ udata.setro(TRUE);
+ }
+#endif
+
+ if (add_db_data(&udata) < 0)
+ return PS_ERROR;
+
+ udata.clear();
+
+ //uninstall_size_full=fh.length_of_all_following_data + sizeof(int) + unicondata_size - 32 + sizeof(int);
+ uninstall_size_full=fh.length_of_all_following_data+m_unicon_size;
+
+ // compressed size
+ uninstall_size=build_datablock.getlen()-uninstdata_offset;
+
+ SCRIPT_MSG("Done!\n");
+ }
+#endif
+ return PS_OK;
+}
+
+#define SWAP(x,y,i) { i _ii; _ii=x; x=y; y=_ii; }
+
+void CEXEBuild::set_uninstall_mode(int un)
+{
+ if (un != uninstall_mode)
+ {
+ uninstall_mode=un;
+ if (un)
+ {
+ cur_datablock=&ubuild_datablock;
+ cur_datablock_cache=&ubuild_datablock_cache;
+ cur_entries=&ubuild_entries;
+ cur_instruction_entry_map=&ubuild_instruction_entry_map;
+ cur_functions=&ubuild_functions;
+ cur_labels=&ubuild_labels;
+ cur_pages=&ubuild_pages;
+ cur_sections=&ubuild_sections;
+ cur_header=&build_uninst;
+ cur_strlist=&ubuild_strlist;
+ cur_langtables=&ubuild_langtables;
+ cur_ctlcolors=&ubuild_ctlcolors;
+
+ definedlist.add("__UNINSTALL__");
+ }
+ else
+ {
+ cur_datablock=&build_datablock;
+ cur_datablock_cache=&build_datablock_cache;
+ cur_entries=&build_entries;
+ cur_instruction_entry_map=&build_instruction_entry_map;
+ cur_functions=&build_functions;
+ cur_labels=&build_labels;
+ cur_pages=&build_pages;
+ cur_sections=&build_sections;
+ cur_header=&build_header;
+ cur_strlist=&build_strlist;
+ cur_langtables=&build_langtables;
+ cur_ctlcolors=&build_ctlcolors;
+
+ definedlist.del("__UNINSTALL__");
+ }
+
+ SWAP(db_opt_save_u,db_opt_save,int);
+ SWAP(db_comp_save_u,db_comp_save,int);
+ SWAP(db_full_size_u,db_full_size,int);
+ }
+}
+
+extern FILE *g_output;
+
+void CEXEBuild::warning(const char *s, ...)
+{
+ char buf[NSIS_MAX_STRLEN*10];
+ va_list val;
+ va_start(val,s);
+#ifdef _WIN32
+ vsprintf(buf,s,val);
+#else
+ vsnprintf(buf,NSIS_MAX_STRLEN*10,s,val);
+#endif
+ va_end(val);
+ m_warnings.add(buf,0);
+ notify(MAKENSIS_NOTIFY_WARNING,buf);
+ if (display_warnings)
+ {
+ fprintf(g_output,"warning: %s\n",buf);
+ fflush(g_output);
+ }
+}
+
+void CEXEBuild::warning_fl(const char *s, ...)
+{
+ char buf[NSIS_MAX_STRLEN*10];
+ va_list val;
+ va_start(val,s);
+#ifdef _WIN32
+ vsprintf(buf,s,val);
+#else
+ vsnprintf(buf,NSIS_MAX_STRLEN*10,s,val);
+#endif
+ va_end(val);
+ sprintf(buf+strlen(buf)," (%s:%d)",curfilename,linecnt);
+ m_warnings.add(buf,0);
+ notify(MAKENSIS_NOTIFY_WARNING,buf);
+ if (display_warnings)
+ {
+ fprintf(g_output,"warning: %s\n",buf);
+ fflush(g_output);
+ }
+}
+
+void CEXEBuild::ERROR_MSG(const char *s, ...) const
+{
+ if (display_errors || notify_hwnd)
+ {
+ char buf[NSIS_MAX_STRLEN*10];
+ va_list val;
+ va_start(val,s);
+#ifdef _WIN32
+ vsprintf(buf,s,val);
+#else
+ vsnprintf(buf,NSIS_MAX_STRLEN*10,s,val);
+#endif
+ va_end(val);
+ notify(MAKENSIS_NOTIFY_ERROR,buf);
+ if (display_errors)
+ {
+ fprintf(g_output,"%s",buf);
+ fflush(g_output);
+ }
+ }
+}
+
+void CEXEBuild::SCRIPT_MSG(const char *s, ...) const
+{
+ if (display_script)
+ {
+ va_list val;
+ va_start(val,s);
+ vfprintf(g_output,s,val);
+ va_end(val);
+ fflush(g_output);
+ }
+}
+
+void CEXEBuild::INFO_MSG(const char *s, ...) const
+{
+ if (display_info)
+ {
+ va_list val;
+ va_start(val,s);
+ vfprintf(g_output,s,val);
+ va_end(val);
+ fflush(g_output);
+ }
+}
+
+void CEXEBuild::print_warnings()
+{
+ int nw=0,x=m_warnings.getlen();
+ if (!x || !display_warnings) return;
+ char *p=m_warnings.get();
+ while (x>0) if (!p[--x]) nw++;
+ fprintf(g_output,"\n%d warning%s:\n",nw,nw==1?"":"s");
+ for (x = 0; x < nw; x ++)
+ {
+ fprintf(g_output," %s\n",p);
+ p+=strlen(p)+1;
+ }
+ fflush(g_output);
+}
+
+void CEXEBuild::notify(notify_e code, const char *data) const
+{
+#ifdef _WIN32
+ if (notify_hwnd)
+ {
+ COPYDATASTRUCT cds = {(DWORD)code, strlen(data)+1, (void *) data};
+ SendMessage(notify_hwnd, WM_COPYDATA, 0, (LPARAM)&cds);
+ }
+#endif
+}
+
+// Added by Ximon Eighteen 5th August 2002
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+void CEXEBuild::build_plugin_table(void)
+{
+ if (plugins_processed)
+ return;
+ plugins_processed=1;
+
+ plugin_used = false;
+ uninst_plugin_used = false;
+ string searchPath = definedlist.find("NSISDIR");
+ searchPath += PLATFORM_PATH_SEPARATOR_STR"Plugins";
+ INFO_MSG("Processing plugin dlls: \"%s" PLATFORM_PATH_SEPARATOR_STR "*.dll\"\n",searchPath.c_str());
+ m_plugins.FindCommands(searchPath, display_info?true:false);
+ INFO_MSG("\n");
+}
+
+#define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags, flag)/sizeof(int))
+
+int CEXEBuild::add_plugins_dir_initializer(void)
+{
+ if (!plugin_used && !uninst_plugin_used) return PS_OK;
+
+ SCRIPT_MSG("Adding plug-ins initializing function... ");
+
+ bool uninstall = !plugin_used;
+
+ int ret;
+ int zero_offset;
+
+ int var_zero;
+ var_zero=m_UserVarNames.get("0");
+
+again:
+ // Function [un.]Initialize_____Plugins
+ ret=add_function(uninstall?"un.Initialize_____Plugins":"Initialize_____Plugins");
+ if (ret != PS_OK) return ret;
+
+ // don't move this, depends on [un.]
+ zero_offset=add_string("$0");
+
+ // SetDetailsPrint none
+ ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), add_intstring(6));
+ if (ret != PS_OK) return ret;
+
+ // StrCmp $PLUGINSDIR ""
+ ret=add_entry_direct(EW_STRCMP, add_string("$PLUGINSDIR"), 0, 0, ns_label.add("Initialize_____Plugins_done",0));
+ if (ret != PS_OK) return ret;
+ // Push $0
+ ret=add_entry_direct(EW_PUSHPOP, zero_offset);
+ if (ret != PS_OK) return ret;
+ // ClearErrors
+ ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(exec_error));
+ if (ret != PS_OK) return ret;
+ // GetTempFileName $0
+ ret=add_entry_direct(EW_GETTEMPFILENAME, var_zero, add_string("$TEMP"));
+ if (ret != PS_OK) return ret;
+ // Delete $0 [simple, nothing that could clash with special temp permissions]
+ ret=add_entry_direct(EW_DELETEFILE, zero_offset, DEL_SIMPLE);
+ if (ret != PS_OK) return ret;
+ // CraeteDirectory $0 - a dir instead of that temp file
+ ret=add_entry_direct(EW_CREATEDIR, zero_offset);
+ if (ret != PS_OK) return ret;
+ // IfErrors Initialize_____Plugins_error - detect errors
+ ret=add_entry_direct(EW_IFFLAG, ns_label.add("Initialize_____Plugins_error",0), 0, FLAG_OFFSET(exec_error));
+ if (ret != PS_OK) return ret;
+ // Copy $0 to $PLUGINSDIR
+ ret=add_entry_direct(EW_ASSIGNVAR, m_UserVarNames.get("PLUGINSDIR"), zero_offset);
+ if (ret != PS_OK) return ret;
+ // Pop $0
+ ret=add_entry_direct(EW_PUSHPOP, var_zero, 1);
+ if (ret != PS_OK) return ret;
+
+ // done
+ if (add_label("Initialize_____Plugins_done")) return PS_ERROR;
+ // Return
+ ret=add_entry_direct(EW_RET);
+ if (ret != PS_OK) return ret;
+
+ // error
+ if (add_label("Initialize_____Plugins_error")) return PS_ERROR;
+ // error message box
+ ret=add_entry_direct(EW_MESSAGEBOX, MB_OK|MB_ICONSTOP|(IDOK<<21), add_string("Error! Can't initialize plug-ins directory. Please try again later."));
+ if (ret != PS_OK) return ret;
+ // Quit
+ ret=add_entry_direct(EW_QUIT);
+ if (ret != PS_OK) return ret;
+
+ // FunctionEnd
+ ret=function_end();
+ if (ret != PS_OK) return ret;
+
+ if (uninst_plugin_used && !uninstall) {
+ uninstall = true;
+ goto again;
+ }
+
+ SCRIPT_MSG("Done!\n");
+
+ return PS_OK;
+}
+#endif // NSIS_CONFIG_PLUGIN_SUPPORT
+
+void CEXEBuild::init_res_editor()
+{
+ build_compressor_set = true;
+ if (!res_editor)
+ res_editor = new CResourceEditor(m_exehead, m_exehead_size);
+}
+
+void CEXEBuild::close_res_editor()
+{
+ if (!res_editor) return;
+ DWORD newsize;
+
+ // get size
+ newsize = res_editor->Save(NULL, newsize);
+ unsigned char *new_header = new unsigned char[newsize];
+
+ // save
+ int rc = res_editor->Save(new_header, newsize);
+ assert(rc == 0);
+
+ update_exehead(new_header, newsize);
+
+ // TODO: resource-controlling class
+ delete [] new_header;
+
+ delete res_editor;
+ res_editor=0;
+}
+
+int CEXEBuild::DeclaredUserVar(const char *szVarName)
+{
+ if (m_ShellConstants.get((char*)szVarName) >= 0)
+ {
+ ERROR_MSG("Error: name \"%s\" in use by constant\n", szVarName);
+ return PS_ERROR;
+ }
+
+ int idxUserVar = m_UserVarNames.get((char*)szVarName);
+ if (idxUserVar >= 0)
+ {
+ ERROR_MSG("Error: variable \"%s\" already declared\n", szVarName);
+ return PS_ERROR;
+ }
+ const char *pVarName = szVarName;
+ int iVarLen = strlen(szVarName);
+
+ if (iVarLen > 60)
+ {
+ ERROR_MSG("Error: variable name too long!\n");
+ return PS_ERROR;
+ }
+ else if (!iVarLen)
+ {
+ ERROR_MSG("Error: variable with empty name!\n");
+ return PS_ERROR;
+ }
+ else
+ {
+ while (*pVarName)
+ {
+ if (!isSimpleChar(*pVarName))
+ {
+ ERROR_MSG("Error: invalid characters in variable name \"%s\", use only characters [a-z][A-Z][0-9] and '_'\n", szVarName);
+ return PS_ERROR;
+ }
+ pVarName++;
+ }
+ }
+
+ m_UserVarNames.add(szVarName);
+ if (m_UserVarNames.getnum() > MAX_CODED)
+ {
+ ERROR_MSG("Error: too many user variables declared. Maximum allowed is %u.\n", MAX_CODED - m_iBaseVarsNum);
+ return PS_ERROR;
+ }
+ return PS_OK;
+}
+
+
+int CEXEBuild::GetUserVarIndex(LineParser &line, int token)
+{
+ char *p = line.gettoken_str(token);
+ if ( *p == '$' && *(p+1) )
+ {
+ int idxUserVar = m_UserVarNames.get((char *)p+1);
+ if (idxUserVar >= 0 && m_UserVarNames.get_reference(idxUserVar) >= 0)
+ {
+ m_UserVarNames.inc_reference(idxUserVar);
+ return idxUserVar;
+ }
+ else
+ {
+ int idxConst = m_ShellConstants.get((char *)p+1);
+ if (idxConst >= 0)
+ {
+ ERROR_MSG("Error: cannot change constants : %s\n", p);
+ }
+ }
+ }
+ return -1;
+}
+
+void CEXEBuild::VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList)
+{
+ for (int i = m_iBaseVarsNum; i < pVarsStringList->getnum(); i++)
+ {
+ if (!pVarsStringList->get_reference(i))
+ {
+ warning("Variable \"%s\" not referenced or never set, wasting memory!", pVarsStringList->idx2name(i));
+ }
+ }
+}
+
+int CEXEBuild::set_compressor(const string& compressor, const bool solid) {
+ string stub = stubs_dir + PLATFORM_PATH_SEPARATOR_STR + compressor;
+ if (solid)
+ stub += "_solid";
+
+ return update_exehead(stub, &m_exehead_original_size);
+}
+
+int CEXEBuild::update_exehead(const string& file, size_t *size/*=NULL*/) {
+ FILE *tmpfile = fopen(file.c_str(), "rb");
+ if (!tmpfile)
+ {
+ ERROR_MSG("Error: opening stub \"%s\"\n", file.c_str());
+ return PS_ERROR;
+ }
+
+ fseek(tmpfile, 0, SEEK_END);
+ size_t exehead_size = ftell(tmpfile);
+
+ unsigned char *exehead = new unsigned char[exehead_size];
+ fseek(tmpfile, 0, SEEK_SET);
+ if (fread(exehead, 1, exehead_size, tmpfile) != exehead_size)
+ {
+ ERROR_MSG("Error: reading stub \"%s\"\n", file.c_str());
+ fclose(tmpfile);
+ delete [] exehead;
+ return PS_ERROR;
+ }
+ fclose(tmpfile);
+
+ update_exehead(exehead, exehead_size);
+
+ if (size)
+ *size = exehead_size;
+
+ delete [] exehead;
+
+ return PS_OK;
+}
+
+void CEXEBuild::update_exehead(const unsigned char *new_exehead, size_t new_size) {
+ assert(m_exehead != new_exehead);
+
+ // align exehead to 512
+ m_exehead_size = align_to_512(new_size);
+
+ delete [] m_exehead;
+ m_exehead = new unsigned char[m_exehead_size];
+
+ // copy exehead
+ memcpy(m_exehead, new_exehead, new_size);
+
+ // zero rest of exehead
+ memset(m_exehead + new_size, 0, m_exehead_size - new_size);
+}
+
+void CEXEBuild::set_code_type_predefines(const char *value)
+{
+ definedlist.del("__SECTION__");
+ definedlist.del("__FUNCTION__");
+ definedlist.del("__PAGEEX__");
+ definedlist.del("__GLOBAL__");
+
+ switch (GetCurrentTokenPlace())
+ {
+ case TP_SEC:
+ definedlist.add("__SECTION__", value==NULL?"":value);
+ break;
+ case TP_FUNC:
+ definedlist.add("__FUNCTION__", value==NULL?"":value);
+ break;
+ case TP_PAGEEX:
+ definedlist.add("__PAGEEX__", value==NULL?"":value);
+ break;
+ default:
+ definedlist.add("__GLOBAL__");
+ }
+}
+
diff --git a/Source/build.h b/Source/build.h
index 6c41a45..1defd58 100755
--- a/Source/build.h
+++ b/Source/build.h
@@ -1,415 +1,418 @@
-/*
- * build.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef _BUILD_H_
-#define _BUILD_H_
-
-#include "strlist.h"
-#include "lineparse.h"
-#include "lang.h"
-#include "ResourceEditor.h"
-#include "ResourceVersionInfo.h"
-#include "uservars.h"
-#include "ShConstants.h"
-#include "mmap.h"
-#include "manifest.h"
-
-#include "exehead/fileform.h"
-#include "exehead/config.h"
-
-#include <string>
-#include <set>
-
-#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
-// Added by Sunil Kamath 11 June 2003
-# include <time.h>
-# include <sys/stat.h>
-#endif
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
-// Changed by Amir Szekely 31st July 2002
-#include "compressor.h"
-#include "czlib.h"
-#include "cbzip2.h"
-#include "clzma.h"
-
-#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
-
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
-# include "Plugins.h"
-#endif //NSIS_CONFIG_PLUGIN_SUPPORT
-
-#define PS_OK 0
-#define PS_EOF 1
-#define PS_ERROR 50
-#define PS_WARNING 100
-
-// token placement
-#define TP_SEC 1
-#define TP_FUNC 2
-#define TP_CODE (TP_SEC | TP_FUNC)
-#define TP_GLOBAL 4
-#define TP_PAGEEX 8
-#define TP_PG (TP_GLOBAL | TP_PAGEEX)
-#define TP_ALL (TP_CODE | TP_PG)
-
-enum notify_e {
- MAKENSIS_NOTIFY_SCRIPT,
- MAKENSIS_NOTIFY_WARNING,
- MAKENSIS_NOTIFY_ERROR,
- MAKENSIS_NOTIFY_OUTPUT
-};
-
-#define PAGE_CUSTOM 0
-#define PAGE_LICENSE 1
-#define PAGE_COMPONENTS 2
-#define PAGE_DIRECTORY 3
-#define PAGE_INSTFILES 4
-#define PAGE_UNINSTCONFIRM 5
-#define PAGE_COMPLETED 6
-
-class CEXEBuild {
- public:
- CEXEBuild();
- void initialize(const char *makensis_path);
- ~CEXEBuild();
-
- // to add a warning to the compiler's warning list.
- void warning(const char *s, ...);
- // warning with file name and line count
- void warning_fl(const char *s, ...);
-
- // to add a defined thing.
- void define(const char *p, const char *v="");
-
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
- // Added by Ximon Eighteen 5th August 2002
- void build_plugin_table(void);
- int plugins_processed;
-#endif //NSIS_CONFIG_PLUGIN_SUPPORT
-
-
- // process a script (you can process as many scripts as you want,
- // it is as if they are concatenated)
- int process_script(FILE *fp, char *curfilename);
- int process_oneline(char *line, char *curfilename, int lineptr);
-
- // you only get to call write_output once, so use it wisely.
- int write_output(void);
-
- void print_help(char *commandname=NULL);
-
- DefineList definedlist;
-
- int display_errors;
- int display_script;
- int display_warnings;
- int display_info;
-
- int linecnt;
- char *curfilename;
- FILE *fp;
-
- HWND notify_hwnd;
- void notify(notify_e code, const char *data) const;
-
- private:
- int check_write_output_errors() const;
- int prepare_uninstaller();
- int pack_exe_header();
-
- int set_compressor(const std::string& compressor, const bool solid);
- int update_exehead(const std::string& file, size_t *size=NULL);
- void update_exehead(const unsigned char *new_exehead, size_t new_size);
-
- // tokens.cpp
- bool is_valid_token(char *s);
- int get_commandtoken(char *s, int *np, int *op, int *pos);
- int GetCurrentTokenPlace();
- int IsTokenPlacedRight(int pos, char *tok);
-
- // script.cpp
-#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
- // Added by Sunil Kamath 11 June 2003
- char* set_file_predefine(char *);
- void restore_file_predefine(char *);
- char* set_timestamp_predefine(char *);
- void restore_timestamp_predefine(char *);
- char* set_line_predefine(int, BOOL);
- void restore_line_predefine(char *);
- void set_date_time_predefines();
- void del_date_time_predefines();
-#endif
- int parseScript();
- int includeScript(char *f);
- int MacroExists(const char *macroname);
-#ifdef NSIS_FIX_DEFINES_IN_STRINGS
- void ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist, bool bIgnoreDefines = false);
-#else
- void ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist);
-#endif
- int doParse(const char *str);
- int doCommand(int which_token, LineParser &line);
-
- int do_add_file(const char *lgss, int attrib, int recurse, int *total_files, const char
- *name_override=0, int generatecode=1, int *data_handle=0,
- const std::set<std::string>& excluded=std::set<std::string>(),
- const std::string& basedir=std::string(""), bool dir_created=false);
- int add_file(const std::string& dir, const std::string& file, int attrib, const char
- *name_override, int generatecode, int *data_handle);
- int do_add_file_create_dir(const std::string& local_dir, const std::string& dir, int attrib=0);
-
- GrowBuf m_linebuild; // used for concatenating lines
-
- // used by doParse to do preprocessing
- struct ifblock
- {
- int hasexeced;
- int elseused;
- int ignore;
- int inherited_ignore;
- } *cur_ifblock;
-
- TinyGrowBuf build_preprocessor_data;
-
- void start_ifblock();
- void end_ifblock();
- int num_ifblock();
-
- int last_line_had_slash;
- bool inside_comment;
- int multiple_entries_instruction;
-
- void ERROR_MSG(const char *s, ...) const;
- void SCRIPT_MSG(const char *s, ...) const;
- void INFO_MSG(const char *s, ...) const;
-
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
- int add_plugins_dir_initializer(void);
-#endif //NSIS_CONFIG_PLUGIN_SUPPORT
-
- // build.cpp functions used mostly by script.cpp
- void set_code_type_predefines(const char *value = NULL);
- int getcurdbsize();
- int add_section(const char *secname, const char *defname, int expand=0);
- int section_end();
- int add_function(const char *funname);
- int function_end();
- void section_add_size_kb(int kb);
- int section_add_flags(int flags);
- int section_add_install_type(int inst_type);
- int add_page(int type);
- int page_end();
- int add_label(const char *name);
- int add_entry(const entry *ent);
- int add_entry_direct(int which, int o0=0, int o1=0, int o2=0, int o3=0, int o4=0, int o5=0);
- int add_db_data(IMMap *map); // returns offset
- int add_db_data(const char *data, int length); // returns offset
- int add_data(const char *data, int length, IGrowBuf *dblock); // returns offset
- int add_string(const char *string, int process=1, WORD codepage=CP_ACP); // returns offset (in string table)
- int add_intstring(const int i); // returns offset in stringblock
-
- int preprocess_string(char *out, const char *in, WORD codepage=CP_ACP);
-
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
- // Added by Ximon Eighteen 5th August 2002
- Plugins m_plugins;
- bool plugin_used;
- bool uninst_plugin_used;
- int build_plugin_unload;
-#endif //NSIS_CONFIG_PLUGIN_SUPPORT
-
- // build.cpp functions used mostly within build.cpp
- int datablock_optimize(int start_offset, int first_int);
- void printline(int l);
- int process_jump(LineParser &line, int wt, int *offs);
-
- int AddVersionInfo();
- int ProcessPages();
- void PrepareInstTypes();
- void AddStandardStrings();
- void PrepareHeaders(IGrowBuf *hdrbuf);
- int SetVarsSection();
- int SetManifest();
-
- int resolve_jump_int(const char *fn, int *a, int offs, int start, int end);
- int resolve_call_int(const char *fn, const char *str, int fptr, int *ofs);
- int resolve_instruction(const char *fn, const char *str, entry *w, int offs, int start, int end);
-
- int resolve_coderefs(const char *str);
- void print_warnings();
- int uninstall_generate();
- void set_uninstall_mode(int un);
-
- // lang.cpp functions and variables
- void InitLangTables();
- LanguageTable *GetLangTable(LANGID &lang, bool create = true);
- char *GetLangNameAndCP(LANGID lang, unsigned int *codepage = NULL);
- int DefineLangString(char *name, int process=-1);
- int DefineInnerLangString(int id, int process=-1);
- int SetLangString(char *name, LANGID lang, char *string);
- int SetInnerString(int id, char *string);
- int GenerateLangTable(LanguageTable *lt, int num_lang_tables);
- int GenerateLangTables();
- void FillLanguageTable(LanguageTable *table);
- int HasUserDefined(int id) {
- const char *us = UserInnerStrings.get(id);
- return us && *us;
- };
-
- LanguageTable *LoadLangFile(char *filename);
- void DeleteLangTable(LanguageTable *table);
-
- NLFRef NLFRefs[NLF_STRINGS];
- bool keep_ref;
- StringsArray UserInnerStrings;
- bool defcodepage_set;
- GrowBuf lang_tables;
- LANGID last_used_lang;
- LangStringList build_langstrings;
- int build_langstring_num, ubuild_langstring_num;
- char build_font[1024];
- int build_font_size;
-
- unsigned int uDefCodePage;
-
- // pages stuff
- int license_res_id;
- page *cur_page;
- int cur_page_type;
- int enable_last_page_cancel, uenable_last_page_cancel;
-
- int disable_window_icon;
-
- // User variables stuff
- int GetUserVarIndex(LineParser &line, int token);
- // Added by ramon 3 jun 2003
- UserVarsStringList m_UserVarNames;
- int m_iBaseVarsNum;
- int DeclaredUserVar(const char *VarName);
- void VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList);
-
- ConstantsStringList m_ShellConstants;
-
- // a whole bunch O data.
-
- std::string stubs_dir;
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- ICompressor *compressor;
- CZlib zlib_compressor;
- CBzip2 bzip2_compressor;
- CLZMA lzma_compressor;
-#endif
- bool build_compressor_set;
- bool build_compressor_final;
- bool build_compress_whole;
- int build_compress;
- int build_compress_level;
- int build_compress_dict_size;
-
- bool no_space_texts;
-
- bool has_called_write_output;
-
- char build_packname[1024], build_packcmd[1024];
- int build_overwrite, build_last_overwrite, build_crcchk,
- build_datesave, build_optimize_datablock,
- build_allowskipfiles; // Added by ramon 23 May 2003
-
- header build_header, build_uninst, *cur_header;
- int uninstall_mode;
- int uninstall_size,uninstall_size_full;
- int uninstaller_writes_used;
-
- char build_output_filename[1024];
-
- int build_include_depth;
-
- // Added by ramon 6 jun 2003
-#ifdef NSIS_SUPPORT_VERSION_INFO
- CResourceVersionInfo rVersionInfo;
- char version_product_v[1024];
-#endif
-
- int sectiongroup_open_cnt;
- FastStringList m_warnings;
- GrowBuf m_macros;
-
- StringList m_macro_entry;
-
- int db_opt_save, db_comp_save, db_full_size, db_opt_save_u,
- db_comp_save_u, db_full_size_u;
-
- FastStringList include_dirs;
-
- StringList ns_func; // function namespace
- StringList ns_label; // label namespace
-
- int build_cursection_isfunc;
- section *build_cursection;
- TinyGrowBuf build_sections, ubuild_sections, *cur_sections;
- GrowBuf build_entries,ubuild_entries, *cur_entries;
- GrowBuf build_instruction_entry_map,ubuild_instruction_entry_map, *cur_instruction_entry_map;
- TinyGrowBuf build_functions, ubuild_functions, *cur_functions;
- TinyGrowBuf build_labels, ubuild_labels, *cur_labels;
- StringList build_strlist, ubuild_strlist, *cur_strlist;
- GrowBuf build_langtables, ubuild_langtables, *cur_langtables;
- TinyGrowBuf build_pages, ubuild_pages, *cur_pages;
- TinyGrowBuf build_ctlcolors, ubuild_ctlcolors, *cur_ctlcolors;
-
- // don't forget to update the cache after updating the datablock
- // see datablock_optimize for an example
- MMapBuf build_datablock, ubuild_datablock;
- TinyGrowBuf build_datablock_cache, ubuild_datablock_cache;
- IGrowBuf *cur_datablock, *cur_datablock_cache;
- struct cached_db_size
- {
- int first_int; // size | (compressed ? 0x80000000 : 0)
- int start_offset;
- };
-
- int build_filebuflen;
-
- TinyGrowBuf verbose_stack;
-
- unsigned char *m_exehead;
- size_t m_exehead_size;
- size_t m_exehead_original_size;
-
- bool branding_image_found;
- WORD branding_image_id;
- unsigned char *m_unicon_data;
- size_t m_unicon_size;
-
-#ifdef NSIS_SUPPORT_BGBG
- LOGFONT bg_font;
- LOGFONT bg_default_font;
-#endif
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- int deflateToFile(FILE *fp, char *buf, int len); // len==0 to flush
-#endif
-
- manifest::comctl manifest_comctl;
- manifest::exec_level manifest_exec_level;
-
- CResourceEditor *res_editor;
- void init_res_editor();
- void close_res_editor();
-};
-
-#endif //_BUILD_H_
+/*
+ * build.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef _BUILD_H_
+#define _BUILD_H_
+
+#include "strlist.h"
+#include "lineparse.h"
+#include "lang.h"
+#include "ResourceEditor.h"
+#include "ResourceVersionInfo.h"
+#include "uservars.h"
+#include "ShConstants.h"
+#include "mmap.h"
+#include "manifest.h"
+#include "icon.h"
+
+#include "exehead/fileform.h"
+#include "exehead/config.h"
+
+#include <string>
+#include <set>
+
+#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
+// Added by Sunil Kamath 11 June 2003
+# include <time.h>
+# include <sys/stat.h>
+#endif
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+// Changed by Amir Szekely 31st July 2002
+#include "compressor.h"
+#include "czlib.h"
+#include "cbzip2.h"
+#include "clzma.h"
+
+#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
+
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+# include "Plugins.h"
+#endif //NSIS_CONFIG_PLUGIN_SUPPORT
+
+#define PS_OK 0
+#define PS_EOF 1
+#define PS_ERROR 50
+#define PS_WARNING 100
+
+// token placement
+#define TP_SEC 1
+#define TP_FUNC 2
+#define TP_CODE (TP_SEC | TP_FUNC)
+#define TP_GLOBAL 4
+#define TP_PAGEEX 8
+#define TP_PG (TP_GLOBAL | TP_PAGEEX)
+#define TP_ALL (TP_CODE | TP_PG)
+
+enum notify_e {
+ MAKENSIS_NOTIFY_SCRIPT,
+ MAKENSIS_NOTIFY_WARNING,
+ MAKENSIS_NOTIFY_ERROR,
+ MAKENSIS_NOTIFY_OUTPUT
+};
+
+#define PAGE_CUSTOM 0
+#define PAGE_LICENSE 1
+#define PAGE_COMPONENTS 2
+#define PAGE_DIRECTORY 3
+#define PAGE_INSTFILES 4
+#define PAGE_UNINSTCONFIRM 5
+#define PAGE_COMPLETED 6
+
+class CEXEBuild {
+ public:
+ CEXEBuild();
+ void initialize(const char *makensis_path);
+ ~CEXEBuild();
+
+ // to add a warning to the compiler's warning list.
+ void warning(const char *s, ...);
+ // warning with file name and line count
+ void warning_fl(const char *s, ...);
+
+ // to add a defined thing.
+ void define(const char *p, const char *v="");
+
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+ // Added by Ximon Eighteen 5th August 2002
+ void build_plugin_table(void);
+ int plugins_processed;
+#endif //NSIS_CONFIG_PLUGIN_SUPPORT
+
+
+ // process a script (you can process as many scripts as you want,
+ // it is as if they are concatenated)
+ int process_script(FILE *fp, char *curfilename);
+ int process_oneline(char *line, char *curfilename, int lineptr);
+
+ // you only get to call write_output once, so use it wisely.
+ int write_output(void);
+
+ void print_help(char *commandname=NULL);
+
+ DefineList definedlist;
+
+ int display_errors;
+ int display_script;
+ int display_warnings;
+ int display_info;
+
+ int linecnt;
+ char *curfilename;
+ FILE *fp;
+
+ HWND notify_hwnd;
+ void notify(notify_e code, const char *data) const;
+
+ private:
+ int check_write_output_errors() const;
+ int prepare_uninstaller();
+ int pack_exe_header();
+
+ int set_compressor(const std::string& compressor, const bool solid);
+ int update_exehead(const std::string& file, size_t *size=NULL);
+ void update_exehead(const unsigned char *new_exehead, size_t new_size);
+
+ // tokens.cpp
+ bool is_valid_token(char *s);
+ int get_commandtoken(char *s, int *np, int *op, int *pos);
+ int GetCurrentTokenPlace();
+ int IsTokenPlacedRight(int pos, char *tok);
+
+ // script.cpp
+#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
+ // Added by Sunil Kamath 11 June 2003
+ char* set_file_predefine(char *);
+ void restore_file_predefine(char *);
+ char* set_timestamp_predefine(char *);
+ void restore_timestamp_predefine(char *);
+ char* set_line_predefine(int, BOOL);
+ void restore_line_predefine(char *);
+ void set_date_time_predefines();
+ void del_date_time_predefines();
+#endif
+ int parseScript();
+ int includeScript(char *f);
+ int MacroExists(const char *macroname);
+#ifdef NSIS_FIX_DEFINES_IN_STRINGS
+ void ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist, bool bIgnoreDefines = false);
+#else
+ void ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist);
+#endif
+ int doParse(const char *str);
+ int doCommand(int which_token, LineParser &line);
+
+ int do_add_file(const char *lgss, int attrib, int recurse, int *total_files, const char
+ *name_override=0, int generatecode=1, int *data_handle=0,
+ const std::set<std::string>& excluded=std::set<std::string>(),
+ const std::string& basedir=std::string(""), bool dir_created=false);
+ int add_file(const std::string& dir, const std::string& file, int attrib, const char
+ *name_override, int generatecode, int *data_handle);
+ int do_add_file_create_dir(const std::string& local_dir, const std::string& dir, int attrib=0);
+
+ GrowBuf m_linebuild; // used for concatenating lines
+
+ // used by doParse to do preprocessing
+ struct ifblock
+ {
+ int hasexeced;
+ int elseused;
+ int ignore;
+ int inherited_ignore;
+ } *cur_ifblock;
+
+ TinyGrowBuf build_preprocessor_data;
+
+ void start_ifblock();
+ void end_ifblock();
+ int num_ifblock();
+
+ int last_line_had_slash;
+ bool inside_comment;
+ int multiple_entries_instruction;
+
+ void ERROR_MSG(const char *s, ...) const;
+ void SCRIPT_MSG(const char *s, ...) const;
+ void INFO_MSG(const char *s, ...) const;
+
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+ int add_plugins_dir_initializer(void);
+#endif //NSIS_CONFIG_PLUGIN_SUPPORT
+
+ // build.cpp functions used mostly by script.cpp
+ void set_code_type_predefines(const char *value = NULL);
+ int getcurdbsize();
+ int add_section(const char *secname, const char *defname, int expand=0);
+ int section_end();
+ int add_function(const char *funname);
+ int function_end();
+ void section_add_size_kb(int kb);
+ int section_add_flags(int flags);
+ int section_add_install_type(int inst_type);
+ int add_page(int type);
+ int page_end();
+ int add_label(const char *name);
+ int add_entry(const entry *ent);
+ int add_entry_direct(int which, int o0=0, int o1=0, int o2=0, int o3=0, int o4=0, int o5=0);
+ int add_db_data(IMMap *map); // returns offset
+ int add_db_data(const char *data, int length); // returns offset
+ int add_data(const char *data, int length, IGrowBuf *dblock); // returns offset
+ int add_string(const char *string, int process=1, WORD codepage=CP_ACP); // returns offset (in string table)
+ int add_intstring(const int i); // returns offset in stringblock
+
+ int preprocess_string(char *out, const char *in, WORD codepage=CP_ACP);
+
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+ // Added by Ximon Eighteen 5th August 2002
+ Plugins m_plugins;
+ bool plugin_used;
+ bool uninst_plugin_used;
+ int build_plugin_unload;
+#endif //NSIS_CONFIG_PLUGIN_SUPPORT
+
+ // build.cpp functions used mostly within build.cpp
+ int datablock_optimize(int start_offset, int first_int);
+ void printline(int l);
+ int process_jump(LineParser &line, int wt, int *offs);
+
+ int AddVersionInfo();
+ int ProcessPages();
+ void PrepareInstTypes();
+ void AddStandardStrings();
+ void PrepareHeaders(IGrowBuf *hdrbuf);
+ int SetVarsSection();
+ int SetManifest();
+
+ int resolve_jump_int(const char *fn, int *a, int offs, int start, int end);
+ int resolve_call_int(const char *fn, const char *str, int fptr, int *ofs);
+ int resolve_instruction(const char *fn, const char *str, entry *w, int offs, int start, int end);
+
+ int resolve_coderefs(const char *str);
+ void print_warnings();
+ int uninstall_generate();
+ void set_uninstall_mode(int un);
+
+ // lang.cpp functions and variables
+ void InitLangTables();
+ LanguageTable *GetLangTable(LANGID &lang, bool create = true);
+ char *GetLangNameAndCP(LANGID lang, unsigned int *codepage = NULL);
+ int DefineLangString(char *name, int process=-1);
+ int DefineInnerLangString(int id, int process=-1);
+ int SetLangString(char *name, LANGID lang, char *string);
+ int SetInnerString(int id, char *string);
+ int GenerateLangTable(LanguageTable *lt, int num_lang_tables);
+ int GenerateLangTables();
+ void FillLanguageTable(LanguageTable *table);
+ int HasUserDefined(int id) {
+ const char *us = UserInnerStrings.get(id);
+ return us && *us;
+ };
+
+ LanguageTable *LoadLangFile(char *filename);
+ void DeleteLangTable(LanguageTable *table);
+
+ NLFRef NLFRefs[NLF_STRINGS];
+ bool keep_ref;
+ StringsArray UserInnerStrings;
+ bool defcodepage_set;
+ GrowBuf lang_tables;
+ LANGID last_used_lang;
+ LangStringList build_langstrings;
+ int build_langstring_num, ubuild_langstring_num;
+ char build_font[1024];
+ int build_font_size;
+
+ unsigned int uDefCodePage;
+
+ // pages stuff
+ int license_res_id;
+ page *cur_page;
+ int cur_page_type;
+ int enable_last_page_cancel, uenable_last_page_cancel;
+
+ int disable_window_icon;
+
+ // User variables stuff
+ int GetUserVarIndex(LineParser &line, int token);
+ // Added by ramon 3 jun 2003
+ UserVarsStringList m_UserVarNames;
+ int m_iBaseVarsNum;
+ int DeclaredUserVar(const char *VarName);
+ void VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList);
+
+ ConstantsStringList m_ShellConstants;
+
+ // a whole bunch O data.
+
+ std::string stubs_dir;
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ ICompressor *compressor;
+ CZlib zlib_compressor;
+ CBzip2 bzip2_compressor;
+ CLZMA lzma_compressor;
+#endif
+ bool build_compressor_set;
+ bool build_compressor_final;
+ bool build_compress_whole;
+ int build_compress;
+ int build_compress_level;
+ int build_compress_dict_size;
+
+ bool no_space_texts;
+
+ bool has_called_write_output;
+
+ char build_packname[1024], build_packcmd[1024];
+ int build_overwrite, build_last_overwrite, build_crcchk,
+ build_datesave, build_optimize_datablock,
+ build_allowskipfiles; // Added by ramon 23 May 2003
+
+ header build_header, build_uninst, *cur_header;
+ int uninstall_mode;
+ int uninstall_size,uninstall_size_full;
+ int uninstaller_writes_used;
+
+ char build_output_filename[1024];
+
+ int build_include_depth;
+
+ // Added by ramon 6 jun 2003
+#ifdef NSIS_SUPPORT_VERSION_INFO
+ CResourceVersionInfo rVersionInfo;
+ char version_product_v[1024];
+#endif
+
+ int sectiongroup_open_cnt;
+ FastStringList m_warnings;
+ GrowBuf m_macros;
+
+ StringList m_macro_entry;
+
+ int db_opt_save, db_comp_save, db_full_size, db_opt_save_u,
+ db_comp_save_u, db_full_size_u;
+
+ FastStringList include_dirs;
+
+ StringList ns_func; // function namespace
+ StringList ns_label; // label namespace
+
+ int build_cursection_isfunc;
+ section *build_cursection;
+ TinyGrowBuf build_sections, ubuild_sections, *cur_sections;
+ GrowBuf build_entries,ubuild_entries, *cur_entries;
+ GrowBuf build_instruction_entry_map,ubuild_instruction_entry_map, *cur_instruction_entry_map;
+ TinyGrowBuf build_functions, ubuild_functions, *cur_functions;
+ TinyGrowBuf build_labels, ubuild_labels, *cur_labels;
+ StringList build_strlist, ubuild_strlist, *cur_strlist;
+ GrowBuf build_langtables, ubuild_langtables, *cur_langtables;
+ TinyGrowBuf build_pages, ubuild_pages, *cur_pages;
+ TinyGrowBuf build_ctlcolors, ubuild_ctlcolors, *cur_ctlcolors;
+
+ // don't forget to update the cache after updating the datablock
+ // see datablock_optimize for an example
+ MMapBuf build_datablock, ubuild_datablock;
+ TinyGrowBuf build_datablock_cache, ubuild_datablock_cache;
+ IGrowBuf *cur_datablock, *cur_datablock_cache;
+ struct cached_db_size
+ {
+ int first_int; // size | (compressed ? 0x80000000 : 0)
+ int start_offset;
+ };
+
+ int build_filebuflen;
+
+ TinyGrowBuf verbose_stack;
+
+ unsigned char *m_exehead;
+ size_t m_exehead_size;
+ size_t m_exehead_original_size;
+
+ bool branding_image_found;
+ WORD branding_image_id;
+
+ IconGroup installer_icon;
+ IconGroup uninstaller_icon;
+ size_t m_unicon_size;
+
+#ifdef NSIS_SUPPORT_BGBG
+ LOGFONT bg_font;
+ LOGFONT bg_default_font;
+#endif
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ int deflateToFile(FILE *fp, char *buf, int len); // len==0 to flush
+#endif
+
+ manifest::comctl manifest_comctl;
+ manifest::exec_level manifest_exec_level;
+
+ CResourceEditor *res_editor;
+ void init_res_editor();
+ void close_res_editor();
+};
+
+#endif //_BUILD_H_
diff --git a/Source/bzip2/blocksort.c b/Source/bzip2/blocksort.c
index 6c2fa34..d752a1a 100755
--- a/Source/bzip2/blocksort.c
+++ b/Source/bzip2/blocksort.c
@@ -1,1109 +1,1109 @@
-/*
- * This file is a part of the bzip2 compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.bzip.org/
- *
- * This modification is not compatible with the original bzip2.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "bzlib.h"
-
-/*-------------------------------------------------------------*/
-/*--- Block sorting machinery ---*/
-/*--- blocksort.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@acm.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
-
- To get some idea how the block sorting algorithms in this file
- work, read my paper
- On the Performance of BWT Sorting Algorithms
- in Proceedings of the IEEE Data Compression Conference 2000,
- Snowbird, Utah, USA, 27-30 March 2000. The main sort in this
- file implements the algorithm called cache in the paper.
---*/
-
-/*---------------------------------------------*/
-/*--- Fallback O(N log(N)^2) sorting ---*/
-/*--- algorithm, for repetitive blocks ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static void fallbackSimpleSort ( UInt32* fmap,
- UInt32* eclass,
- Int32 lo,
- Int32 hi )
-{
- Int32 i, j, tmp;
- UInt32 ec_tmp;
-
- if (lo == hi) return;
-
- if (hi - lo > 3) {
- for ( i = hi-4; i >= lo; i-- ) {
- tmp = fmap[i];
- ec_tmp = eclass[tmp];
- for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
- fmap[j-4] = fmap[j];
- fmap[j-4] = tmp;
- }
- }
-
- for ( i = hi-1; i >= lo; i-- ) {
- tmp = fmap[i];
- ec_tmp = eclass[tmp];
- for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
- fmap[j-1] = fmap[j];
- fmap[j-1] = tmp;
- }
-}
-
-
-/*---------------------------------------------*/
-#define fswap(zz1, zz2) \
- { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define fvswap(zzp1, zzp2, zzn) \
-{ \
- Int32 yyp1 = (zzp1); \
- Int32 yyp2 = (zzp2); \
- Int32 yyn = (zzn); \
- while (yyn > 0) { \
- fswap(fmap[yyp1], fmap[yyp2]); \
- yyp1++; yyp2++; yyn--; \
- } \
-}
-
-
-#define fmin(a,b) ((a) < (b)) ? (a) : (b)
-
-#define fpush(lz,hz) { stackLo[sp] = lz; \
- stackHi[sp] = hz; \
- sp++; }
-
-#define fpop(lz,hz) { sp--; \
- lz = stackLo[sp]; \
- hz = stackHi[sp]; }
-
-#define FALLBACK_QSORT_SMALL_THRESH 10
-#define FALLBACK_QSORT_STACK_SIZE 100
-
-
-static
-void fallbackQSort3 ( UInt32* fmap,
- UInt32* eclass,
- Int32 loSt,
- Int32 hiSt )
-{
- Int32 unLo, unHi, ltLo, gtHi, n, m;
- Int32 sp, lo, hi;
- UInt32 med, r, r3;
- Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
- Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
-
- r = 0;
-
- sp = 0;
- fpush ( loSt, hiSt );
-
- while (sp > 0) {
-
- AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
-
- fpop ( lo, hi );
- if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
- fallbackSimpleSort ( fmap, eclass, lo, hi );
- continue;
- }
-
- /* Random partitioning. Median of 3 sometimes fails to
- avoid bad cases. Median of 9 seems to help but
- looks rather expensive. This too seems to work but
- is cheaper. Guidance for the magic constants
- 7621 and 32768 is taken from Sedgewick's algorithms
- book, chapter 35.
- */
- r = ((r * 7621) + 1) % 32768;
- r3 = r % 3;
- if (r3 == 0) med = eclass[fmap[lo]]; else
- if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
- med = eclass[fmap[hi]];
-
- unLo = ltLo = lo;
- unHi = gtHi = hi;
-
- while (1) {
- while (1) {
- if (unLo > unHi) break;
- n = (Int32)eclass[fmap[unLo]] - (Int32)med;
- if (n == 0) {
- fswap(fmap[unLo], fmap[ltLo]);
- ltLo++; unLo++;
- continue;
- };
- if (n > 0) break;
- unLo++;
- }
- while (1) {
- if (unLo > unHi) break;
- n = (Int32)eclass[fmap[unHi]] - (Int32)med;
- if (n == 0) {
- fswap(fmap[unHi], fmap[gtHi]);
- gtHi--; unHi--;
- continue;
- };
- if (n < 0) break;
- unHi--;
- }
- if (unLo > unHi) break;
- fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
- }
-
- AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
-
- if (gtHi < ltLo) continue;
-
- n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
- m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
-
- n = lo + unLo - ltLo - 1;
- m = hi - (gtHi - unHi) + 1;
-
- if (n - lo > hi - m) {
- fpush ( lo, n );
- fpush ( m, hi );
- } else {
- fpush ( m, hi );
- fpush ( lo, n );
- }
- }
-}
-
-#undef fmin
-#undef fpush
-#undef fpop
-#undef fswap
-#undef fvswap
-#undef FALLBACK_QSORT_SMALL_THRESH
-#undef FALLBACK_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
- nblock > 0
- eclass exists for [0 .. nblock-1]
- ((UChar*)eclass) [0 .. nblock-1] holds block
- ptr exists for [0 .. nblock-1]
-
- Post:
- ((UChar*)eclass) [0 .. nblock-1] holds block
- All other areas of eclass destroyed
- fmap [0 .. nblock-1] holds sorted order
- bhtab [ 0 .. 2+(nblock/32) ] destroyed
-*/
-
-#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
-#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
-#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
-#define WORD_BH(zz) bhtab[(zz) >> 5]
-#define UNALIGNED_BH(zz) ((zz) & 0x01f)
-
-static
-void fallbackSort ( UInt32* fmap,
- UInt32* eclass,
- UInt32* bhtab,
- Int32 nblock)
-{
- Int32 ftab[257];
- Int32 ftabCopy[256];
- Int32 H, i, j, k, l, r, cc, cc1;
- Int32 nNotDone;
- Int32 nBhtab;
- UChar* eclass8 = (UChar*)eclass;
-
- /*--
- Initial 1-char radix sort to generate
- initial fmap and initial BH bits.
- --*/
- for (i = 0; i < 257; i++) ftab[i] = 0;
- for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
- for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
- for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
-
- for (i = 0; i < nblock; i++) {
- j = eclass8[i];
- k = ftab[j] - 1;
- ftab[j] = k;
- fmap[k] = i;
- }
-
- nBhtab = 2 + (nblock / 32);
- for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
- for (i = 0; i < 256; i++) SET_BH(ftab[i]);
-
- /*--
- Inductively refine the buckets. Kind-of an
- "exponential radix sort" (!), inspired by the
- Manber-Myers suffix array construction algorithm.
- --*/
-
- /*-- set sentinel bits for block-end detection --*/
- for (i = 0; i < 32; i++) {
- SET_BH(nblock + 2*i);
- CLEAR_BH(nblock + 2*i + 1);
- }
-
- /*-- the log(N) loop --*/
- H = 1;
- while (1) {
-
- j = 0;
- for (i = 0; i < nblock; i++) {
- if (ISSET_BH(i)) j = i;
- k = fmap[i] - H; if (k < 0) k += nblock;
- eclass[k] = j;
- }
-
- nNotDone = 0;
- r = -1;
- while (1) {
-
- /*-- find the next non-singleton bucket --*/
- k = r + 1;
- while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
- if (ISSET_BH(k)) {
- while (WORD_BH(k) == 0xffffffff) k += 32;
- while (ISSET_BH(k)) k++;
- }
- l = k - 1;
- if (l >= nblock) break;
- while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
- if (!ISSET_BH(k)) {
- while (WORD_BH(k) == 0x00000000) k += 32;
- while (!ISSET_BH(k)) k++;
- }
- r = k - 1;
- if (r >= nblock) break;
-
- /*-- now [l, r] bracket current bucket --*/
- if (r > l) {
- nNotDone += (r - l + 1);
- fallbackQSort3 ( fmap, eclass, l, r );
-
- /*-- scan bucket and generate header bits-- */
- cc = -1;
- for (i = l; i <= r; i++) {
- cc1 = eclass[fmap[i]];
- if (cc != cc1) { SET_BH(i); cc = cc1; };
- }
- }
- }
-
- H *= 2;
- if (H > nblock || nNotDone == 0) break;
- }
-
- /*--
- Reconstruct the original block in
- eclass8 [0 .. nblock-1], since the
- previous phase destroyed it.
- --*/
- j = 0;
- for (i = 0; i < nblock; i++) {
- while (ftabCopy[j] == 0) j++;
- ftabCopy[j]--;
- eclass8[fmap[i]] = (UChar)j;
- }
- AssertH ( j < 256, 1005 );
-}
-
-#undef SET_BH
-#undef CLEAR_BH
-#undef ISSET_BH
-#undef WORD_BH
-#undef UNALIGNED_BH
-
-
-/*---------------------------------------------*/
-/*--- The main, O(N^2 log(N)) sorting ---*/
-/*--- algorithm. Faster for "normal" ---*/
-/*--- non-repetitive blocks. ---*/
-/*---------------------------------------------*/
-
-/*---------------------------------------------*/
-static Bool mainGtU ( UInt32 i1,
- UInt32 i2,
- UChar* block,
- UInt16* quadrant,
- UInt32 nblock,
- Int32* budget )
-{
- Int32 k;
- UChar c1, c2;
- UInt16 s1, s2;
-
- AssertD ( i1 != i2, "mainGtU" );
- /* 1 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 2 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 3 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 4 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 5 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 6 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 7 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 8 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 9 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 10 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 11 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
- /* 12 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- i1++; i2++;
-
- k = nblock + 8;
-
- do {
- /* 1 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 2 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 3 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 4 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 5 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 6 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 7 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
- /* 8 */
- c1 = block[i1]; c2 = block[i2];
- if (c1 != c2) return (c1 > c2);
- s1 = quadrant[i1]; s2 = quadrant[i2];
- if (s1 != s2) return (s1 > s2);
- i1++; i2++;
-
- if (i1 >= nblock) i1 -= nblock;
- if (i2 >= nblock) i2 -= nblock;
-
- k -= 8;
- (*budget)--;
- }
- while (k >= 0);
-
- return False;
-}
-
-
-/*---------------------------------------------*/
-/*--
- Knuth's increments seem to work better
- than Incerpi-Sedgewick here. Possibly
- because the number of elems to sort is
- usually small, typically <= 20.
---*/
-static
-Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
- 9841, 29524, 88573, 265720,
- 797161, 2391484 };
-
-static
-void mainSimpleSort ( UInt32* ptr,
- UChar* block,
- UInt16* quadrant,
- Int32 nblock,
- Int32 lo,
- Int32 hi,
- Int32 d,
- Int32* budget )
-{
- Int32 i, j, h, bigN, hp;
- UInt32 v;
-
- bigN = hi - lo + 1;
- if (bigN < 2) return;
-
- hp = 0;
- while (incs[hp] < bigN) hp++;
- hp--;
-
- for (; hp >= 0; hp--) {
- h = incs[hp];
-
- i = lo + h;
- while (True) {
-
- /*-- copy 1 --*/
- if (i > hi) break;
- v = ptr[i];
- j = i;
- while ( mainGtU (
- ptr[j-h]+d, v+d, block, quadrant, nblock, budget
- ) ) {
- ptr[j] = ptr[j-h];
- j = j - h;
- if (j <= (lo + h - 1)) break;
- }
- ptr[j] = v;
- i++;
-
- /*-- copy 2 --*/
- if (i > hi) break;
- v = ptr[i];
- j = i;
- while ( mainGtU (
- ptr[j-h]+d, v+d, block, quadrant, nblock, budget
- ) ) {
- ptr[j] = ptr[j-h];
- j = j - h;
- if (j <= (lo + h - 1)) break;
- }
- ptr[j] = v;
- i++;
-
- /*-- copy 3 --*/
- if (i > hi) break;
- v = ptr[i];
- j = i;
- while ( mainGtU (
- ptr[j-h]+d, v+d, block, quadrant, nblock, budget
- ) ) {
- ptr[j] = ptr[j-h];
- j = j - h;
- if (j <= (lo + h - 1)) break;
- }
- ptr[j] = v;
- i++;
-
- if (*budget < 0) return;
- }
- }
-}
-
-
-/*---------------------------------------------*/
-/*--
- The following is an implementation of
- an elegant 3-way quicksort for strings,
- described in a paper "Fast Algorithms for
- Sorting and Searching Strings", by Robert
- Sedgewick and Jon L. Bentley.
---*/
-
-#define mswap(zz1, zz2) \
- { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
-
-#define mvswap(zzp1, zzp2, zzn) \
-{ \
- Int32 yyp1 = (zzp1); \
- Int32 yyp2 = (zzp2); \
- Int32 yyn = (zzn); \
- while (yyn > 0) { \
- mswap(ptr[yyp1], ptr[yyp2]); \
- yyp1++; yyp2++; yyn--; \
- } \
-}
-
-static
-UChar mmed3 ( UChar a, UChar b, UChar c )
-{
- UChar t;
- if (a > b) { t = a; a = b; b = t; };
- if (b > c) {
- b = c;
- if (a > b) b = a;
- }
- return b;
-}
-
-#define mmin(a,b) ((a) < (b)) ? (a) : (b)
-
-#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
- stackHi[sp] = hz; \
- stackD [sp] = dz; \
- sp++; }
-
-#define mpop(lz,hz,dz) { sp--; \
- lz = stackLo[sp]; \
- hz = stackHi[sp]; \
- dz = stackD [sp]; }
-
-
-#define mnextsize(az) (nextHi[az]-nextLo[az])
-
-#define mnextswap(az,bz) \
- { Int32 tz; \
- tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
- tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
- tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
-
-
-#define MAIN_QSORT_SMALL_THRESH 20
-#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
-#define MAIN_QSORT_STACK_SIZE 100
-
-static
-void mainQSort3 ( UInt32* ptr,
- UChar* block,
- UInt16* quadrant,
- Int32 nblock,
- Int32 loSt,
- Int32 hiSt,
- Int32 dSt,
- Int32* budget )
-{
- Int32 unLo, unHi, ltLo, gtHi, n, m, med;
- Int32 sp, lo, hi, d;
-
- Int32 stackLo[MAIN_QSORT_STACK_SIZE];
- Int32 stackHi[MAIN_QSORT_STACK_SIZE];
- Int32 stackD [MAIN_QSORT_STACK_SIZE];
-
- Int32 nextLo[3];
- Int32 nextHi[3];
- Int32 nextD [3];
-
- sp = 0;
- mpush ( loSt, hiSt, dSt );
-
- while (sp > 0) {
-
- AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
-
- mpop ( lo, hi, d );
- if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
- d > MAIN_QSORT_DEPTH_THRESH) {
- mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
- if (*budget < 0) return;
- continue;
- }
-
- med = (Int32)
- mmed3 ( block[ptr[ lo ]+d],
- block[ptr[ hi ]+d],
- block[ptr[ (lo+hi)>>1 ]+d] );
-
- unLo = ltLo = lo;
- unHi = gtHi = hi;
-
- while (True) {
- while (True) {
- if (unLo > unHi) break;
- n = ((Int32)block[ptr[unLo]+d]) - med;
- if (n == 0) {
- mswap(ptr[unLo], ptr[ltLo]);
- ltLo++; unLo++; continue;
- };
- if (n > 0) break;
- unLo++;
- }
- while (True) {
- if (unLo > unHi) break;
- n = ((Int32)block[ptr[unHi]+d]) - med;
- if (n == 0) {
- mswap(ptr[unHi], ptr[gtHi]);
- gtHi--; unHi--; continue;
- };
- if (n < 0) break;
- unHi--;
- }
- if (unLo > unHi) break;
- mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
- }
-
- AssertD ( unHi == unLo-1, "mainQSort3(2)" );
-
- if (gtHi < ltLo) {
- mpush(lo, hi, d+1 );
- continue;
- }
-
- n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
- m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
-
- n = lo + unLo - ltLo - 1;
- m = hi - (gtHi - unHi) + 1;
-
- nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
- nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
- nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
-
- if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
- if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
- if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
-
- AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
- AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
-
- mpush (nextLo[0], nextHi[0], nextD[0]);
- mpush (nextLo[1], nextHi[1], nextD[1]);
- mpush (nextLo[2], nextHi[2], nextD[2]);
- }
-}
-
-#undef mswap
-#undef mvswap
-#undef mpush
-#undef mpop
-#undef mmin
-#undef mnextsize
-#undef mnextswap
-#undef MAIN_QSORT_SMALL_THRESH
-#undef MAIN_QSORT_DEPTH_THRESH
-#undef MAIN_QSORT_STACK_SIZE
-
-
-/*---------------------------------------------*/
-/* Pre:
- nblock > N_OVERSHOOT
- block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
- ((UChar*)block32) [0 .. nblock-1] holds block
- ptr exists for [0 .. nblock-1]
-
- Post:
- ((UChar*)block32) [0 .. nblock-1] holds block
- All other areas of block32 destroyed
- ftab [0 .. 65536 ] destroyed
- ptr [0 .. nblock-1] holds sorted order
- if (*budget < 0), sorting was abandoned
-*/
-
-#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
-#define SETMASK (1 << 21)
-#define CLEARMASK (~(SETMASK))
-
-static
-void mainSort ( UInt32* ptr,
- UChar* block,
- UInt16* quadrant,
- UInt32* ftab,
- Int32 nblock,
- Int32* budget )
-{
- Int32 i, j, k, ss, sb;
- Int32 runningOrder[256];
- Bool bigDone[256];
- Int32 copyStart[256];
- Int32 copyEnd [256];
- UChar c1;
- Int32 numQSorted;
- UInt16 s;
-
- /*-- set up the 2-byte frequency table --*/
- for (i = 65536; i >= 0; i--) ftab[i] = 0;
-
- j = block[0] << 8;
- i = nblock-1;
- for (; i >= 3; i -= 4) {
- quadrant[i] = 0;
- j = (j >> 8) | ( ((UInt16)block[i]) << 8);
- ftab[j]++;
- quadrant[i-1] = 0;
- j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
- ftab[j]++;
- quadrant[i-2] = 0;
- j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
- ftab[j]++;
- quadrant[i-3] = 0;
- j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
- ftab[j]++;
- }
- for (; i >= 0; i--) {
- quadrant[i] = 0;
- j = (j >> 8) | ( ((UInt16)block[i]) << 8);
- ftab[j]++;
- }
-
- /*-- (emphasises close relationship of block & quadrant) --*/
- for (i = 0; i < BZ_N_OVERSHOOT; i++) {
- block [nblock+i] = block[i];
- quadrant[nblock+i] = 0;
- }
-
- /*-- Complete the initial radix sort --*/
- for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
-
- s = block[0] << 8;
- i = nblock-1;
- for (; i >= 3; i -= 4) {
- s = (s >> 8) | (block[i] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i;
- s = (s >> 8) | (block[i-1] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i-1;
- s = (s >> 8) | (block[i-2] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i-2;
- s = (s >> 8) | (block[i-3] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i-3;
- }
- for (; i >= 0; i--) {
- s = (s >> 8) | (block[i] << 8);
- j = ftab[s] -1;
- ftab[s] = j;
- ptr[j] = i;
- }
-
- /*--
- Now ftab contains the first loc of every small bucket.
- Calculate the running order, from smallest to largest
- big bucket.
- --*/
- for (i = 0; i <= 255; i++) {
- bigDone [i] = False;
- runningOrder[i] = i;
- }
-
- {
- Int32 vv;
- Int32 h = 1;
- do h = 3 * h + 1; while (h <= 256);
- do {
- h = h / 3;
- for (i = h; i <= 255; i++) {
- vv = runningOrder[i];
- j = i;
- while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
- runningOrder[j] = runningOrder[j-h];
- j = j - h;
- if (j <= (h - 1)) goto zero;
- }
- zero:
- runningOrder[j] = vv;
- }
- } while (h != 1);
- }
-
- /*--
- The main sorting loop.
- --*/
-
- numQSorted = 0;
-
- for (i = 0; i <= 255; i++) {
-
- /*--
- Process big buckets, starting with the least full.
- Basically this is a 3-step process in which we call
- mainQSort3 to sort the small buckets [ss, j], but
- also make a big effort to avoid the calls if we can.
- --*/
- ss = runningOrder[i];
-
- /*--
- Step 1:
- Complete the big bucket [ss] by quicksorting
- any unsorted small buckets [ss, j], for j != ss.
- Hopefully previous pointer-scanning phases have already
- completed many of the small buckets [ss, j], so
- we don't have to sort them at all.
- --*/
- for (j = 0; j <= 255; j++) {
- if (j != ss) {
- sb = (ss << 8) + j;
- if ( ! (ftab[sb] & SETMASK) ) {
- Int32 lo = ftab[sb] & CLEARMASK;
- Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
- if (hi > lo) {
- mainQSort3 (
- ptr, block, quadrant, nblock,
- lo, hi, BZ_N_RADIX, budget
- );
- numQSorted += (hi - lo + 1);
- if (*budget < 0) return;
- }
- }
- ftab[sb] |= SETMASK;
- }
- }
-
- AssertH ( !bigDone[ss], 1006 );
-
- /*--
- Step 2:
- Now scan this big bucket [ss] so as to synthesise the
- sorted order for small buckets [t, ss] for all t,
- including, magically, the bucket [ss,ss] too.
- This will avoid doing Real Work in subsequent Step 1's.
- --*/
- {
- for (j = 0; j <= 255; j++) {
- copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
- copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
- }
- for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
- k = ptr[j]-1; if (k < 0) k += nblock;
- c1 = block[k];
- if (!bigDone[c1])
- ptr[ copyStart[c1]++ ] = k;
- }
- for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
- k = ptr[j]-1; if (k < 0) k += nblock;
- c1 = block[k];
- if (!bigDone[c1])
- ptr[ copyEnd[c1]-- ] = k;
- }
- }
-
- AssertH ( copyStart[ss]-1 == copyEnd[ss], 1007 );
-
- for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
-
- /*--
- Step 3:
- The [ss] big bucket is now done. Record this fact,
- and update the quadrant descriptors. Remember to
- update quadrants in the overshoot area too, if
- necessary. The "if (i < 255)" test merely skips
- this updating for the last bucket processed, since
- updating for the last bucket is pointless.
-
- The quadrant array provides a way to incrementally
- cache sort orderings, as they appear, so as to
- make subsequent comparisons in fullGtU() complete
- faster. For repetitive blocks this makes a big
- difference (but not big enough to be able to avoid
- the fallback sorting mechanism, exponential radix sort).
-
- The precise meaning is: at all times:
-
- for 0 <= i < nblock and 0 <= j <= nblock
-
- if block[i] != block[j],
-
- then the relative values of quadrant[i] and
- quadrant[j] are meaningless.
-
- else {
- if quadrant[i] < quadrant[j]
- then the string starting at i lexicographically
- precedes the string starting at j
-
- else if quadrant[i] > quadrant[j]
- then the string starting at j lexicographically
- precedes the string starting at i
-
- else
- the relative ordering of the strings starting
- at i and j has not yet been determined.
- }
- --*/
- bigDone[ss] = True;
-
- if (i < 255) {
- Int32 bbStart = ftab[ss << 8] & CLEARMASK;
- Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
- Int32 shifts = 0;
-
- while ((bbSize >> shifts) > 65534) shifts++;
-
- for (j = bbSize-1; j >= 0; j--) {
- Int32 a2update = ptr[bbStart + j];
- UInt16 qVal = (UInt16)(j >> shifts);
- quadrant[a2update] = qVal;
- if (a2update < BZ_N_OVERSHOOT)
- quadrant[a2update + nblock] = qVal;
- }
- AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
- }
-
- }
-}
-
-#undef BIGFREQ
-#undef SETMASK
-#undef CLEARMASK
-
-
-/*---------------------------------------------*/
-/* Pre:
- nblock > 0
- arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
- ((UChar*)arr2) [0 .. nblock-1] holds block
- arr1 exists for [0 .. nblock-1]
-
- Post:
- ((UChar*)arr2) [0 .. nblock-1] holds block
- All other areas of block destroyed
- ftab [ 0 .. 65536 ] destroyed
- arr1 [0 .. nblock-1] holds sorted order
-*/
-void BZ2_blockSort ( EState* s )
-{
- UInt32* ptr = s->ptr;
- UChar* block = s->block;
- UInt32* ftab = s->ftab;
- Int32 nblock = s->nblock;
- Int32 wfact = s->workFactor;
- UInt16* quadrant;
- Int32 budget;
- Int32 budgetInit;
- Int32 i;
-
- if (nblock < 10000) {
- fallbackSort ( s->arr1, s->arr2, ftab, nblock );
- } else {
- /* Calculate the location for quadrant, remembering to get
- the alignment right. Assumes that &(block[0]) is at least
- 2-byte aligned -- this should be ok since block is really
- the first section of arr2.
- */
- i = nblock+BZ_N_OVERSHOOT;
- if (i & 1) i++;
- quadrant = (UInt16*)(&(block[i]));
-
- /* (wfact-1) / 3 puts the default-factor-30
- transition point at very roughly the same place as
- with v0.1 and v0.9.0.
- Not that it particularly matters any more, since the
- resulting compressed stream is now the same regardless
- of whether or not we use the main sort or fallback sort.
- */
- if (wfact < 1 ) wfact = 1;
- if (wfact > 100) wfact = 100;
- budgetInit = nblock * ((wfact-1) / 3);
- budget = budgetInit;
-
- mainSort ( ptr, block, quadrant, ftab, nblock, &budget );
- if (budget < 0) {
- fallbackSort ( s->arr1, s->arr2, ftab, nblock );
- }
- }
-
- s->origPtr = -1;
- for (i = 0; i < s->nblock; i++)
- if (ptr[i] == 0)
- { s->origPtr = i; break; };
-
- AssertH( s->origPtr != -1, 1003 );
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end blocksort.c ---*/
-/*-------------------------------------------------------------*/
+/*
+ * This file is a part of the bzip2 compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.bzip.org/
+ *
+ * This modification is not compatible with the original bzip2.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "bzlib.h"
+
+/*-------------------------------------------------------------*/
+/*--- Block sorting machinery ---*/
+/*--- blocksort.c ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+ This file is a part of bzip2 and/or libbzip2, a program and
+ library for lossless, block-sorting data compression.
+
+ Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+ 3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+ 4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Julian Seward, Cambridge, UK.
+ jseward@acm.org
+ bzip2/libbzip2 version 1.0 of 21 March 2000
+
+ This program is based on (at least) the work of:
+ Mike Burrows
+ David Wheeler
+ Peter Fenwick
+ Alistair Moffat
+ Radford Neal
+ Ian H. Witten
+ Robert Sedgewick
+ Jon L. Bentley
+
+ For more information on these sources, see the manual.
+
+ To get some idea how the block sorting algorithms in this file
+ work, read my paper
+ On the Performance of BWT Sorting Algorithms
+ in Proceedings of the IEEE Data Compression Conference 2000,
+ Snowbird, Utah, USA, 27-30 March 2000. The main sort in this
+ file implements the algorithm called cache in the paper.
+--*/
+
+/*---------------------------------------------*/
+/*--- Fallback O(N log(N)^2) sorting ---*/
+/*--- algorithm, for repetitive blocks ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static void fallbackSimpleSort ( UInt32* fmap,
+ UInt32* eclass,
+ Int32 lo,
+ Int32 hi )
+{
+ Int32 i, j, tmp;
+ UInt32 ec_tmp;
+
+ if (lo == hi) return;
+
+ if (hi - lo > 3) {
+ for ( i = hi-4; i >= lo; i-- ) {
+ tmp = fmap[i];
+ ec_tmp = eclass[tmp];
+ for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 )
+ fmap[j-4] = fmap[j];
+ fmap[j-4] = tmp;
+ }
+ }
+
+ for ( i = hi-1; i >= lo; i-- ) {
+ tmp = fmap[i];
+ ec_tmp = eclass[tmp];
+ for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ )
+ fmap[j-1] = fmap[j];
+ fmap[j-1] = tmp;
+ }
+}
+
+
+/*---------------------------------------------*/
+#define fswap(zz1, zz2) \
+ { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define fvswap(zzp1, zzp2, zzn) \
+{ \
+ Int32 yyp1 = (zzp1); \
+ Int32 yyp2 = (zzp2); \
+ Int32 yyn = (zzn); \
+ while (yyn > 0) { \
+ fswap(fmap[yyp1], fmap[yyp2]); \
+ yyp1++; yyp2++; yyn--; \
+ } \
+}
+
+
+#define fmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define fpush(lz,hz) { stackLo[sp] = lz; \
+ stackHi[sp] = hz; \
+ sp++; }
+
+#define fpop(lz,hz) { sp--; \
+ lz = stackLo[sp]; \
+ hz = stackHi[sp]; }
+
+#define FALLBACK_QSORT_SMALL_THRESH 10
+#define FALLBACK_QSORT_STACK_SIZE 100
+
+
+static
+void fallbackQSort3 ( UInt32* fmap,
+ UInt32* eclass,
+ Int32 loSt,
+ Int32 hiSt )
+{
+ Int32 unLo, unHi, ltLo, gtHi, n, m;
+ Int32 sp, lo, hi;
+ UInt32 med, r, r3;
+ Int32 stackLo[FALLBACK_QSORT_STACK_SIZE];
+ Int32 stackHi[FALLBACK_QSORT_STACK_SIZE];
+
+ r = 0;
+
+ sp = 0;
+ fpush ( loSt, hiSt );
+
+ while (sp > 0) {
+
+ AssertH ( sp < FALLBACK_QSORT_STACK_SIZE, 1004 );
+
+ fpop ( lo, hi );
+ if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
+ fallbackSimpleSort ( fmap, eclass, lo, hi );
+ continue;
+ }
+
+ /* Random partitioning. Median of 3 sometimes fails to
+ avoid bad cases. Median of 9 seems to help but
+ looks rather expensive. This too seems to work but
+ is cheaper. Guidance for the magic constants
+ 7621 and 32768 is taken from Sedgewick's algorithms
+ book, chapter 35.
+ */
+ r = ((r * 7621) + 1) % 32768;
+ r3 = r % 3;
+ if (r3 == 0) med = eclass[fmap[lo]]; else
+ if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else
+ med = eclass[fmap[hi]];
+
+ unLo = ltLo = lo;
+ unHi = gtHi = hi;
+
+ while (1) {
+ while (1) {
+ if (unLo > unHi) break;
+ n = (Int32)eclass[fmap[unLo]] - (Int32)med;
+ if (n == 0) {
+ fswap(fmap[unLo], fmap[ltLo]);
+ ltLo++; unLo++;
+ continue;
+ };
+ if (n > 0) break;
+ unLo++;
+ }
+ while (1) {
+ if (unLo > unHi) break;
+ n = (Int32)eclass[fmap[unHi]] - (Int32)med;
+ if (n == 0) {
+ fswap(fmap[unHi], fmap[gtHi]);
+ gtHi--; unHi--;
+ continue;
+ };
+ if (n < 0) break;
+ unHi--;
+ }
+ if (unLo > unHi) break;
+ fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
+ }
+
+ AssertD ( unHi == unLo-1, "fallbackQSort3(2)" );
+
+ if (gtHi < ltLo) continue;
+
+ n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n);
+ m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m);
+
+ n = lo + unLo - ltLo - 1;
+ m = hi - (gtHi - unHi) + 1;
+
+ if (n - lo > hi - m) {
+ fpush ( lo, n );
+ fpush ( m, hi );
+ } else {
+ fpush ( m, hi );
+ fpush ( lo, n );
+ }
+ }
+}
+
+#undef fmin
+#undef fpush
+#undef fpop
+#undef fswap
+#undef fvswap
+#undef FALLBACK_QSORT_SMALL_THRESH
+#undef FALLBACK_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+ nblock > 0
+ eclass exists for [0 .. nblock-1]
+ ((UChar*)eclass) [0 .. nblock-1] holds block
+ ptr exists for [0 .. nblock-1]
+
+ Post:
+ ((UChar*)eclass) [0 .. nblock-1] holds block
+ All other areas of eclass destroyed
+ fmap [0 .. nblock-1] holds sorted order
+ bhtab [ 0 .. 2+(nblock/32) ] destroyed
+*/
+
+#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
+#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
+#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
+#define WORD_BH(zz) bhtab[(zz) >> 5]
+#define UNALIGNED_BH(zz) ((zz) & 0x01f)
+
+static
+void fallbackSort ( UInt32* fmap,
+ UInt32* eclass,
+ UInt32* bhtab,
+ Int32 nblock)
+{
+ Int32 ftab[257];
+ Int32 ftabCopy[256];
+ Int32 H, i, j, k, l, r, cc, cc1;
+ Int32 nNotDone;
+ Int32 nBhtab;
+ UChar* eclass8 = (UChar*)eclass;
+
+ /*--
+ Initial 1-char radix sort to generate
+ initial fmap and initial BH bits.
+ --*/
+ for (i = 0; i < 257; i++) ftab[i] = 0;
+ for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
+ for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i];
+ for (i = 1; i < 257; i++) ftab[i] += ftab[i-1];
+
+ for (i = 0; i < nblock; i++) {
+ j = eclass8[i];
+ k = ftab[j] - 1;
+ ftab[j] = k;
+ fmap[k] = i;
+ }
+
+ nBhtab = 2 + (nblock / 32);
+ for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
+ for (i = 0; i < 256; i++) SET_BH(ftab[i]);
+
+ /*--
+ Inductively refine the buckets. Kind-of an
+ "exponential radix sort" (!), inspired by the
+ Manber-Myers suffix array construction algorithm.
+ --*/
+
+ /*-- set sentinel bits for block-end detection --*/
+ for (i = 0; i < 32; i++) {
+ SET_BH(nblock + 2*i);
+ CLEAR_BH(nblock + 2*i + 1);
+ }
+
+ /*-- the log(N) loop --*/
+ H = 1;
+ while (1) {
+
+ j = 0;
+ for (i = 0; i < nblock; i++) {
+ if (ISSET_BH(i)) j = i;
+ k = fmap[i] - H; if (k < 0) k += nblock;
+ eclass[k] = j;
+ }
+
+ nNotDone = 0;
+ r = -1;
+ while (1) {
+
+ /*-- find the next non-singleton bucket --*/
+ k = r + 1;
+ while (ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+ if (ISSET_BH(k)) {
+ while (WORD_BH(k) == 0xffffffff) k += 32;
+ while (ISSET_BH(k)) k++;
+ }
+ l = k - 1;
+ if (l >= nblock) break;
+ while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++;
+ if (!ISSET_BH(k)) {
+ while (WORD_BH(k) == 0x00000000) k += 32;
+ while (!ISSET_BH(k)) k++;
+ }
+ r = k - 1;
+ if (r >= nblock) break;
+
+ /*-- now [l, r] bracket current bucket --*/
+ if (r > l) {
+ nNotDone += (r - l + 1);
+ fallbackQSort3 ( fmap, eclass, l, r );
+
+ /*-- scan bucket and generate header bits-- */
+ cc = -1;
+ for (i = l; i <= r; i++) {
+ cc1 = eclass[fmap[i]];
+ if (cc != cc1) { SET_BH(i); cc = cc1; };
+ }
+ }
+ }
+
+ H *= 2;
+ if (H > nblock || nNotDone == 0) break;
+ }
+
+ /*--
+ Reconstruct the original block in
+ eclass8 [0 .. nblock-1], since the
+ previous phase destroyed it.
+ --*/
+ j = 0;
+ for (i = 0; i < nblock; i++) {
+ while (ftabCopy[j] == 0) j++;
+ ftabCopy[j]--;
+ eclass8[fmap[i]] = (UChar)j;
+ }
+ AssertH ( j < 256, 1005 );
+}
+
+#undef SET_BH
+#undef CLEAR_BH
+#undef ISSET_BH
+#undef WORD_BH
+#undef UNALIGNED_BH
+
+
+/*---------------------------------------------*/
+/*--- The main, O(N^2 log(N)) sorting ---*/
+/*--- algorithm. Faster for "normal" ---*/
+/*--- non-repetitive blocks. ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static Bool mainGtU ( UInt32 i1,
+ UInt32 i2,
+ UChar* block,
+ UInt16* quadrant,
+ UInt32 nblock,
+ Int32* budget )
+{
+ Int32 k;
+ UChar c1, c2;
+ UInt16 s1, s2;
+
+ AssertD ( i1 != i2, "mainGtU" );
+ /* 1 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 2 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 3 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 4 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 5 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 6 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 7 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 8 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 9 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 10 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 11 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+ /* 12 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ i1++; i2++;
+
+ k = nblock + 8;
+
+ do {
+ /* 1 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 2 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 3 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 4 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 5 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 6 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 7 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+ /* 8 */
+ c1 = block[i1]; c2 = block[i2];
+ if (c1 != c2) return (c1 > c2);
+ s1 = quadrant[i1]; s2 = quadrant[i2];
+ if (s1 != s2) return (s1 > s2);
+ i1++; i2++;
+
+ if (i1 >= nblock) i1 -= nblock;
+ if (i2 >= nblock) i2 -= nblock;
+
+ k -= 8;
+ (*budget)--;
+ }
+ while (k >= 0);
+
+ return False;
+}
+
+
+/*---------------------------------------------*/
+/*--
+ Knuth's increments seem to work better
+ than Incerpi-Sedgewick here. Possibly
+ because the number of elems to sort is
+ usually small, typically <= 20.
+--*/
+static
+Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
+ 9841, 29524, 88573, 265720,
+ 797161, 2391484 };
+
+static
+void mainSimpleSort ( UInt32* ptr,
+ UChar* block,
+ UInt16* quadrant,
+ Int32 nblock,
+ Int32 lo,
+ Int32 hi,
+ Int32 d,
+ Int32* budget )
+{
+ Int32 i, j, h, bigN, hp;
+ UInt32 v;
+
+ bigN = hi - lo + 1;
+ if (bigN < 2) return;
+
+ hp = 0;
+ while (incs[hp] < bigN) hp++;
+ hp--;
+
+ for (; hp >= 0; hp--) {
+ h = incs[hp];
+
+ i = lo + h;
+ while (True) {
+
+ /*-- copy 1 --*/
+ if (i > hi) break;
+ v = ptr[i];
+ j = i;
+ while ( mainGtU (
+ ptr[j-h]+d, v+d, block, quadrant, nblock, budget
+ ) ) {
+ ptr[j] = ptr[j-h];
+ j = j - h;
+ if (j <= (lo + h - 1)) break;
+ }
+ ptr[j] = v;
+ i++;
+
+ /*-- copy 2 --*/
+ if (i > hi) break;
+ v = ptr[i];
+ j = i;
+ while ( mainGtU (
+ ptr[j-h]+d, v+d, block, quadrant, nblock, budget
+ ) ) {
+ ptr[j] = ptr[j-h];
+ j = j - h;
+ if (j <= (lo + h - 1)) break;
+ }
+ ptr[j] = v;
+ i++;
+
+ /*-- copy 3 --*/
+ if (i > hi) break;
+ v = ptr[i];
+ j = i;
+ while ( mainGtU (
+ ptr[j-h]+d, v+d, block, quadrant, nblock, budget
+ ) ) {
+ ptr[j] = ptr[j-h];
+ j = j - h;
+ if (j <= (lo + h - 1)) break;
+ }
+ ptr[j] = v;
+ i++;
+
+ if (*budget < 0) return;
+ }
+ }
+}
+
+
+/*---------------------------------------------*/
+/*--
+ The following is an implementation of
+ an elegant 3-way quicksort for strings,
+ described in a paper "Fast Algorithms for
+ Sorting and Searching Strings", by Robert
+ Sedgewick and Jon L. Bentley.
+--*/
+
+#define mswap(zz1, zz2) \
+ { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; }
+
+#define mvswap(zzp1, zzp2, zzn) \
+{ \
+ Int32 yyp1 = (zzp1); \
+ Int32 yyp2 = (zzp2); \
+ Int32 yyn = (zzn); \
+ while (yyn > 0) { \
+ mswap(ptr[yyp1], ptr[yyp2]); \
+ yyp1++; yyp2++; yyn--; \
+ } \
+}
+
+static
+UChar mmed3 ( UChar a, UChar b, UChar c )
+{
+ UChar t;
+ if (a > b) { t = a; a = b; b = t; };
+ if (b > c) {
+ b = c;
+ if (a > b) b = a;
+ }
+ return b;
+}
+
+#define mmin(a,b) ((a) < (b)) ? (a) : (b)
+
+#define mpush(lz,hz,dz) { stackLo[sp] = lz; \
+ stackHi[sp] = hz; \
+ stackD [sp] = dz; \
+ sp++; }
+
+#define mpop(lz,hz,dz) { sp--; \
+ lz = stackLo[sp]; \
+ hz = stackHi[sp]; \
+ dz = stackD [sp]; }
+
+
+#define mnextsize(az) (nextHi[az]-nextLo[az])
+
+#define mnextswap(az,bz) \
+ { Int32 tz; \
+ tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
+ tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
+ tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; }
+
+
+#define MAIN_QSORT_SMALL_THRESH 20
+#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
+#define MAIN_QSORT_STACK_SIZE 100
+
+static
+void mainQSort3 ( UInt32* ptr,
+ UChar* block,
+ UInt16* quadrant,
+ Int32 nblock,
+ Int32 loSt,
+ Int32 hiSt,
+ Int32 dSt,
+ Int32* budget )
+{
+ Int32 unLo, unHi, ltLo, gtHi, n, m, med;
+ Int32 sp, lo, hi, d;
+
+ Int32 stackLo[MAIN_QSORT_STACK_SIZE];
+ Int32 stackHi[MAIN_QSORT_STACK_SIZE];
+ Int32 stackD [MAIN_QSORT_STACK_SIZE];
+
+ Int32 nextLo[3];
+ Int32 nextHi[3];
+ Int32 nextD [3];
+
+ sp = 0;
+ mpush ( loSt, hiSt, dSt );
+
+ while (sp > 0) {
+
+ AssertH ( sp < MAIN_QSORT_STACK_SIZE, 1001 );
+
+ mpop ( lo, hi, d );
+ if (hi - lo < MAIN_QSORT_SMALL_THRESH ||
+ d > MAIN_QSORT_DEPTH_THRESH) {
+ mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget );
+ if (*budget < 0) return;
+ continue;
+ }
+
+ med = (Int32)
+ mmed3 ( block[ptr[ lo ]+d],
+ block[ptr[ hi ]+d],
+ block[ptr[ (lo+hi)>>1 ]+d] );
+
+ unLo = ltLo = lo;
+ unHi = gtHi = hi;
+
+ while (True) {
+ while (True) {
+ if (unLo > unHi) break;
+ n = ((Int32)block[ptr[unLo]+d]) - med;
+ if (n == 0) {
+ mswap(ptr[unLo], ptr[ltLo]);
+ ltLo++; unLo++; continue;
+ };
+ if (n > 0) break;
+ unLo++;
+ }
+ while (True) {
+ if (unLo > unHi) break;
+ n = ((Int32)block[ptr[unHi]+d]) - med;
+ if (n == 0) {
+ mswap(ptr[unHi], ptr[gtHi]);
+ gtHi--; unHi--; continue;
+ };
+ if (n < 0) break;
+ unHi--;
+ }
+ if (unLo > unHi) break;
+ mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--;
+ }
+
+ AssertD ( unHi == unLo-1, "mainQSort3(2)" );
+
+ if (gtHi < ltLo) {
+ mpush(lo, hi, d+1 );
+ continue;
+ }
+
+ n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n);
+ m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m);
+
+ n = lo + unLo - ltLo - 1;
+ m = hi - (gtHi - unHi) + 1;
+
+ nextLo[0] = lo; nextHi[0] = n; nextD[0] = d;
+ nextLo[1] = m; nextHi[1] = hi; nextD[1] = d;
+ nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
+
+ if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+ if (mnextsize(1) < mnextsize(2)) mnextswap(1,2);
+ if (mnextsize(0) < mnextsize(1)) mnextswap(0,1);
+
+ AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" );
+ AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" );
+
+ mpush (nextLo[0], nextHi[0], nextD[0]);
+ mpush (nextLo[1], nextHi[1], nextD[1]);
+ mpush (nextLo[2], nextHi[2], nextD[2]);
+ }
+}
+
+#undef mswap
+#undef mvswap
+#undef mpush
+#undef mpop
+#undef mmin
+#undef mnextsize
+#undef mnextswap
+#undef MAIN_QSORT_SMALL_THRESH
+#undef MAIN_QSORT_DEPTH_THRESH
+#undef MAIN_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+ nblock > N_OVERSHOOT
+ block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
+ ((UChar*)block32) [0 .. nblock-1] holds block
+ ptr exists for [0 .. nblock-1]
+
+ Post:
+ ((UChar*)block32) [0 .. nblock-1] holds block
+ All other areas of block32 destroyed
+ ftab [0 .. 65536 ] destroyed
+ ptr [0 .. nblock-1] holds sorted order
+ if (*budget < 0), sorting was abandoned
+*/
+
+#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
+#define SETMASK (1 << 21)
+#define CLEARMASK (~(SETMASK))
+
+static
+void mainSort ( UInt32* ptr,
+ UChar* block,
+ UInt16* quadrant,
+ UInt32* ftab,
+ Int32 nblock,
+ Int32* budget )
+{
+ Int32 i, j, k, ss, sb;
+ Int32 runningOrder[256];
+ Bool bigDone[256];
+ Int32 copyStart[256];
+ Int32 copyEnd [256];
+ UChar c1;
+ Int32 numQSorted;
+ UInt16 s;
+
+ /*-- set up the 2-byte frequency table --*/
+ for (i = 65536; i >= 0; i--) ftab[i] = 0;
+
+ j = block[0] << 8;
+ i = nblock-1;
+ for (; i >= 3; i -= 4) {
+ quadrant[i] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+ ftab[j]++;
+ quadrant[i-1] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i-1]) << 8);
+ ftab[j]++;
+ quadrant[i-2] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i-2]) << 8);
+ ftab[j]++;
+ quadrant[i-3] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i-3]) << 8);
+ ftab[j]++;
+ }
+ for (; i >= 0; i--) {
+ quadrant[i] = 0;
+ j = (j >> 8) | ( ((UInt16)block[i]) << 8);
+ ftab[j]++;
+ }
+
+ /*-- (emphasises close relationship of block & quadrant) --*/
+ for (i = 0; i < BZ_N_OVERSHOOT; i++) {
+ block [nblock+i] = block[i];
+ quadrant[nblock+i] = 0;
+ }
+
+ /*-- Complete the initial radix sort --*/
+ for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1];
+
+ s = block[0] << 8;
+ i = nblock-1;
+ for (; i >= 3; i -= 4) {
+ s = (s >> 8) | (block[i] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i;
+ s = (s >> 8) | (block[i-1] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i-1;
+ s = (s >> 8) | (block[i-2] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i-2;
+ s = (s >> 8) | (block[i-3] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i-3;
+ }
+ for (; i >= 0; i--) {
+ s = (s >> 8) | (block[i] << 8);
+ j = ftab[s] -1;
+ ftab[s] = j;
+ ptr[j] = i;
+ }
+
+ /*--
+ Now ftab contains the first loc of every small bucket.
+ Calculate the running order, from smallest to largest
+ big bucket.
+ --*/
+ for (i = 0; i <= 255; i++) {
+ bigDone [i] = False;
+ runningOrder[i] = i;
+ }
+
+ {
+ Int32 vv;
+ Int32 h = 1;
+ do h = 3 * h + 1; while (h <= 256);
+ do {
+ h = h / 3;
+ for (i = h; i <= 255; i++) {
+ vv = runningOrder[i];
+ j = i;
+ while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) {
+ runningOrder[j] = runningOrder[j-h];
+ j = j - h;
+ if (j <= (h - 1)) goto zero;
+ }
+ zero:
+ runningOrder[j] = vv;
+ }
+ } while (h != 1);
+ }
+
+ /*--
+ The main sorting loop.
+ --*/
+
+ numQSorted = 0;
+
+ for (i = 0; i <= 255; i++) {
+
+ /*--
+ Process big buckets, starting with the least full.
+ Basically this is a 3-step process in which we call
+ mainQSort3 to sort the small buckets [ss, j], but
+ also make a big effort to avoid the calls if we can.
+ --*/
+ ss = runningOrder[i];
+
+ /*--
+ Step 1:
+ Complete the big bucket [ss] by quicksorting
+ any unsorted small buckets [ss, j], for j != ss.
+ Hopefully previous pointer-scanning phases have already
+ completed many of the small buckets [ss, j], so
+ we don't have to sort them at all.
+ --*/
+ for (j = 0; j <= 255; j++) {
+ if (j != ss) {
+ sb = (ss << 8) + j;
+ if ( ! (ftab[sb] & SETMASK) ) {
+ Int32 lo = ftab[sb] & CLEARMASK;
+ Int32 hi = (ftab[sb+1] & CLEARMASK) - 1;
+ if (hi > lo) {
+ mainQSort3 (
+ ptr, block, quadrant, nblock,
+ lo, hi, BZ_N_RADIX, budget
+ );
+ numQSorted += (hi - lo + 1);
+ if (*budget < 0) return;
+ }
+ }
+ ftab[sb] |= SETMASK;
+ }
+ }
+
+ AssertH ( !bigDone[ss], 1006 );
+
+ /*--
+ Step 2:
+ Now scan this big bucket [ss] so as to synthesise the
+ sorted order for small buckets [t, ss] for all t,
+ including, magically, the bucket [ss,ss] too.
+ This will avoid doing Real Work in subsequent Step 1's.
+ --*/
+ {
+ for (j = 0; j <= 255; j++) {
+ copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK;
+ copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
+ }
+ for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
+ k = ptr[j]-1; if (k < 0) k += nblock;
+ c1 = block[k];
+ if (!bigDone[c1])
+ ptr[ copyStart[c1]++ ] = k;
+ }
+ for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
+ k = ptr[j]-1; if (k < 0) k += nblock;
+ c1 = block[k];
+ if (!bigDone[c1])
+ ptr[ copyEnd[c1]-- ] = k;
+ }
+ }
+
+ AssertH ( copyStart[ss]-1 == copyEnd[ss], 1007 );
+
+ for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK;
+
+ /*--
+ Step 3:
+ The [ss] big bucket is now done. Record this fact,
+ and update the quadrant descriptors. Remember to
+ update quadrants in the overshoot area too, if
+ necessary. The "if (i < 255)" test merely skips
+ this updating for the last bucket processed, since
+ updating for the last bucket is pointless.
+
+ The quadrant array provides a way to incrementally
+ cache sort orderings, as they appear, so as to
+ make subsequent comparisons in fullGtU() complete
+ faster. For repetitive blocks this makes a big
+ difference (but not big enough to be able to avoid
+ the fallback sorting mechanism, exponential radix sort).
+
+ The precise meaning is: at all times:
+
+ for 0 <= i < nblock and 0 <= j <= nblock
+
+ if block[i] != block[j],
+
+ then the relative values of quadrant[i] and
+ quadrant[j] are meaningless.
+
+ else {
+ if quadrant[i] < quadrant[j]
+ then the string starting at i lexicographically
+ precedes the string starting at j
+
+ else if quadrant[i] > quadrant[j]
+ then the string starting at j lexicographically
+ precedes the string starting at i
+
+ else
+ the relative ordering of the strings starting
+ at i and j has not yet been determined.
+ }
+ --*/
+ bigDone[ss] = True;
+
+ if (i < 255) {
+ Int32 bbStart = ftab[ss << 8] & CLEARMASK;
+ Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
+ Int32 shifts = 0;
+
+ while ((bbSize >> shifts) > 65534) shifts++;
+
+ for (j = bbSize-1; j >= 0; j--) {
+ Int32 a2update = ptr[bbStart + j];
+ UInt16 qVal = (UInt16)(j >> shifts);
+ quadrant[a2update] = qVal;
+ if (a2update < BZ_N_OVERSHOOT)
+ quadrant[a2update + nblock] = qVal;
+ }
+ AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 );
+ }
+
+ }
+}
+
+#undef BIGFREQ
+#undef SETMASK
+#undef CLEARMASK
+
+
+/*---------------------------------------------*/
+/* Pre:
+ nblock > 0
+ arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
+ ((UChar*)arr2) [0 .. nblock-1] holds block
+ arr1 exists for [0 .. nblock-1]
+
+ Post:
+ ((UChar*)arr2) [0 .. nblock-1] holds block
+ All other areas of block destroyed
+ ftab [ 0 .. 65536 ] destroyed
+ arr1 [0 .. nblock-1] holds sorted order
+*/
+void BZ2_blockSort ( EState* s )
+{
+ UInt32* ptr = s->ptr;
+ UChar* block = s->block;
+ UInt32* ftab = s->ftab;
+ Int32 nblock = s->nblock;
+ Int32 wfact = s->workFactor;
+ UInt16* quadrant;
+ Int32 budget;
+ Int32 budgetInit;
+ Int32 i;
+
+ if (nblock < 10000) {
+ fallbackSort ( s->arr1, s->arr2, ftab, nblock );
+ } else {
+ /* Calculate the location for quadrant, remembering to get
+ the alignment right. Assumes that &(block[0]) is at least
+ 2-byte aligned -- this should be ok since block is really
+ the first section of arr2.
+ */
+ i = nblock+BZ_N_OVERSHOOT;
+ if (i & 1) i++;
+ quadrant = (UInt16*)(&(block[i]));
+
+ /* (wfact-1) / 3 puts the default-factor-30
+ transition point at very roughly the same place as
+ with v0.1 and v0.9.0.
+ Not that it particularly matters any more, since the
+ resulting compressed stream is now the same regardless
+ of whether or not we use the main sort or fallback sort.
+ */
+ if (wfact < 1 ) wfact = 1;
+ if (wfact > 100) wfact = 100;
+ budgetInit = nblock * ((wfact-1) / 3);
+ budget = budgetInit;
+
+ mainSort ( ptr, block, quadrant, ftab, nblock, &budget );
+ if (budget < 0) {
+ fallbackSort ( s->arr1, s->arr2, ftab, nblock );
+ }
+ }
+
+ s->origPtr = -1;
+ for (i = 0; i < s->nblock; i++)
+ if (ptr[i] == 0)
+ { s->origPtr = i; break; };
+
+ AssertH( s->origPtr != -1, 1003 );
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end blocksort.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/Source/bzip2/bzlib.c b/Source/bzip2/bzlib.c
index 4aec93a..8fba030 100755
--- a/Source/bzip2/bzlib.c
+++ b/Source/bzip2/bzlib.c
@@ -1,621 +1,621 @@
-/*
- * This file is a part of the bzip2 compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.bzip.org/
- *
- * This modification is not compatible with the original bzip2.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "bzlib.h"
-
-/*-------------------------------------------------------------*/
-/*--- Library top-level functions. ---*/
-/*--- bzlib.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@acm.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-/*--
- CHANGES
- ~~~~~~~
- 0.9.0 -- original version.
-
- 0.9.0a/b -- no changes in this file.
-
- 0.9.0c
- * made zero-length BZ_FLUSH work correctly in bzCompress().
- * fixed bzWrite/bzRead to ignore zero-length requests.
- * fixed bzread to correctly handle read requests after EOF.
- * wrong parameter order in call to bzDecompressInit in
- bzBuffToBuffDecompress. Fixed.
---*/
-#include "bzlib.h"
-
-
-/*---------------------------------------------------*/
-/*--- Compression stuff ---*/
-/*---------------------------------------------------*/
-
-
-#ifndef EXEHEAD
-
-/*---------------------------------------------------*/
-static
-void prepare_new_block ( EState* s )
-{
- Int32 i;
- s->nblock = 0;
- s->numZ = 0;
- s->state_out_pos = 0;
- for (i = 0; i < 256; i++) s->inUse[i] = False;
- s->blockNo++;
-}
-
-
-/*---------------------------------------------------*/
-static
-void init_RL ( EState* s )
-{
- s->state_in_ch = 256;
- s->state_in_len = 0;
-}
-
-
-static
-Bool isempty_RL ( EState* s )
-{
- if (s->state_in_ch < 256 && s->state_in_len > 0)
- return False; else
- return True;
-}
-
-/*---------------------------------------------------*/
-int BZ2_bzCompressInit( bz_stream* strm,
- int blockSize100k,
- int verbosity,
- int workFactor )
-{
- Int32 n;
- EState* s;
-
- if (strm == NULL ||
- workFactor < 0 || workFactor > 250)
- return BZ_PARAM_ERROR;
-
- if (workFactor == 0) workFactor = 30;
-
- s = BZALLOC( sizeof(EState) );
- if (s == NULL) return BZ_MEM_ERROR;
- s->strm = strm;
-
- s->arr1 = NULL;
- s->arr2 = NULL;
- s->ftab = NULL;
-
- n = NSIS_COMPRESS_BZIP2_LEVEL*100000;
- s->arr1 = BZALLOC( n * sizeof(UInt32) );
- s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
- s->ftab = BZALLOC( 65537 * sizeof(UInt32) );
-
- if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
- BZFREE(s->arr1);
- BZFREE(s->arr2);
- BZFREE(s->ftab);
- BZFREE(s);
- return BZ_MEM_ERROR;
- }
-
- s->blockNo = 0;
- s->state = BZ_S_INPUT;
- s->mode = BZ_M_RUNNING;
- s->nblockMAX = 100000 * NSIS_COMPRESS_BZIP2_LEVEL - 19;
- s->workFactor = workFactor;
-
- s->block = (UChar*)s->arr2;
- s->mtfv = (UInt16*)s->arr1;
- s->zbits = NULL;
- s->ptr = (UInt32*)s->arr1;
-
- strm->state = s;
- init_RL ( s );
- prepare_new_block ( s );
- return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-static
-void add_pair_to_block ( EState* s )
-{
- UChar ch = (UChar)(s->state_in_ch);
- s->inUse[s->state_in_ch] = True;
- switch (s->state_in_len) {
- case 1:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- case 2:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- case 3:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- default:
- s->inUse[s->state_in_len-4] = True;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = ((UChar)(s->state_in_len-4));
- s->nblock++;
- break;
- }
-}
-
-
-/*---------------------------------------------------*/
-static
-void flush_RL ( EState* s )
-{
- if (s->state_in_ch < 256) add_pair_to_block ( s );
- init_RL ( s );
-}
-
-
-/*---------------------------------------------------*/
-#define ADD_CHAR_TO_BLOCK(zs,zchh0) \
-{ \
- UInt32 zchh = (UInt32)(zchh0); \
- /*-- fast track the common case --*/ \
- if (zchh != zs->state_in_ch && \
- zs->state_in_len == 1) { \
- UChar ch = (UChar)(zs->state_in_ch); \
- zs->inUse[zs->state_in_ch] = True; \
- zs->block[zs->nblock] = (UChar)ch; \
- zs->nblock++; \
- zs->state_in_ch = zchh; \
- } \
- else \
- /*-- general, uncommon cases --*/ \
- if (zchh != zs->state_in_ch || \
- zs->state_in_len == 255) { \
- if (zs->state_in_ch < 256) \
- add_pair_to_block ( zs ); \
- zs->state_in_ch = zchh; \
- zs->state_in_len = 1; \
- } else { \
- zs->state_in_len++; \
- } \
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_input_until_stop ( EState* s )
-{
- Bool progress_in = False;
-
- if (s->mode == BZ_M_RUNNING) {
-
- /*-- fast track the common case --*/
- while (True) {
- /*-- block full? --*/
- if (s->nblock >= s->nblockMAX) break;
- /*-- no input? --*/
- if (s->strm->avail_in == 0) break;
- progress_in = True;
- ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
- s->strm->next_in++;
- s->strm->avail_in--;
- // s->strm->total_in_lo32++;
-// if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
- }
-
- } else {
-
- /*-- general, uncommon case --*/
- while (True) {
- /*-- block full? --*/
- if (s->nblock >= s->nblockMAX) break;
- /*-- no input? --*/
- if (s->strm->avail_in == 0) break;
- /*-- flush/finish end? --*/
- if (s->avail_in_expect == 0) break;
- progress_in = True;
- ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
- s->strm->next_in++;
- s->strm->avail_in--;
- // s->strm->total_in_lo32++;
-// if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
- s->avail_in_expect--;
- }
- }
- return progress_in;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_output_until_stop ( EState* s )
-{
- Bool progress_out = False;
-
- while (True) {
-
- /*-- no output space? --*/
- if (s->strm->avail_out == 0) break;
-
- /*-- block done? --*/
- if (s->state_out_pos >= s->numZ) break;
-
- progress_out = True;
- *(s->strm->next_out) = s->zbits[s->state_out_pos];
- s->state_out_pos++;
- s->strm->avail_out--;
- s->strm->next_out++;
-// s->strm->total_out_lo32++;
- // if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- return progress_out;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool handle_compress ( bz_stream* strm )
-{
- Bool progress_in = False;
- Bool progress_out = False;
- EState* s = strm->state;
-
- while (True) {
-
- if (s->state == BZ_S_OUTPUT) {
- progress_out |= copy_output_until_stop ( s );
- if (s->state_out_pos < s->numZ) break;
- if (s->mode == BZ_M_FINISHING &&
- s->avail_in_expect == 0 &&
- isempty_RL(s)) break;
- prepare_new_block ( s );
- s->state = BZ_S_INPUT;
- if (s->mode == BZ_M_FLUSHING &&
- s->avail_in_expect == 0 &&
- isempty_RL(s)) break;
- }
-
- if (s->state == BZ_S_INPUT) {
- progress_in |= copy_input_until_stop ( s );
- if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
- flush_RL ( s );
- BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
- s->state = BZ_S_OUTPUT;
- }
- else
- if (s->nblock >= s->nblockMAX) {
- BZ2_compressBlock ( s, False );
- s->state = BZ_S_OUTPUT;
- }
- else
- if (s->strm->avail_in == 0) {
- break;
- }
- }
-
- }
-
- return progress_in || progress_out;
-}
-
-
-/*---------------------------------------------------*/
-int BZ2_bzCompress( bz_stream *strm, int action )
-{
- Bool progress;
- EState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- preswitch:
- switch (s->mode) {
-
- case BZ_M_IDLE:
- return BZ_SEQUENCE_ERROR;
-
- case BZ_M_RUNNING:
- if (action == BZ_RUN) {
- progress = handle_compress ( strm );
- return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
- }
- else
- if (action == BZ_FLUSH) {
- s->avail_in_expect = strm->avail_in;
- s->mode = BZ_M_FLUSHING;
- goto preswitch;
- }
- else
- if (action == BZ_FINISH) {
- s->avail_in_expect = strm->avail_in;
- s->mode = BZ_M_FINISHING;
- goto preswitch;
- }
- else
- return BZ_PARAM_ERROR;
-
- case BZ_M_FLUSHING:
- if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect != s->strm->avail_in)
- return BZ_SEQUENCE_ERROR;
- progress = handle_compress ( strm );
- if (s->avail_in_expect > 0 || !isempty_RL(s) ||
- s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
- s->mode = BZ_M_RUNNING;
- return BZ_RUN_OK;
-
- case BZ_M_FINISHING:
- if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect != s->strm->avail_in)
- return BZ_SEQUENCE_ERROR;
- progress = handle_compress ( strm );
- if (!progress) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect > 0 || !isempty_RL(s) ||
- s->state_out_pos < s->numZ) return BZ_FINISH_OK;
- s->mode = BZ_M_IDLE;
- return BZ_STREAM_END;
- }
- return BZ_OK; /*--not reached--*/
-}
-
-
-/*---------------------------------------------------*/
-int BZ2_bzCompressEnd( bz_stream *strm )
-{
- EState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- BZFREE(s->arr1);
- BZFREE(s->arr2);
- BZFREE(s->ftab);
- BZFREE(strm->state);
-
- strm->state = NULL;
-
- return BZ_OK;
-}
-#else // EXEHEAD
-
-#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
-/*---------------------------------------------------*/
-
-Int32 NSISCALL BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
-{
- Int32 nb, na, mid;
- nb = 0;
- na = 256;
- do {
- mid = (nb + na) >> 1;
- if (indx >= cftab[mid]) nb = mid;
- else na = mid;
- } while (na - nb != 1);
- return nb;
-}
-
-
-static
-void NSISCALL unRLE_obuf_to_output_SMALL ( DState* s )
-{
- UChar k1;
- while (True) {
- /* try to finish existing run */
- while (True) {
- if (s->avail_out == 0) return;
- if (s->state_out_len == 0) break;
- *( (UChar*)(s->next_out) ) = s->state_out_ch;
- s->state_out_len--;
- s->next_out++;
- s->avail_out--;
- }
-
- /* can a new run be started? */
- if (s->nblock_used == s->save.nblock+1) return;
-
- s->state_out_len = 1;
- s->state_out_ch = s->k0;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save.nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 2;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save.nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 3;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save.nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- BZ_GET_SMALL(k1); s->nblock_used++;
- s->state_out_len = ((Int32)k1) + 4;
- BZ_GET_SMALL(s->k0); s->nblock_used++;
- }
-}
-#else//!small, fast
-static void NSISCALL unRLE_obuf_to_output_FAST ( DState* s )
-{
- UChar k1;
-
- /* restore */
- UChar c_state_out_ch = s->state_out_ch;
- Int32 c_state_out_len = s->state_out_len;
- Int32 c_nblock_used = s->nblock_used;
- Int32 c_k0 = s->k0;
- UInt32 c_tPos = s->tPos;
-
- char* cs_next_out = s->next_out;
- unsigned int cs_avail_out = s->avail_out;
- /* end restore */
-
- UInt32* c_tt = s->tt;
- Int32 s_save_nblockPP = s->save.nblock+1;
-// unsigned int total_out_lo32_old;
-
- while (True) {
-
- /* try to finish existing run */
- if (c_state_out_len > 0) {
- while (True) {
- if (cs_avail_out == 0) goto return_notr;
- if (c_state_out_len == 1) break;
- *( (UChar*)(cs_next_out) ) = c_state_out_ch;
- c_state_out_len--;
- cs_next_out++;
- cs_avail_out--;
- }
- s_state_out_len_eq_one:
- {
- if (cs_avail_out == 0) {
- c_state_out_len = 1; goto return_notr;
- };
- *( (UChar*)(cs_next_out) ) = c_state_out_ch;
- cs_next_out++;
- cs_avail_out--;
- }
- }
- /* can a new run be started? */
- if (c_nblock_used == s_save_nblockPP) {
- c_state_out_len = 0; goto return_notr;
- };
- c_state_out_ch = c_k0;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (k1 != c_k0) {
- c_k0 = k1; goto s_state_out_len_eq_one;
- };
- if (c_nblock_used == s_save_nblockPP)
- goto s_state_out_len_eq_one;
-
- c_state_out_len = 2;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (c_nblock_used == s_save_nblockPP) continue;
- if (k1 != c_k0) { c_k0 = k1; continue; };
-
- c_state_out_len = 3;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (c_nblock_used == s_save_nblockPP) continue;
- if (k1 != c_k0) { c_k0 = k1; continue; };
-
- BZ_GET_FAST_C(k1); c_nblock_used++;
- c_state_out_len = ((Int32)k1) + 4;
- BZ_GET_FAST_C(c_k0); c_nblock_used++;
- }
-
- return_notr:
- s->state_out_ch = c_state_out_ch;
- s->state_out_len = c_state_out_len;
- s->nblock_used = c_nblock_used;
- s->k0 = c_k0;
- s->tPos = c_tPos;
- s->next_out = cs_next_out;
- s->avail_out = cs_avail_out;
- /* end save */
-}
-
-#endif
-
-
-/*---------------------------------------------------*/
-int NSISCALL BZ2_bzDecompress( DState *s )
-{
- while (True) {
- if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
- if (s->state == BZ_X_OUTPUT) {
-#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
- unRLE_obuf_to_output_SMALL ( s );
-#else
- unRLE_obuf_to_output_FAST ( s );
-#endif
- if (s->nblock_used == s->save.nblock+1 && s->state_out_len == 0) {
- s->state = BZ_X_BLKHDR_1;
- } else {
- return BZ_OK;
- }
- }
- if (s->state >= BZ_X_BLKHDR_1) {
- Int32 r = BZ2_decompress ( s );
- if (r == BZ_STREAM_END) {
- return r;
- }
- if (s->state != BZ_X_OUTPUT) return r;
- }
- }
-}
-
-
-
-#endif
+/*
+ * This file is a part of the bzip2 compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.bzip.org/
+ *
+ * This modification is not compatible with the original bzip2.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "bzlib.h"
+
+/*-------------------------------------------------------------*/
+/*--- Library top-level functions. ---*/
+/*--- bzlib.c ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+ This file is a part of bzip2 and/or libbzip2, a program and
+ library for lossless, block-sorting data compression.
+
+ Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+ 3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+ 4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Julian Seward, Cambridge, UK.
+ jseward@acm.org
+ bzip2/libbzip2 version 1.0 of 21 March 2000
+
+ This program is based on (at least) the work of:
+ Mike Burrows
+ David Wheeler
+ Peter Fenwick
+ Alistair Moffat
+ Radford Neal
+ Ian H. Witten
+ Robert Sedgewick
+ Jon L. Bentley
+
+ For more information on these sources, see the manual.
+--*/
+
+/*--
+ CHANGES
+ ~~~~~~~
+ 0.9.0 -- original version.
+
+ 0.9.0a/b -- no changes in this file.
+
+ 0.9.0c
+ * made zero-length BZ_FLUSH work correctly in bzCompress().
+ * fixed bzWrite/bzRead to ignore zero-length requests.
+ * fixed bzread to correctly handle read requests after EOF.
+ * wrong parameter order in call to bzDecompressInit in
+ bzBuffToBuffDecompress. Fixed.
+--*/
+#include "bzlib.h"
+
+
+/*---------------------------------------------------*/
+/*--- Compression stuff ---*/
+/*---------------------------------------------------*/
+
+
+#ifndef EXEHEAD
+
+/*---------------------------------------------------*/
+static
+void prepare_new_block ( EState* s )
+{
+ Int32 i;
+ s->nblock = 0;
+ s->numZ = 0;
+ s->state_out_pos = 0;
+ for (i = 0; i < 256; i++) s->inUse[i] = False;
+ s->blockNo++;
+}
+
+
+/*---------------------------------------------------*/
+static
+void init_RL ( EState* s )
+{
+ s->state_in_ch = 256;
+ s->state_in_len = 0;
+}
+
+
+static
+Bool isempty_RL ( EState* s )
+{
+ if (s->state_in_ch < 256 && s->state_in_len > 0)
+ return False; else
+ return True;
+}
+
+/*---------------------------------------------------*/
+int BZ2_bzCompressInit( bz_stream* strm,
+ int blockSize100k,
+ int verbosity,
+ int workFactor )
+{
+ Int32 n;
+ EState* s;
+
+ if (strm == NULL ||
+ workFactor < 0 || workFactor > 250)
+ return BZ_PARAM_ERROR;
+
+ if (workFactor == 0) workFactor = 30;
+
+ s = BZALLOC( sizeof(EState) );
+ if (s == NULL) return BZ_MEM_ERROR;
+ s->strm = strm;
+
+ s->arr1 = NULL;
+ s->arr2 = NULL;
+ s->ftab = NULL;
+
+ n = NSIS_COMPRESS_BZIP2_LEVEL*100000;
+ s->arr1 = BZALLOC( n * sizeof(UInt32) );
+ s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
+ s->ftab = BZALLOC( 65537 * sizeof(UInt32) );
+
+ if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
+ BZFREE(s->arr1);
+ BZFREE(s->arr2);
+ BZFREE(s->ftab);
+ BZFREE(s);
+ return BZ_MEM_ERROR;
+ }
+
+ s->blockNo = 0;
+ s->state = BZ_S_INPUT;
+ s->mode = BZ_M_RUNNING;
+ s->nblockMAX = 100000 * NSIS_COMPRESS_BZIP2_LEVEL - 19;
+ s->workFactor = workFactor;
+
+ s->block = (UChar*)s->arr2;
+ s->mtfv = (UInt16*)s->arr1;
+ s->zbits = NULL;
+ s->ptr = (UInt32*)s->arr1;
+
+ strm->state = s;
+ init_RL ( s );
+ prepare_new_block ( s );
+ return BZ_OK;
+}
+
+
+/*---------------------------------------------------*/
+static
+void add_pair_to_block ( EState* s )
+{
+ UChar ch = (UChar)(s->state_in_ch);
+ s->inUse[s->state_in_ch] = True;
+ switch (s->state_in_len) {
+ case 1:
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ break;
+ case 2:
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ break;
+ case 3:
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ break;
+ default:
+ s->inUse[s->state_in_len-4] = True;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = (UChar)ch; s->nblock++;
+ s->block[s->nblock] = ((UChar)(s->state_in_len-4));
+ s->nblock++;
+ break;
+ }
+}
+
+
+/*---------------------------------------------------*/
+static
+void flush_RL ( EState* s )
+{
+ if (s->state_in_ch < 256) add_pair_to_block ( s );
+ init_RL ( s );
+}
+
+
+/*---------------------------------------------------*/
+#define ADD_CHAR_TO_BLOCK(zs,zchh0) \
+{ \
+ UInt32 zchh = (UInt32)(zchh0); \
+ /*-- fast track the common case --*/ \
+ if (zchh != zs->state_in_ch && \
+ zs->state_in_len == 1) { \
+ UChar ch = (UChar)(zs->state_in_ch); \
+ zs->inUse[zs->state_in_ch] = True; \
+ zs->block[zs->nblock] = (UChar)ch; \
+ zs->nblock++; \
+ zs->state_in_ch = zchh; \
+ } \
+ else \
+ /*-- general, uncommon cases --*/ \
+ if (zchh != zs->state_in_ch || \
+ zs->state_in_len == 255) { \
+ if (zs->state_in_ch < 256) \
+ add_pair_to_block ( zs ); \
+ zs->state_in_ch = zchh; \
+ zs->state_in_len = 1; \
+ } else { \
+ zs->state_in_len++; \
+ } \
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_input_until_stop ( EState* s )
+{
+ Bool progress_in = False;
+
+ if (s->mode == BZ_M_RUNNING) {
+
+ /*-- fast track the common case --*/
+ while (True) {
+ /*-- block full? --*/
+ if (s->nblock >= s->nblockMAX) break;
+ /*-- no input? --*/
+ if (s->strm->avail_in == 0) break;
+ progress_in = True;
+ ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
+ s->strm->next_in++;
+ s->strm->avail_in--;
+ // s->strm->total_in_lo32++;
+// if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+ }
+
+ } else {
+
+ /*-- general, uncommon case --*/
+ while (True) {
+ /*-- block full? --*/
+ if (s->nblock >= s->nblockMAX) break;
+ /*-- no input? --*/
+ if (s->strm->avail_in == 0) break;
+ /*-- flush/finish end? --*/
+ if (s->avail_in_expect == 0) break;
+ progress_in = True;
+ ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
+ s->strm->next_in++;
+ s->strm->avail_in--;
+ // s->strm->total_in_lo32++;
+// if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
+ s->avail_in_expect--;
+ }
+ }
+ return progress_in;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool copy_output_until_stop ( EState* s )
+{
+ Bool progress_out = False;
+
+ while (True) {
+
+ /*-- no output space? --*/
+ if (s->strm->avail_out == 0) break;
+
+ /*-- block done? --*/
+ if (s->state_out_pos >= s->numZ) break;
+
+ progress_out = True;
+ *(s->strm->next_out) = s->zbits[s->state_out_pos];
+ s->state_out_pos++;
+ s->strm->avail_out--;
+ s->strm->next_out++;
+// s->strm->total_out_lo32++;
+ // if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
+ }
+
+ return progress_out;
+}
+
+
+/*---------------------------------------------------*/
+static
+Bool handle_compress ( bz_stream* strm )
+{
+ Bool progress_in = False;
+ Bool progress_out = False;
+ EState* s = strm->state;
+
+ while (True) {
+
+ if (s->state == BZ_S_OUTPUT) {
+ progress_out |= copy_output_until_stop ( s );
+ if (s->state_out_pos < s->numZ) break;
+ if (s->mode == BZ_M_FINISHING &&
+ s->avail_in_expect == 0 &&
+ isempty_RL(s)) break;
+ prepare_new_block ( s );
+ s->state = BZ_S_INPUT;
+ if (s->mode == BZ_M_FLUSHING &&
+ s->avail_in_expect == 0 &&
+ isempty_RL(s)) break;
+ }
+
+ if (s->state == BZ_S_INPUT) {
+ progress_in |= copy_input_until_stop ( s );
+ if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
+ flush_RL ( s );
+ BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
+ s->state = BZ_S_OUTPUT;
+ }
+ else
+ if (s->nblock >= s->nblockMAX) {
+ BZ2_compressBlock ( s, False );
+ s->state = BZ_S_OUTPUT;
+ }
+ else
+ if (s->strm->avail_in == 0) {
+ break;
+ }
+ }
+
+ }
+
+ return progress_in || progress_out;
+}
+
+
+/*---------------------------------------------------*/
+int BZ2_bzCompress( bz_stream *strm, int action )
+{
+ Bool progress;
+ EState* s;
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ s = strm->state;
+ if (s == NULL) return BZ_PARAM_ERROR;
+ if (s->strm != strm) return BZ_PARAM_ERROR;
+
+ preswitch:
+ switch (s->mode) {
+
+ case BZ_M_IDLE:
+ return BZ_SEQUENCE_ERROR;
+
+ case BZ_M_RUNNING:
+ if (action == BZ_RUN) {
+ progress = handle_compress ( strm );
+ return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
+ }
+ else
+ if (action == BZ_FLUSH) {
+ s->avail_in_expect = strm->avail_in;
+ s->mode = BZ_M_FLUSHING;
+ goto preswitch;
+ }
+ else
+ if (action == BZ_FINISH) {
+ s->avail_in_expect = strm->avail_in;
+ s->mode = BZ_M_FINISHING;
+ goto preswitch;
+ }
+ else
+ return BZ_PARAM_ERROR;
+
+ case BZ_M_FLUSHING:
+ if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
+ if (s->avail_in_expect != s->strm->avail_in)
+ return BZ_SEQUENCE_ERROR;
+ progress = handle_compress ( strm );
+ if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+ s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
+ s->mode = BZ_M_RUNNING;
+ return BZ_RUN_OK;
+
+ case BZ_M_FINISHING:
+ if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
+ if (s->avail_in_expect != s->strm->avail_in)
+ return BZ_SEQUENCE_ERROR;
+ progress = handle_compress ( strm );
+ if (!progress) return BZ_SEQUENCE_ERROR;
+ if (s->avail_in_expect > 0 || !isempty_RL(s) ||
+ s->state_out_pos < s->numZ) return BZ_FINISH_OK;
+ s->mode = BZ_M_IDLE;
+ return BZ_STREAM_END;
+ }
+ return BZ_OK; /*--not reached--*/
+}
+
+
+/*---------------------------------------------------*/
+int BZ2_bzCompressEnd( bz_stream *strm )
+{
+ EState* s;
+ if (strm == NULL) return BZ_PARAM_ERROR;
+ s = strm->state;
+ if (s == NULL) return BZ_PARAM_ERROR;
+ if (s->strm != strm) return BZ_PARAM_ERROR;
+
+ BZFREE(s->arr1);
+ BZFREE(s->arr2);
+ BZFREE(s->ftab);
+ BZFREE(strm->state);
+
+ strm->state = NULL;
+
+ return BZ_OK;
+}
+#else // EXEHEAD
+
+#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
+/*---------------------------------------------------*/
+
+Int32 NSISCALL BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
+{
+ Int32 nb, na, mid;
+ nb = 0;
+ na = 256;
+ do {
+ mid = (nb + na) >> 1;
+ if (indx >= cftab[mid]) nb = mid;
+ else na = mid;
+ } while (na - nb != 1);
+ return nb;
+}
+
+
+static
+void NSISCALL unRLE_obuf_to_output_SMALL ( DState* s )
+{
+ UChar k1;
+ while (True) {
+ /* try to finish existing run */
+ while (True) {
+ if (s->avail_out == 0) return;
+ if (s->state_out_len == 0) break;
+ *( (UChar*)(s->next_out) ) = s->state_out_ch;
+ s->state_out_len--;
+ s->next_out++;
+ s->avail_out--;
+ }
+
+ /* can a new run be started? */
+ if (s->nblock_used == s->save.nblock+1) return;
+
+ s->state_out_len = 1;
+ s->state_out_ch = s->k0;
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ if (s->nblock_used == s->save.nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 2;
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ if (s->nblock_used == s->save.nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ s->state_out_len = 3;
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ if (s->nblock_used == s->save.nblock+1) continue;
+ if (k1 != s->k0) { s->k0 = k1; continue; };
+
+ BZ_GET_SMALL(k1); s->nblock_used++;
+ s->state_out_len = ((Int32)k1) + 4;
+ BZ_GET_SMALL(s->k0); s->nblock_used++;
+ }
+}
+#else//!small, fast
+static void NSISCALL unRLE_obuf_to_output_FAST ( DState* s )
+{
+ UChar k1;
+
+ /* restore */
+ UChar c_state_out_ch = s->state_out_ch;
+ Int32 c_state_out_len = s->state_out_len;
+ Int32 c_nblock_used = s->nblock_used;
+ Int32 c_k0 = s->k0;
+ UInt32 c_tPos = s->tPos;
+
+ char* cs_next_out = s->next_out;
+ unsigned int cs_avail_out = s->avail_out;
+ /* end restore */
+
+ UInt32* c_tt = s->tt;
+ Int32 s_save_nblockPP = s->save.nblock+1;
+// unsigned int total_out_lo32_old;
+
+ while (True) {
+
+ /* try to finish existing run */
+ if (c_state_out_len > 0) {
+ while (True) {
+ if (cs_avail_out == 0) goto return_notr;
+ if (c_state_out_len == 1) break;
+ *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+ c_state_out_len--;
+ cs_next_out++;
+ cs_avail_out--;
+ }
+ s_state_out_len_eq_one:
+ {
+ if (cs_avail_out == 0) {
+ c_state_out_len = 1; goto return_notr;
+ };
+ *( (UChar*)(cs_next_out) ) = c_state_out_ch;
+ cs_next_out++;
+ cs_avail_out--;
+ }
+ }
+ /* can a new run be started? */
+ if (c_nblock_used == s_save_nblockPP) {
+ c_state_out_len = 0; goto return_notr;
+ };
+ c_state_out_ch = c_k0;
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ if (k1 != c_k0) {
+ c_k0 = k1; goto s_state_out_len_eq_one;
+ };
+ if (c_nblock_used == s_save_nblockPP)
+ goto s_state_out_len_eq_one;
+
+ c_state_out_len = 2;
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ if (c_nblock_used == s_save_nblockPP) continue;
+ if (k1 != c_k0) { c_k0 = k1; continue; };
+
+ c_state_out_len = 3;
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ if (c_nblock_used == s_save_nblockPP) continue;
+ if (k1 != c_k0) { c_k0 = k1; continue; };
+
+ BZ_GET_FAST_C(k1); c_nblock_used++;
+ c_state_out_len = ((Int32)k1) + 4;
+ BZ_GET_FAST_C(c_k0); c_nblock_used++;
+ }
+
+ return_notr:
+ s->state_out_ch = c_state_out_ch;
+ s->state_out_len = c_state_out_len;
+ s->nblock_used = c_nblock_used;
+ s->k0 = c_k0;
+ s->tPos = c_tPos;
+ s->next_out = cs_next_out;
+ s->avail_out = cs_avail_out;
+ /* end save */
+}
+
+#endif
+
+
+/*---------------------------------------------------*/
+int NSISCALL BZ2_bzDecompress( DState *s )
+{
+ while (True) {
+ if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
+ if (s->state == BZ_X_OUTPUT) {
+#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
+ unRLE_obuf_to_output_SMALL ( s );
+#else
+ unRLE_obuf_to_output_FAST ( s );
+#endif
+ if (s->nblock_used == s->save.nblock+1 && s->state_out_len == 0) {
+ s->state = BZ_X_BLKHDR_1;
+ } else {
+ return BZ_OK;
+ }
+ }
+ if (s->state >= BZ_X_BLKHDR_1) {
+ Int32 r = BZ2_decompress ( s );
+ if (r == BZ_STREAM_END) {
+ return r;
+ }
+ if (s->state != BZ_X_OUTPUT) return r;
+ }
+ }
+}
+
+
+
+#endif
diff --git a/Source/bzip2/bzlib.h b/Source/bzip2/bzlib.h
index 2554364..c5a5c37 100755
--- a/Source/bzip2/bzlib.h
+++ b/Source/bzip2/bzlib.h
@@ -1,444 +1,444 @@
-/*
- * This file is a part of the bzip2 compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.bzip.org/
- *
- * This modification is not compatible with the original bzip2.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-/*-------------------------------------------------------------*/
-/*--- Public header file for the library. ---*/
-/*--- bzlib.h ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@acm.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-
-#ifndef _BZLIB_H
-#define _BZLIB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "../exehead/config.h"
-#include "../Platform.h"
-
-#define BZ_RUN 0
-#define BZ_FLUSH 1
-#define BZ_FINISH 2
-
-#define BZ_OK 0
-#define BZ_RUN_OK 1
-#define BZ_FLUSH_OK 2
-#define BZ_FINISH_OK 3
-#define BZ_STREAM_END 4
-#define BZ_SEQUENCE_ERROR (-1)
-#define BZ_PARAM_ERROR (-2)
-#define BZ_MEM_ERROR (-3)
-#define BZ_DATA_ERROR (-4)
-#define BZ_DATA_ERROR_MAGIC (-5)
-#define BZ_IO_ERROR (-6)
-#define BZ_UNEXPECTED_EOF (-7)
-#define BZ_OUTBUFF_FULL (-8)
-#define BZ_CONFIG_ERROR (-9)
-
-/*-- Constants for the back end. --*/
-
-#define BZ_MAX_ALPHA_SIZE 258
-#define BZ_MAX_CODE_LEN 23
-
-#define BZ_RUNA 0
-#define BZ_RUNB 1
-
-#define BZ_N_GROUPS 6
-#define BZ_G_SIZE 50
-#define BZ_N_ITERS 4
-
-#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
-
-typedef char Char;
-typedef unsigned char Bool;
-typedef unsigned char UChar;
-typedef int Int32;
-typedef unsigned int UInt32;
-typedef short Int16;
-typedef unsigned short UInt16;
-
-#define True ((Bool)1)
-#define False ((Bool)0)
-
-#define AssertD(cond,msg) /* */
-#define AssertH(cond,errcode) /* */
-#define AssertD(cond,msg) /* */
-#define VPrintf0(zf) /* */
-#define VPrintf1(zf,za1) /* */
-#define VPrintf2(zf,za1,za2) /* */
-#define VPrintf3(zf,za1,za2,za3) /* */
-#define VPrintf4(zf,za1,za2,za3,za4) /* */
-#define VPrintf5(zf,za1,za2,za3,za4,za5) /* */
-
-#ifndef EXEHEAD
-
-#define BZALLOC(items) malloc(items)
-#define BZFREE(addr) { if (addr) free(addr); }
-#define mini_memcpy memcpy
-
-typedef struct {
- char *next_in;
- unsigned int avail_in;
-
- char *next_out;
- unsigned int avail_out;
-
- void *state;
-} bz_stream;
-
-/*-- Core (low-level) library functions --*/
-
-extern int BZ2_bzCompressInit(
- bz_stream* strm,
- int blockSize100k,
- int verbosity,
- int workFactor
- );
-
-extern int BZ2_bzCompress( bz_stream* strm, int action );
-extern int BZ2_bzCompressEnd(bz_stream* strm );
-
-/*-- States and modes for compression. --*/
-
-#define BZ_M_IDLE 1
-#define BZ_M_RUNNING 2
-#define BZ_M_FLUSHING 3
-#define BZ_M_FINISHING 4
-
-#define BZ_S_OUTPUT 1
-#define BZ_S_INPUT 2
-
-#define BZ_N_RADIX 2
-#define BZ_N_QSORT 12
-#define BZ_N_SHELL 18
-#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
-
-/*-- Structure holding all the compression-side stuff. --*/
-
-typedef struct {
- /* pointer back to the struct bz_stream */
- bz_stream *strm;
-
- /* mode this stream is in, and whether inputting */
- /* or outputting data */
- Int32 mode;
- Int32 state;
-
- /* remembers avail_in when flush/finish requested */
- UInt32 avail_in_expect;
-
- /* for doing the block sorting */
- UInt32* arr1;
- UInt32* arr2;
- UInt32* ftab;
- Int32 origPtr;
-
- /* aliases for arr1 and arr2 */
- UInt32* ptr;
- UChar* block;
- UInt16* mtfv;
- UChar* zbits;
-
- /* for deciding when to use the fallback sorting algorithm */
- Int32 workFactor;
-
- /* run-length-encoding of the input */
- UInt32 state_in_ch;
- Int32 state_in_len;
-
- /* input and output limits and current posns */
- Int32 nblock;
- Int32 nblockMAX;
- Int32 numZ;
- Int32 state_out_pos;
-
- /* map of bytes used in block */
- Int32 nInUse;
- Bool inUse[256];
- UChar unseqToSeq[256];
-
- /* the buffer for bit stream creation */
- UInt32 bsBuff;
- Int32 bsLive;
-
- /* misc administratium */
- Int32 blockNo;
-
- /* stuff for coding the MTF values */
- Int32 nMTF;
- Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
- UChar selector [BZ_MAX_SELECTORS];
- UChar selectorMtf[BZ_MAX_SELECTORS];
-
- UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- /* second dimension: only 3 needed; 4 makes index calculations faster */
- UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
-
-} EState;
-
-
-
-/*-- externs for compression. --*/
-
-extern void BZ2_blockSort ( EState* );
-extern void BZ2_compressBlock ( EState*, Bool );
-extern void BZ2_bsInitWrite ( EState* );
-extern void BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
-extern void BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
-
-#else//EXEHEAD
-
-/*-- states for decompression. --*/
-
-#define BZ_X_IDLE 1
-#define BZ_X_OUTPUT 2
-
-#define BZ_X_BLKHDR_1 11
-#define BZ_X_RANDBIT 12
-#define BZ_X_ORIGPTR_1 13
-#define BZ_X_ORIGPTR_2 14
-#define BZ_X_ORIGPTR_3 15
-#define BZ_X_MAPPING_1 16
-#define BZ_X_MAPPING_2 17
-#define BZ_X_SELECTOR_1 18
-#define BZ_X_SELECTOR_2 19
-#define BZ_X_SELECTOR_3 20
-#define BZ_X_CODING_1 21
-#define BZ_X_CODING_2 22
-#define BZ_X_CODING_3 23
-#define BZ_X_MTF_1 24
-#define BZ_X_MTF_2 25
-#define BZ_X_MTF_3 26
-#define BZ_X_MTF_4 27
-#define BZ_X_MTF_5 28
-#define BZ_X_MTF_6 29
-
-
-
-/*-- Constants for the fast MTF decoder. --*/
-
-#define MTFA_SIZE 4096
-#define MTFL_SIZE 16
-
-
-
-/* save area for scalars in the main decompress code */
-typedef struct {
- Int32 i;
- Int32 j;
- Int32 t;
- Int32 alphaSize;
- Int32 nGroups;
- Int32 nSelectors;
- Int32 EOB;
- Int32 groupNo;
- Int32 groupPos;
- Int32 nextSym;
- Int32 nblockMAX;
- Int32 nblock;
- Int32 es;
- Int32 N;
- Int32 curr;
- Int32 zt;
- Int32 zn;
- Int32 zvec;
- Int32 zj;
- Int32 gSel;
- Int32 gMinlen;
- Int32* gLimit;
- Int32* gBase;
- Int32* gPerm;
-} DState_save;
-
-/*-- Structure holding all the decompression-side stuff. --*/
-
-typedef struct {
- /* pointer back to the struct bz_stream */
- char *next_in;
- unsigned int avail_in;
-
- char *next_out;
- unsigned int avail_out;
-
- /* state indicator for this stream */
- char state;
-
- UChar state_out_ch;
- Int32 state_out_len;
- Int32 nblock_used;
- Int32 k0;
- UInt32 tPos;
-
- /* the buffer for bit stream reading */
- UInt32 bsBuff;
- Int32 bsLive;
-
- /* for undoing the Burrows-Wheeler transform */
- Int32 origPtr;
- Int32 unzftab[256];
- Int32 cftab[257];
- Int32 cftabCopy[257];
-
-#ifndef NSIS_COMPRESS_BZIP2_SMALLMODE
- /* for undoing the Burrows-Wheeler transform (FAST) */
- UInt32 tt[ NSIS_COMPRESS_BZIP2_LEVEL * 100000 ];
-#else
- /* for undoing the Burrows-Wheeler transform (SMALL) */
- UInt16 ll16 [ NSIS_COMPRESS_BZIP2_LEVEL*100000 ];
- UChar ll4 [((1 + NSIS_COMPRESS_BZIP2_LEVEL*100000) >> 1) ];
-#endif
-
- /* map of bytes used in block */
- Int32 nInUse;
- Bool inUse[256];
- Bool inUse16[16];
- UChar seqToUnseq[256];
-
- /* for decoding the MTF values */
- UChar mtfa [MTFA_SIZE];
- Int32 mtfbase[256 / MTFL_SIZE];
- UChar selector [BZ_MAX_SELECTORS];
- UChar selectorMtf[BZ_MAX_SELECTORS];
- UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
-
- Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 minLens[BZ_N_GROUPS];
-
- /* save area for scalars in the main decompress code */
- DState_save save;
-} DState;
-
-
-#ifndef NSIS_COMPRESS_BZIP2_SMALLMODE
-/*-- Macros for decompression. --*/
-
-#define BZ_GET_FAST(cccc) \
- s->tPos = s->tt[s->tPos]; \
- cccc = (UChar)(s->tPos & 0xff); \
- s->tPos >>= 8;
-
-#define BZ_GET_FAST_C(cccc) \
- c_tPos = c_tt[c_tPos]; \
- cccc = (UChar)(c_tPos & 0xff); \
- c_tPos >>= 8;
-
-
-#else//NSIS_COMPRESS_BZIP2_SMALLMODE
-
-#define SET_LL4(i,n) \
- { if (((i) & 0x1) == 0) \
- s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
- s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
- }
-
-#define GET_LL4(i) \
- ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
-
-#define SET_LL(i,n) \
- { s->ll16[i] = (UInt16)(n & 0x0000ffff); \
- SET_LL4(i, n >> 16); \
- }
-
-#define GET_LL(i) \
- (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
-
-#define BZ_GET_SMALL(cccc) \
- cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
- s->tPos = GET_LL(s->tPos);
-
-extern Int32 BZ2_indexIntoF( Int32, Int32* );
-
-#endif//smallmode
-
-/*-- externs for decompression. --*/
-extern Int32 NSISCALL BZ2_decompress ( DState* );
-
-extern void NSISCALL BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
- Int32, Int32, Int32 );
-
-
-#define BZ2_bzDecompressInit(s) { (s)->state = BZ_X_BLKHDR_1; (s)->bsLive = 0; }
-int NSISCALL BZ2_bzDecompress(DState *s);
-
-#endif//EXEHEAD
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/*-------------------------------------------------------------*/
-/*--- end bzlib.h ---*/
-/*-------------------------------------------------------------*/
+/*
+ * This file is a part of the bzip2 compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.bzip.org/
+ *
+ * This modification is not compatible with the original bzip2.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library. ---*/
+/*--- bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+ This file is a part of bzip2 and/or libbzip2, a program and
+ library for lossless, block-sorting data compression.
+
+ Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+ 3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+ 4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Julian Seward, Cambridge, UK.
+ jseward@acm.org
+ bzip2/libbzip2 version 1.0 of 21 March 2000
+
+ This program is based on (at least) the work of:
+ Mike Burrows
+ David Wheeler
+ Peter Fenwick
+ Alistair Moffat
+ Radford Neal
+ Ian H. Witten
+ Robert Sedgewick
+ Jon L. Bentley
+
+ For more information on these sources, see the manual.
+--*/
+
+
+#ifndef _BZLIB_H
+#define _BZLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../exehead/config.h"
+#include "../Platform.h"
+
+#define BZ_RUN 0
+#define BZ_FLUSH 1
+#define BZ_FINISH 2
+
+#define BZ_OK 0
+#define BZ_RUN_OK 1
+#define BZ_FLUSH_OK 2
+#define BZ_FINISH_OK 3
+#define BZ_STREAM_END 4
+#define BZ_SEQUENCE_ERROR (-1)
+#define BZ_PARAM_ERROR (-2)
+#define BZ_MEM_ERROR (-3)
+#define BZ_DATA_ERROR (-4)
+#define BZ_DATA_ERROR_MAGIC (-5)
+#define BZ_IO_ERROR (-6)
+#define BZ_UNEXPECTED_EOF (-7)
+#define BZ_OUTBUFF_FULL (-8)
+#define BZ_CONFIG_ERROR (-9)
+
+/*-- Constants for the back end. --*/
+
+#define BZ_MAX_ALPHA_SIZE 258
+#define BZ_MAX_CODE_LEN 23
+
+#define BZ_RUNA 0
+#define BZ_RUNB 1
+
+#define BZ_N_GROUPS 6
+#define BZ_G_SIZE 50
+#define BZ_N_ITERS 4
+
+#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
+
+typedef char Char;
+typedef unsigned char Bool;
+typedef unsigned char UChar;
+typedef int Int32;
+typedef unsigned int UInt32;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#define True ((Bool)1)
+#define False ((Bool)0)
+
+#define AssertD(cond,msg) /* */
+#define AssertH(cond,errcode) /* */
+#define AssertD(cond,msg) /* */
+#define VPrintf0(zf) /* */
+#define VPrintf1(zf,za1) /* */
+#define VPrintf2(zf,za1,za2) /* */
+#define VPrintf3(zf,za1,za2,za3) /* */
+#define VPrintf4(zf,za1,za2,za3,za4) /* */
+#define VPrintf5(zf,za1,za2,za3,za4,za5) /* */
+
+#ifndef EXEHEAD
+
+#define BZALLOC(items) malloc(items)
+#define BZFREE(addr) { if (addr) free(addr); }
+#define mini_memcpy memcpy
+
+typedef struct {
+ char *next_in;
+ unsigned int avail_in;
+
+ char *next_out;
+ unsigned int avail_out;
+
+ void *state;
+} bz_stream;
+
+/*-- Core (low-level) library functions --*/
+
+extern int BZ2_bzCompressInit(
+ bz_stream* strm,
+ int blockSize100k,
+ int verbosity,
+ int workFactor
+ );
+
+extern int BZ2_bzCompress( bz_stream* strm, int action );
+extern int BZ2_bzCompressEnd(bz_stream* strm );
+
+/*-- States and modes for compression. --*/
+
+#define BZ_M_IDLE 1
+#define BZ_M_RUNNING 2
+#define BZ_M_FLUSHING 3
+#define BZ_M_FINISHING 4
+
+#define BZ_S_OUTPUT 1
+#define BZ_S_INPUT 2
+
+#define BZ_N_RADIX 2
+#define BZ_N_QSORT 12
+#define BZ_N_SHELL 18
+#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
+
+/*-- Structure holding all the compression-side stuff. --*/
+
+typedef struct {
+ /* pointer back to the struct bz_stream */
+ bz_stream *strm;
+
+ /* mode this stream is in, and whether inputting */
+ /* or outputting data */
+ Int32 mode;
+ Int32 state;
+
+ /* remembers avail_in when flush/finish requested */
+ UInt32 avail_in_expect;
+
+ /* for doing the block sorting */
+ UInt32* arr1;
+ UInt32* arr2;
+ UInt32* ftab;
+ Int32 origPtr;
+
+ /* aliases for arr1 and arr2 */
+ UInt32* ptr;
+ UChar* block;
+ UInt16* mtfv;
+ UChar* zbits;
+
+ /* for deciding when to use the fallback sorting algorithm */
+ Int32 workFactor;
+
+ /* run-length-encoding of the input */
+ UInt32 state_in_ch;
+ Int32 state_in_len;
+
+ /* input and output limits and current posns */
+ Int32 nblock;
+ Int32 nblockMAX;
+ Int32 numZ;
+ Int32 state_out_pos;
+
+ /* map of bytes used in block */
+ Int32 nInUse;
+ Bool inUse[256];
+ UChar unseqToSeq[256];
+
+ /* the buffer for bit stream creation */
+ UInt32 bsBuff;
+ Int32 bsLive;
+
+ /* misc administratium */
+ Int32 blockNo;
+
+ /* stuff for coding the MTF values */
+ Int32 nMTF;
+ Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
+ UChar selector [BZ_MAX_SELECTORS];
+ UChar selectorMtf[BZ_MAX_SELECTORS];
+
+ UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ /* second dimension: only 3 needed; 4 makes index calculations faster */
+ UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
+
+} EState;
+
+
+
+/*-- externs for compression. --*/
+
+extern void BZ2_blockSort ( EState* );
+extern void BZ2_compressBlock ( EState*, Bool );
+extern void BZ2_bsInitWrite ( EState* );
+extern void BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
+extern void BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
+
+#else//EXEHEAD
+
+/*-- states for decompression. --*/
+
+#define BZ_X_IDLE 1
+#define BZ_X_OUTPUT 2
+
+#define BZ_X_BLKHDR_1 11
+#define BZ_X_RANDBIT 12
+#define BZ_X_ORIGPTR_1 13
+#define BZ_X_ORIGPTR_2 14
+#define BZ_X_ORIGPTR_3 15
+#define BZ_X_MAPPING_1 16
+#define BZ_X_MAPPING_2 17
+#define BZ_X_SELECTOR_1 18
+#define BZ_X_SELECTOR_2 19
+#define BZ_X_SELECTOR_3 20
+#define BZ_X_CODING_1 21
+#define BZ_X_CODING_2 22
+#define BZ_X_CODING_3 23
+#define BZ_X_MTF_1 24
+#define BZ_X_MTF_2 25
+#define BZ_X_MTF_3 26
+#define BZ_X_MTF_4 27
+#define BZ_X_MTF_5 28
+#define BZ_X_MTF_6 29
+
+
+
+/*-- Constants for the fast MTF decoder. --*/
+
+#define MTFA_SIZE 4096
+#define MTFL_SIZE 16
+
+
+
+/* save area for scalars in the main decompress code */
+typedef struct {
+ Int32 i;
+ Int32 j;
+ Int32 t;
+ Int32 alphaSize;
+ Int32 nGroups;
+ Int32 nSelectors;
+ Int32 EOB;
+ Int32 groupNo;
+ Int32 groupPos;
+ Int32 nextSym;
+ Int32 nblockMAX;
+ Int32 nblock;
+ Int32 es;
+ Int32 N;
+ Int32 curr;
+ Int32 zt;
+ Int32 zn;
+ Int32 zvec;
+ Int32 zj;
+ Int32 gSel;
+ Int32 gMinlen;
+ Int32* gLimit;
+ Int32* gBase;
+ Int32* gPerm;
+} DState_save;
+
+/*-- Structure holding all the decompression-side stuff. --*/
+
+typedef struct {
+ /* pointer back to the struct bz_stream */
+ char *next_in;
+ unsigned int avail_in;
+
+ char *next_out;
+ unsigned int avail_out;
+
+ /* state indicator for this stream */
+ char state;
+
+ UChar state_out_ch;
+ Int32 state_out_len;
+ Int32 nblock_used;
+ Int32 k0;
+ UInt32 tPos;
+
+ /* the buffer for bit stream reading */
+ UInt32 bsBuff;
+ Int32 bsLive;
+
+ /* for undoing the Burrows-Wheeler transform */
+ Int32 origPtr;
+ Int32 unzftab[256];
+ Int32 cftab[257];
+ Int32 cftabCopy[257];
+
+#ifndef NSIS_COMPRESS_BZIP2_SMALLMODE
+ /* for undoing the Burrows-Wheeler transform (FAST) */
+ UInt32 tt[ NSIS_COMPRESS_BZIP2_LEVEL * 100000 ];
+#else
+ /* for undoing the Burrows-Wheeler transform (SMALL) */
+ UInt16 ll16 [ NSIS_COMPRESS_BZIP2_LEVEL*100000 ];
+ UChar ll4 [((1 + NSIS_COMPRESS_BZIP2_LEVEL*100000) >> 1) ];
+#endif
+
+ /* map of bytes used in block */
+ Int32 nInUse;
+ Bool inUse[256];
+ Bool inUse16[16];
+ UChar seqToUnseq[256];
+
+ /* for decoding the MTF values */
+ UChar mtfa [MTFA_SIZE];
+ Int32 mtfbase[256 / MTFL_SIZE];
+ UChar selector [BZ_MAX_SELECTORS];
+ UChar selectorMtf[BZ_MAX_SELECTORS];
+ UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+
+ Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 minLens[BZ_N_GROUPS];
+
+ /* save area for scalars in the main decompress code */
+ DState_save save;
+} DState;
+
+
+#ifndef NSIS_COMPRESS_BZIP2_SMALLMODE
+/*-- Macros for decompression. --*/
+
+#define BZ_GET_FAST(cccc) \
+ s->tPos = s->tt[s->tPos]; \
+ cccc = (UChar)(s->tPos & 0xff); \
+ s->tPos >>= 8;
+
+#define BZ_GET_FAST_C(cccc) \
+ c_tPos = c_tt[c_tPos]; \
+ cccc = (UChar)(c_tPos & 0xff); \
+ c_tPos >>= 8;
+
+
+#else//NSIS_COMPRESS_BZIP2_SMALLMODE
+
+#define SET_LL4(i,n) \
+ { if (((i) & 0x1) == 0) \
+ s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
+ s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
+ }
+
+#define GET_LL4(i) \
+ ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
+
+#define SET_LL(i,n) \
+ { s->ll16[i] = (UInt16)(n & 0x0000ffff); \
+ SET_LL4(i, n >> 16); \
+ }
+
+#define GET_LL(i) \
+ (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
+
+#define BZ_GET_SMALL(cccc) \
+ cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
+ s->tPos = GET_LL(s->tPos);
+
+extern Int32 BZ2_indexIntoF( Int32, Int32* );
+
+#endif//smallmode
+
+/*-- externs for decompression. --*/
+extern Int32 NSISCALL BZ2_decompress ( DState* );
+
+extern void NSISCALL BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
+ Int32, Int32, Int32 );
+
+
+#define BZ2_bzDecompressInit(s) { (s)->state = BZ_X_BLKHDR_1; (s)->bsLive = 0; }
+int NSISCALL BZ2_bzDecompress(DState *s);
+
+#endif//EXEHEAD
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end bzlib.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/Source/bzip2/compress.c b/Source/bzip2/compress.c
index 67485f4..6263c5f 100755
--- a/Source/bzip2/compress.c
+++ b/Source/bzip2/compress.c
@@ -1,669 +1,669 @@
-/*
- * This file is a part of the bzip2 compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.bzip.org/
- *
- * This modification is not compatible with the original bzip2.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-/*-------------------------------------------------------------*/
-/*--- Compression machinery (not incl block sorting) ---*/
-/*--- compress.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@acm.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-/*--
- CHANGES
- ~~~~~~~
- 0.9.0 -- original version.
-
- 0.9.0a/b -- no changes in this file.
-
- 0.9.0c
- * changed setting of nGroups in sendMTFValues() so as to
- do a bit better on small files
---*/
-
-#include "bzlib.h"
-
-
-/*---------------------------------------------------*/
-/*--- Bit stream I/O ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-void BZ2_bsInitWrite ( EState* s )
-{
- s->bsLive = 0;
- s->bsBuff = 0;
-}
-
-
-/*---------------------------------------------------*/
-static
-void bsFinishWrite ( EState* s )
-{
- while (s->bsLive > 0) {
- s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
- s->numZ++;
- s->bsBuff <<= 8;
- s->bsLive -= 8;
- }
-}
-
-
-/*---------------------------------------------------*/
-#define bsNEEDW(nz) \
-{ \
- while (s->bsLive >= 8) { \
- s->zbits[s->numZ] \
- = (UChar)(s->bsBuff >> 24); \
- s->numZ++; \
- s->bsBuff <<= 8; \
- s->bsLive -= 8; \
- } \
-}
-
-
-/*---------------------------------------------------*/
-static void bsW ( EState* s, Int32 n, UInt32 v )
-{
- bsNEEDW ( n );
- s->bsBuff |= (v << (32 - s->bsLive - n));
- s->bsLive += n;
-}
-
-
-/*---------------------------------------------------*/
-/*static
-void bsPutUInt32 ( EState* s, UInt32 u )
-{
- bsW ( s, 8, (u >> 24) & 0xffL );
- bsW ( s, 8, (u >> 16) & 0xffL );
- bsW ( s, 8, (u >> 8) & 0xffL );
- bsW ( s, 8, u & 0xffL );
-}*/
-
-
-/*---------------------------------------------------*/
-static
-void bsPutUChar ( EState* s, UChar c )
-{
- bsW( s, 8, (UInt32)c );
-}
-
-
-/*---------------------------------------------------*/
-/*--- The back end proper ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-static
-void makeMaps_e ( EState* s )
-{
- Int32 i;
- s->nInUse = 0;
- for (i = 0; i < 256; i++)
- if (s->inUse[i]) {
- s->unseqToSeq[i] = s->nInUse;
- s->nInUse++;
- }
-}
-
-
-/*---------------------------------------------------*/
-static
-void generateMTFValues ( EState* s )
-{
- UChar yy[256];
- Int32 i, j;
- Int32 zPend;
- Int32 wr;
- Int32 EOB;
-
- /*
- After sorting (eg, here),
- s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
- and
- ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
- holds the original block data.
-
- The first thing to do is generate the MTF values,
- and put them in
- ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
- Because there are strictly fewer or equal MTF values
- than block values, ptr values in this area are overwritten
- with MTF values only when they are no longer needed.
-
- The final compressed bitstream is generated into the
- area starting at
- (UChar*) (&((UChar*)s->arr2)[s->nblock])
-
- These storage aliases are set up in bzCompressInit(),
- except for the last one, which is arranged in
- compressBlock().
- */
- UInt32* ptr = s->ptr;
- UChar* block = s->block;
- UInt16* mtfv = s->mtfv;
-
- makeMaps_e ( s );
- EOB = s->nInUse+1;
-
- for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
-
- wr = 0;
- zPend = 0;
- for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
-
- for (i = 0; i < s->nblock; i++) {
- UChar ll_i;
- AssertD ( wr <= i, "generateMTFValues(1)" );
- j = ptr[i]-1; if (j < 0) j += s->nblock;
- ll_i = s->unseqToSeq[block[j]];
- AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
-
- if (yy[0] == ll_i) {
- zPend++;
- } else {
-
- if (zPend > 0) {
- zPend--;
- while (True) {
- if (zPend & 1) {
- mtfv[wr] = BZ_RUNB; wr++;
- s->mtfFreq[BZ_RUNB]++;
- } else {
- mtfv[wr] = BZ_RUNA; wr++;
- s->mtfFreq[BZ_RUNA]++;
- }
- if (zPend < 2) break;
- zPend = (zPend - 2) / 2;
- };
- zPend = 0;
- }
- {
- register UChar rtmp;
- register UChar* ryy_j;
- register UChar rll_i;
- rtmp = yy[1];
- yy[1] = yy[0];
- ryy_j = &(yy[1]);
- rll_i = ll_i;
- while ( rll_i != rtmp ) {
- register UChar rtmp2;
- ryy_j++;
- rtmp2 = rtmp;
- rtmp = *ryy_j;
- *ryy_j = rtmp2;
- };
- yy[0] = rtmp;
- j = ryy_j - &(yy[0]);
- mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
- }
-
- }
- }
-
- if (zPend > 0) {
- zPend--;
- while (True) {
- if (zPend & 1) {
- mtfv[wr] = BZ_RUNB; wr++;
- s->mtfFreq[BZ_RUNB]++;
- } else {
- mtfv[wr] = BZ_RUNA; wr++;
- s->mtfFreq[BZ_RUNA]++;
- }
- if (zPend < 2) break;
- zPend = (zPend - 2) / 2;
- };
- zPend = 0;
- }
-
- mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
-
- s->nMTF = wr;
-}
-
-
-/*---------------------------------------------------*/
-#define BZ_LESSER_ICOST 0
-#define BZ_GREATER_ICOST 15
-
-static
-void sendMTFValues ( EState* s )
-{
- Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
- Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
- Int32 nGroups, nBytes;
-
- /*--
- UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- is a global since the decoder also needs it.
-
- Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
- are also globals only used in this proc.
- Made global to keep stack frame size small.
- --*/
-
-
- UInt16 cost[BZ_N_GROUPS];
- Int32 fave[BZ_N_GROUPS];
-
- UInt16* mtfv = s->mtfv;
-
-
- alphaSize = s->nInUse+2;
- for (t = 0; t < BZ_N_GROUPS; t++)
- for (v = 0; v < alphaSize; v++)
- s->len[t][v] = BZ_GREATER_ICOST;
-
- /*--- Decide how many coding tables to use ---*/
- AssertH ( s->nMTF > 0, 3001 );
- if (s->nMTF < 200) nGroups = 2; else
- if (s->nMTF < 600) nGroups = 3; else
- if (s->nMTF < 1200) nGroups = 4; else
- if (s->nMTF < 2400) nGroups = 5; else
- nGroups = 6;
-
- /*--- Generate an initial set of coding tables ---*/
- {
- Int32 nPart, remF, tFreq, aFreq;
-
- nPart = nGroups;
- remF = s->nMTF;
- gs = 0;
- while (nPart > 0) {
- tFreq = remF / nPart;
- ge = gs-1;
- aFreq = 0;
- while (aFreq < tFreq && ge < alphaSize-1) {
- ge++;
- aFreq += s->mtfFreq[ge];
- }
-
- if (ge > gs
- && nPart != nGroups && nPart != 1
- && ((nGroups-nPart) % 2 == 1)) {
- aFreq -= s->mtfFreq[ge];
- ge--;
- }
-
- for (v = 0; v < alphaSize; v++)
- if (v >= gs && v <= ge)
- s->len[nPart-1][v] = BZ_LESSER_ICOST; else
- s->len[nPart-1][v] = BZ_GREATER_ICOST;
-
- nPart--;
- gs = ge+1;
- remF -= aFreq;
- }
- }
-
- /*---
- Iterate up to BZ_N_ITERS times to improve the tables.
- ---*/
- for (iter = 0; iter < BZ_N_ITERS; iter++) {
-
- for (t = 0; t < nGroups; t++) fave[t] = 0;
-
- for (t = 0; t < nGroups; t++)
- for (v = 0; v < alphaSize; v++)
- s->rfreq[t][v] = 0;
-
- /*---
- Set up an auxiliary length table which is used to fast-track
- the common case (nGroups == 6).
- ---*/
- if (nGroups == 6) {
- for (v = 0; v < alphaSize; v++) {
- s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
- s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
- s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
- }
- }
-
- nSelectors = 0;
- totc = 0;
- gs = 0;
- while (True) {
-
- /*--- Set group start & end marks. --*/
- if (gs >= s->nMTF) break;
- ge = gs + BZ_G_SIZE - 1;
- if (ge >= s->nMTF) ge = s->nMTF-1;
-
- /*--
- Calculate the cost of this group as coded
- by each of the coding tables.
- --*/
- for (t = 0; t < nGroups; t++) cost[t] = 0;
-
- if (nGroups == 6 && 50 == ge-gs+1) {
- /*--- fast track the common case ---*/
- register UInt32 cost01, cost23, cost45;
- register UInt16 icv;
- cost01 = cost23 = cost45 = 0;
-
-# define BZ_ITER(nn) \
- icv = mtfv[gs+(nn)]; \
- cost01 += s->len_pack[icv][0]; \
- cost23 += s->len_pack[icv][1]; \
- cost45 += s->len_pack[icv][2]; \
-
- BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
- BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
- BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
- BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
- BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
- BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
- BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
- BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
- BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
- BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
-
-# undef BZ_ITER
-
- cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
- cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
- cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
-
- } else {
- /*--- slow version which correctly handles all situations ---*/
- for (i = gs; i <= ge; i++) {
- UInt16 icv = mtfv[i];
- for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
- }
- }
-
- /*--
- Find the coding table which is best for this group,
- and record its identity in the selector table.
- --*/
- bc = 999999999; bt = -1;
- for (t = 0; t < nGroups; t++)
- if (cost[t] < bc) { bc = cost[t]; bt = t; };
- totc += bc;
- fave[bt]++;
- s->selector[nSelectors] = bt;
- nSelectors++;
-
- /*--
- Increment the symbol frequencies for the selected table.
- --*/
- if (nGroups == 6 && 50 == ge-gs+1) {
- /*--- fast track the common case ---*/
-
-# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
-
- BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
- BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
- BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
- BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
- BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
- BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
- BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
- BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
- BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
- BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
-
-# undef BZ_ITUR
-
- } else {
- /*--- slow version which correctly handles all situations ---*/
- for (i = gs; i <= ge; i++)
- s->rfreq[bt][ mtfv[i] ]++;
- }
-
- gs = ge+1;
- }
-
- /*--
- Recompute the tables based on the accumulated frequencies.
- --*/
- for (t = 0; t < nGroups; t++)
- BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
- alphaSize, 20 );
- }
-
-
- AssertH( nGroups < 8, 3002 );
- AssertH( nSelectors < 32768 &&
- nSelectors <= (2 + (NSIS_COMPRESS_BZIP2_LEVEL * 100000 / BZ_G_SIZE)),
- 3003 );
-
-
- /*--- Compute MTF values for the selectors. ---*/
- {
- UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
- for (i = 0; i < nGroups; i++) pos[i] = i;
- for (i = 0; i < nSelectors; i++) {
- ll_i = s->selector[i];
- j = 0;
- tmp = pos[j];
- while ( ll_i != tmp ) {
- j++;
- tmp2 = tmp;
- tmp = pos[j];
- pos[j] = tmp2;
- };
- pos[0] = tmp;
- s->selectorMtf[i] = j;
- }
- };
-
- /*--- Assign actual codes for the tables. --*/
- for (t = 0; t < nGroups; t++) {
- minLen = 32;
- maxLen = 0;
- for (i = 0; i < alphaSize; i++) {
- if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
- if (s->len[t][i] < minLen) minLen = s->len[t][i];
- }
- AssertH ( !(maxLen > 20), 3004 );
- AssertH ( !(minLen < 1), 3005 );
- BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
- minLen, maxLen, alphaSize );
- }
-
- /*--- Transmit the mapping table. ---*/
- {
- Bool inUse16[16];
- for (i = 0; i < 16; i++) {
- inUse16[i] = False;
- for (j = 0; j < 16; j++)
- if (s->inUse[i * 16 + j]) inUse16[i] = True;
- }
-
- nBytes = s->numZ;
- for (i = 0; i < 16; i++)
- if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
-
- for (i = 0; i < 16; i++)
- if (inUse16[i])
- for (j = 0; j < 16; j++) {
- if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
- }
-
- }
-
- /*--- Now the selectors. ---*/
- nBytes = s->numZ;
- bsW ( s, 3, nGroups );
- bsW ( s, 15, nSelectors );
- for (i = 0; i < nSelectors; i++) {
- for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
- bsW(s,1,0);
- }
-
- /*--- Now the coding tables. ---*/
- nBytes = s->numZ;
-
- for (t = 0; t < nGroups; t++) {
- Int32 curr = s->len[t][0];
- bsW ( s, 5, curr );
- for (i = 0; i < alphaSize; i++) {
- while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
- while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
- bsW ( s, 1, 0 );
- }
- }
-
-
- /*--- And finally, the block data proper ---*/
- nBytes = s->numZ;
- selCtr = 0;
- gs = 0;
- while (True) {
- if (gs >= s->nMTF) break;
- ge = gs + BZ_G_SIZE - 1;
- if (ge >= s->nMTF) ge = s->nMTF-1;
- AssertH ( s->selector[selCtr] < nGroups, 3006 );
-
- if (nGroups == 6 && 50 == ge-gs+1) {
- /*--- fast track the common case ---*/
- UInt16 mtfv_i;
- UChar* s_len_sel_selCtr
- = &(s->len[s->selector[selCtr]][0]);
- Int32* s_code_sel_selCtr
- = &(s->code[s->selector[selCtr]][0]);
-
-# define BZ_ITAH(nn) \
- mtfv_i = mtfv[gs+(nn)]; \
- bsW ( s, \
- s_len_sel_selCtr[mtfv_i], \
- s_code_sel_selCtr[mtfv_i] )
-
- BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
- BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
- BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
- BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
- BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
- BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
- BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
- BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
- BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
- BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
-
-# undef BZ_ITAH
-
- } else {
- /*--- slow version which correctly handles all situations ---*/
- for (i = gs; i <= ge; i++) {
- bsW ( s,
- s->len [s->selector[selCtr]] [mtfv[i]],
- s->code [s->selector[selCtr]] [mtfv[i]] );
- }
- }
-
-
- gs = ge+1;
- selCtr++;
- }
- AssertH( selCtr == nSelectors, 3007 );
-
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_compressBlock ( EState* s, Bool is_last_block )
-{
- if (s->nblock > 0) {
-
- if (s->blockNo > 1) s->numZ = 0;
-
-
- BZ2_blockSort ( s );
- }
-
- s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
-
- /*-- If this is the first block, create the stream header. --*/
- if (s->blockNo == 1) {
- BZ2_bsInitWrite ( s );
- }
-
- if (s->nblock > 0) {
-
- bsPutUChar ( s, 0x31 );
-
- bsW ( s, 24, s->origPtr );
- generateMTFValues ( s );
- sendMTFValues ( s );
- }
-
-
- /*-- If this is the last block, add the stream trailer. --*/
- if (is_last_block) {
-
- bsPutUChar ( s, 0x17 );
- bsFinishWrite ( s );
- }
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end compress.c ---*/
-/*-------------------------------------------------------------*/
+/*
+ * This file is a part of the bzip2 compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.bzip.org/
+ *
+ * This modification is not compatible with the original bzip2.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+/*-------------------------------------------------------------*/
+/*--- Compression machinery (not incl block sorting) ---*/
+/*--- compress.c ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+ This file is a part of bzip2 and/or libbzip2, a program and
+ library for lossless, block-sorting data compression.
+
+ Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+ 3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+ 4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Julian Seward, Cambridge, UK.
+ jseward@acm.org
+ bzip2/libbzip2 version 1.0 of 21 March 2000
+
+ This program is based on (at least) the work of:
+ Mike Burrows
+ David Wheeler
+ Peter Fenwick
+ Alistair Moffat
+ Radford Neal
+ Ian H. Witten
+ Robert Sedgewick
+ Jon L. Bentley
+
+ For more information on these sources, see the manual.
+--*/
+
+/*--
+ CHANGES
+ ~~~~~~~
+ 0.9.0 -- original version.
+
+ 0.9.0a/b -- no changes in this file.
+
+ 0.9.0c
+ * changed setting of nGroups in sendMTFValues() so as to
+ do a bit better on small files
+--*/
+
+#include "bzlib.h"
+
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+void BZ2_bsInitWrite ( EState* s )
+{
+ s->bsLive = 0;
+ s->bsBuff = 0;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsFinishWrite ( EState* s )
+{
+ while (s->bsLive > 0) {
+ s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
+ s->numZ++;
+ s->bsBuff <<= 8;
+ s->bsLive -= 8;
+ }
+}
+
+
+/*---------------------------------------------------*/
+#define bsNEEDW(nz) \
+{ \
+ while (s->bsLive >= 8) { \
+ s->zbits[s->numZ] \
+ = (UChar)(s->bsBuff >> 24); \
+ s->numZ++; \
+ s->bsBuff <<= 8; \
+ s->bsLive -= 8; \
+ } \
+}
+
+
+/*---------------------------------------------------*/
+static void bsW ( EState* s, Int32 n, UInt32 v )
+{
+ bsNEEDW ( n );
+ s->bsBuff |= (v << (32 - s->bsLive - n));
+ s->bsLive += n;
+}
+
+
+/*---------------------------------------------------*/
+/*static
+void bsPutUInt32 ( EState* s, UInt32 u )
+{
+ bsW ( s, 8, (u >> 24) & 0xffL );
+ bsW ( s, 8, (u >> 16) & 0xffL );
+ bsW ( s, 8, (u >> 8) & 0xffL );
+ bsW ( s, 8, u & 0xffL );
+}*/
+
+
+/*---------------------------------------------------*/
+static
+void bsPutUChar ( EState* s, UChar c )
+{
+ bsW( s, 8, (UInt32)c );
+}
+
+
+/*---------------------------------------------------*/
+/*--- The back end proper ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void makeMaps_e ( EState* s )
+{
+ Int32 i;
+ s->nInUse = 0;
+ for (i = 0; i < 256; i++)
+ if (s->inUse[i]) {
+ s->unseqToSeq[i] = s->nInUse;
+ s->nInUse++;
+ }
+}
+
+
+/*---------------------------------------------------*/
+static
+void generateMTFValues ( EState* s )
+{
+ UChar yy[256];
+ Int32 i, j;
+ Int32 zPend;
+ Int32 wr;
+ Int32 EOB;
+
+ /*
+ After sorting (eg, here),
+ s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
+ and
+ ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
+ holds the original block data.
+
+ The first thing to do is generate the MTF values,
+ and put them in
+ ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
+ Because there are strictly fewer or equal MTF values
+ than block values, ptr values in this area are overwritten
+ with MTF values only when they are no longer needed.
+
+ The final compressed bitstream is generated into the
+ area starting at
+ (UChar*) (&((UChar*)s->arr2)[s->nblock])
+
+ These storage aliases are set up in bzCompressInit(),
+ except for the last one, which is arranged in
+ compressBlock().
+ */
+ UInt32* ptr = s->ptr;
+ UChar* block = s->block;
+ UInt16* mtfv = s->mtfv;
+
+ makeMaps_e ( s );
+ EOB = s->nInUse+1;
+
+ for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
+
+ wr = 0;
+ zPend = 0;
+ for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
+
+ for (i = 0; i < s->nblock; i++) {
+ UChar ll_i;
+ AssertD ( wr <= i, "generateMTFValues(1)" );
+ j = ptr[i]-1; if (j < 0) j += s->nblock;
+ ll_i = s->unseqToSeq[block[j]];
+ AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
+
+ if (yy[0] == ll_i) {
+ zPend++;
+ } else {
+
+ if (zPend > 0) {
+ zPend--;
+ while (True) {
+ if (zPend & 1) {
+ mtfv[wr] = BZ_RUNB; wr++;
+ s->mtfFreq[BZ_RUNB]++;
+ } else {
+ mtfv[wr] = BZ_RUNA; wr++;
+ s->mtfFreq[BZ_RUNA]++;
+ }
+ if (zPend < 2) break;
+ zPend = (zPend - 2) / 2;
+ };
+ zPend = 0;
+ }
+ {
+ register UChar rtmp;
+ register UChar* ryy_j;
+ register UChar rll_i;
+ rtmp = yy[1];
+ yy[1] = yy[0];
+ ryy_j = &(yy[1]);
+ rll_i = ll_i;
+ while ( rll_i != rtmp ) {
+ register UChar rtmp2;
+ ryy_j++;
+ rtmp2 = rtmp;
+ rtmp = *ryy_j;
+ *ryy_j = rtmp2;
+ };
+ yy[0] = rtmp;
+ j = ryy_j - &(yy[0]);
+ mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
+ }
+
+ }
+ }
+
+ if (zPend > 0) {
+ zPend--;
+ while (True) {
+ if (zPend & 1) {
+ mtfv[wr] = BZ_RUNB; wr++;
+ s->mtfFreq[BZ_RUNB]++;
+ } else {
+ mtfv[wr] = BZ_RUNA; wr++;
+ s->mtfFreq[BZ_RUNA]++;
+ }
+ if (zPend < 2) break;
+ zPend = (zPend - 2) / 2;
+ };
+ zPend = 0;
+ }
+
+ mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
+
+ s->nMTF = wr;
+}
+
+
+/*---------------------------------------------------*/
+#define BZ_LESSER_ICOST 0
+#define BZ_GREATER_ICOST 15
+
+static
+void sendMTFValues ( EState* s )
+{
+ Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
+ Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
+ Int32 nGroups, nBytes;
+
+ /*--
+ UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ is a global since the decoder also needs it.
+
+ Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+ are also globals only used in this proc.
+ Made global to keep stack frame size small.
+ --*/
+
+
+ UInt16 cost[BZ_N_GROUPS];
+ Int32 fave[BZ_N_GROUPS];
+
+ UInt16* mtfv = s->mtfv;
+
+
+ alphaSize = s->nInUse+2;
+ for (t = 0; t < BZ_N_GROUPS; t++)
+ for (v = 0; v < alphaSize; v++)
+ s->len[t][v] = BZ_GREATER_ICOST;
+
+ /*--- Decide how many coding tables to use ---*/
+ AssertH ( s->nMTF > 0, 3001 );
+ if (s->nMTF < 200) nGroups = 2; else
+ if (s->nMTF < 600) nGroups = 3; else
+ if (s->nMTF < 1200) nGroups = 4; else
+ if (s->nMTF < 2400) nGroups = 5; else
+ nGroups = 6;
+
+ /*--- Generate an initial set of coding tables ---*/
+ {
+ Int32 nPart, remF, tFreq, aFreq;
+
+ nPart = nGroups;
+ remF = s->nMTF;
+ gs = 0;
+ while (nPart > 0) {
+ tFreq = remF / nPart;
+ ge = gs-1;
+ aFreq = 0;
+ while (aFreq < tFreq && ge < alphaSize-1) {
+ ge++;
+ aFreq += s->mtfFreq[ge];
+ }
+
+ if (ge > gs
+ && nPart != nGroups && nPart != 1
+ && ((nGroups-nPart) % 2 == 1)) {
+ aFreq -= s->mtfFreq[ge];
+ ge--;
+ }
+
+ for (v = 0; v < alphaSize; v++)
+ if (v >= gs && v <= ge)
+ s->len[nPart-1][v] = BZ_LESSER_ICOST; else
+ s->len[nPart-1][v] = BZ_GREATER_ICOST;
+
+ nPart--;
+ gs = ge+1;
+ remF -= aFreq;
+ }
+ }
+
+ /*---
+ Iterate up to BZ_N_ITERS times to improve the tables.
+ ---*/
+ for (iter = 0; iter < BZ_N_ITERS; iter++) {
+
+ for (t = 0; t < nGroups; t++) fave[t] = 0;
+
+ for (t = 0; t < nGroups; t++)
+ for (v = 0; v < alphaSize; v++)
+ s->rfreq[t][v] = 0;
+
+ /*---
+ Set up an auxiliary length table which is used to fast-track
+ the common case (nGroups == 6).
+ ---*/
+ if (nGroups == 6) {
+ for (v = 0; v < alphaSize; v++) {
+ s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
+ s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
+ s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
+ }
+ }
+
+ nSelectors = 0;
+ totc = 0;
+ gs = 0;
+ while (True) {
+
+ /*--- Set group start & end marks. --*/
+ if (gs >= s->nMTF) break;
+ ge = gs + BZ_G_SIZE - 1;
+ if (ge >= s->nMTF) ge = s->nMTF-1;
+
+ /*--
+ Calculate the cost of this group as coded
+ by each of the coding tables.
+ --*/
+ for (t = 0; t < nGroups; t++) cost[t] = 0;
+
+ if (nGroups == 6 && 50 == ge-gs+1) {
+ /*--- fast track the common case ---*/
+ register UInt32 cost01, cost23, cost45;
+ register UInt16 icv;
+ cost01 = cost23 = cost45 = 0;
+
+# define BZ_ITER(nn) \
+ icv = mtfv[gs+(nn)]; \
+ cost01 += s->len_pack[icv][0]; \
+ cost23 += s->len_pack[icv][1]; \
+ cost45 += s->len_pack[icv][2]; \
+
+ BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
+ BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
+ BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
+ BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
+ BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
+ BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
+ BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
+ BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
+ BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
+ BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
+
+# undef BZ_ITER
+
+ cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
+ cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
+ cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
+
+ } else {
+ /*--- slow version which correctly handles all situations ---*/
+ for (i = gs; i <= ge; i++) {
+ UInt16 icv = mtfv[i];
+ for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
+ }
+ }
+
+ /*--
+ Find the coding table which is best for this group,
+ and record its identity in the selector table.
+ --*/
+ bc = 999999999; bt = -1;
+ for (t = 0; t < nGroups; t++)
+ if (cost[t] < bc) { bc = cost[t]; bt = t; };
+ totc += bc;
+ fave[bt]++;
+ s->selector[nSelectors] = bt;
+ nSelectors++;
+
+ /*--
+ Increment the symbol frequencies for the selected table.
+ --*/
+ if (nGroups == 6 && 50 == ge-gs+1) {
+ /*--- fast track the common case ---*/
+
+# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
+
+ BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
+ BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
+ BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
+ BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
+ BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
+ BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
+ BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
+ BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
+ BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
+ BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
+
+# undef BZ_ITUR
+
+ } else {
+ /*--- slow version which correctly handles all situations ---*/
+ for (i = gs; i <= ge; i++)
+ s->rfreq[bt][ mtfv[i] ]++;
+ }
+
+ gs = ge+1;
+ }
+
+ /*--
+ Recompute the tables based on the accumulated frequencies.
+ --*/
+ for (t = 0; t < nGroups; t++)
+ BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
+ alphaSize, 20 );
+ }
+
+
+ AssertH( nGroups < 8, 3002 );
+ AssertH( nSelectors < 32768 &&
+ nSelectors <= (2 + (NSIS_COMPRESS_BZIP2_LEVEL * 100000 / BZ_G_SIZE)),
+ 3003 );
+
+
+ /*--- Compute MTF values for the selectors. ---*/
+ {
+ UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
+ for (i = 0; i < nGroups; i++) pos[i] = i;
+ for (i = 0; i < nSelectors; i++) {
+ ll_i = s->selector[i];
+ j = 0;
+ tmp = pos[j];
+ while ( ll_i != tmp ) {
+ j++;
+ tmp2 = tmp;
+ tmp = pos[j];
+ pos[j] = tmp2;
+ };
+ pos[0] = tmp;
+ s->selectorMtf[i] = j;
+ }
+ };
+
+ /*--- Assign actual codes for the tables. --*/
+ for (t = 0; t < nGroups; t++) {
+ minLen = 32;
+ maxLen = 0;
+ for (i = 0; i < alphaSize; i++) {
+ if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+ if (s->len[t][i] < minLen) minLen = s->len[t][i];
+ }
+ AssertH ( !(maxLen > 20), 3004 );
+ AssertH ( !(minLen < 1), 3005 );
+ BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
+ minLen, maxLen, alphaSize );
+ }
+
+ /*--- Transmit the mapping table. ---*/
+ {
+ Bool inUse16[16];
+ for (i = 0; i < 16; i++) {
+ inUse16[i] = False;
+ for (j = 0; j < 16; j++)
+ if (s->inUse[i * 16 + j]) inUse16[i] = True;
+ }
+
+ nBytes = s->numZ;
+ for (i = 0; i < 16; i++)
+ if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
+
+ for (i = 0; i < 16; i++)
+ if (inUse16[i])
+ for (j = 0; j < 16; j++) {
+ if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
+ }
+
+ }
+
+ /*--- Now the selectors. ---*/
+ nBytes = s->numZ;
+ bsW ( s, 3, nGroups );
+ bsW ( s, 15, nSelectors );
+ for (i = 0; i < nSelectors; i++) {
+ for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
+ bsW(s,1,0);
+ }
+
+ /*--- Now the coding tables. ---*/
+ nBytes = s->numZ;
+
+ for (t = 0; t < nGroups; t++) {
+ Int32 curr = s->len[t][0];
+ bsW ( s, 5, curr );
+ for (i = 0; i < alphaSize; i++) {
+ while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
+ while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
+ bsW ( s, 1, 0 );
+ }
+ }
+
+
+ /*--- And finally, the block data proper ---*/
+ nBytes = s->numZ;
+ selCtr = 0;
+ gs = 0;
+ while (True) {
+ if (gs >= s->nMTF) break;
+ ge = gs + BZ_G_SIZE - 1;
+ if (ge >= s->nMTF) ge = s->nMTF-1;
+ AssertH ( s->selector[selCtr] < nGroups, 3006 );
+
+ if (nGroups == 6 && 50 == ge-gs+1) {
+ /*--- fast track the common case ---*/
+ UInt16 mtfv_i;
+ UChar* s_len_sel_selCtr
+ = &(s->len[s->selector[selCtr]][0]);
+ Int32* s_code_sel_selCtr
+ = &(s->code[s->selector[selCtr]][0]);
+
+# define BZ_ITAH(nn) \
+ mtfv_i = mtfv[gs+(nn)]; \
+ bsW ( s, \
+ s_len_sel_selCtr[mtfv_i], \
+ s_code_sel_selCtr[mtfv_i] )
+
+ BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
+ BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
+ BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
+ BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
+ BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
+ BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
+ BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
+ BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
+ BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
+ BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
+
+# undef BZ_ITAH
+
+ } else {
+ /*--- slow version which correctly handles all situations ---*/
+ for (i = gs; i <= ge; i++) {
+ bsW ( s,
+ s->len [s->selector[selCtr]] [mtfv[i]],
+ s->code [s->selector[selCtr]] [mtfv[i]] );
+ }
+ }
+
+
+ gs = ge+1;
+ selCtr++;
+ }
+ AssertH( selCtr == nSelectors, 3007 );
+
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_compressBlock ( EState* s, Bool is_last_block )
+{
+ if (s->nblock > 0) {
+
+ if (s->blockNo > 1) s->numZ = 0;
+
+
+ BZ2_blockSort ( s );
+ }
+
+ s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
+
+ /*-- If this is the first block, create the stream header. --*/
+ if (s->blockNo == 1) {
+ BZ2_bsInitWrite ( s );
+ }
+
+ if (s->nblock > 0) {
+
+ bsPutUChar ( s, 0x31 );
+
+ bsW ( s, 24, s->origPtr );
+ generateMTFValues ( s );
+ sendMTFValues ( s );
+ }
+
+
+ /*-- If this is the last block, add the stream trailer. --*/
+ if (is_last_block) {
+
+ bsPutUChar ( s, 0x17 );
+ bsFinishWrite ( s );
+ }
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end compress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/Source/bzip2/decompress.c b/Source/bzip2/decompress.c
index 675c186..bf00a67 100755
--- a/Source/bzip2/decompress.c
+++ b/Source/bzip2/decompress.c
@@ -1,534 +1,534 @@
-/*
- * This file is a part of the bzip2 compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.bzip.org/
- *
- * This modification is not compatible with the original bzip2.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "bzlib.h"
-
-/*-------------------------------------------------------------*/
-/*--- Decompression machinery ---*/
-/*--- decompress.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@acm.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-
-/*---------------------------------------------------*/
-#define RETURN(rrr) \
- { retVal = rrr; goto save_state_and_return; };
-
-
-static int NSISCALL __mygetbits(int *vtmp, int nnn, DState* s)
-{
- for (;;) {
- if (s->bsLive >= nnn) {
- UInt32 v;
- v = (s->bsBuff >>
- (s->bsLive-nnn)) & ((1 << nnn)-1);
- s->bsLive -= nnn;
- *vtmp = v;
- return 0;
- }
- if (s->avail_in == 0) return 1;
- s->bsBuff = (s->bsBuff << 8) | ((UInt32) (*((UChar*)(s->next_in))));
- s->bsLive += 8;
- s->next_in++;
- s->avail_in--;
- }
-}
-
-#define GET_BITS(lll,vvv,nnn) \
- case lll: s->state = lll; \
- if (__mygetbits(&vvv,nnn,s)) RETURN(BZ_OK)
-
-#define GET_UCHAR(lll,uuu) \
- GET_BITS(lll,uuu,8)
-
-#define GET_BIT(lll,uuu) \
- GET_BITS(lll,uuu,1)
-
-static int NSISCALL getmtf1(DState_save *sv,DState* s)
-{
- if (sv->groupPos == 0) {
- sv->groupNo++;
- if (sv->groupNo >= sv->nSelectors) return 1;
- sv->groupPos = BZ_G_SIZE;
- sv->gSel = s->selector[sv->groupNo];
- sv->gMinlen = s->minLens[sv->gSel];
- sv->gLimit = &(s->limit[sv->gSel][0]);
- sv->gPerm = &(s->perm[sv->gSel][0]);
- sv->gBase = &(s->base[sv->gSel][0]);
- }
- sv->groupPos--;
- sv->zn = sv->gMinlen;
- return 0;
-}
-
-/*---------------------------------------------------*/
-#define GET_MTF_VAL(label1,label2,lval) \
-{ \
- if (getmtf1(&sv,s)) RETURN(BZ_DATA_ERROR); \
- GET_BITS(label1, zvec, zn); \
- for (;;) { \
- if (zn > 20 /* the longest code */) RETURN(BZ_DATA_ERROR); \
- if (zvec <= gLimit[zn]) break; \
- zn++; \
- GET_BIT(label2, zj); \
- zvec = (zvec << 1) | zj; \
- }; \
- if (zvec - gBase[zn] < 0 \
- || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
- RETURN(BZ_DATA_ERROR); \
- lval = gPerm[zvec - gBase[zn]]; \
-}
-
-
-/*---------------------------------------------------*/
-Int32 NSISCALL BZ2_decompress ( DState* s )
-{
- Int32 uc;
- Int32 retVal;
- Int32 minLen, maxLen;
-
- /* stuff that needs to be saved/restored */
- DState_save sv;
-
- /*restore from the save area*/
- sv=s->save;//mini_memcpy(&sv, &(s->save), sizeof(sv));
-
- #define i (sv.i)
- #define j (sv.j)
- #define t (sv.t)
- #define alphaSize (sv.alphaSize)
- #define nGroups (sv.nGroups)
- #define nSelectors (sv.nSelectors)
- #define EOB (sv.EOB)
- #define groupNo (sv.groupNo)
- #define groupPos (sv.groupPos)
- #define nextSym (sv.nextSym)
- #define nblockMAX (sv.nblockMAX)
- #define nblock (sv.nblock)
- #define es (sv.es)
- #define N (sv.N)
- #define curr (sv.curr)
- #define zt (sv.zt)
- #define zn (sv.zn)
- #define zvec (sv.zvec)
- #define zj (sv.zj)
- #define gSel (sv.gSel)
- #define gMinlen (sv.gMinlen)
- #define gLimit (sv.gLimit)
- #define gBase (sv.gBase)
- #define gPerm (sv.gPerm)
-
- retVal = BZ_OK;
-
- switch (s->state) {
-
-
- GET_UCHAR(BZ_X_BLKHDR_1, uc);
-
- if (uc == 0x17)
- {
- s->state = BZ_X_IDLE;
- RETURN(BZ_STREAM_END);
- }
- if (uc != 0x31) RETURN(BZ_DATA_ERROR);
-
- s->origPtr = 0;
- GET_UCHAR(BZ_X_ORIGPTR_1, uc);
- s->origPtr = (s->origPtr << 8) | ((Int32)uc);
- GET_UCHAR(BZ_X_ORIGPTR_2, uc);
- s->origPtr = (s->origPtr << 8) | ((Int32)uc);
- GET_UCHAR(BZ_X_ORIGPTR_3, uc);
- s->origPtr = (s->origPtr << 8) | ((Int32)uc);
-
- if (s->origPtr < 0)
- RETURN(BZ_DATA_ERROR);
- if (s->origPtr > 10 + NSIS_COMPRESS_BZIP2_LEVEL*100000)
- RETURN(BZ_DATA_ERROR);
-
- /*--- Receive the mapping table ---*/
- for (i = 0; i < 16; i++) {
- GET_BIT(BZ_X_MAPPING_1, uc);
- if (uc == 1)
- s->inUse16[i] = True; else
- s->inUse16[i] = False;
- }
-
- for (i = 0; i < 256; i++) s->inUse[i] = False;
-
- for (i = 0; i < 16; i++)
- if (s->inUse16[i])
- for (j = 0; j < 16; j++) {
- GET_BIT(BZ_X_MAPPING_2, uc);
- if (uc == 1) s->inUse[i * 16 + j] = True;
- }
- {
- Int32 qi;
- s->nInUse = 0;
- for (qi = 0; qi < 256; qi++)
- if (s->inUse[qi])
- s->seqToUnseq[s->nInUse++] = qi;
- }
-
- if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
- alphaSize = s->nInUse+2;
-
- /*--- Now the selectors ---*/
- GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
- if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
- GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
- if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
- for (i = 0; i < nSelectors; i++) {
- j = 0;
- while (True) {
- GET_BIT(BZ_X_SELECTOR_3, uc);
- if (uc == 0) break;
- j++;
- if (j >= nGroups) RETURN(BZ_DATA_ERROR);
- }
- s->selectorMtf[i] = j;
- }
-
- /*--- Undo the MTF values for the selectors. ---*/
- {
- UChar pos[BZ_N_GROUPS], tmp, v;
- for (v = 0; v < nGroups; v++) pos[v] = v;
-
- for (i = 0; i < nSelectors; i++) {
- v = s->selectorMtf[i];
- tmp = pos[v];
- while (v > 0) { pos[v] = pos[v-1]; v--; }
- pos[0] = tmp;
- s->selector[i] = tmp;
- }
- }
-
- /*--- Now the coding tables ---*/
- for (t = 0; t < nGroups; t++) {
- GET_BITS(BZ_X_CODING_1, curr, 5);
- for (i = 0; i < alphaSize; i++) {
- while (True) {
- if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
- GET_BIT(BZ_X_CODING_2, uc);
- if (uc == 0) break;
- GET_BIT(BZ_X_CODING_3, uc);
- if (uc == 0) curr++; else curr--;
- }
- s->len[t][i] = curr;
- }
- }
-
- /*--- Create the Huffman decoding tables ---*/
- for (t = 0; t < nGroups; t++) {
- minLen = 32;
- maxLen = 0;
- for (i = 0; i < alphaSize; i++) {
- if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
- if (s->len[t][i] < minLen) minLen = s->len[t][i];
- }
- BZ2_hbCreateDecodeTables (
- &(s->limit[t][0]),
- &(s->base[t][0]),
- &(s->perm[t][0]),
- &(s->len[t][0]),
- minLen, maxLen, alphaSize
- );
- s->minLens[t] = minLen;
- }
-
- /*--- Now the MTF values ---*/
-
- EOB = s->nInUse+1;
- nblockMAX = NSIS_COMPRESS_BZIP2_LEVEL*100000;
- groupNo = -1;
- groupPos = 0;
-
- for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
-
- /*-- MTF init --*/
- {
- Int32 ii, jj, kk = MTFA_SIZE-1;
- for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
- for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
- s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
- kk--;
- }
- s->mtfbase[ii] = kk + 1;
- }
- }
- /*-- end MTF init --*/
-
- nblock = 0;
- GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
-
- while (True) {
-
- if (nextSym == EOB) break;
-
- if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
-
- es = -1;
- N = 1;
- while (nextSym == BZ_RUNA || nextSym == BZ_RUNB)
- {
- if (nextSym == BZ_RUNA) es += N;
- N = N << 1;
- if (nextSym == BZ_RUNB) es += N;
- GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
- }
-
- es++;
- uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
- s->unzftab[uc] += es;
-
-#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
- while (es > 0) {
- if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
- s->ll16[nblock] = (UInt16)uc;
- nblock++;
- es--;
- }
-#else
- while (es > 0) {
- if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
- s->tt[nblock] = (UInt32)uc;
- nblock++;
- es--;
- }
-#endif
- continue;
-
- } else {
-
- if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
-
- /*-- uc = MTF ( nextSym-1 ) --*/
- {
- Int32 ii, jj, kk, pp, lno, off;
- UInt32 nn;
- nn = (UInt32)(nextSym - 1);
-
- if (nn < MTFL_SIZE) {
- /* avoid general-case expense */
- pp = s->mtfbase[0];
- uc = s->mtfa[pp+nn];
- /*while (nn > 3) {
- Int32 z = pp+nn;
- s->mtfa[(z) ] = s->mtfa[(z)-1];
- s->mtfa[(z)-1] = s->mtfa[(z)-2];
- s->mtfa[(z)-2] = s->mtfa[(z)-3];
- s->mtfa[(z)-3] = s->mtfa[(z)-4];
- nn -= 4;
- }
- */
- while (nn > 0) {
- s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
- };
- s->mtfa[pp] = uc;
- } else {
- /* general case */
- lno = nn / MTFL_SIZE;
- off = nn % MTFL_SIZE;
- pp = s->mtfbase[lno] + off;
- uc = s->mtfa[pp];
- while (pp > s->mtfbase[lno]) {
- s->mtfa[pp] = s->mtfa[pp-1]; pp--;
- };
- s->mtfbase[lno]++;
- while (lno > 0) {
- s->mtfbase[lno]--;
- s->mtfa[s->mtfbase[lno]]
- = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
- lno--;
- }
- s->mtfbase[0]--;
- s->mtfa[s->mtfbase[0]] = uc;
- if (s->mtfbase[0] == 0) {
- kk = MTFA_SIZE-1;
- for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
- for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
- s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
- kk--;
- }
- s->mtfbase[ii] = kk + 1;
- }
- }
- }
- }
- /*-- end uc = MTF ( nextSym-1 ) --*/
-
- s->unzftab[s->seqToUnseq[uc]]++;
-#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
- s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]);
-#else
- s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
-#endif
- nblock++;
-
- GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
- continue;
- }
- }
-
- /* Now we know what nblock is, we can do a better sanity
- check on s->origPtr.
- */
- if (s->origPtr < 0 || s->origPtr >= nblock)
- RETURN(BZ_DATA_ERROR);
-
- s->state_out_len = 0;
- s->state_out_ch = 0;
- s->state = BZ_X_OUTPUT;
-
- /*-- Set up cftab to facilitate generation of T^(-1) --*/
- s->cftab[0] = 0;
- for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]+s->cftab[i-1];
-// for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
-
-#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
- {
- /*-- Make a copy of cftab, used in generation of T --*/
- for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
-
- /*-- compute the T vector --*/
- for (i = 0; i < nblock; i++) {
- uc = (UChar)(s->ll16[i]);
- SET_LL(i, s->cftabCopy[uc]);
- s->cftabCopy[uc]++;
- }
-
- /*-- Compute T^(-1) by pointer reversal on T --*/
- i = s->origPtr;
- j = GET_LL(i);
- do {
- Int32 tmp = GET_LL(j);
- SET_LL(j, i);
- i = j;
- j = tmp;
- }
- while (i != s->origPtr);
-
- s->tPos = s->origPtr;
- s->nblock_used = 0;
- BZ_GET_SMALL(s->k0); s->nblock_used++;
- }
-#else//!small
-
- /*-- compute the T^(-1) vector --*/
- for (i = 0; i < nblock; i++) {
- uc = (UChar)(s->tt[i] & 0xff);
- s->tt[s->cftab[uc]] |= (i << 8);
- s->cftab[uc]++;
- }
-
- s->tPos = s->tt[s->origPtr] >> 8;
- s->nblock_used = 0;
- BZ_GET_FAST(s->k0); s->nblock_used++;
-#endif
- RETURN(BZ_OK);
-
- default: AssertH ( False, 4001 );
- }
-
- AssertH ( False, 4002 );
-
- save_state_and_return:
-
- s->save=sv; //mini_memcpy(&(s->save), &sv, sizeof(sv));
-
- #undef i
- #undef j
- #undef t
- #undef alphaSize
- #undef nGroups
- #undef nSelectors
- #undef EOB
- #undef groupNo
- #undef groupPos
- #undef nextSym
- #undef nblockMAX
- #undef nblock
- #undef es
- #undef N
- #undef curr
- #undef zt
- #undef zn
- #undef zvec
- #undef zj
- #undef gSel
- #undef gMinlen
- #undef gLimit
- #undef gBase
- #undef gPerm
-
- return retVal;
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end decompress.c ---*/
-/*-------------------------------------------------------------*/
+/*
+ * This file is a part of the bzip2 compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.bzip.org/
+ *
+ * This modification is not compatible with the original bzip2.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "bzlib.h"
+
+/*-------------------------------------------------------------*/
+/*--- Decompression machinery ---*/
+/*--- decompress.c ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+ This file is a part of bzip2 and/or libbzip2, a program and
+ library for lossless, block-sorting data compression.
+
+ Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+ 3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+ 4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Julian Seward, Cambridge, UK.
+ jseward@acm.org
+ bzip2/libbzip2 version 1.0 of 21 March 2000
+
+ This program is based on (at least) the work of:
+ Mike Burrows
+ David Wheeler
+ Peter Fenwick
+ Alistair Moffat
+ Radford Neal
+ Ian H. Witten
+ Robert Sedgewick
+ Jon L. Bentley
+
+ For more information on these sources, see the manual.
+--*/
+
+
+/*---------------------------------------------------*/
+#define RETURN(rrr) \
+ { retVal = rrr; goto save_state_and_return; };
+
+
+static int NSISCALL __mygetbits(int *vtmp, int nnn, DState* s)
+{
+ for (;;) {
+ if (s->bsLive >= nnn) {
+ UInt32 v;
+ v = (s->bsBuff >>
+ (s->bsLive-nnn)) & ((1 << nnn)-1);
+ s->bsLive -= nnn;
+ *vtmp = v;
+ return 0;
+ }
+ if (s->avail_in == 0) return 1;
+ s->bsBuff = (s->bsBuff << 8) | ((UInt32) (*((UChar*)(s->next_in))));
+ s->bsLive += 8;
+ s->next_in++;
+ s->avail_in--;
+ }
+}
+
+#define GET_BITS(lll,vvv,nnn) \
+ case lll: s->state = lll; \
+ if (__mygetbits(&vvv,nnn,s)) RETURN(BZ_OK)
+
+#define GET_UCHAR(lll,uuu) \
+ GET_BITS(lll,uuu,8)
+
+#define GET_BIT(lll,uuu) \
+ GET_BITS(lll,uuu,1)
+
+static int NSISCALL getmtf1(DState_save *sv,DState* s)
+{
+ if (sv->groupPos == 0) {
+ sv->groupNo++;
+ if (sv->groupNo >= sv->nSelectors) return 1;
+ sv->groupPos = BZ_G_SIZE;
+ sv->gSel = s->selector[sv->groupNo];
+ sv->gMinlen = s->minLens[sv->gSel];
+ sv->gLimit = &(s->limit[sv->gSel][0]);
+ sv->gPerm = &(s->perm[sv->gSel][0]);
+ sv->gBase = &(s->base[sv->gSel][0]);
+ }
+ sv->groupPos--;
+ sv->zn = sv->gMinlen;
+ return 0;
+}
+
+/*---------------------------------------------------*/
+#define GET_MTF_VAL(label1,label2,lval) \
+{ \
+ if (getmtf1(&sv,s)) RETURN(BZ_DATA_ERROR); \
+ GET_BITS(label1, zvec, zn); \
+ for (;;) { \
+ if (zn > 20 /* the longest code */) RETURN(BZ_DATA_ERROR); \
+ if (zvec <= gLimit[zn]) break; \
+ zn++; \
+ GET_BIT(label2, zj); \
+ zvec = (zvec << 1) | zj; \
+ }; \
+ if (zvec - gBase[zn] < 0 \
+ || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
+ RETURN(BZ_DATA_ERROR); \
+ lval = gPerm[zvec - gBase[zn]]; \
+}
+
+
+/*---------------------------------------------------*/
+Int32 NSISCALL BZ2_decompress ( DState* s )
+{
+ Int32 uc;
+ Int32 retVal;
+ Int32 minLen, maxLen;
+
+ /* stuff that needs to be saved/restored */
+ DState_save sv;
+
+ /*restore from the save area*/
+ sv=s->save;//mini_memcpy(&sv, &(s->save), sizeof(sv));
+
+ #define i (sv.i)
+ #define j (sv.j)
+ #define t (sv.t)
+ #define alphaSize (sv.alphaSize)
+ #define nGroups (sv.nGroups)
+ #define nSelectors (sv.nSelectors)
+ #define EOB (sv.EOB)
+ #define groupNo (sv.groupNo)
+ #define groupPos (sv.groupPos)
+ #define nextSym (sv.nextSym)
+ #define nblockMAX (sv.nblockMAX)
+ #define nblock (sv.nblock)
+ #define es (sv.es)
+ #define N (sv.N)
+ #define curr (sv.curr)
+ #define zt (sv.zt)
+ #define zn (sv.zn)
+ #define zvec (sv.zvec)
+ #define zj (sv.zj)
+ #define gSel (sv.gSel)
+ #define gMinlen (sv.gMinlen)
+ #define gLimit (sv.gLimit)
+ #define gBase (sv.gBase)
+ #define gPerm (sv.gPerm)
+
+ retVal = BZ_OK;
+
+ switch (s->state) {
+
+
+ GET_UCHAR(BZ_X_BLKHDR_1, uc);
+
+ if (uc == 0x17)
+ {
+ s->state = BZ_X_IDLE;
+ RETURN(BZ_STREAM_END);
+ }
+ if (uc != 0x31) RETURN(BZ_DATA_ERROR);
+
+ s->origPtr = 0;
+ GET_UCHAR(BZ_X_ORIGPTR_1, uc);
+ s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+ GET_UCHAR(BZ_X_ORIGPTR_2, uc);
+ s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+ GET_UCHAR(BZ_X_ORIGPTR_3, uc);
+ s->origPtr = (s->origPtr << 8) | ((Int32)uc);
+
+ if (s->origPtr < 0)
+ RETURN(BZ_DATA_ERROR);
+ if (s->origPtr > 10 + NSIS_COMPRESS_BZIP2_LEVEL*100000)
+ RETURN(BZ_DATA_ERROR);
+
+ /*--- Receive the mapping table ---*/
+ for (i = 0; i < 16; i++) {
+ GET_BIT(BZ_X_MAPPING_1, uc);
+ if (uc == 1)
+ s->inUse16[i] = True; else
+ s->inUse16[i] = False;
+ }
+
+ for (i = 0; i < 256; i++) s->inUse[i] = False;
+
+ for (i = 0; i < 16; i++)
+ if (s->inUse16[i])
+ for (j = 0; j < 16; j++) {
+ GET_BIT(BZ_X_MAPPING_2, uc);
+ if (uc == 1) s->inUse[i * 16 + j] = True;
+ }
+ {
+ Int32 qi;
+ s->nInUse = 0;
+ for (qi = 0; qi < 256; qi++)
+ if (s->inUse[qi])
+ s->seqToUnseq[s->nInUse++] = qi;
+ }
+
+ if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
+ alphaSize = s->nInUse+2;
+
+ /*--- Now the selectors ---*/
+ GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
+ if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
+ GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
+ if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
+ for (i = 0; i < nSelectors; i++) {
+ j = 0;
+ while (True) {
+ GET_BIT(BZ_X_SELECTOR_3, uc);
+ if (uc == 0) break;
+ j++;
+ if (j >= nGroups) RETURN(BZ_DATA_ERROR);
+ }
+ s->selectorMtf[i] = j;
+ }
+
+ /*--- Undo the MTF values for the selectors. ---*/
+ {
+ UChar pos[BZ_N_GROUPS], tmp, v;
+ for (v = 0; v < nGroups; v++) pos[v] = v;
+
+ for (i = 0; i < nSelectors; i++) {
+ v = s->selectorMtf[i];
+ tmp = pos[v];
+ while (v > 0) { pos[v] = pos[v-1]; v--; }
+ pos[0] = tmp;
+ s->selector[i] = tmp;
+ }
+ }
+
+ /*--- Now the coding tables ---*/
+ for (t = 0; t < nGroups; t++) {
+ GET_BITS(BZ_X_CODING_1, curr, 5);
+ for (i = 0; i < alphaSize; i++) {
+ while (True) {
+ if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
+ GET_BIT(BZ_X_CODING_2, uc);
+ if (uc == 0) break;
+ GET_BIT(BZ_X_CODING_3, uc);
+ if (uc == 0) curr++; else curr--;
+ }
+ s->len[t][i] = curr;
+ }
+ }
+
+ /*--- Create the Huffman decoding tables ---*/
+ for (t = 0; t < nGroups; t++) {
+ minLen = 32;
+ maxLen = 0;
+ for (i = 0; i < alphaSize; i++) {
+ if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+ if (s->len[t][i] < minLen) minLen = s->len[t][i];
+ }
+ BZ2_hbCreateDecodeTables (
+ &(s->limit[t][0]),
+ &(s->base[t][0]),
+ &(s->perm[t][0]),
+ &(s->len[t][0]),
+ minLen, maxLen, alphaSize
+ );
+ s->minLens[t] = minLen;
+ }
+
+ /*--- Now the MTF values ---*/
+
+ EOB = s->nInUse+1;
+ nblockMAX = NSIS_COMPRESS_BZIP2_LEVEL*100000;
+ groupNo = -1;
+ groupPos = 0;
+
+ for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
+
+ /*-- MTF init --*/
+ {
+ Int32 ii, jj, kk = MTFA_SIZE-1;
+ for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
+ for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+ s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
+ kk--;
+ }
+ s->mtfbase[ii] = kk + 1;
+ }
+ }
+ /*-- end MTF init --*/
+
+ nblock = 0;
+ GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
+
+ while (True) {
+
+ if (nextSym == EOB) break;
+
+ if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
+
+ es = -1;
+ N = 1;
+ while (nextSym == BZ_RUNA || nextSym == BZ_RUNB)
+ {
+ if (nextSym == BZ_RUNA) es += N;
+ N = N << 1;
+ if (nextSym == BZ_RUNB) es += N;
+ GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
+ }
+
+ es++;
+ uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
+ s->unzftab[uc] += es;
+
+#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
+ while (es > 0) {
+ if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+ s->ll16[nblock] = (UInt16)uc;
+ nblock++;
+ es--;
+ }
+#else
+ while (es > 0) {
+ if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+ s->tt[nblock] = (UInt32)uc;
+ nblock++;
+ es--;
+ }
+#endif
+ continue;
+
+ } else {
+
+ if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
+
+ /*-- uc = MTF ( nextSym-1 ) --*/
+ {
+ Int32 ii, jj, kk, pp, lno, off;
+ UInt32 nn;
+ nn = (UInt32)(nextSym - 1);
+
+ if (nn < MTFL_SIZE) {
+ /* avoid general-case expense */
+ pp = s->mtfbase[0];
+ uc = s->mtfa[pp+nn];
+ /*while (nn > 3) {
+ Int32 z = pp+nn;
+ s->mtfa[(z) ] = s->mtfa[(z)-1];
+ s->mtfa[(z)-1] = s->mtfa[(z)-2];
+ s->mtfa[(z)-2] = s->mtfa[(z)-3];
+ s->mtfa[(z)-3] = s->mtfa[(z)-4];
+ nn -= 4;
+ }
+ */
+ while (nn > 0) {
+ s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
+ };
+ s->mtfa[pp] = uc;
+ } else {
+ /* general case */
+ lno = nn / MTFL_SIZE;
+ off = nn % MTFL_SIZE;
+ pp = s->mtfbase[lno] + off;
+ uc = s->mtfa[pp];
+ while (pp > s->mtfbase[lno]) {
+ s->mtfa[pp] = s->mtfa[pp-1]; pp--;
+ };
+ s->mtfbase[lno]++;
+ while (lno > 0) {
+ s->mtfbase[lno]--;
+ s->mtfa[s->mtfbase[lno]]
+ = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
+ lno--;
+ }
+ s->mtfbase[0]--;
+ s->mtfa[s->mtfbase[0]] = uc;
+ if (s->mtfbase[0] == 0) {
+ kk = MTFA_SIZE-1;
+ for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
+ for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
+ s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
+ kk--;
+ }
+ s->mtfbase[ii] = kk + 1;
+ }
+ }
+ }
+ }
+ /*-- end uc = MTF ( nextSym-1 ) --*/
+
+ s->unzftab[s->seqToUnseq[uc]]++;
+#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
+ s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]);
+#else
+ s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
+#endif
+ nblock++;
+
+ GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
+ continue;
+ }
+ }
+
+ /* Now we know what nblock is, we can do a better sanity
+ check on s->origPtr.
+ */
+ if (s->origPtr < 0 || s->origPtr >= nblock)
+ RETURN(BZ_DATA_ERROR);
+
+ s->state_out_len = 0;
+ s->state_out_ch = 0;
+ s->state = BZ_X_OUTPUT;
+
+ /*-- Set up cftab to facilitate generation of T^(-1) --*/
+ s->cftab[0] = 0;
+ for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]+s->cftab[i-1];
+// for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
+
+#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
+ {
+ /*-- Make a copy of cftab, used in generation of T --*/
+ for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
+
+ /*-- compute the T vector --*/
+ for (i = 0; i < nblock; i++) {
+ uc = (UChar)(s->ll16[i]);
+ SET_LL(i, s->cftabCopy[uc]);
+ s->cftabCopy[uc]++;
+ }
+
+ /*-- Compute T^(-1) by pointer reversal on T --*/
+ i = s->origPtr;
+ j = GET_LL(i);
+ do {
+ Int32 tmp = GET_LL(j);
+ SET_LL(j, i);
+ i = j;
+ j = tmp;
+ }
+ while (i != s->origPtr);
+
+ s->tPos = s->origPtr;
+ s->nblock_used = 0;
+ BZ_GET_SMALL(s->k0); s->nblock_used++;
+ }
+#else//!small
+
+ /*-- compute the T^(-1) vector --*/
+ for (i = 0; i < nblock; i++) {
+ uc = (UChar)(s->tt[i] & 0xff);
+ s->tt[s->cftab[uc]] |= (i << 8);
+ s->cftab[uc]++;
+ }
+
+ s->tPos = s->tt[s->origPtr] >> 8;
+ s->nblock_used = 0;
+ BZ_GET_FAST(s->k0); s->nblock_used++;
+#endif
+ RETURN(BZ_OK);
+
+ default: AssertH ( False, 4001 );
+ }
+
+ AssertH ( False, 4002 );
+
+ save_state_and_return:
+
+ s->save=sv; //mini_memcpy(&(s->save), &sv, sizeof(sv));
+
+ #undef i
+ #undef j
+ #undef t
+ #undef alphaSize
+ #undef nGroups
+ #undef nSelectors
+ #undef EOB
+ #undef groupNo
+ #undef groupPos
+ #undef nextSym
+ #undef nblockMAX
+ #undef nblock
+ #undef es
+ #undef N
+ #undef curr
+ #undef zt
+ #undef zn
+ #undef zvec
+ #undef zj
+ #undef gSel
+ #undef gMinlen
+ #undef gLimit
+ #undef gBase
+ #undef gPerm
+
+ return retVal;
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end decompress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/Source/bzip2/huffman.c b/Source/bzip2/huffman.c
index d36ccb0..1273e60 100755
--- a/Source/bzip2/huffman.c
+++ b/Source/bzip2/huffman.c
@@ -1,244 +1,244 @@
-/*
- * This file is a part of the bzip2 compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.bzip.org/
- *
- * This modification is not compatible with the original bzip2.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "bzlib.h"
-
-/*-------------------------------------------------------------*/
-/*--- Huffman coding low-level stuff ---*/
-/*--- huffman.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@acm.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-#ifndef EXEHEAD
-/*---------------------------------------------------*/
-#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
-#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
-#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
-
-#define ADDWEIGHTS(zw1,zw2) \
- (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
- (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
-
-#define UPHEAP(z) \
-{ \
- Int32 zz, tmp; \
- zz = z; tmp = heap[zz]; \
- while (weight[tmp] < weight[heap[zz >> 1]]) { \
- heap[zz] = heap[zz >> 1]; \
- zz >>= 1; \
- } \
- heap[zz] = tmp; \
-}
-
-#define DOWNHEAP(z) \
-{ \
- Int32 zz, yy, tmp; \
- zz = z; tmp = heap[zz]; \
- while (True) { \
- yy = zz << 1; \
- if (yy > nHeap) break; \
- if (yy < nHeap && \
- weight[heap[yy+1]] < weight[heap[yy]]) \
- yy++; \
- if (weight[tmp] < weight[heap[yy]]) break; \
- heap[zz] = heap[yy]; \
- zz = yy; \
- } \
- heap[zz] = tmp; \
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbMakeCodeLengths ( UChar *len,
- Int32 *freq,
- Int32 alphaSize,
- Int32 maxLen )
-{
- /*--
- Nodes and heap entries run from 1. Entry 0
- for both the heap and nodes is a sentinel.
- --*/
- Int32 nNodes, nHeap, n1, n2, i, j, k;
- Bool tooLong;
-
- static Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
- static Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
- static Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
-
- for (i = 0; i < alphaSize; i++)
- weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
-
- while (True) {
-
- nNodes = alphaSize;
- nHeap = 0;
-
- heap[0] = 0;
- weight[0] = 0;
- parent[0] = -2;
-
- for (i = 1; i <= alphaSize; i++) {
- parent[i] = -1;
- nHeap++;
- heap[nHeap] = i;
- UPHEAP(nHeap);
- }
-
- AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
-
- while (nHeap > 1) {
- n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
- n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
- nNodes++;
- parent[n1] = parent[n2] = nNodes;
- weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
- parent[nNodes] = -1;
- nHeap++;
- heap[nHeap] = nNodes;
- UPHEAP(nHeap);
- }
-
- AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
-
- tooLong = False;
- for (i = 1; i <= alphaSize; i++) {
- j = 0;
- k = i;
- while (parent[k] >= 0) { k = parent[k]; j++; }
- len[i-1] = j;
- if (j > maxLen) tooLong = True;
- }
-
- if (! tooLong) break;
-
- for (i = 1; i < alphaSize; i++) {
- j = weight[i] >> 8;
- j = 1 + (j / 2);
- weight[i] = j << 8;
- }
- }
-}
-
-
-/*---------------------------------------------------*/
-void BZ2_hbAssignCodes ( Int32 *code,
- UChar *length,
- Int32 minLen,
- Int32 maxLen,
- Int32 alphaSize )
-{
- Int32 n, vec, i;
-
- vec = 0;
- for (n = minLen; n <= maxLen; n++) {
- for (i = 0; i < alphaSize; i++)
- if (length[i] == n) { code[i] = vec; vec++; };
- vec <<= 1;
- }
-}
-#endif
-
-
-/*---------------------------------------------------*/
-void NSISCALL
-BZ2_hbCreateDecodeTables ( Int32 *limit,
- Int32 *base,
- Int32 *perm,
- UChar *length,
- Int32 minLen,
- Int32 maxLen,
- Int32 alphaSize )
-{
- Int32 pp, i, j, vec;
-
- pp = 0;
- for (i = minLen; i <= maxLen; i++)
- for (j = 0; j < alphaSize; j++)
- if (length[j] == i) { perm[pp] = j; pp++; };
-
- for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
- for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
-
- for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
-
- for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
- vec = 0;
-
- for (i = minLen; i <= maxLen; i++) {
- vec += (base[i+1] - base[i]);
- limit[i] = vec-1;
- vec <<= 1;
- }
- for (i = minLen + 1; i <= maxLen; i++)
- base[i] = ((limit[i-1] + 1) << 1) - base[i];
-}
-
-
-/*-------------------------------------------------------------*/
-/*--- end huffman.c ---*/
-/*-------------------------------------------------------------*/
+/*
+ * This file is a part of the bzip2 compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.bzip.org/
+ *
+ * This modification is not compatible with the original bzip2.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "bzlib.h"
+
+/*-------------------------------------------------------------*/
+/*--- Huffman coding low-level stuff ---*/
+/*--- huffman.c ---*/
+/*-------------------------------------------------------------*/
+
+/*--
+ This file is a part of bzip2 and/or libbzip2, a program and
+ library for lossless, block-sorting data compression.
+
+ Copyright (C) 1996-2000 Julian R Seward. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+ 3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+ 4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Julian Seward, Cambridge, UK.
+ jseward@acm.org
+ bzip2/libbzip2 version 1.0 of 21 March 2000
+
+ This program is based on (at least) the work of:
+ Mike Burrows
+ David Wheeler
+ Peter Fenwick
+ Alistair Moffat
+ Radford Neal
+ Ian H. Witten
+ Robert Sedgewick
+ Jon L. Bentley
+
+ For more information on these sources, see the manual.
+--*/
+
+#ifndef EXEHEAD
+/*---------------------------------------------------*/
+#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
+#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
+#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
+
+#define ADDWEIGHTS(zw1,zw2) \
+ (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
+ (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
+
+#define UPHEAP(z) \
+{ \
+ Int32 zz, tmp; \
+ zz = z; tmp = heap[zz]; \
+ while (weight[tmp] < weight[heap[zz >> 1]]) { \
+ heap[zz] = heap[zz >> 1]; \
+ zz >>= 1; \
+ } \
+ heap[zz] = tmp; \
+}
+
+#define DOWNHEAP(z) \
+{ \
+ Int32 zz, yy, tmp; \
+ zz = z; tmp = heap[zz]; \
+ while (True) { \
+ yy = zz << 1; \
+ if (yy > nHeap) break; \
+ if (yy < nHeap && \
+ weight[heap[yy+1]] < weight[heap[yy]]) \
+ yy++; \
+ if (weight[tmp] < weight[heap[yy]]) break; \
+ heap[zz] = heap[yy]; \
+ zz = yy; \
+ } \
+ heap[zz] = tmp; \
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbMakeCodeLengths ( UChar *len,
+ Int32 *freq,
+ Int32 alphaSize,
+ Int32 maxLen )
+{
+ /*--
+ Nodes and heap entries run from 1. Entry 0
+ for both the heap and nodes is a sentinel.
+ --*/
+ Int32 nNodes, nHeap, n1, n2, i, j, k;
+ Bool tooLong;
+
+ static Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
+ static Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
+ static Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
+
+ for (i = 0; i < alphaSize; i++)
+ weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
+
+ while (True) {
+
+ nNodes = alphaSize;
+ nHeap = 0;
+
+ heap[0] = 0;
+ weight[0] = 0;
+ parent[0] = -2;
+
+ for (i = 1; i <= alphaSize; i++) {
+ parent[i] = -1;
+ nHeap++;
+ heap[nHeap] = i;
+ UPHEAP(nHeap);
+ }
+
+ AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
+
+ while (nHeap > 1) {
+ n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+ n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
+ nNodes++;
+ parent[n1] = parent[n2] = nNodes;
+ weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
+ parent[nNodes] = -1;
+ nHeap++;
+ heap[nHeap] = nNodes;
+ UPHEAP(nHeap);
+ }
+
+ AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
+
+ tooLong = False;
+ for (i = 1; i <= alphaSize; i++) {
+ j = 0;
+ k = i;
+ while (parent[k] >= 0) { k = parent[k]; j++; }
+ len[i-1] = j;
+ if (j > maxLen) tooLong = True;
+ }
+
+ if (! tooLong) break;
+
+ for (i = 1; i < alphaSize; i++) {
+ j = weight[i] >> 8;
+ j = 1 + (j / 2);
+ weight[i] = j << 8;
+ }
+ }
+}
+
+
+/*---------------------------------------------------*/
+void BZ2_hbAssignCodes ( Int32 *code,
+ UChar *length,
+ Int32 minLen,
+ Int32 maxLen,
+ Int32 alphaSize )
+{
+ Int32 n, vec, i;
+
+ vec = 0;
+ for (n = minLen; n <= maxLen; n++) {
+ for (i = 0; i < alphaSize; i++)
+ if (length[i] == n) { code[i] = vec; vec++; };
+ vec <<= 1;
+ }
+}
+#endif
+
+
+/*---------------------------------------------------*/
+void NSISCALL
+BZ2_hbCreateDecodeTables ( Int32 *limit,
+ Int32 *base,
+ Int32 *perm,
+ UChar *length,
+ Int32 minLen,
+ Int32 maxLen,
+ Int32 alphaSize )
+{
+ Int32 pp, i, j, vec;
+
+ pp = 0;
+ for (i = minLen; i <= maxLen; i++)
+ for (j = 0; j < alphaSize; j++)
+ if (length[j] == i) { perm[pp] = j; pp++; };
+
+ for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
+ for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
+
+ for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
+
+ for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
+ vec = 0;
+
+ for (i = minLen; i <= maxLen; i++) {
+ vec += (base[i+1] - base[i]);
+ limit[i] = vec-1;
+ vec <<= 1;
+ }
+ for (i = minLen + 1; i <= maxLen; i++)
+ base[i] = ((limit[i-1] + 1) << 1) - base[i];
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end huffman.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/Source/cbzip2.h b/Source/cbzip2.h
index 840af93..638b16c 100755
--- a/Source/cbzip2.h
+++ b/Source/cbzip2.h
@@ -1,99 +1,99 @@
-/*
- * cbzip2.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __CBZIP2_H__
-#define __CBZIP2_H__
-
-#include "compressor.h"
-#include "bzip2/bzlib.h"
-
-class CBzip2 : public ICompressor {
- public:
- virtual ~CBzip2() {}
-
- int Init(int level, unsigned int dict_size) {
- last_ret = !BZ_STREAM_END;
- stream = new bz_stream;
- if (!stream) return BZ_MEM_ERROR;
- return BZ2_bzCompressInit(stream, level, 0, 30);
- }
-
- int End() {
- int ret = BZ2_bzCompressEnd(stream);
- delete stream;
- return ret;
- }
-
- int Compress(bool finish) {
- // act like zlib when it comes to stream ending
- if (last_ret == BZ_STREAM_END && finish)
- return C_FINISHED;
- last_ret = BZ2_bzCompress(stream, finish?BZ_FINISH:0);
-
- if (last_ret < 0)
- return last_ret;
-
- return C_OK;
- }
-
- void SetNextIn(char *in, unsigned int size) {
- stream->next_in = in;
- stream->avail_in = size;
- }
-
- void SetNextOut(char *out, unsigned int size) {
- stream->next_out = out;
- stream->avail_out = size;
- }
-
- virtual char* GetNextOut() {
- return stream->next_out;
- }
-
- virtual unsigned int GetAvailIn() {
- return stream->avail_in;
- }
-
- virtual unsigned int GetAvailOut() {
- return stream->avail_out;
- }
-
- const char* GetName() {
- return "bzip2";
- }
-
- const char* GetErrStr(int err) {
- switch (err)
- {
- case BZ_SEQUENCE_ERROR:
- return "sequence error - bad call";
- case BZ_PARAM_ERROR:
- return "parameter error - bad call";
- case BZ_MEM_ERROR:
- return "not enough memory";
- case BZ_CONFIG_ERROR:
- return "config error";
- default:
- return "unknown error";
- }
- }
-
- private:
- bz_stream *stream;
- int last_ret;
-};
-
-#endif
+/*
+ * cbzip2.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __CBZIP2_H__
+#define __CBZIP2_H__
+
+#include "compressor.h"
+#include "bzip2/bzlib.h"
+
+class CBzip2 : public ICompressor {
+ public:
+ virtual ~CBzip2() {}
+
+ int Init(int level, unsigned int dict_size) {
+ last_ret = !BZ_STREAM_END;
+ stream = new bz_stream;
+ if (!stream) return BZ_MEM_ERROR;
+ return BZ2_bzCompressInit(stream, level, 0, 30);
+ }
+
+ int End() {
+ int ret = BZ2_bzCompressEnd(stream);
+ delete stream;
+ return ret;
+ }
+
+ int Compress(bool finish) {
+ // act like zlib when it comes to stream ending
+ if (last_ret == BZ_STREAM_END && finish)
+ return C_FINISHED;
+ last_ret = BZ2_bzCompress(stream, finish?BZ_FINISH:0);
+
+ if (last_ret < 0)
+ return last_ret;
+
+ return C_OK;
+ }
+
+ void SetNextIn(char *in, unsigned int size) {
+ stream->next_in = in;
+ stream->avail_in = size;
+ }
+
+ void SetNextOut(char *out, unsigned int size) {
+ stream->next_out = out;
+ stream->avail_out = size;
+ }
+
+ virtual char* GetNextOut() {
+ return stream->next_out;
+ }
+
+ virtual unsigned int GetAvailIn() {
+ return stream->avail_in;
+ }
+
+ virtual unsigned int GetAvailOut() {
+ return stream->avail_out;
+ }
+
+ const char* GetName() {
+ return "bzip2";
+ }
+
+ const char* GetErrStr(int err) {
+ switch (err)
+ {
+ case BZ_SEQUENCE_ERROR:
+ return "sequence error - bad call";
+ case BZ_PARAM_ERROR:
+ return "parameter error - bad call";
+ case BZ_MEM_ERROR:
+ return "not enough memory";
+ case BZ_CONFIG_ERROR:
+ return "config error";
+ default:
+ return "unknown error";
+ }
+ }
+
+ private:
+ bz_stream *stream;
+ int last_ret;
+};
+
+#endif
diff --git a/Source/clzma.cpp b/Source/clzma.cpp
index 366b179..2714055 100755
--- a/Source/clzma.cpp
+++ b/Source/clzma.cpp
@@ -1,464 +1,464 @@
-/*
- * clzma.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include <algorithm> // for std::min
-#include "clzma.h"
-
-using namespace std;
-
-#ifndef _WIN32
-struct evnet_t
-{
- pthread_cond_t cond;
- pthread_mutex_t mutex;
- bool signaled;
-};
-
-HANDLE CreateEvent(void *, BOOL, BOOL, char *)
-{
- evnet_t *event = (evnet_t *) malloc(sizeof(evnet_t));
- if (!event)
- return 0;
- if (pthread_cond_init(&event->cond, NULL))
- {
- free(event);
- return 0;
- }
- if (pthread_mutex_init(&event->mutex, NULL))
- {
- pthread_cond_destroy(&event->cond);
- free(event);
- return 0;
- }
- event->signaled = false;
- return (HANDLE) event;
-}
-
-BOOL SetEvent(HANDLE _event)
-{
- evnet_t *event = (evnet_t *) _event;
- if (pthread_mutex_lock(&event->mutex))
- return FALSE;
- event->signaled = true;
- pthread_cond_signal(&event->cond);
- if (pthread_mutex_unlock(&event->mutex))
- return FALSE;
- return TRUE;
-}
-
-BOOL ResetEvent(HANDLE _event)
-{
- evnet_t *event = (evnet_t *) _event;
- if (pthread_mutex_lock(&event->mutex))
- return FALSE;
- event->signaled = false;
- if (pthread_mutex_unlock(&event->mutex))
- return FALSE;
- return TRUE;
-}
-
-BOOL CloseHandle(HANDLE _event)
-{
- BOOL ret = TRUE;
- evnet_t *event = (evnet_t *) _event;
- if (!event)
- return FALSE;
- if (pthread_cond_destroy(&event->cond))
- ret = FALSE;
- if (pthread_mutex_destroy(&event->mutex))
- ret = FALSE;
- free(event);
- return ret;
-}
-
-#define WAIT_OBJECT_0 0
-#define INFINITE 0
-DWORD WaitForSingleObject(HANDLE _event, DWORD) {
- DWORD ret = WAIT_OBJECT_0;
- evnet_t *event = (evnet_t *) _event;
- if (pthread_mutex_lock(&event->mutex))
- return !WAIT_OBJECT_0;
- if (!event->signaled)
- {
- if (pthread_cond_wait(&event->cond, &event->mutex))
- {
- ret = !WAIT_OBJECT_0;
- }
- }
- event->signaled = false;
- pthread_mutex_unlock(&event->mutex);
- return ret;
-}
-
-#define WaitForMultipleObjects(x, list, y, t) WaitForSingleObject(list[0], t)
-
-#endif
-
-#ifdef _WIN32
-DWORD CLZMA::lzmaCompressThread(LPVOID lpParameter)
-#else
-void* CLZMA::lzmaCompressThread(void *lpParameter)
-#endif
-{
- CLZMA *Compressor = (CLZMA *) lpParameter;
- if (!Compressor)
- return 0;
-
- Compressor->CompressReal();
- return 0;
-}
-
-int CLZMA::ConvertError(HRESULT result)
-{
- if (result != S_OK)
- {
- if (result == E_OUTOFMEMORY)
- return LZMA_MEM_ERROR;
- else
- return LZMA_IO_ERROR;
- }
- return C_OK;
-}
-
-CLZMA::CLZMA(): _encoder(NULL)
-{
- _encoder = new NCompress::NLZMA::CEncoder();
- _encoder->SetWriteEndMarkerMode(true);
-#ifdef _WIN32
- hCompressionThread = NULL;
-#else
- hCompressionThread = 0;
-#endif
- hNeedIOEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- hIOReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- finish = FALSE;
- compressor_finished = TRUE;
- hCompressionThread = 0;
- SetNextOut(NULL, 0);
- SetNextIn(NULL, 0);
-
- AddRef(); // will be manually deleted, not released
-}
-
-CLZMA::~CLZMA()
-{
- End();
- if (hNeedIOEvent)
- {
- CloseHandle(hNeedIOEvent);
- hNeedIOEvent = NULL;
- }
- if (hIOReadyEvent)
- {
- CloseHandle(hIOReadyEvent);
- hIOReadyEvent = NULL;
- }
- if (_encoder)
- {
- delete _encoder;
- _encoder = NULL;
- }
-}
-
-int CLZMA::Init(int level, unsigned int dicSize)
-{
- End();
-
- compressor_finished = FALSE;
- finish = FALSE;
- res = C_OK;
-
- if (!hNeedIOEvent || !hIOReadyEvent)
- {
- return LZMA_INIT_ERROR;
- }
-
- ResetEvent(hNeedIOEvent);
- ResetEvent(hIOReadyEvent);
-
- res = C_OK;
-
- PROPID propdIDs [] =
- {
- NCoderPropID::kAlgorithm,
- NCoderPropID::kDictionarySize,
- NCoderPropID::kNumFastBytes
- };
- const int kNumProps = sizeof(propdIDs) / sizeof(propdIDs[0]);
- PROPVARIANT props[kNumProps];
- // NCoderPropID::kAlgorithm
- props[0].vt = VT_UI4;
- props[0].ulVal = 2;
- // NCoderPropID::kDictionarySize
- props[1].vt = VT_UI4;
- props[1].ulVal = dicSize;
- // NCoderPropID::kNumFastBytes
- props[2].vt = VT_UI4;
- props[2].ulVal = 64;
- if (_encoder->SetCoderProperties(propdIDs, props, kNumProps) != 0)
- return LZMA_INIT_ERROR;
- return _encoder->SetStreams(this, this, 0, 0) == S_OK ? C_OK : LZMA_INIT_ERROR;
-}
-
-int CLZMA::End()
-{
- // has compressor not finished?
- if (hCompressionThread && !compressor_finished)
- {
- // kill compression thread
- avail_in = 0;
- avail_out = 0;
- compressor_finished = TRUE;
-
- SetEvent(hIOReadyEvent);
-#ifdef _WIN32
- WaitForSingleObject(hCompressionThread, INFINITE);
-#else
- pthread_join(hCompressionThread, NULL);
-#endif
- }
- if (hCompressionThread)
- {
-#ifdef _WIN32
- CloseHandle(hCompressionThread);
- hCompressionThread = NULL;
-#else
- pthread_detach(hCompressionThread);
- hCompressionThread = 0;
-#endif
- }
- SetNextOut(NULL, 0);
- SetNextIn(NULL, 0);
- return C_OK;
-}
-
-int CLZMA::CompressReal()
-{
- try
- {
- HRESULT hResult = _encoder->WriteCoderProperties(this);
- if (hResult == S_OK)
- {
- while (true)
- {
- UINT64 inSize, outSize;
- INT32 finished;
- hResult = _encoder->CodeOneBlock(&inSize, &outSize, &finished);
- if (hResult != S_OK && res == C_OK)
- res = ConvertError(hResult);
- if (res != C_OK)
- break;
- if (finished)
- {
- res = C_FINISHED;
- break;
- }
- }
- }
- else
- {
- if (res == C_OK)
- res = ConvertError(hResult);
- }
- }
- catch (...)
- {
- if (res == C_OK)
- res = LZMA_IO_ERROR;
- }
-
- compressor_finished = TRUE;
- SetEvent(hNeedIOEvent);
- return C_OK;
-}
-
-int CLZMA::Compress(bool flush)
-{
- if (compressor_finished)
- {
- // act like zlib when it comes to stream ending
- if (flush)
- return C_OK;
- else
- return LZMA_BAD_CALL;
- }
-
- finish = flush;
-
- if (!hCompressionThread)
- {
-#ifdef _WIN32
- DWORD dwThreadId;
-
- hCompressionThread = CreateThread(0, 0, lzmaCompressThread, (LPVOID) this, 0, &dwThreadId);
- if (!hCompressionThread)
-#else
- if (pthread_create(&hCompressionThread, NULL, lzmaCompressThread, (LPVOID) this))
-#endif
- return LZMA_INIT_ERROR;
- }
- else
- {
- SetEvent(hIOReadyEvent);
- }
-
- HANDLE waitList[2] = {hNeedIOEvent, (HANDLE) hCompressionThread};
- if (WaitForMultipleObjects(2, waitList, FALSE, INFINITE) != WAIT_OBJECT_0)
- {
- // thread ended or WaitForMultipleObjects failed
- compressor_finished = TRUE;
- SetEvent(hIOReadyEvent);
- return LZMA_THREAD_ERROR;
- }
-
- if (compressor_finished)
- {
- return res;
- }
-
- return C_OK;
-}
-
-void CLZMA::GetMoreIO()
-{
- SetEvent(hNeedIOEvent);
- if (WaitForSingleObject(hIOReadyEvent, INFINITE) != WAIT_OBJECT_0)
- {
- compressor_finished = TRUE;
- res = LZMA_THREAD_ERROR;
- }
-}
-
-HRESULT CLZMA::Read(void *data, UINT32 size, UINT32 *processedSize)
-{
- return ReadPart(data, size, processedSize);
-}
-
-HRESULT CLZMA::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
-{
- if (processedSize)
- *processedSize = 0;
- while (size)
- {
- if (!avail_in)
- {
- if (finish)
- {
- return S_OK;
- }
- GetMoreIO();
- if (!avail_in)
- {
- if (finish)
- {
- return S_OK;
- }
- return E_ABORT;
- }
- if (compressor_finished)
- return E_ABORT;
- }
- UINT32 l = min(size, avail_in);
- memcpy(data, next_in, l);
- avail_in -= l;
- size -= l;
- next_in += l;
- data = LPBYTE(data) + l;
- if (processedSize)
- *processedSize += l;
- }
- return S_OK;
-}
-
-HRESULT CLZMA::Write(const void *data, UINT32 size, UINT32 *processedSize)
-{
- return WritePart(data, size, processedSize);
-}
-
-HRESULT CLZMA::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
-{
- if (processedSize)
- *processedSize = 0;
- while (size)
- {
- if (!avail_out)
- {
- GetMoreIO();
- if (!avail_out)
- return E_ABORT;
- }
- UINT32 l = min(size, avail_out);
- memcpy(next_out, data, l);
- avail_out -= l;
- size -= l;
- next_out += l;
- data = LPBYTE(data) + l;
- if (processedSize)
- *processedSize += l;
- }
- return S_OK;
-}
-
-void CLZMA::SetNextIn(char *in, unsigned int size)
-{
- next_in = (LPBYTE) in;
- avail_in = size;
-}
-
-void CLZMA::SetNextOut(char *out, unsigned int size)
-{
- next_out = (LPBYTE) out;
- avail_out = size;
-}
-
-char* CLZMA::GetNextOut()
-{
- return (char *) next_out;
-}
-
-unsigned int CLZMA::GetAvailIn()
-{
- return avail_in;
-}
-
-unsigned int CLZMA::GetAvailOut()
-{
- return avail_out;
-}
-
-const char* CLZMA::GetName()
-{
- return "lzma";
-}
-
-const char* CLZMA::GetErrStr(int err)
-{
- switch (err)
- {
- case LZMA_BAD_CALL:
- return "bad call";
- case LZMA_INIT_ERROR:
- return "initialization failed";
- case LZMA_THREAD_ERROR:
- return "thread synchronization error";
- case LZMA_IO_ERROR:
- return "input/output error";
- case LZMA_MEM_ERROR:
- return "not enough memory";
- default:
- return "unknown error";
- }
-}
+/*
+ * clzma.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include <algorithm> // for std::min
+#include "clzma.h"
+
+using namespace std;
+
+#ifndef _WIN32
+struct evnet_t
+{
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+ bool signaled;
+};
+
+HANDLE CreateEvent(void *, BOOL, BOOL, char *)
+{
+ evnet_t *event = (evnet_t *) malloc(sizeof(evnet_t));
+ if (!event)
+ return 0;
+ if (pthread_cond_init(&event->cond, NULL))
+ {
+ free(event);
+ return 0;
+ }
+ if (pthread_mutex_init(&event->mutex, NULL))
+ {
+ pthread_cond_destroy(&event->cond);
+ free(event);
+ return 0;
+ }
+ event->signaled = false;
+ return (HANDLE) event;
+}
+
+BOOL SetEvent(HANDLE _event)
+{
+ evnet_t *event = (evnet_t *) _event;
+ if (pthread_mutex_lock(&event->mutex))
+ return FALSE;
+ event->signaled = true;
+ pthread_cond_signal(&event->cond);
+ if (pthread_mutex_unlock(&event->mutex))
+ return FALSE;
+ return TRUE;
+}
+
+BOOL ResetEvent(HANDLE _event)
+{
+ evnet_t *event = (evnet_t *) _event;
+ if (pthread_mutex_lock(&event->mutex))
+ return FALSE;
+ event->signaled = false;
+ if (pthread_mutex_unlock(&event->mutex))
+ return FALSE;
+ return TRUE;
+}
+
+BOOL CloseHandle(HANDLE _event)
+{
+ BOOL ret = TRUE;
+ evnet_t *event = (evnet_t *) _event;
+ if (!event)
+ return FALSE;
+ if (pthread_cond_destroy(&event->cond))
+ ret = FALSE;
+ if (pthread_mutex_destroy(&event->mutex))
+ ret = FALSE;
+ free(event);
+ return ret;
+}
+
+#define WAIT_OBJECT_0 0
+#define INFINITE 0
+DWORD WaitForSingleObject(HANDLE _event, DWORD) {
+ DWORD ret = WAIT_OBJECT_0;
+ evnet_t *event = (evnet_t *) _event;
+ if (pthread_mutex_lock(&event->mutex))
+ return !WAIT_OBJECT_0;
+ if (!event->signaled)
+ {
+ if (pthread_cond_wait(&event->cond, &event->mutex))
+ {
+ ret = !WAIT_OBJECT_0;
+ }
+ }
+ event->signaled = false;
+ pthread_mutex_unlock(&event->mutex);
+ return ret;
+}
+
+#define WaitForMultipleObjects(x, list, y, t) WaitForSingleObject(list[0], t)
+
+#endif
+
+#ifdef _WIN32
+DWORD CLZMA::lzmaCompressThread(LPVOID lpParameter)
+#else
+void* CLZMA::lzmaCompressThread(void *lpParameter)
+#endif
+{
+ CLZMA *Compressor = (CLZMA *) lpParameter;
+ if (!Compressor)
+ return 0;
+
+ Compressor->CompressReal();
+ return 0;
+}
+
+int CLZMA::ConvertError(HRESULT result)
+{
+ if (result != S_OK)
+ {
+ if (result == E_OUTOFMEMORY)
+ return LZMA_MEM_ERROR;
+ else
+ return LZMA_IO_ERROR;
+ }
+ return C_OK;
+}
+
+CLZMA::CLZMA(): _encoder(NULL)
+{
+ _encoder = new NCompress::NLZMA::CEncoder();
+ _encoder->SetWriteEndMarkerMode(true);
+#ifdef _WIN32
+ hCompressionThread = NULL;
+#else
+ hCompressionThread = 0;
+#endif
+ hNeedIOEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ hIOReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ finish = FALSE;
+ compressor_finished = TRUE;
+ hCompressionThread = 0;
+ SetNextOut(NULL, 0);
+ SetNextIn(NULL, 0);
+
+ AddRef(); // will be manually deleted, not released
+}
+
+CLZMA::~CLZMA()
+{
+ End();
+ if (hNeedIOEvent)
+ {
+ CloseHandle(hNeedIOEvent);
+ hNeedIOEvent = NULL;
+ }
+ if (hIOReadyEvent)
+ {
+ CloseHandle(hIOReadyEvent);
+ hIOReadyEvent = NULL;
+ }
+ if (_encoder)
+ {
+ delete _encoder;
+ _encoder = NULL;
+ }
+}
+
+int CLZMA::Init(int level, unsigned int dicSize)
+{
+ End();
+
+ compressor_finished = FALSE;
+ finish = FALSE;
+ res = C_OK;
+
+ if (!hNeedIOEvent || !hIOReadyEvent)
+ {
+ return LZMA_INIT_ERROR;
+ }
+
+ ResetEvent(hNeedIOEvent);
+ ResetEvent(hIOReadyEvent);
+
+ res = C_OK;
+
+ PROPID propdIDs [] =
+ {
+ NCoderPropID::kAlgorithm,
+ NCoderPropID::kDictionarySize,
+ NCoderPropID::kNumFastBytes
+ };
+ const int kNumProps = sizeof(propdIDs) / sizeof(propdIDs[0]);
+ PROPVARIANT props[kNumProps];
+ // NCoderPropID::kAlgorithm
+ props[0].vt = VT_UI4;
+ props[0].ulVal = 2;
+ // NCoderPropID::kDictionarySize
+ props[1].vt = VT_UI4;
+ props[1].ulVal = dicSize;
+ // NCoderPropID::kNumFastBytes
+ props[2].vt = VT_UI4;
+ props[2].ulVal = 64;
+ if (_encoder->SetCoderProperties(propdIDs, props, kNumProps) != 0)
+ return LZMA_INIT_ERROR;
+ return _encoder->SetStreams(this, this, 0, 0) == S_OK ? C_OK : LZMA_INIT_ERROR;
+}
+
+int CLZMA::End()
+{
+ // has compressor not finished?
+ if (hCompressionThread && !compressor_finished)
+ {
+ // kill compression thread
+ avail_in = 0;
+ avail_out = 0;
+ compressor_finished = TRUE;
+
+ SetEvent(hIOReadyEvent);
+#ifdef _WIN32
+ WaitForSingleObject(hCompressionThread, INFINITE);
+#else
+ pthread_join(hCompressionThread, NULL);
+#endif
+ }
+ if (hCompressionThread)
+ {
+#ifdef _WIN32
+ CloseHandle(hCompressionThread);
+ hCompressionThread = NULL;
+#else
+ pthread_detach(hCompressionThread);
+ hCompressionThread = 0;
+#endif
+ }
+ SetNextOut(NULL, 0);
+ SetNextIn(NULL, 0);
+ return C_OK;
+}
+
+int CLZMA::CompressReal()
+{
+ try
+ {
+ HRESULT hResult = _encoder->WriteCoderProperties(this);
+ if (hResult == S_OK)
+ {
+ while (true)
+ {
+ UINT64 inSize, outSize;
+ INT32 finished;
+ hResult = _encoder->CodeOneBlock(&inSize, &outSize, &finished);
+ if (hResult != S_OK && res == C_OK)
+ res = ConvertError(hResult);
+ if (res != C_OK)
+ break;
+ if (finished)
+ {
+ res = C_FINISHED;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (res == C_OK)
+ res = ConvertError(hResult);
+ }
+ }
+ catch (...)
+ {
+ if (res == C_OK)
+ res = LZMA_IO_ERROR;
+ }
+
+ compressor_finished = TRUE;
+ SetEvent(hNeedIOEvent);
+ return C_OK;
+}
+
+int CLZMA::Compress(bool flush)
+{
+ if (compressor_finished)
+ {
+ // act like zlib when it comes to stream ending
+ if (flush)
+ return C_OK;
+ else
+ return LZMA_BAD_CALL;
+ }
+
+ finish = flush;
+
+ if (!hCompressionThread)
+ {
+#ifdef _WIN32
+ DWORD dwThreadId;
+
+ hCompressionThread = CreateThread(0, 0, lzmaCompressThread, (LPVOID) this, 0, &dwThreadId);
+ if (!hCompressionThread)
+#else
+ if (pthread_create(&hCompressionThread, NULL, lzmaCompressThread, (LPVOID) this))
+#endif
+ return LZMA_INIT_ERROR;
+ }
+ else
+ {
+ SetEvent(hIOReadyEvent);
+ }
+
+ HANDLE waitList[2] = {hNeedIOEvent, (HANDLE) hCompressionThread};
+ if (WaitForMultipleObjects(2, waitList, FALSE, INFINITE) != WAIT_OBJECT_0)
+ {
+ // thread ended or WaitForMultipleObjects failed
+ compressor_finished = TRUE;
+ SetEvent(hIOReadyEvent);
+ return LZMA_THREAD_ERROR;
+ }
+
+ if (compressor_finished)
+ {
+ return res;
+ }
+
+ return C_OK;
+}
+
+void CLZMA::GetMoreIO()
+{
+ SetEvent(hNeedIOEvent);
+ if (WaitForSingleObject(hIOReadyEvent, INFINITE) != WAIT_OBJECT_0)
+ {
+ compressor_finished = TRUE;
+ res = LZMA_THREAD_ERROR;
+ }
+}
+
+HRESULT CLZMA::Read(void *data, UINT32 size, UINT32 *processedSize)
+{
+ return ReadPart(data, size, processedSize);
+}
+
+HRESULT CLZMA::ReadPart(void *data, UINT32 size, UINT32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+ while (size)
+ {
+ if (!avail_in)
+ {
+ if (finish)
+ {
+ return S_OK;
+ }
+ GetMoreIO();
+ if (!avail_in)
+ {
+ if (finish)
+ {
+ return S_OK;
+ }
+ return E_ABORT;
+ }
+ if (compressor_finished)
+ return E_ABORT;
+ }
+ UINT32 l = min(size, avail_in);
+ memcpy(data, next_in, l);
+ avail_in -= l;
+ size -= l;
+ next_in += l;
+ data = LPBYTE(data) + l;
+ if (processedSize)
+ *processedSize += l;
+ }
+ return S_OK;
+}
+
+HRESULT CLZMA::Write(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ return WritePart(data, size, processedSize);
+}
+
+HRESULT CLZMA::WritePart(const void *data, UINT32 size, UINT32 *processedSize)
+{
+ if (processedSize)
+ *processedSize = 0;
+ while (size)
+ {
+ if (!avail_out)
+ {
+ GetMoreIO();
+ if (!avail_out)
+ return E_ABORT;
+ }
+ UINT32 l = min(size, avail_out);
+ memcpy(next_out, data, l);
+ avail_out -= l;
+ size -= l;
+ next_out += l;
+ data = LPBYTE(data) + l;
+ if (processedSize)
+ *processedSize += l;
+ }
+ return S_OK;
+}
+
+void CLZMA::SetNextIn(char *in, unsigned int size)
+{
+ next_in = (LPBYTE) in;
+ avail_in = size;
+}
+
+void CLZMA::SetNextOut(char *out, unsigned int size)
+{
+ next_out = (LPBYTE) out;
+ avail_out = size;
+}
+
+char* CLZMA::GetNextOut()
+{
+ return (char *) next_out;
+}
+
+unsigned int CLZMA::GetAvailIn()
+{
+ return avail_in;
+}
+
+unsigned int CLZMA::GetAvailOut()
+{
+ return avail_out;
+}
+
+const char* CLZMA::GetName()
+{
+ return "lzma";
+}
+
+const char* CLZMA::GetErrStr(int err)
+{
+ switch (err)
+ {
+ case LZMA_BAD_CALL:
+ return "bad call";
+ case LZMA_INIT_ERROR:
+ return "initialization failed";
+ case LZMA_THREAD_ERROR:
+ return "thread synchronization error";
+ case LZMA_IO_ERROR:
+ return "input/output error";
+ case LZMA_MEM_ERROR:
+ return "not enough memory";
+ default:
+ return "unknown error";
+ }
+}
diff --git a/Source/clzma.h b/Source/clzma.h
index 677cf78..ac90339 100755
--- a/Source/clzma.h
+++ b/Source/clzma.h
@@ -1,103 +1,103 @@
-/*
- * clzma.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __CLZMA_H__
-#define __CLZMA_H__
-
-#include "Platform.h"
-
-#ifndef _WIN32
-# include <pthread.h>
-#endif
-
-#include "compressor.h"
-#include "7zip/7zip/IStream.h"
-#include "7zip/7zip/Compress/LZMA/LZMAEncoder.h"
-#include "7zip/Common/MyCom.h"
-#include "7zip/Common/Defs.h"
-
-#define LZMA_BAD_CALL -1
-#define LZMA_INIT_ERROR -2
-#define LZMA_THREAD_ERROR -3
-#define LZMA_IO_ERROR -4
-#define LZMA_MEM_ERROR -5
-
-class CLZMA:
- public ICompressor,
- public ISequentialInStream,
- public ISequentialOutStream,
- public CMyUnknownImp
-{
-private:
- NCompress::NLZMA::CEncoder *_encoder;
-
-#ifdef _WIN32
- HANDLE hCompressionThread;
-#else
- pthread_t hCompressionThread;
-#endif
- HANDLE hNeedIOEvent;
- HANDLE hIOReadyEvent;
-
- BYTE *next_in; /* next input byte */
- UINT avail_in; /* number of bytes available at next_in */
-
- BYTE *next_out; /* next output byte should be put there */
- UINT avail_out; /* remaining free space at next_out */
-
- int res;
-
- BOOL finish;
- BOOL compressor_finished;
-
- int ConvertError(HRESULT result);
-
- void GetMoreIO();
- int CompressReal();
-
-#ifdef _WIN32
- static DWORD WINAPI lzmaCompressThread(LPVOID lpParameter);
-#else
- static void* lzmaCompressThread(void *lpParameter);
-#endif
-
-public:
- MY_UNKNOWN_IMP
-
- CLZMA();
- virtual ~CLZMA();
-
- virtual int Init(int level, unsigned int dicSize);
- virtual int End();
- virtual int Compress(bool flush);
-
- STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
- STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
- STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
- STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
-
- virtual void SetNextIn(char *in, unsigned int size);
- virtual void SetNextOut(char *out, unsigned int size);
-
- virtual char *GetNextOut();
- virtual unsigned int GetAvailIn();
- virtual unsigned int GetAvailOut();
- virtual const char *GetName();
-
- virtual const char* GetErrStr(int err);
-};
-
-#endif
+/*
+ * clzma.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __CLZMA_H__
+#define __CLZMA_H__
+
+#include "Platform.h"
+
+#ifndef _WIN32
+# include <pthread.h>
+#endif
+
+#include "compressor.h"
+#include "7zip/7zip/IStream.h"
+#include "7zip/7zip/Compress/LZMA/LZMAEncoder.h"
+#include "7zip/Common/MyCom.h"
+#include "7zip/Common/Defs.h"
+
+#define LZMA_BAD_CALL -1
+#define LZMA_INIT_ERROR -2
+#define LZMA_THREAD_ERROR -3
+#define LZMA_IO_ERROR -4
+#define LZMA_MEM_ERROR -5
+
+class CLZMA:
+ public ICompressor,
+ public ISequentialInStream,
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+private:
+ NCompress::NLZMA::CEncoder *_encoder;
+
+#ifdef _WIN32
+ HANDLE hCompressionThread;
+#else
+ pthread_t hCompressionThread;
+#endif
+ HANDLE hNeedIOEvent;
+ HANDLE hIOReadyEvent;
+
+ BYTE *next_in; /* next input byte */
+ UINT avail_in; /* number of bytes available at next_in */
+
+ BYTE *next_out; /* next output byte should be put there */
+ UINT avail_out; /* remaining free space at next_out */
+
+ int res;
+
+ BOOL finish;
+ BOOL compressor_finished;
+
+ int ConvertError(HRESULT result);
+
+ void GetMoreIO();
+ int CompressReal();
+
+#ifdef _WIN32
+ static DWORD WINAPI lzmaCompressThread(LPVOID lpParameter);
+#else
+ static void* lzmaCompressThread(void *lpParameter);
+#endif
+
+public:
+ MY_UNKNOWN_IMP
+
+ CLZMA();
+ virtual ~CLZMA();
+
+ virtual int Init(int level, unsigned int dicSize);
+ virtual int End();
+ virtual int Compress(bool flush);
+
+ STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(ReadPart)(void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
+ STDMETHOD(WritePart)(const void *data, UINT32 size, UINT32 *processedSize);
+
+ virtual void SetNextIn(char *in, unsigned int size);
+ virtual void SetNextOut(char *out, unsigned int size);
+
+ virtual char *GetNextOut();
+ virtual unsigned int GetAvailIn();
+ virtual unsigned int GetAvailOut();
+ virtual const char *GetName();
+
+ virtual const char* GetErrStr(int err);
+};
+
+#endif
diff --git a/Source/compressor.h b/Source/compressor.h
index aae7569..49524a0 100755
--- a/Source/compressor.h
+++ b/Source/compressor.h
@@ -1,46 +1,46 @@
-/*
- * compressor.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __COMPRESSOR_H__
-#define __COMPRESSOR_H__
-
-#define C_OK 0
-#define C_FINISHED 1
-
-#define C_FINISH true
-
-class ICompressor {
- public:
- virtual ~ICompressor() {}
-
- virtual int Init(int level, unsigned int dict_size) = 0;
- virtual int End() = 0;
- virtual int Compress(bool finish) = 0;
-
- virtual void SetNextIn(char *in, unsigned int size) = 0;
- virtual void SetNextOut(char *out, unsigned int size) = 0;
-
- virtual char* GetNextOut() = 0;
-
- virtual unsigned int GetAvailIn() = 0;
- virtual unsigned int GetAvailOut() = 0;
-
- virtual const char* GetName() = 0;
-
- virtual const char* GetErrStr(int err) = 0;
-};
-
-#endif
+/*
+ * compressor.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __COMPRESSOR_H__
+#define __COMPRESSOR_H__
+
+#define C_OK 0
+#define C_FINISHED 1
+
+#define C_FINISH true
+
+class ICompressor {
+ public:
+ virtual ~ICompressor() {}
+
+ virtual int Init(int level, unsigned int dict_size) = 0;
+ virtual int End() = 0;
+ virtual int Compress(bool finish) = 0;
+
+ virtual void SetNextIn(char *in, unsigned int size) = 0;
+ virtual void SetNextOut(char *out, unsigned int size) = 0;
+
+ virtual char* GetNextOut() = 0;
+
+ virtual unsigned int GetAvailIn() = 0;
+ virtual unsigned int GetAvailOut() = 0;
+
+ virtual const char* GetName() = 0;
+
+ virtual const char* GetErrStr(int err) = 0;
+};
+
+#endif
diff --git a/Source/crc32.c b/Source/crc32.c
index eb3a988..e8fabf9 100755
--- a/Source/crc32.c
+++ b/Source/crc32.c
@@ -1,47 +1,47 @@
-/*
- * crc32.c
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-#include "crc32.h"
-#include "exehead/config.h"
-#ifdef NSIS_CONFIG_CRC_SUPPORT
-
-// this is based on the (slow,small) CRC32 implementation from zlib.
-crc32_t NSISCALL CRC32(crc32_t crc, const unsigned char *buf, unsigned int len)
-{
- static crc32_t crc_table[256];
-
- if (!crc_table[1])
- {
- crc32_t c;
- int n, k;
-
- for (n = 0; n < 256; n++)
- {
- c = (crc32_t)n;
- for (k = 0; k < 8; k++) c = (c >> 1) ^ (c & 1 ? 0xedb88320L : 0);
- crc_table[n] = c;
- }
- }
-
- crc = crc ^ 0xffffffffL;
- while (len-- > 0) {
- crc = crc_table[(crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
- }
- return crc ^ 0xffffffffL;
-}
-
-#endif
+/*
+ * crc32.c
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+#include "crc32.h"
+#include "exehead/config.h"
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+
+// this is based on the (slow,small) CRC32 implementation from zlib.
+crc32_t NSISCALL CRC32(crc32_t crc, const unsigned char *buf, unsigned int len)
+{
+ static crc32_t crc_table[256];
+
+ if (!crc_table[1])
+ {
+ crc32_t c;
+ int n, k;
+
+ for (n = 0; n < 256; n++)
+ {
+ c = (crc32_t)n;
+ for (k = 0; k < 8; k++) c = (c >> 1) ^ (c & 1 ? 0xedb88320L : 0);
+ crc_table[n] = c;
+ }
+ }
+
+ crc = crc ^ 0xffffffffL;
+ while (len-- > 0) {
+ crc = crc_table[(crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+ }
+ return crc ^ 0xffffffffL;
+}
+
+#endif
diff --git a/Source/crc32.h b/Source/crc32.h
index 8245b6f..92fb7c9 100755
--- a/Source/crc32.h
+++ b/Source/crc32.h
@@ -1,29 +1,29 @@
-/*
- * crc32.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-
-#ifndef ___CRC32__H___
-#define ___CRC32__H___
-
-typedef UINT32 crc32_t;
-
-#ifdef __cplusplus
-extern "C"
-#endif
-crc32_t NSISCALL CRC32(crc32_t crc, const unsigned char *buf, unsigned int len);
-
-#endif//!___CRC32__H___
+/*
+ * crc32.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+
+#ifndef ___CRC32__H___
+#define ___CRC32__H___
+
+typedef UINT32 crc32_t;
+
+#ifdef __cplusplus
+extern "C"
+#endif
+crc32_t NSISCALL CRC32(crc32_t crc, const unsigned char *buf, unsigned int len);
+
+#endif//!___CRC32__H___
diff --git a/Source/czlib.h b/Source/czlib.h
index 7d1b3e9..c929dea 100755
--- a/Source/czlib.h
+++ b/Source/czlib.h
@@ -1,91 +1,91 @@
-/*
- * czlib.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __CZLIB_H__
-#define __CZLIB_H__
-
-#include "compressor.h"
-#include "zlib/ZLIB.H"
-
-class CZlib : public ICompressor {
- public:
- virtual ~CZlib() {}
-
- int Init(int level, unsigned int dict_size) {
- stream = new z_stream;
- if (!stream) return Z_MEM_ERROR;
- return deflateInit(stream, level);
- }
-
- int End() {
- int ret = deflateEnd(stream);
- delete stream;
- return ret;
- }
-
- int Compress(bool finish) {
- return deflate(stream, finish?Z_FINISH:0);
- }
-
- void SetNextIn(char *in, unsigned int size) {
- stream->next_in = (unsigned char*)in;
- stream->avail_in = size;
- }
-
- void SetNextOut(char *out, unsigned int size) {
- stream->next_out = (unsigned char*)out;
- stream->avail_out = size;
- }
-
- virtual char* GetNextOut() {
- return (char*)stream->next_out;
- }
-
- virtual unsigned int GetAvailIn() {
- return stream->avail_in;
- }
-
- virtual unsigned int GetAvailOut() {
- return stream->avail_out;
- }
-
- const char* GetName() {
- return "zlib";
- }
-
- const char* GetErrStr(int err) {
- switch (err)
- {
- case Z_STREAM_ERROR:
- return "invalid stream - bad call";
- case Z_DATA_ERROR:
- return "data error";
- case Z_MEM_ERROR:
- return "not enough memory";
- case Z_BUF_ERROR:
- return "buffer error - bad call";
- case Z_VERSION_ERROR:
- return "version error";
- default:
- return "unknown error";
- }
- }
-
- private:
- z_stream *stream;
-};
-
-#endif
+/*
+ * czlib.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __CZLIB_H__
+#define __CZLIB_H__
+
+#include "compressor.h"
+#include "zlib/ZLIB.H"
+
+class CZlib : public ICompressor {
+ public:
+ virtual ~CZlib() {}
+
+ int Init(int level, unsigned int dict_size) {
+ stream = new z_stream;
+ if (!stream) return Z_MEM_ERROR;
+ return deflateInit(stream, level);
+ }
+
+ int End() {
+ int ret = deflateEnd(stream);
+ delete stream;
+ return ret;
+ }
+
+ int Compress(bool finish) {
+ return deflate(stream, finish?Z_FINISH:0);
+ }
+
+ void SetNextIn(char *in, unsigned int size) {
+ stream->next_in = (unsigned char*)in;
+ stream->avail_in = size;
+ }
+
+ void SetNextOut(char *out, unsigned int size) {
+ stream->next_out = (unsigned char*)out;
+ stream->avail_out = size;
+ }
+
+ virtual char* GetNextOut() {
+ return (char*)stream->next_out;
+ }
+
+ virtual unsigned int GetAvailIn() {
+ return stream->avail_in;
+ }
+
+ virtual unsigned int GetAvailOut() {
+ return stream->avail_out;
+ }
+
+ const char* GetName() {
+ return "zlib";
+ }
+
+ const char* GetErrStr(int err) {
+ switch (err)
+ {
+ case Z_STREAM_ERROR:
+ return "invalid stream - bad call";
+ case Z_DATA_ERROR:
+ return "data error";
+ case Z_MEM_ERROR:
+ return "not enough memory";
+ case Z_BUF_ERROR:
+ return "buffer error - bad call";
+ case Z_VERSION_ERROR:
+ return "version error";
+ default:
+ return "unknown error";
+ }
+ }
+
+ private:
+ z_stream *stream;
+};
+
+#endif
diff --git a/Source/dirreader.cpp b/Source/dirreader.cpp
index f6b9052..5dd0616 100755
--- a/Source/dirreader.cpp
+++ b/Source/dirreader.cpp
@@ -1,244 +1,244 @@
-/*
- * dirreader.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-#include "dirreader.h"
-#include <string>
-#include <set>
-
-#include <string.h> // for stricmp()
-#include <ctype.h> // for tolower()
-
-using namespace std;
-
-dir_reader::dir_reader() {
- exclude(".");
- exclude("..");
-}
-
-const set<string>& dir_reader::files() {
- return m_files;
-}
-
-const set<string>& dir_reader::dirs() {
- return m_dirs;
-}
-
-void dir_reader::exclude(const string& spec) {
- if (spec.find_first_of("?*") != string::npos) {
- m_wildcard_excluded.insert(spec);
- } else {
- m_excluded.insert(spec);
- }
-}
-
-void dir_reader::exclude(const set<string>& specs) {
- iterator i = specs.begin();
- iterator e = specs.end();
-
- for (; i != e; i++) {
- exclude(*i);
- }
-}
-
-bool dir_reader::matches(const string& name, const string& spec) {
- string::const_iterator name_itr = name.begin();
- string::const_iterator name_end = name.end();
-
- string::const_iterator spec_itr = spec.begin();
- string::const_iterator spec_end = spec.end();
-
- string::const_iterator last_good_spec = spec_end;
- string::const_iterator last_good_name = name_end;
-
- while (name_itr != name_end && spec_itr != spec_end) {
- switch (*spec_itr) {
- case '?':
- // question mark mathes one char
- name_itr++;
- spec_itr++;
- break;
-
- case '*':
- // double asterisk is the same as a single asterisk
- while (*spec_itr == '*') {
- spec_itr++;
- // asterisk at the end of the spec matches the end of the name
- if (spec_itr == spec_end)
- return true;
- }
-
- // remember last good name and spec for prematurely stopped asterisk
- last_good_spec = spec_itr;
- last_good_name = name_itr;
-
- break;
-
- default:
- if (::tolower(*name_itr) != ::tolower(*spec_itr)) {
- if (last_good_spec != spec_end) {
- // matched wrong part of the name, try again
- spec_itr = last_good_spec;
- name_itr = ++last_good_name;
- } else {
- // no match and no asterisk to use
- return false;
- }
- } else {
- // remember last good name for prematurely stopped asterisk
- last_good_name = name_itr;
-
- spec_itr++;
- name_itr++;
-
- if (spec_itr == spec_end && name_itr != name_end && last_good_spec != spec_end) {
- // asterisk hasn't matched enough, keep matching
- spec_itr = last_good_spec;
- }
- }
- break;
- }
- }
-
- // skip any redundant asterisks and periods at the end of the name
- while (spec_itr != spec_end) {
- if (*spec_itr != '.' && *spec_itr != '*') {
- break;
- }
- spec_itr++;
- }
-
- // return true only if managed to match everything
- return name_itr == name_end && spec_itr == spec_end;
-}
-
-void dir_reader::add_file(const string& file) {
- if (!is_excluded(file)) {
- m_files.insert(file);
- }
-}
-
-void dir_reader::add_dir(const string& dir) {
- if (!is_excluded(dir)) {
- m_dirs.insert(dir);
- }
-}
-
-bool dir_reader::is_excluded(const string& name) const {
- iterator i = m_excluded.begin();
- iterator e = m_excluded.end();
-
- for (; i != e; i++) {
- if (!::stricmp(name.c_str(), i->c_str())) {
- return true;
- }
- }
-
- i = m_wildcard_excluded.begin();
- e = m_wildcard_excluded.end();
-
- for (; i != e; i++) {
- if (matches(name, *i)) {
- return true;
- }
- }
-
- return false;
-}
-
-#ifdef _WIN32
-
-class win32_dir_reader : public dir_reader {
-public:
-
- virtual void read(const string& dir) {
- WIN32_FIND_DATA fd;
-
- string spec = dir + PLATFORM_PATH_SEPARATOR_STR + "*.*";
-
- HANDLE h = ::FindFirstFile(spec.c_str(), &fd);
- if (h != INVALID_HANDLE_VALUE) {
- do {
- if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- dir_reader::add_dir(fd.cFileName);
- } else {
- dir_reader::add_file(fd.cFileName);
- }
- } while (::FindNextFile(h, &fd));
- ::FindClose(h);
- }
- }
-
-};
-
-#else
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <dirent.h>
-
-class posix_dir_reader : public dir_reader {
-public:
-
- virtual void read(const string& dir) {
- //convert(dir);
-
- DIR *dip = ::opendir(dir.c_str());
- if (dip) {
- dirent *dit;
- while ((dit = ::readdir(dip))) {
- struct stat st;
- string file = dir + PLATFORM_PATH_SEPARATOR_STR + dit->d_name;
-
- if (!stat(file.c_str(), &st)) {
- if (S_ISDIR(st.st_mode)) {
- dir_reader::add_dir(dit->d_name);
- } else {
- dir_reader::add_file(dit->d_name);
- }
- }
- }
- ::closedir(dip);
- }
- }
-
-private:
-
- void convert(string& path) {
- string::size_type pos = path.find('\\');
- while (pos != string::npos) {
- path[pos] = '/';
- pos = path.find('\\');
- }
-
- /* Replace drive letter X: by /x */
- if (path[1] == ':') {
- path[1] = ::tolower(path[0]);
- path[0] = '/';
- }
- }
-
-};
-
-#endif
-
-dir_reader* new_dir_reader() {
-#ifdef _WIN32
- return new win32_dir_reader();
-#else
- return new posix_dir_reader();
-#endif
-}
+/*
+ * dirreader.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+#include "dirreader.h"
+#include <string>
+#include <set>
+
+#include <string.h> // for stricmp()
+#include <ctype.h> // for tolower()
+
+using namespace std;
+
+dir_reader::dir_reader() {
+ exclude(".");
+ exclude("..");
+}
+
+const set<string>& dir_reader::files() {
+ return m_files;
+}
+
+const set<string>& dir_reader::dirs() {
+ return m_dirs;
+}
+
+void dir_reader::exclude(const string& spec) {
+ if (spec.find_first_of("?*") != string::npos) {
+ m_wildcard_excluded.insert(spec);
+ } else {
+ m_excluded.insert(spec);
+ }
+}
+
+void dir_reader::exclude(const set<string>& specs) {
+ iterator i = specs.begin();
+ iterator e = specs.end();
+
+ for (; i != e; i++) {
+ exclude(*i);
+ }
+}
+
+bool dir_reader::matches(const string& name, const string& spec) {
+ string::const_iterator name_itr = name.begin();
+ string::const_iterator name_end = name.end();
+
+ string::const_iterator spec_itr = spec.begin();
+ string::const_iterator spec_end = spec.end();
+
+ string::const_iterator last_good_spec = spec_end;
+ string::const_iterator last_good_name = name_end;
+
+ while (name_itr != name_end && spec_itr != spec_end) {
+ switch (*spec_itr) {
+ case '?':
+ // question mark mathes one char
+ name_itr++;
+ spec_itr++;
+ break;
+
+ case '*':
+ // double asterisk is the same as a single asterisk
+ while (*spec_itr == '*') {
+ spec_itr++;
+ // asterisk at the end of the spec matches the end of the name
+ if (spec_itr == spec_end)
+ return true;
+ }
+
+ // remember last good name and spec for prematurely stopped asterisk
+ last_good_spec = spec_itr;
+ last_good_name = name_itr;
+
+ break;
+
+ default:
+ if (::tolower(*name_itr) != ::tolower(*spec_itr)) {
+ if (last_good_spec != spec_end) {
+ // matched wrong part of the name, try again
+ spec_itr = last_good_spec;
+ name_itr = ++last_good_name;
+ } else {
+ // no match and no asterisk to use
+ return false;
+ }
+ } else {
+ // remember last good name for prematurely stopped asterisk
+ last_good_name = name_itr;
+
+ spec_itr++;
+ name_itr++;
+
+ if (spec_itr == spec_end && name_itr != name_end && last_good_spec != spec_end) {
+ // asterisk hasn't matched enough, keep matching
+ spec_itr = last_good_spec;
+ }
+ }
+ break;
+ }
+ }
+
+ // skip any redundant asterisks and periods at the end of the name
+ while (spec_itr != spec_end) {
+ if (*spec_itr != '.' && *spec_itr != '*') {
+ break;
+ }
+ spec_itr++;
+ }
+
+ // return true only if managed to match everything
+ return name_itr == name_end && spec_itr == spec_end;
+}
+
+void dir_reader::add_file(const string& file) {
+ if (!is_excluded(file)) {
+ m_files.insert(file);
+ }
+}
+
+void dir_reader::add_dir(const string& dir) {
+ if (!is_excluded(dir)) {
+ m_dirs.insert(dir);
+ }
+}
+
+bool dir_reader::is_excluded(const string& name) const {
+ iterator i = m_excluded.begin();
+ iterator e = m_excluded.end();
+
+ for (; i != e; i++) {
+ if (!::stricmp(name.c_str(), i->c_str())) {
+ return true;
+ }
+ }
+
+ i = m_wildcard_excluded.begin();
+ e = m_wildcard_excluded.end();
+
+ for (; i != e; i++) {
+ if (matches(name, *i)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#ifdef _WIN32
+
+class win32_dir_reader : public dir_reader {
+public:
+
+ virtual void read(const string& dir) {
+ WIN32_FIND_DATA fd;
+
+ string spec = dir + PLATFORM_PATH_SEPARATOR_STR + "*.*";
+
+ HANDLE h = ::FindFirstFile(spec.c_str(), &fd);
+ if (h != INVALID_HANDLE_VALUE) {
+ do {
+ if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ dir_reader::add_dir(fd.cFileName);
+ } else {
+ dir_reader::add_file(fd.cFileName);
+ }
+ } while (::FindNextFile(h, &fd));
+ ::FindClose(h);
+ }
+ }
+
+};
+
+#else
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+class posix_dir_reader : public dir_reader {
+public:
+
+ virtual void read(const string& dir) {
+ //convert(dir);
+
+ DIR *dip = ::opendir(dir.c_str());
+ if (dip) {
+ dirent *dit;
+ while ((dit = ::readdir(dip))) {
+ struct stat st;
+ string file = dir + PLATFORM_PATH_SEPARATOR_STR + dit->d_name;
+
+ if (!stat(file.c_str(), &st)) {
+ if (S_ISDIR(st.st_mode)) {
+ dir_reader::add_dir(dit->d_name);
+ } else {
+ dir_reader::add_file(dit->d_name);
+ }
+ }
+ }
+ ::closedir(dip);
+ }
+ }
+
+private:
+
+ void convert(string& path) {
+ string::size_type pos = path.find('\\');
+ while (pos != string::npos) {
+ path[pos] = '/';
+ pos = path.find('\\');
+ }
+
+ /* Replace drive letter X: by /x */
+ if (path[1] == ':') {
+ path[1] = ::tolower(path[0]);
+ path[0] = '/';
+ }
+ }
+
+};
+
+#endif
+
+dir_reader* new_dir_reader() {
+#ifdef _WIN32
+ return new win32_dir_reader();
+#else
+ return new posix_dir_reader();
+#endif
+}
diff --git a/Source/dirreader.h b/Source/dirreader.h
index c0bcbb4..d7426a8 100755
--- a/Source/dirreader.h
+++ b/Source/dirreader.h
@@ -1,56 +1,56 @@
-/*
- * dirreader.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-#include <string>
-#include <set>
-
-class dir_reader {
-public:
-
- typedef std::set<std::string>::const_iterator iterator;
-
- dir_reader();
- virtual ~dir_reader() {}
-
- virtual void read(const std::string& dir) = 0;
-
- virtual const std::set<std::string>& files();
- virtual const std::set<std::string>& dirs();
-
- virtual void exclude(const std::string& spec);
- virtual void exclude(const std::set<std::string>& specs);
-
- static bool matches(const std::string& name, const std::string& spec);
-
-protected:
-
- virtual void add_file(const std::string& file);
- virtual void add_dir(const std::string& dir);
-
- virtual bool is_excluded(const std::string& name) const;
-
-private:
-
- std::set<std::string> m_excluded;
- std::set<std::string> m_wildcard_excluded;
-
- std::set<std::string> m_files;
- std::set<std::string> m_dirs;
-
-};
-
-dir_reader* new_dir_reader();
+/*
+ * dirreader.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+#include <string>
+#include <set>
+
+class dir_reader {
+public:
+
+ typedef std::set<std::string>::const_iterator iterator;
+
+ dir_reader();
+ virtual ~dir_reader() {}
+
+ virtual void read(const std::string& dir) = 0;
+
+ virtual const std::set<std::string>& files();
+ virtual const std::set<std::string>& dirs();
+
+ virtual void exclude(const std::string& spec);
+ virtual void exclude(const std::set<std::string>& specs);
+
+ static bool matches(const std::string& name, const std::string& spec);
+
+protected:
+
+ virtual void add_file(const std::string& file);
+ virtual void add_dir(const std::string& dir);
+
+ virtual bool is_excluded(const std::string& name) const;
+
+private:
+
+ std::set<std::string> m_excluded;
+ std::set<std::string> m_wildcard_excluded;
+
+ std::set<std::string> m_files;
+ std::set<std::string> m_dirs;
+
+};
+
+dir_reader* new_dir_reader();
diff --git a/Source/exehead/Main.c b/Source/exehead/Main.c
index 26cdd4f..5c91796 100755
--- a/Source/exehead/Main.c
+++ b/Source/exehead/Main.c
@@ -1,348 +1,348 @@
-/*
- * main.c: executable header main code
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "../Platform.h"
-#include <shlobj.h>
-#include <shellapi.h>
-#include "resource.h"
-#include "util.h"
-#include "fileform.h"
-#include "state.h"
-#include "ui.h"
-#include "lang.h"
-#include "state.h"
-#include "exec.h"
-
-#if !defined(NSIS_CONFIG_VISIBLE_SUPPORT) && !defined(NSIS_CONFIG_SILENT_SUPPORT)
-#error One of NSIS_CONFIG_SILENT_SUPPORT or NSIS_CONFIG_VISIBLE_SUPPORT must be defined.
-#endif
-#ifdef NSIS_COMPRESS_WHOLE
-extern HANDLE dbd_hFile;
-#endif
-
-char g_caption[NSIS_MAX_STRLEN*2];
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-HWND g_hwnd;
-HANDLE g_hInstance;
-#endif
-
-void NSISCALL CleanUp();
-
-char *ValidateTempDir()
-{
- validate_filename(state_temp_dir);
- if (!validpathspec(state_temp_dir))
- return NULL;
- addtrailingslash(state_temp_dir);
- CreateDirectory(state_temp_dir, NULL);
- // state_language is used as a temp var here
- return my_GetTempFileName(state_language, state_temp_dir);
-}
-
-void *g_SHGetFolderPath;
-
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, int nCmdShow)
-{
- int ret = 0;
- const char *m_Err = _LANG_ERRORWRITINGTEMP;
-
- int cl_flags = 0;
-
- char *realcmds;
- char seekchar=' ';
- char *cmdline;
-
- InitCommonControls();
-
- SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
-
-#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
- {
- extern HRESULT g_hres;
- g_hres=OleInitialize(NULL);
- }
-#endif
-
- // load shfolder.dll before any script code is executed to avoid
- // weird situations where SetOutPath or even the extraction of
- // shfolder.dll will cause unexpected behavior.
- //
- // this also prevents the following:
- //
- // SetOutPath "C:\Program Files\NSIS" # maybe read from reg
- // File shfolder.dll
- // Delete $PROGRAMFILES\shfolder.dll # can't be deleted, as the
- // # new shfolder.dll is used
- // # to find its own path.
- g_SHGetFolderPath = myGetProcAddress(MGA_SHGetFolderPathA);
-
- {
- // workaround for bug #1008632
- // http://sourceforge.net/tracker/index.php?func=detail&aid=1008632&group_id=22049&atid=373085
- //
- // without this, SHGetSpecialFolderLocation doesn't always recognize
- // some special folders, like the desktop folder for all users, on
- // Windows 9x. unlike SHGetSpecialFolderPath, which is not available
- // on all versions of Windows, SHGetSpecialFolderLocation doesn't try
- // too hard to make sure the caller gets what he asked for. so we give
- // it a little push in the right direction by doing part of the work
- // for it.
- //
- // part of what SHGetFileInfo does, is to convert a path into an idl.
- // to do this conversion, it first needs to initialize the list of
- // special idls, which are exactly the idls we use to get the paths
- // of special folders (CSIDL_*).
-
- SHFILEINFO shfi;
- SHGetFileInfo("", 0, &shfi, sizeof(SHFILEINFO), 0);
- }
-
- mystrcpy(g_caption,_LANG_GENERIC_ERROR);
-
- mystrcpy(state_command_line, GetCommandLine());
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- g_hInstance = GetModuleHandle(NULL);
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
-
- cmdline = state_command_line;
- if (*cmdline == '\"') seekchar = *cmdline++;
-
- cmdline=findchar(cmdline, seekchar);
- cmdline=CharNext(cmdline);
- realcmds=cmdline;
-
- while (*cmdline)
- {
- // skip over any spaces
- while (*cmdline == ' ') cmdline++;
-
- // get char we should look for to get the next parm
- seekchar = ' ';
- if (cmdline[0] == '\"')
- {
- cmdline++;
- seekchar = '\"';
- }
-
- // is it a switch?
- if (cmdline[0] == '/')
- {
- cmdline++;
-
-// this only works with spaces because they have just one bit on
-#define END_OF_ARG(c) (((c)|' ')==' ')
-
-#if defined(NSIS_CONFIG_VISIBLE_SUPPORT) && defined(NSIS_CONFIG_SILENT_SUPPORT)
- if (cmdline[0] == 'S' && END_OF_ARG(cmdline[1]))
- cl_flags |= FH_FLAGS_SILENT;
-#endif//NSIS_CONFIG_SILENT_SUPPORT && NSIS_CONFIG_VISIBLE_SUPPORT
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- if (*(LPDWORD)cmdline == CHAR4_TO_DWORD('N','C','R','C') && END_OF_ARG(cmdline[4]))
- cl_flags |= FH_FLAGS_NO_CRC;
-#endif//NSIS_CONFIG_CRC_SUPPORT
-
- if (*(LPDWORD)(cmdline-2) == CHAR4_TO_DWORD(' ', '/', 'D','='))
- {
- *(LPDWORD)(cmdline-2)=0; // keep this from being passed to uninstaller if necessary
- mystrcpy(state_install_directory,cmdline+2);
- break; // /D= must always be last
- }
- }
-
- // skip over our parm
- cmdline = findchar(cmdline, seekchar);
- // skip the quote
- if (*cmdline == '\"')
- cmdline++;
- }
-
- GetTempPath(NSIS_MAX_STRLEN, state_temp_dir);
- if (!ValidateTempDir())
- {
- GetWindowsDirectory(state_temp_dir, NSIS_MAX_STRLEN - 5); // leave space for \Temp
- mystrcat(state_temp_dir, "\\Temp");
- if (!ValidateTempDir())
- {
- goto end;
- }
- }
- DeleteFile(state_language);
-
- m_Err = loadHeaders(cl_flags);
- if (m_Err) goto end;
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (g_is_uninstaller)
- {
- char *p = findchar(state_command_line, 0);
-
- // state_command_line has state_install_directory right after it in memory, so reading
- // a bit over state_command_line won't do any harm
- while (p >= state_command_line && *(LPDWORD)p != CHAR4_TO_DWORD(' ', '_', '?', '=')) p--;
-
- m_Err = _LANG_UNINSTINITERROR;
-
- if (p >= state_command_line)
- {
- *p=0; // terminate before "_?="
- p+=4; // skip over " _?="
- if (is_valid_instpath(p))
- {
- mystrcpy(state_install_directory, p);
- mystrcpy(state_output_directory, p);
- m_Err = 0;
- }
- else
- {
- goto end;
- }
- }
- else
- {
- int x;
-
- mystrcat(state_temp_dir,"~nsu.tmp");
-
- // check if already running from uninstaller temp dir
- // this prevents recursive uninstaller calls
- if (!lstrcmpi(state_temp_dir,state_exe_directory))
- goto end;
-
- CreateDirectory(state_temp_dir,NULL);
- SetCurrentDirectory(state_temp_dir);
-
- if (!state_install_directory[0])
- mystrcpy(state_install_directory,state_exe_directory);
-
- mystrcpy(g_usrvars[0], realcmds);
- *(LPWORD)g_usrvars[1] = CHAR2_TO_WORD('A',0);
-
- for (x = 0; x < 26; x ++)
- {
- static char buf2[NSIS_MAX_STRLEN];
-
- GetNSISString(buf2,g_header->str_uninstchild); // $TEMP\$1u_.exe
-
- DeleteFile(buf2); // clean up after all the other ones if they are there
-
- if (m_Err) // not done yet
- {
- // copy file
- if (CopyFile(state_exe_path,buf2,TRUE))
- {
- HANDLE hProc;
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
- MoveFileOnReboot(buf2,NULL);
-#endif
- GetNSISString(buf2,g_header->str_uninstcmd); // '"$TEMP\$1u_.exe" $0 _?=$INSTDIR\'
- hProc=myCreateProcess(buf2);
- if (hProc)
- {
- CloseHandle(hProc);
- // success
- m_Err = 0;
- }
- }
- }
- g_usrvars[1][0]++;
- }
-
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
- MoveFileOnReboot(state_temp_dir,NULL);
-#endif
-
- goto end;
- }
- }
-#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
-
- g_exec_flags.errlvl = -1;
- ret = ui_doinstall();
-
-#ifdef NSIS_CONFIG_LOG
-#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
- log_write(1);
-#endif//!NSIS_CONFIG_LOG_ODS && !NSIS_CONFIG_LOG_STDOUT
-#endif//NSIS_CONFIG_LOG
-end:
-
- CleanUp();
-
-#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
- OleUninitialize();
-#endif
-
- if (m_Err)
- {
- my_MessageBox(m_Err, MB_OK | MB_ICONSTOP | (IDOK << 21));
- ExitProcess(2);
- return 0;
- }
-
-#ifdef NSIS_SUPPORT_REBOOT
- if (g_exec_flags.reboot_called)
- {
- BOOL (WINAPI *OPT)(HANDLE, DWORD,PHANDLE);
- BOOL (WINAPI *LPV)(LPCTSTR,LPCTSTR,PLUID);
- BOOL (WINAPI *ATP)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
- OPT=myGetProcAddress(MGA_OpenProcessToken);
- LPV=myGetProcAddress(MGA_LookupPrivilegeValueA);
- ATP=myGetProcAddress(MGA_AdjustTokenPrivileges);
- if (OPT && LPV && ATP)
- {
- HANDLE hToken;
- TOKEN_PRIVILEGES tkp;
- if (OPT(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
- {
- LPV(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
- tkp.PrivilegeCount = 1;
- tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- ATP(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
- }
- }
-
- if (!ExitWindowsEx(EWX_REBOOT,0))
- ExecuteCallbackFunction(CB_ONREBOOTFAILED);
- }
-#endif//NSIS_SUPPORT_REBOOT
-
- if (g_exec_flags.errlvl != -1)
- ret = g_exec_flags.errlvl;
-
- ExitProcess(ret);
- return 0;
-}
-
-void NSISCALL CleanUp()
-{
- if (g_db_hFile != INVALID_HANDLE_VALUE)
- {
- CloseHandle(g_db_hFile);
- g_db_hFile = INVALID_HANDLE_VALUE;
- }
-#ifdef NSIS_COMPRESS_WHOLE
- if (dbd_hFile != INVALID_HANDLE_VALUE)
- {
- CloseHandle(dbd_hFile);
- dbd_hFile = INVALID_HANDLE_VALUE;
- }
-#endif
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
- // Clean up after plug-ins
- myDelete(state_plugins_dir, DEL_DIR | DEL_RECURSE | DEL_REBOOT);
-#endif // NSIS_CONFIG_PLUGIN_SUPPORT
-}
+/*
+ * main.c: executable header main code
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "../Platform.h"
+#include <shlobj.h>
+#include <shellapi.h>
+#include "resource.h"
+#include "util.h"
+#include "fileform.h"
+#include "state.h"
+#include "ui.h"
+#include "lang.h"
+#include "state.h"
+#include "exec.h"
+
+#if !defined(NSIS_CONFIG_VISIBLE_SUPPORT) && !defined(NSIS_CONFIG_SILENT_SUPPORT)
+#error One of NSIS_CONFIG_SILENT_SUPPORT or NSIS_CONFIG_VISIBLE_SUPPORT must be defined.
+#endif
+#ifdef NSIS_COMPRESS_WHOLE
+extern HANDLE dbd_hFile;
+#endif
+
+char g_caption[NSIS_MAX_STRLEN*2];
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+HWND g_hwnd;
+HANDLE g_hInstance;
+#endif
+
+void NSISCALL CleanUp();
+
+char *ValidateTempDir()
+{
+ validate_filename(state_temp_dir);
+ if (!validpathspec(state_temp_dir))
+ return NULL;
+ addtrailingslash(state_temp_dir);
+ CreateDirectory(state_temp_dir, NULL);
+ // state_language is used as a temp var here
+ return my_GetTempFileName(state_language, state_temp_dir);
+}
+
+void *g_SHGetFolderPath;
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, int nCmdShow)
+{
+ int ret = 0;
+ const char *m_Err = _LANG_ERRORWRITINGTEMP;
+
+ int cl_flags = 0;
+
+ char *realcmds;
+ char seekchar=' ';
+ char *cmdline;
+
+ InitCommonControls();
+
+ SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
+
+#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
+ {
+ extern HRESULT g_hres;
+ g_hres=OleInitialize(NULL);
+ }
+#endif
+
+ // load shfolder.dll before any script code is executed to avoid
+ // weird situations where SetOutPath or even the extraction of
+ // shfolder.dll will cause unexpected behavior.
+ //
+ // this also prevents the following:
+ //
+ // SetOutPath "C:\Program Files\NSIS" # maybe read from reg
+ // File shfolder.dll
+ // Delete $PROGRAMFILES\shfolder.dll # can't be deleted, as the
+ // # new shfolder.dll is used
+ // # to find its own path.
+ g_SHGetFolderPath = myGetProcAddress(MGA_SHGetFolderPathA);
+
+ {
+ // workaround for bug #1008632
+ // http://sourceforge.net/tracker/index.php?func=detail&aid=1008632&group_id=22049&atid=373085
+ //
+ // without this, SHGetSpecialFolderLocation doesn't always recognize
+ // some special folders, like the desktop folder for all users, on
+ // Windows 9x. unlike SHGetSpecialFolderPath, which is not available
+ // on all versions of Windows, SHGetSpecialFolderLocation doesn't try
+ // too hard to make sure the caller gets what he asked for. so we give
+ // it a little push in the right direction by doing part of the work
+ // for it.
+ //
+ // part of what SHGetFileInfo does, is to convert a path into an idl.
+ // to do this conversion, it first needs to initialize the list of
+ // special idls, which are exactly the idls we use to get the paths
+ // of special folders (CSIDL_*).
+
+ SHFILEINFO shfi;
+ SHGetFileInfo("", 0, &shfi, sizeof(SHFILEINFO), 0);
+ }
+
+ mystrcpy(g_caption,_LANG_GENERIC_ERROR);
+
+ mystrcpy(state_command_line, GetCommandLine());
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ g_hInstance = GetModuleHandle(NULL);
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+
+ cmdline = state_command_line;
+ if (*cmdline == '\"') seekchar = *cmdline++;
+
+ cmdline=findchar(cmdline, seekchar);
+ cmdline=CharNext(cmdline);
+ realcmds=cmdline;
+
+ while (*cmdline)
+ {
+ // skip over any spaces
+ while (*cmdline == ' ') cmdline++;
+
+ // get char we should look for to get the next parm
+ seekchar = ' ';
+ if (cmdline[0] == '\"')
+ {
+ cmdline++;
+ seekchar = '\"';
+ }
+
+ // is it a switch?
+ if (cmdline[0] == '/')
+ {
+ cmdline++;
+
+// this only works with spaces because they have just one bit on
+#define END_OF_ARG(c) (((c)|' ')==' ')
+
+#if defined(NSIS_CONFIG_VISIBLE_SUPPORT) && defined(NSIS_CONFIG_SILENT_SUPPORT)
+ if (cmdline[0] == 'S' && END_OF_ARG(cmdline[1]))
+ cl_flags |= FH_FLAGS_SILENT;
+#endif//NSIS_CONFIG_SILENT_SUPPORT && NSIS_CONFIG_VISIBLE_SUPPORT
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ if (*(LPDWORD)cmdline == CHAR4_TO_DWORD('N','C','R','C') && END_OF_ARG(cmdline[4]))
+ cl_flags |= FH_FLAGS_NO_CRC;
+#endif//NSIS_CONFIG_CRC_SUPPORT
+
+ if (*(LPDWORD)(cmdline-2) == CHAR4_TO_DWORD(' ', '/', 'D','='))
+ {
+ *(LPDWORD)(cmdline-2)=0; // keep this from being passed to uninstaller if necessary
+ mystrcpy(state_install_directory,cmdline+2);
+ break; // /D= must always be last
+ }
+ }
+
+ // skip over our parm
+ cmdline = findchar(cmdline, seekchar);
+ // skip the quote
+ if (*cmdline == '\"')
+ cmdline++;
+ }
+
+ GetTempPath(NSIS_MAX_STRLEN, state_temp_dir);
+ if (!ValidateTempDir())
+ {
+ GetWindowsDirectory(state_temp_dir, NSIS_MAX_STRLEN - 5); // leave space for \Temp
+ mystrcat(state_temp_dir, "\\Temp");
+ if (!ValidateTempDir())
+ {
+ goto end;
+ }
+ }
+ DeleteFile(state_language);
+
+ m_Err = loadHeaders(cl_flags);
+ if (m_Err) goto end;
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (g_is_uninstaller)
+ {
+ char *p = findchar(state_command_line, 0);
+
+ // state_command_line has state_install_directory right after it in memory, so reading
+ // a bit over state_command_line won't do any harm
+ while (p >= state_command_line && *(LPDWORD)p != CHAR4_TO_DWORD(' ', '_', '?', '=')) p--;
+
+ m_Err = _LANG_UNINSTINITERROR;
+
+ if (p >= state_command_line)
+ {
+ *p=0; // terminate before "_?="
+ p+=4; // skip over " _?="
+ if (is_valid_instpath(p))
+ {
+ mystrcpy(state_install_directory, p);
+ mystrcpy(state_output_directory, p);
+ m_Err = 0;
+ }
+ else
+ {
+ goto end;
+ }
+ }
+ else
+ {
+ int x;
+
+ mystrcat(state_temp_dir,"~nsu.tmp");
+
+ // check if already running from uninstaller temp dir
+ // this prevents recursive uninstaller calls
+ if (!lstrcmpi(state_temp_dir,state_exe_directory))
+ goto end;
+
+ CreateDirectory(state_temp_dir,NULL);
+ SetCurrentDirectory(state_temp_dir);
+
+ if (!state_install_directory[0])
+ mystrcpy(state_install_directory,state_exe_directory);
+
+ mystrcpy(g_usrvars[0], realcmds);
+ *(LPWORD)g_usrvars[1] = CHAR2_TO_WORD('A',0);
+
+ for (x = 0; x < 26; x ++)
+ {
+ static char buf2[NSIS_MAX_STRLEN];
+
+ GetNSISString(buf2,g_header->str_uninstchild); // $TEMP\$1u_.exe
+
+ DeleteFile(buf2); // clean up after all the other ones if they are there
+
+ if (m_Err) // not done yet
+ {
+ // copy file
+ if (CopyFile(state_exe_path,buf2,TRUE))
+ {
+ HANDLE hProc;
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+ MoveFileOnReboot(buf2,NULL);
+#endif
+ GetNSISString(buf2,g_header->str_uninstcmd); // '"$TEMP\$1u_.exe" $0 _?=$INSTDIR\'
+ hProc=myCreateProcess(buf2);
+ if (hProc)
+ {
+ CloseHandle(hProc);
+ // success
+ m_Err = 0;
+ }
+ }
+ }
+ g_usrvars[1][0]++;
+ }
+
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+ MoveFileOnReboot(state_temp_dir,NULL);
+#endif
+
+ goto end;
+ }
+ }
+#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
+
+ g_exec_flags.errlvl = -1;
+ ret = ui_doinstall();
+
+#ifdef NSIS_CONFIG_LOG
+#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
+ log_write(1);
+#endif//!NSIS_CONFIG_LOG_ODS && !NSIS_CONFIG_LOG_STDOUT
+#endif//NSIS_CONFIG_LOG
+end:
+
+ CleanUp();
+
+#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
+ OleUninitialize();
+#endif
+
+ if (m_Err)
+ {
+ my_MessageBox(m_Err, MB_OK | MB_ICONSTOP | (IDOK << 21));
+ ExitProcess(2);
+ return 0;
+ }
+
+#ifdef NSIS_SUPPORT_REBOOT
+ if (g_exec_flags.reboot_called)
+ {
+ BOOL (WINAPI *OPT)(HANDLE, DWORD,PHANDLE);
+ BOOL (WINAPI *LPV)(LPCTSTR,LPCTSTR,PLUID);
+ BOOL (WINAPI *ATP)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
+ OPT=myGetProcAddress(MGA_OpenProcessToken);
+ LPV=myGetProcAddress(MGA_LookupPrivilegeValueA);
+ ATP=myGetProcAddress(MGA_AdjustTokenPrivileges);
+ if (OPT && LPV && ATP)
+ {
+ HANDLE hToken;
+ TOKEN_PRIVILEGES tkp;
+ if (OPT(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
+ {
+ LPV(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
+ tkp.PrivilegeCount = 1;
+ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ ATP(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
+ }
+ }
+
+ if (!ExitWindowsEx(EWX_REBOOT,0))
+ ExecuteCallbackFunction(CB_ONREBOOTFAILED);
+ }
+#endif//NSIS_SUPPORT_REBOOT
+
+ if (g_exec_flags.errlvl != -1)
+ ret = g_exec_flags.errlvl;
+
+ ExitProcess(ret);
+ return 0;
+}
+
+void NSISCALL CleanUp()
+{
+ if (g_db_hFile != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(g_db_hFile);
+ g_db_hFile = INVALID_HANDLE_VALUE;
+ }
+#ifdef NSIS_COMPRESS_WHOLE
+ if (dbd_hFile != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(dbd_hFile);
+ dbd_hFile = INVALID_HANDLE_VALUE;
+ }
+#endif
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+ // Clean up after plug-ins
+ myDelete(state_plugins_dir, DEL_DIR | DEL_RECURSE | DEL_REBOOT);
+#endif // NSIS_CONFIG_PLUGIN_SUPPORT
+}
diff --git a/Source/exehead/SConscript b/Source/exehead/SConscript
index 9baa3bb..b004c79 100755
--- a/Source/exehead/SConscript
+++ b/Source/exehead/SConscript
@@ -1,101 +1,101 @@
-files = Split("""
- bgbg.c
- components.c
- exec.c
- fileform.c
- Main.c
- Ui.c
- util.c
- #Source/crc32.c
-""")
-
-resources = Split("""
- resource.rc
-""")
-
-resource_files = Split("""
- nsis.ico
- uninst.ico
- bitmap1.bmp
-""")
-
-bzip2_files = Split("""
- #Source/bzip2/bzlib.c
- #Source/bzip2/decompress.c
- #Source/bzip2/huffman.c
-""")
-
-lzma_files = Split("""
- #Source/7zip/LZMADecode.c
-""")
-
-zlib_files = Split("""
- #Source/zlib/INFBLOCK.C
-""")
-
-libs = Split("""
- kernel32
- user32
- gdi32
- shell32
- advapi32
- comdlg32
- comctl32
- ole32
- version
- uuid
-""")
-
-Import('env compression solid_compression')
-
-### Defines
-
-env.Append(CPPDEFINES = ['EXEHEAD'])
-env.Append(CPPDEFINES = ['WIN32_LEAN_AND_MEAN'])
-env.Append(CPPDEFINES = ['_WIN32_IE=0x0500'])
-
-### Some other settings
-
-if 'NSIS_CONFIG_LOG_STDOUT' in env['NSIS_CPPDEFINES']:
- env.Append(LINKFLAGS = env['SUBSYS_CON'])
-
-### Compression specific configuration
-
-if compression == 'bzip2':
- env.Append(CPPDEFINES = ['NSIS_COMPRESS_USE_BZIP2'])
- files += bzip2_files
-elif compression == 'lzma':
- env.Append(CPPDEFINES = ['NSIS_COMPRESS_USE_LZMA'])
- env.Append(CPPDEFINES = ['LZMACALL=__fastcall'])
- files += lzma_files
-elif compression == 'zlib':
- env.Append(CPPDEFINES = ['NSIS_COMPRESS_USE_ZLIB'])
- env.Append(CPPDEFINES = ['ZEXPORT=__stdcall'])
- files += zlib_files
-
-if solid_compression:
- env.Append(CPPDEFINES = ['NSIS_COMPRESS_WHOLE'])
-
-### Build with no sub-build-directories
-
-objs = []
-
-def basename(file):
- return file.split('/')[-1].split('.')[0]
-
-for file in files:
- objs.append(env.Object(target = basename(file), source = file))
-
-### Resources
-
-res = env.RES(resources)
-env.Depends(res, resource_files)
-objs = objs + res
-
-### Build stub
-
-stub = env.Program(target = 'stub_' + compression, source = objs, LIBS = libs)
-
-### Return stub
-
-Return('stub')
+files = Split("""
+ bgbg.c
+ components.c
+ exec.c
+ fileform.c
+ Main.c
+ Ui.c
+ util.c
+ #Source/crc32.c
+""")
+
+resources = Split("""
+ resource.rc
+""")
+
+resource_files = Split("""
+ nsis.ico
+ uninst.ico
+ bitmap1.bmp
+""")
+
+bzip2_files = Split("""
+ #Source/bzip2/bzlib.c
+ #Source/bzip2/decompress.c
+ #Source/bzip2/huffman.c
+""")
+
+lzma_files = Split("""
+ #Source/7zip/LZMADecode.c
+""")
+
+zlib_files = Split("""
+ #Source/zlib/INFBLOCK.C
+""")
+
+libs = Split("""
+ kernel32
+ user32
+ gdi32
+ shell32
+ advapi32
+ comdlg32
+ comctl32
+ ole32
+ version
+ uuid
+""")
+
+Import('env compression solid_compression')
+
+### Defines
+
+env.Append(CPPDEFINES = ['EXEHEAD'])
+env.Append(CPPDEFINES = ['WIN32_LEAN_AND_MEAN'])
+env.Append(CPPDEFINES = ['_WIN32_IE=0x0500'])
+
+### Some other settings
+
+if 'NSIS_CONFIG_LOG_STDOUT' in env['NSIS_CPPDEFINES']:
+ env.Append(LINKFLAGS = env['SUBSYS_CON'])
+
+### Compression specific configuration
+
+if compression == 'bzip2':
+ env.Append(CPPDEFINES = ['NSIS_COMPRESS_USE_BZIP2'])
+ files += bzip2_files
+elif compression == 'lzma':
+ env.Append(CPPDEFINES = ['NSIS_COMPRESS_USE_LZMA'])
+ env.Append(CPPDEFINES = ['LZMACALL=__fastcall'])
+ files += lzma_files
+elif compression == 'zlib':
+ env.Append(CPPDEFINES = ['NSIS_COMPRESS_USE_ZLIB'])
+ env.Append(CPPDEFINES = ['ZEXPORT=__stdcall'])
+ files += zlib_files
+
+if solid_compression:
+ env.Append(CPPDEFINES = ['NSIS_COMPRESS_WHOLE'])
+
+### Build with no sub-build-directories
+
+objs = []
+
+def basename(file):
+ return file.split('/')[-1].split('.')[0]
+
+for file in files:
+ objs.append(env.Object(target = basename(file), source = file))
+
+### Resources
+
+res = env.RES(resources)
+env.Depends(res, resource_files)
+objs = objs + res
+
+### Build stub
+
+stub = env.Program(target = 'stub_' + compression, source = objs, LIBS = libs)
+
+### Return stub
+
+Return('stub')
diff --git a/Source/exehead/Ui.c b/Source/exehead/Ui.c
index 65f5f5f..7f9ce03 100755
--- a/Source/exehead/Ui.c
+++ b/Source/exehead/Ui.c
@@ -1,1692 +1,1692 @@
-/*
- * Ui.c
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft, Jeff Doozan and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include <windowsx.h>
-#include <shlobj.h>
-#include <shellapi.h>
-#include <shlwapi.h>
-
-#include "../Platform.h"
-
-#include "resource.h"
-
-#include "fileform.h"
-#include "state.h"
-#include "util.h"
-#include "ui.h"
-#include "exec.h"
-#include "lang.h"
-#include "components.h"
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-HICON g_hIcon;
-#endif
-
-int dlg_offset;
-int ui_dlg_visible=0; // At start main window is not visible
-int g_quit_flag; // set when Quit has been called (meaning bail out ASAP)
-
-#if NSIS_MAX_INST_TYPES > 32 || NSIS_MAX_INST_TYPES < 1
-#error invalid value for NSIS_MAX_INST_TYPES
-#endif
-
-int progress_bar_pos, progress_bar_len;
-
-#if NSIS_MAX_STRLEN < 1024
-static char g_tmp[4096];
-#else
-static char g_tmp[NSIS_MAX_STRLEN * 4];
-#endif
-
-static int m_page=-1,m_retcode,m_delta;
-static page *g_this_page;
-
-#define NOTIFY_BYE_BYE 'x'
-
-static void NSISCALL outernotify(int delta) {
- if (delta==NOTIFY_BYE_BYE)
- g_quit_flag++;
- SendMessage(g_hwnd,WM_NOTIFY_OUTER_NEXT,(WPARAM)delta,0);
-}
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-static int CALLBACK WINAPI BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData);
-#ifdef NSIS_CONFIG_LICENSEPAGE
-static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-#endif
-static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-static BOOL CALLBACK UninstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
-
-static DWORD WINAPI install_thread(LPVOID p);
-
-void NSISCALL CleanUp();
-
-HWND insthwnd, insthwnd2, insthwndbutton;
-
-HWND m_curwnd;
-static HWND m_bgwnd, m_hwndOK, m_hwndCancel;
-
-static BOOL NSISCALL SetDlgItemTextFromLang_(HWND dlg, int id, int lid) {
- return my_SetDialogItemText(dlg,id+1000,GetNSISStringTT(lid));
-}
-
-static void NSISCALL SetNextDef()
-{
- SendMessage(g_exec_flags.abort ? m_hwndCancel : m_hwndOK, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
-}
-
-static void NSISCALL EnableNext(BOOL e)
-{
- EnableWindow(m_hwndOK, e);
-}
-
-static void NSISCALL SetActiveCtl(HWND hCtl)
-{
- SendMessage(g_hwnd, WM_NEXTDLGCTL, (WPARAM) hCtl, TRUE);
-}
-
-static void NSISCALL NotifyCurWnd(UINT uNotifyCode)
-{
- if (m_curwnd)
- SendMessage(m_curwnd, uNotifyCode, 0, 0);
-}
-
-#define SetDlgItemTextFromLang(dlg,id,lid) SetDlgItemTextFromLang_(dlg,(id)-1000,lid)
-
-#define SetUITextFromLang(it,la) SetDlgItemTextFromLang_(hwndDlg,(it)-1000,la)
-#define SetUITextNT(it,text) my_SetDialogItemText(hwndDlg,it,text)
-#define GetUIText(it,s) my_GetDialogItemText(it,s)
-#define GetUIItem(it) GetDlgItem(hwndDlg,it)
-
-#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
-#define HandleStaticBkColor() _HandleStaticBkColor(uMsg, wParam, lParam)
-static BOOL NSISCALL _HandleStaticBkColor(UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- if ((uMsg - WM_CTLCOLOREDIT) <= (WM_CTLCOLORSTATIC - WM_CTLCOLOREDIT))
- {
- ctlcolors *c = (ctlcolors *)GetWindowLong((HWND)lParam, GWL_USERDATA);
-
- if (c) {
- COLORREF text;
- LOGBRUSH lh;
-
- text = c->text;
- if (c->flags & CC_TEXT_SYS)
- text = GetSysColor(text);
- if (c->flags & CC_TEXT)
- SetTextColor((HDC)wParam, text);
-
- SetBkMode((HDC)wParam, c->bkmode);
-
- lh.lbColor = c->bkc;
- if (c->flags & CC_BK_SYS)
- lh.lbColor = GetSysColor(lh.lbColor);
- if (c->flags & CC_BK)
- SetBkColor((HDC)wParam, lh.lbColor);
-
- if (c->flags & CC_BKB)
- {
- lh.lbStyle = c->lbStyle;
- if (c->bkb)
- DeleteObject(c->bkb);
- c->bkb = CreateBrushIndirect(&lh);
- }
-
- return (BOOL)c->bkb;
- }
- }
- return 0;
-}
-#else
-#define HandleStaticBkColor() 0
-#endif//!NSIS_CONFIG_ENHANCEDUI_SUPPORT
-
-#ifdef NSIS_CONFIG_LOG
-#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
-void NSISCALL build_g_logfile()
-{
- mystrcat(addtrailingslash(mystrcpy(g_log_file,state_install_directory)),"install.log");
-}
-#endif
-#endif
-
-int *cur_langtable;
-
-static void NSISCALL set_language()
-{
- LANGID lang_mask=(LANGID)~0;
- LANGID lang=myatoi(state_language);
- char *language_table=0;
- int lang_num;
- int *selected_langtable=0;
-
-lang_again:
- lang_num=g_blocks[NB_LANGTABLES].num;
- while (lang_num--) {
- language_table=((char*)g_blocks[NB_LANGTABLES].offset)+lang_num*g_header->langtable_size;
- if (!((lang ^ *(LANGID*)language_table) & lang_mask)) {
- dlg_offset=*(int*)(language_table+sizeof(LANGID));
- g_exec_flags.rtl=*(int*)(language_table+sizeof(LANGID)+sizeof(int));
- selected_langtable=(int*)(language_table+sizeof(LANGID)+2*sizeof(int));
- break;
- }
- }
- if (!selected_langtable) {
- if (lang_mask == (LANGID)~0)
- lang_mask=0x3ff; // primary lang
- else // we already tried once and we still don't have a language table
- lang_mask=0; // first lang
- goto lang_again;
- }
-
- cur_langtable = selected_langtable;
-
- myitoa(state_language, *(LANGID*)language_table);
- {
- char *caption = GetNSISString(g_caption,LANG_CAPTION);
-#ifdef NSIS_SUPPORT_BGBG
- my_SetWindowText(m_bgwnd, caption);
-#endif
- }
-
- // reload section names
- {
- section *sec = g_sections;
- int x = num_sections;
-
- while (x--)
- {
- if (sec->name_ptr)
- {
- GetNSISString(sec->name, sec->name_ptr);
- }
- sec++;
- }
- }
-}
-
-FORCE_INLINE int NSISCALL ui_doinstall(void)
-{
- header *header = g_header;
- static WNDCLASS wc; // richedit subclassing and bgbg creation
-
- // detect default language
- // more information at:
- // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_0xrn.asp
-
- LANGID (WINAPI *GUDUIL)();
-
- GUDUIL = myGetProcAddress(MGA_GetUserDefaultUILanguage);
- if (GUDUIL)
- {
- // Windows ME/2000+
- myitoa(state_language, GUDUIL());
- }
- else
- {
- static const char reg_9x_locale[] = "Control Panel\\Desktop\\ResourceLocale";
- static const char reg_nt_locale_key[] = ".DEFAULT\\Control Panel\\International";
- const char *reg_nt_locale_val = &reg_9x_locale[30]; // = "Locale" with opt
-
- *(DWORD*)state_language = CHAR4_TO_DWORD('0', 'x', 0, 0);
-
- {
- // Windows 9x
- myRegGetStr(HKEY_CURRENT_USER, reg_9x_locale, NULL, g_tmp, 0);
- }
-
- if (!g_tmp[0])
- {
- // Windows NT
- // This key exists on 9x as well, so it's only read if ResourceLocale wasn't found
- myRegGetStr(HKEY_USERS, reg_nt_locale_key, reg_nt_locale_val, g_tmp, 0);
- }
-
- mystrcat(state_language, g_tmp);
- }
-
- // set default language
- set_language();
-
- // initialize auto close flag
- g_exec_flags.autoclose=g_flags&CH_FLAGS_AUTO_CLOSE;
-
- // read install directory from registry
- if (!is_valid_instpath(state_install_directory))
- {
- if (header->install_reg_key_ptr)
- {
- myRegGetStr(
- (HKEY)header->install_reg_rootkey,
- GetNSISStringNP(header->install_reg_key_ptr),
- GetNSISStringNP(header->install_reg_value_ptr),
- ps_tmpbuf,
- 0
- );
- if (ps_tmpbuf[0])
- {
- char *p=ps_tmpbuf;
- char *e;
- if (p[0]=='\"')
- {
- char *p2;
- p++;
- p2 = findchar(p, '"');
- *p2 = 0;
- }
- // p is the path now, check for .exe extension
-
- e=p+mystrlen(p)-4;
- if (e > p)
- {
- // if filename ends in .exe, and is not a directory, remove the filename
- if (!lstrcmpi(e, ".exe")) // check extension
- {
- DWORD d;
- d=GetFileAttributes(p);
- if (d == INVALID_FILE_ATTRIBUTES || !(d&FILE_ATTRIBUTE_DIRECTORY))
- {
- // if there is no back-slash, the string will become empty, but that's ok because
- // it would make an invalid instdir anyway
- trimslashtoend(p);
- }
- }
- }
-
- mystrcpy(state_install_directory,addtrailingslash(p));
- }
- }
- }
- if (!is_valid_instpath(state_install_directory))
- {
- GetNSISString(state_install_directory,header->install_directory_ptr);
- }
-
-#ifdef NSIS_CONFIG_LOG
- if (g_flags & CH_FLAGS_SILENT_LOG && !g_is_uninstaller)
- {
-#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
- build_g_logfile();
-#endif
- log_dolog=1;
- }
-#endif
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- g_hIcon=LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED);
-#ifdef NSIS_SUPPORT_BGBG
- if (header->bg_color1 != -1)
- {
- DWORD cn = CHAR4_TO_DWORD('_', 'N', 'b', 0);
- RECT vp;
- extern LRESULT CALLBACK BG_WndProc(HWND, UINT, WPARAM, LPARAM);
- wc.lpfnWndProc = BG_WndProc;
- wc.hInstance = g_hInstance;
- wc.hIcon = g_hIcon;
- //wc.hCursor = LoadCursor(NULL,IDC_ARROW);
- wc.lpszClassName = (LPCSTR)&cn;
-
- if (!RegisterClass(&wc)) return 0;
-
- SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0);
-
- m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,(LPCSTR)&cn,0,WS_POPUP,
- vp.left,vp.top,vp.right-vp.left,vp.bottom-vp.top,0,NULL,g_hInstance,NULL);
- }
-
-#endif//NSIS_SUPPORT_BGBG
-
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- // Select language
- if (ExecuteCallbackFunction(CB_ONINIT)) return 2;
- set_language();
-#endif
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- if (!g_exec_flags.silent)
-#endif//NSIS_CONFIG_SILENT_SUPPORT
- {
-#ifdef NSIS_SUPPORT_BGBG
- ShowWindow(m_bgwnd, SW_SHOW);
-#endif//NSIS_SUPPORT_BGBG
-
-#ifdef NSIS_CONFIG_LICENSEPAGE
- { // load richedit DLL
- static const char riched20[]="RichEd20";
- static const char riched32[]="RichEd32";
- static const char richedit20a[]="RichEdit20A";
- static const char richedit[]="RichEdit";
- if (!LoadLibrary(riched20))
- {
- LoadLibrary(riched32);
- }
-
- // make richedit20a point to RICHEDIT
- if (!GetClassInfo(NULL,richedit20a,&wc))
- {
- GetClassInfo(NULL,richedit,&wc);
- wc.lpszClassName = richedit20a;
- RegisterClass(&wc);
- }
- }
-#endif
-
- {
- int ret=DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST+dlg_offset),0,DialogProc);
-#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
- ExecuteCallbackFunction(CB_ONGUIEND);
-#endif
- return ret;
- }
- }
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- else
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
- {
- if (install_thread(NULL))
- {
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- if (!g_quit_flag) ExecuteCallbackFunction(CB_ONINSTFAILED);
-#endif//NSIS_SUPPORT_CODECALLBACKS
- return 2;
- }
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- ExecuteCallbackFunction(CB_ONINSTSUCCESS);
-#endif//NSIS_SUPPORT_CODECALLBACKS
-
- return 0;
- }
-#endif//NSIS_CONFIG_SILENT_SUPPORT
-}
-
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-static int CALLBACK WINAPI BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
-{
- if (uMsg==BFFM_INITIALIZED)
- {
- my_GetDialogItemText(IDC_DIR,(char*)lpData);
- SendMessage(hwnd,BFFM_SETSELECTION,(WPARAM)1,lpData);
- }
- if (uMsg==BFFM_SELCHANGED)
- {
- SendMessage(
- hwnd,
- BFFM_ENABLEOK,
- 0,
- SHGetPathFromIDList((LPITEMIDLIST)lParam,(char*)lpData)
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- && !ExecuteCallbackFunction(CB_ONVERIFYINSTDIR)
-#endif
- );
- }
- return 0;
-}
-
-BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- if (uMsg == WM_INITDIALOG || uMsg == WM_NOTIFY_OUTER_NEXT)
- {
- page *this_page;
- static DLGPROC winprocs[]=
- {
-#ifdef NSIS_CONFIG_LICENSEPAGE
- LicenseProc,
-#endif
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- SelProc,
-#endif
- DirProc,
- InstProc,
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- UninstProc
-#endif
- };
-
- m_delta = wParam;
-
- if (uMsg == WM_INITDIALOG)
- {
- g_hwnd=hwndDlg;
- m_hwndOK=GetDlgItem(hwndDlg,IDOK);
- m_hwndCancel=GetDlgItem(hwndDlg,IDCANCEL);
- SetDlgItemTextFromLang(hwndDlg,IDC_VERSTR,LANG_BRANDING);
- SetClassLong(hwndDlg,GCL_HICON,(long)g_hIcon);
- // use the following line instead of the above, if .rdata needs shirking
- //SendMessage(hwndDlg,WM_SETICON,ICON_BIG,(LPARAM)g_hIcon);
-#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
- g_quit_flag = ExecuteCallbackFunction(CB_ONGUIINIT);
-#endif
- //ShowWindow(hwndDlg, SW_SHOW);
- m_delta = 1;
- }
-
- this_page=g_pages+m_page;
-
- if (m_page>=0) {
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- // Call leave function. If Abort used don't move to the next page.
- // But if quit called we must exit now
- if (m_delta==1) if (ExecuteCodeSegment(this_page->leavefunc,NULL)) {
- SendMessage(m_curwnd, WM_IN_UPDATEMSG, 0, 1);
- return !g_quit_flag;
- }
-#endif
-
- // if the last page was a custom page, wait for it to finish by itself.
- // if it doesn't, it's a BAD plugin.
- // plugins should react to WM_NOTIFY_OUTER_NEXT.
- if (!this_page->dlg_id) return 0;
- }
-
- NotifyCurWnd(WM_NOTIFY_INIGO_MONTOYA);
-
-nextPage:
- m_page+=m_delta;
- this_page+=m_delta;
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- if (m_page==g_blocks[NB_PAGES].num) ExecuteCallbackFunction(CB_ONINSTSUCCESS);
-#endif//NSIS_SUPPORT_CODECALLBACKS
-
- if (g_quit_flag || (unsigned int)m_page >= (unsigned int)g_blocks[NB_PAGES].num)
- {
- DestroyWindow(m_curwnd);
- g_hwnd = 0;
- EndDialog(hwndDlg,m_retcode);
- }
- else
- {
- HWND hwndtmp;
-
- int pflags = this_page->flags;
-
- GetNSISString(state_click_next, this_page->clicknext);
- SetDlgItemTextFromLang(hwndDlg, IDOK, this_page->next);
- SetDlgItemTextFromLang(hwndDlg, IDC_BACK, this_page->back);
- SetDlgItemTextFromLang(hwndDlg, IDCANCEL, this_page->cancel);
-
- hwndtmp = GetDlgItem(hwndDlg, IDC_BACK);
-
- if (g_exec_flags.abort)
- {
- pflags &= ~(PF_BACK_ENABLE | PF_NEXT_ENABLE);
- pflags |= PF_CANCEL_ENABLE;
- }
-
- ShowWindow(hwndtmp, pflags & PF_BACK_SHOW);// SW_HIDE = 0, PF_BACK_SHOW = SW_SHOWNA = 8
- EnableWindow(hwndtmp, pflags & PF_BACK_ENABLE);
- EnableNext(pflags & PF_NEXT_ENABLE);
- EnableWindow(m_hwndCancel, pflags & PF_CANCEL_ENABLE);
-
- if (pflags & PF_CANCEL_ENABLE)
- EnableMenuItem(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND | MF_ENABLED);
- else
- EnableMenuItem(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
-
- SendMessage(hwndtmp, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
-
- if (g_exec_flags.abort)
- {
- SendMessage(hwndDlg, DM_SETDEFID, IDCANCEL, 0);
- SetActiveCtl(m_hwndCancel);
- }
- else
- {
- SetActiveCtl(m_hwndOK);
- }
-
- mystrcpy(g_tmp,g_caption);
- GetNSISString(g_tmp+mystrlen(g_tmp),this_page->caption);
- my_SetWindowText(hwndDlg,g_tmp);
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- // custom page or user used abort in prefunc
- if (ExecuteCodeSegment(this_page->prefunc, NULL) || !this_page->dlg_id) {
- goto nextPage;
- }
-#endif //NSIS_SUPPORT_CODECALLBACKS
-
- if (this_page->wndproc_id != PWP_COMPLETED)
- {
- DestroyWindow(m_curwnd);
- }
- else {
- if (!g_exec_flags.abort && g_exec_flags.autoclose)
- goto nextPage;
- // no need to go to skipPage because PWP_COMPLETED always follows PWP_INSTFILES
- return FALSE;
- }
-
- // update g_this_page for the dialog proc
- g_this_page=this_page;
-
- if (this_page->dlg_id > 0) // NSIS page
- {
- m_curwnd=CreateDialogParam(
- g_hInstance,
- MAKEINTRESOURCE(this_page->dlg_id+dlg_offset),
- hwndDlg,winprocs[this_page->wndproc_id],(LPARAM)this_page
- );
- if (m_curwnd)
- {
- RECT r;
-
- SetDlgItemTextFromLang(m_curwnd,IDC_INTROTEXT,this_page->parms[0]);
-
- GetWindowRect(GetDlgItem(hwndDlg,IDC_CHILDRECT),&r);
- ScreenToClient(hwndDlg,(LPPOINT)&r);
- SetWindowPos(m_curwnd,0,r.left,r.top,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- ExecuteCodeSegment(this_page->showfunc,NULL);
- if (g_quit_flag)
- return FALSE;
-#endif //NSIS_SUPPORT_CODECALLBACKS
- ShowWindow(m_curwnd,SW_SHOWNA);
- NotifyCurWnd(WM_NOTIFY_START);
- }
- }
- }
-
-skipPage:
-
- if (!ui_dlg_visible && m_curwnd)
- {
- ShowWindow(hwndDlg, SW_SHOWDEFAULT);
- ui_dlg_visible = 1;
- }
-
- return FALSE;
- }
-
-#ifdef NSIS_SUPPORT_BGBG
- if (uMsg == WM_WINDOWPOSCHANGED)
- {
- SetWindowPos(m_bgwnd, hwndDlg, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
- }
- if (uMsg == WM_SIZE) {
- ShowWindow(m_bgwnd, wParam == SIZE_MINIMIZED ? SW_HIDE : SW_SHOW);
- }
-#endif //NSIS_SUPPORT_BGBG
-
- if (uMsg == WM_NOTIFY_CUSTOM_READY) {
- DestroyWindow(m_curwnd);
- m_curwnd = (HWND)wParam;
- goto skipPage;
- }
- if (uMsg == WM_QUERYENDSESSION)
- {
- SetWindowLong(hwndDlg, DWL_MSGRESULT, FALSE);
- return TRUE;
- }
- if (uMsg == WM_COMMAND)
- {
- int id = LOWORD(wParam);
- HWND hCtl = GetDlgItem(hwndDlg, id); // lParam might be NULL
- if (hCtl)
- {
- SendMessage(hCtl, BM_SETSTATE, FALSE, 0);
- if (!IsWindowEnabled(hCtl))
- return 0;
- }
-
- if (id == IDOK)
- {
- outernotify(1);
- }
- else if (id == IDC_BACK && m_page>0)
- {
- outernotify(-1);
- }
- else if (id == IDCANCEL)
- {
- if (g_exec_flags.abort)
- {
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- ExecuteCallbackFunction(CB_ONINSTFAILED);
-#endif//NSIS_SUPPORT_CODECALLBACKS
- m_retcode=2;
- outernotify(NOTIFY_BYE_BYE);
- }
- else
- {
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- if (!ExecuteCallbackFunction(CB_ONUSERABORT))
-#endif//NSIS_SUPPORT_CODECALLBACKS
- {
- m_retcode=1;
- outernotify(NOTIFY_BYE_BYE);
- }
- }
- }
- else
- {
- // Forward WM_COMMANDs to inner dialogs, can be custom ones.
- // Without this, enter on buttons in inner dialogs won't work.
- SendMessage(m_curwnd, WM_COMMAND, wParam, lParam);
- }
- }
- return HandleStaticBkColor();
-}
-
-#define this_page ((page*)lParam)
-
-#ifdef NSIS_CONFIG_LICENSEPAGE
-
-#define _RICHEDIT_VER 0x0200
-#include <richedit.h>
-#undef _RICHEDIT_VER
-static DWORD dwRead;
-DWORD CALLBACK StreamLicense(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
-{
- lstrcpyn(pbBuff,(char*)dwCookie+dwRead,cb);
- *pcb=mystrlen(pbBuff);
- dwRead+=*pcb;
- return 0;
-}
-
-static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- page *m_this_page=g_this_page;
- HWND hwLicense;
- static int ignoreWMCommand;
-
- if (uMsg == WM_INITDIALOG)
- {
- char *l = (char *)GetNSISStringNP(GetNSISTab(this_page->parms[1]));
- int lt = *l;
- EDITSTREAM es = {
- (DWORD)(++l),
- 0,
- StreamLicense
- };
-
- int selected = (this_page->flags & PF_LICENSE_SELECTED) | !(this_page->flags & PF_LICENSE_FORCE_SELECTION);
-
- SetUITextFromLang(IDC_LICENSEAGREE,this_page->parms[2]);
- SetUITextFromLang(IDC_LICENSEDISAGREE,this_page->parms[3]);
- CheckDlgButton(hwndDlg,IDC_LICENSEAGREE+!selected,BST_CHECKED);
- EnableNext(selected);
-
- hwLicense=GetUIItem(IDC_EDIT1);
- SetActiveCtl(hwLicense);
- SendMessage(hwLicense,EM_AUTOURLDETECT,TRUE,0);
-#define lbg g_header->license_bg
- SendMessage(hwLicense,EM_SETBKGNDCOLOR,0,lbg>=0?lbg:GetSysColor(-lbg));
-#undef lbg
- SendMessage(hwLicense,EM_SETEVENTMASK,0,ENM_LINK|ENM_KEYEVENTS); //XGE 8th September 2002 Or'd in ENM_KEYEVENTS
- dwRead=0;
- SendMessage(hwLicense,EM_EXLIMITTEXT,0,mystrlen(l));
- SendMessage(hwLicense,EM_STREAMIN,lt,(LPARAM)&es);
- ignoreWMCommand = 0;
- return FALSE;
- }
- if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && !ignoreWMCommand) {
- if (m_this_page->flags & PF_LICENSE_FORCE_SELECTION) {
- int is = SendMessage(GetUIItem(IDC_LICENSEAGREE), BM_GETCHECK, 0, 0) & BST_CHECKED;
- m_this_page->flags &= ~PF_LICENSE_SELECTED;
- m_this_page->flags |= is;
- EnableNext(is);
- SetNextDef();
- }
- }
- if (uMsg == WM_NOTIFY) {
- hwLicense=GetUIItem(IDC_EDIT1);
- #define nmhdr ((NMHDR *)lParam)
- #define enlink ((ENLINK *)lParam)
- #define msgfilter ((MSGFILTER *)lParam)
- if (nmhdr->code==EN_LINK) {
- if (enlink->msg==WM_LBUTTONDOWN) {
- TEXTRANGE tr = {
- {
- enlink->chrg.cpMin,
- enlink->chrg.cpMax,
- },
- ps_tmpbuf
- };
- if (tr.chrg.cpMax-tr.chrg.cpMin < sizeof(ps_tmpbuf)) {
- SendMessage(hwLicense,EM_GETTEXTRANGE,0,(LPARAM)&tr);
- SetCursor(LoadCursor(0, IDC_WAIT));
- ShellExecute(hwndDlg,"open",tr.lpstrText,NULL,NULL,SW_SHOWNORMAL);
- SetCursor(LoadCursor(0, IDC_ARROW));
- }
- }
- }
- //Ximon Eighteen 8th September 2002 Capture return key presses in the rich
- //edit control now that the control gets the focus rather than the default
- //push button. When the user presses return ask the outer dialog to move
- //the installer onto the next page. MSDN docs say return non-zero if the
- //rich edit control should NOT process this message, hence the return 1.
- //
- //This is required because the RichEdit control is eating all the key hits.
- //It does try to release some and convert VK_ESCAPE to WM_CLOSE, VK_ENTER
- //to a push on the default button and VM_TAB to WM_NEXTDLGCTL. But sadly it
- //it sends all of these messages to its parent instead of just letting the
- //dialog manager handle them. Instead of properly handling WM_GETDLGCODE,
- //it mimics the dialog manager.
- if (nmhdr->code==EN_MSGFILTER)
- {
- if (msgfilter->msg==WM_KEYDOWN)
- {
- if (msgfilter->wParam==VK_RETURN) {
- SendMessage(g_hwnd, WM_COMMAND, IDOK, 0);
- }
- if (msgfilter->wParam==VK_ESCAPE) {
- SendMessage(g_hwnd, WM_CLOSE, 0, 0);
- }
- return 1;
- }
- }
- #undef nmhdr
- #undef enlink
- #undef msgfilter
- }
- if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
- {
- ignoreWMCommand++;
- }
- return HandleStaticBkColor();
-}
-#endif
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
-static BOOL CALLBACK UninstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- if (uMsg == WM_INITDIALOG)
- {
- SetUITextFromLang(IDC_UNINSTFROM,this_page->parms[1]);
- SetUITextNT(IDC_EDIT1,g_usrvars[this_page->parms[4]]);
- }
- return HandleStaticBkColor();
-}
-#endif
-
-
-static void NSISCALL SetSizeText(int dlgItem, int prefix, unsigned kb)
-{
- char scalestr[32], byte[32];
- unsigned sh = 20;
- int scale = LANG_GIGA;
-
- if (kb < 1024 * 1024) { sh = 10; scale = LANG_MEGA; }
- if (kb < 1024) { sh = 0; scale = LANG_KILO; }
-
- if (kb < (0xFFFFFFFF - ((1 << 20) / 20))) // check for overflow
- kb += (1 << sh) / 20; // round numbers for better display (e.g. 1.59 => 1.6)
-
- wsprintf(
- GetNSISString(g_tmp, prefix) + mystrlen(g_tmp),
- "%u.%u%s%s",
- kb >> sh,
- (((kb & 0x00FFFFFF) * 10) >> sh) % 10, // 0x00FFFFFF mask is used to
- // prevent overflow that causes
- // bad results
- GetNSISString(scalestr, scale),
- GetNSISString(byte, LANG_BYTE)
- );
-
- my_SetDialogItemText(m_curwnd,dlgItem,g_tmp);
-}
-
-static int NSISCALL _sumsecsfield(int idx)
-{
- int total = 0;
- int x = num_sections;
- section *s = g_sections;
- while (x--)
- {
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- if (s->flags & SF_SELECTED)
-#endif
- total += ((int *)s)[idx];
- s++;
- }
- return total;
-}
-
-#define sumsecsfield(x) _sumsecsfield(SECTION_OFFSET(x))
-
-static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- static int dontsetdefstyle;
- page *thispage = g_this_page;
- char *dir = g_usrvars[thispage->parms[4]];
- int browse_text = thispage->parms[3];
- if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
- {
- GetUIText(IDC_DIR,dir);
- validate_filename(dir);
-#ifdef NSIS_CONFIG_LOG
-#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
- build_g_logfile();
-#endif
- if (GetUIItem(IDC_CHECK1) != NULL)
- log_dolog = IsDlgButtonChecked(hwndDlg,IDC_CHECK1);
-#endif
- }
- if (uMsg == WM_INITDIALOG)
- {
- HWND hDir = GetUIItem(IDC_DIR);
-
-#ifdef NSIS_CONFIG_LOG
- if (GetAsyncKeyState(VK_SHIFT)&0x8000)
- {
- HWND h=GetUIItem(IDC_CHECK1);
- SetUITextFromLang(IDC_CHECK1,LANG_LOG_INSTALL_PROCESS);
- ShowWindow(h,SW_SHOWNA);
- }
-#endif
- if (validpathspec(dir) && !skip_root(dir))
- addtrailingslash(dir);
-
- // workaround for bug #1209843
- //
- // m_curwnd is only updated once WM_INITDIALOG returns.
- // my_SetWindowText triggers an EN_CHANGE message that
- // triggers a WM_IN_UPDATEMSG message that uses m_curwnd
- // to get the selected directory (GetUIText).
- // because m_curwnd is still outdated, dir varialble is
- // filled with an empty string. by default, dir points
- // to $INSTDIR.
- //
- // to solve this, m_curwnd is manually set to the correct
- // window handle.
-
- m_curwnd=hwndDlg;
-
- my_SetWindowText(hDir,dir);
- SetUITextFromLang(IDC_BROWSE,this_page->parms[2]);
- SetUITextFromLang(IDC_SELDIRTEXT,this_page->parms[1]);
- SetActiveCtl(hDir);
-
- {
- typedef HRESULT (WINAPI *SHAutoCompletePtr)(HWND, DWORD);
- SHAutoCompletePtr fSHAutoComplete;
- fSHAutoComplete = (SHAutoCompletePtr) myGetProcAddress(MGA_SHAutoComplete);
- if (fSHAutoComplete)
- {
- fSHAutoComplete(hDir, SHACF_FILESYSTEM);
- }
- }
- }
- if (uMsg == WM_COMMAND)
- {
- int id=LOWORD(wParam);
- if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE)
- {
- uMsg = WM_IN_UPDATEMSG;
- }
- if (id == IDC_BROWSE)
- {
- static char bt[NSIS_MAX_STRLEN];
- BROWSEINFO bi = {0,};
- ITEMIDLIST *idlist;
- bi.hwndOwner = hwndDlg;
- bi.pszDisplayName = g_tmp;
- bi.lpfn = BrowseCallbackProc;
- bi.lParam = (LPARAM)dir;
- bi.lpszTitle = GetNSISString(bt, browse_text);
- bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
- idlist = SHBrowseForFolder(&bi);
- if (idlist)
- {
- // free idlist
- CoTaskMemFree(idlist);
-
- addtrailingslash(dir);
-
- if (g_header->install_directory_auto_append &&
- dir == state_install_directory) // only append to $INSTDIR (bug #1174184)
- {
- const char *post_str = ps_tmpbuf;
- GetNSISStringTT(g_header->install_directory_auto_append);
- // display name gives just the folder name
- if (lstrcmpi(post_str, g_tmp))
- {
- mystrcat(dir, post_str);
- }
- }
-
- dontsetdefstyle++;
- SetUITextNT(IDC_DIR,dir);
- }
- else
- {
- uMsg = WM_IN_UPDATEMSG;
- }
- }
- }
- if (uMsg == WM_IN_UPDATEMSG || uMsg == WM_NOTIFY_START)
- {
- static char s[NSIS_MAX_STRLEN];
- char *p;
- int error = 0;
- int available_set = 0;
- unsigned total, available = 0xFFFFFFFF;
-
- GetUIText(IDC_DIR,dir);
- if (!is_valid_instpath(dir))
- error = NSIS_INSTDIR_INVALID;
-
- mystrcpy(s,dir);
- p=skip_root(s);
- if (p)
- *p=0;
-
- // Test for and use the GetDiskFreeSpaceEx API
- {
- BOOL (WINAPI *GDFSE)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
- myGetProcAddress(MGA_GetDiskFreeSpaceExA);
- if (GDFSE)
- {
- ULARGE_INTEGER available64;
- ULARGE_INTEGER a, b;
- if (GDFSE(s, &available64, &a, &b))
- {
-#ifndef _NSIS_NO_INT64_SHR
- available = (int)(available64.QuadPart >> 10);
-#else
- available = (int)(Int64ShrlMod32(available64.QuadPart, 10));
-#endif
- available_set++;
- }
- }
- }
-
- if (!available_set)
- {
- // GetDiskFreeSpaceEx is not available
- DWORD spc, bps, fc, tc;
- if (GetDiskFreeSpace(s, &spc, &bps, &fc, &tc))
- {
- available = (int)MulDiv(bps * spc, fc, 1 << 10);
- available_set++;
- }
- }
-
- total = (unsigned) sumsecsfield(size_kb);
-
- if (available < total)
- error = NSIS_INSTDIR_NOT_ENOUGH_SPACE;
-
- if (LANG_STR_TAB(LANG_SPACE_REQ)) {
- SetSizeText(IDC_SPACEREQUIRED,LANG_SPACE_REQ,total);
- if (available_set)
- SetSizeText(IDC_SPACEAVAILABLE,LANG_SPACE_AVAIL,available);
- else
- SetUITextNT(IDC_SPACEAVAILABLE,"");
- }
-
- g_exec_flags.instdir_error = error;
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- if (!error)
- error = ExecuteCallbackFunction(CB_ONVERIFYINSTDIR);
-#endif
-
- if (thispage->flags & PF_DIR_NO_BTN_DISABLE)
- error = 0;
-
- EnableNext(!error);
- if (!error && !dontsetdefstyle)
- SetNextDef();
- dontsetdefstyle = 0;
- }
- return HandleStaticBkColor();
-}
-
-#ifdef NSIS_CONFIG_COMPONENTPAGE
-
-static void FORCE_INLINE NSISCALL RefreshComponents(HWND hwTree, HTREEITEM *items)
-{
- TVITEM item;
- int i, flags, state;
- section *sec;
-
- item.stateMask = TVIS_STATEIMAGEMASK | TVIS_EXPANDED | TVIS_BOLD;
-
- for (i = 0, sec = g_sections; i < num_sections; i++, sec++)
- {
- if (!items[i])
- {
- continue;
- }
-
- flags = sec->flags;
-
- item.hItem = items[i];
-
- item.mask = TVIF_STATE;
-
- if (flags & SF_NAMECHG)
- {
- item.mask |= TVIF_TEXT;
- item.pszText = sec->name;
- sec->flags &= ~SF_NAMECHG;
- }
-
- if (flags & SF_PSELECTED)
- {
- state = 3;
- }
- else
- {
- state = 1 + (flags & SF_SELECTED); // SF_SELECTED == 1
- if (flags & SF_RO) state += 3;
- }
-
- item.state = (flags & SF_BOLD) << 1; // (SF_BOLD << 1) == 16 == TVIS_BOLD
- item.state |= flags & SF_EXPAND; // TVIS_EXPANDED == SF_EXPAND
- item.state |= INDEXTOSTATEIMAGEMASK(state);
-
- // TVE_COLLAPSE = 1, TVE_EXPAND = 2
- TreeView_Expand(hwTree, item.hItem, TVE_COLLAPSE + ((flags & SF_EXPAND) / SF_EXPAND));
-
- TreeView_SetItem(hwTree, &item);
- }
-
- // workaround for bug #1397031
- //
- // windows 95 doesn't erase the background of the state image
- // before it draws a new one. because of this parts of the old
- // state image will show where the new state image is masked.
- //
- // to solve this, the following line forces the background to
- // be erased. sadly, this redraws the entire control. it might
- // be a good idea to figure out where the state images are and
- // redraw only those.
-
- InvalidateRect(hwTree, NULL, TRUE);
-}
-
-int NSISCALL TreeGetSelectedSection(HWND tree, BOOL mouse)
-{
- HTREEITEM hItem = TreeView_GetSelection(tree);
- TVITEM item;
-
- if (mouse)
- {
- TVHITTESTINFO ht;
- DWORD dwpos = GetMessagePos();
-
- ht.pt.x = GET_X_LPARAM(dwpos);
- ht.pt.y = GET_Y_LPARAM(dwpos);
- ScreenToClient(tree, &ht.pt);
-
- TreeView_HitTest(tree, &ht);
-
-#ifdef NSIS_CONFIG_COMPONENTPAGE_ALTERNATIVE
- if (!(ht.flags & TVHT_ONITEMSTATEICON))
-#else
- if (!(ht.flags & (TVHT_ONITEMSTATEICON|TVHT_ONITEMLABEL|TVHT_ONITEMRIGHT|TVHT_ONITEM)))
-#endif
- return -1;
-
- hItem = ht.hItem;
- }
-
- item.mask = TVIF_PARAM;
- item.hItem = hItem;
- TreeView_GetItem(tree, &item);
-
- return (int) item.lParam;
-}
-
-static LONG oldTreeWndProc;
-static LPARAM last_selected_tree_item;
-static DWORD WINAPI newTreeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- if (uMsg == WM_CHAR && wParam == VK_SPACE) {
- NotifyCurWnd(WM_TREEVIEW_KEYHACK);
- return 0;
- }
-#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
-#ifndef NSIS_CONFIG_COMPONENTPAGE_ALTERNATIVE
- if (uMsg == WM_MOUSEMOVE) {
- if (IsWindowVisible(hwnd)) {
- lParam = TreeGetSelectedSection(hwnd, TRUE);
- uMsg = WM_NOTIFY_SELCHANGE;
- }
- }
-#endif
- if (uMsg == WM_NOTIFY_SELCHANGE) {
- if (last_selected_tree_item != lParam)
- {
- last_selected_tree_item = lParam;
-
- mystrcpy(g_tmp, g_usrvars[0]);
-
- myitoa(g_usrvars[0], lParam);
-
- ExecuteCallbackFunction(CB_ONMOUSEOVERSECTION);
-
- mystrcpy(g_usrvars[0], g_tmp);
- }
- }
-#endif//NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_ENHANCEDUI_SUPPORT
- return CallWindowProc((WNDPROC)oldTreeWndProc,hwnd,uMsg,wParam,lParam);
-}
-
-static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- static HTREEITEM *hTreeItems;
- static HIMAGELIST hImageList;
- HWND hwndCombo1 = GetUIItem(IDC_COMBO1);
- HWND hwndTree1 = GetUIItem(IDC_TREE1);
- extern HWND g_SectionHack;
- section *sections=g_sections;
- int *install_types=g_header->install_types;
- if (uMsg == WM_INITDIALOG)
- {
- int doLines=0;
- HTREEITEM Par;
- HBITMAP hBMcheck1;
- int x, lastGoodX, i, noCombo=2;
-
- g_SectionHack=hwndDlg;
-
- hTreeItems=(HTREEITEM*)GlobalAlloc(GPTR,sizeof(HTREEITEM)*num_sections);
-
- hBMcheck1=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
-
- last_selected_tree_item=-1;
- oldTreeWndProc=SetWindowLong(hwndTree1,GWL_WNDPROC,(long)newTreeWndProc);
-
- hImageList = ImageList_Create(16,16, ILC_COLOR32|ILC_MASK, 6, 0);
- ImageList_AddMasked(hImageList,hBMcheck1,RGB(255,0,255));
-
- TreeView_SetImageList(hwndTree1, hImageList, TVSIL_STATE);
-
- if (TreeView_GetItemHeight(hwndTree1) < 16)
- TreeView_SetItemHeight(hwndTree1, 16);
-
- DeleteObject(hBMcheck1);
-
- for (i = 0; i < NSIS_MAX_INST_TYPES+1; i++)
- {
- if (install_types[i])
- {
- int j;
- if (i != NSIS_MAX_INST_TYPES) noCombo = 0;
- j=SendMessage(hwndCombo1,CB_ADDSTRING,0,(LPARAM)GetNSISStringTT(install_types[i]));
- SendMessage(hwndCombo1,CB_SETITEMDATA,j,i);
- }
- }
-
- SetUITextFromLang(IDC_TEXT1,this_page->parms[1+noCombo]);
- SetUITextFromLang(IDC_TEXT2,this_page->parms[2+noCombo]);
-
- Par=NULL;
-
- for (lastGoodX = x = 0; x < num_sections; x ++)
- {
- section *sec=sections+x;
-
- if (sec->name[0])
- {
- TVINSERTSTRUCT tv;
-
- tv.hParent = Par;
- tv.hInsertAfter = TVI_LAST;
- tv.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE;
- tv.item.stateMask = TVIS_EXPANDED;
- tv.item.lParam = x;
- tv.item.pszText = sec->name;
-
- tv.item.state = sec->flags & SF_EXPAND; // TVIS_EXPANDED == SF_EXPAND
-
- if (sec->flags & SF_SECGRP)
- {
- tv.item.mask |= TVIF_CHILDREN;
- tv.item.cChildren = 1;
- Par = hTreeItems[x] = TreeView_InsertItem(hwndTree1, &tv);
- doLines = 1;
- }
- else if (sec->flags & SF_SECGRPEND)
- {
- Par = TreeView_GetParent(hwndTree1, Par);
- }
- else
- {
- lastGoodX = x;
- hTreeItems[x] = TreeView_InsertItem(hwndTree1, &tv);
- }
- }
- }
-
- if (!doLines)
- {
- SetWindowLong(hwndTree1,GWL_STYLE,GetWindowLong(hwndTree1,GWL_STYLE)&~(TVS_LINESATROOT));
- }
-
- if (!noCombo)
- {
- ShowWindow(hwndCombo1, SW_SHOW);
- SetActiveCtl(hwndCombo1);
- }
- else
- SetActiveCtl(hwndTree1);
- }
-
- if (uMsg == WM_NOTIFY_START)
- {
- wParam = 0;
- lParam = 1;
- uMsg = WM_IN_UPDATEMSG;
- }
-
- if (uMsg == WM_NOTIFY || uMsg == WM_TREEVIEW_KEYHACK)
- {
- LPNMHDR lpnmh = (LPNMHDR) lParam;
- if (uMsg == WM_TREEVIEW_KEYHACK || lpnmh->idFrom == IDC_TREE1)
- {
- if (!(g_flags&CH_FLAGS_NO_CUSTOM) && (uMsg == WM_TREEVIEW_KEYHACK || lpnmh->code == NM_CLICK))
- {
- int secid = TreeGetSelectedSection(hwndTree1, uMsg != WM_TREEVIEW_KEYHACK);
-
- if (secid >= 0)
- {
- int flags = sections[secid].flags;
-
- if ((flags & SF_RO) == 0)
- {
- if ((flags & SF_PSELECTED))
- {
- flags ^= SF_TOGGLED;
-
- if (flags & SF_TOGGLED)
- {
- flags |= SF_SELECTED;
- }
- else
- {
- flags &= ~SF_SELECTED;
- }
- }
- else
- {
- flags ^= SF_SELECTED;
- }
-
- sections[secid].flags = flags;
-
- SectionFlagsChanged(secid);
-
- wParam = 1;
- lParam = !(g_flags & CH_FLAGS_COMP_ONLY_ON_CUSTOM);
- uMsg = WM_IN_UPDATEMSG;
- }
- } // was valid click
- } // was click or hack
-#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
- if (lpnmh)
- {
- if (lpnmh->code == TVN_SELCHANGED)
- {
- SendMessage(hwndTree1, WM_NOTIFY_SELCHANGE, 0, ((LPNMTREEVIEW)lpnmh)->itemNew.lParam);
- }
- if (lpnmh->code == TVN_ITEMEXPANDED)
- {
- LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lpnmh;
- if (pnmtv->action == TVE_EXPAND)
- sections[pnmtv->itemNew.lParam].flags |= SF_EXPAND;
- else
- sections[pnmtv->itemNew.lParam].flags &= ~SF_EXPAND;
- }
- }
-#endif//NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_ENHANCEDUI_SUPPORT
- }
- }
-
- if (uMsg == WM_COMMAND && LOWORD(wParam) == IDC_COMBO1 && HIWORD(wParam) == CBN_SELCHANGE)
- {
- int t = SendMessage(hwndCombo1,CB_GETCURSEL,0,0);
- if (t != CB_ERR)
- {
- int whichcfg = SendMessage(hwndCombo1, CB_GETITEMDATA, t, 0);
-
- if (whichcfg == CB_ERR || !install_types[whichcfg])
- whichcfg = NSIS_MAX_INST_TYPES;
-
- SetInstType(whichcfg);
-
- SendMessage(hwndDlg, WM_NOTIFY_INSTTYPE_CHANGED, 0, whichcfg);
-
- wParam = 1;
- lParam = 0;
- uMsg = WM_IN_UPDATEMSG;
- }
- }
-
- if (uMsg == WM_MOUSEMOVE)
- {
- SendMessage(hwndTree1, WM_MOUSEMOVE, 0, 0);
- }
-
- if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
- {
- if (hImageList) ImageList_Destroy(hImageList);
- if (hTreeItems) GlobalFree(hTreeItems);
- hImageList = NULL;
- hTreeItems = NULL;
- g_SectionHack = NULL;
- }
-
- if (uMsg == WM_IN_UPDATEMSG)
- {
- RefreshSectionGroups();
-
-#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_COMPONENTPAGE)
- if (wParam)
- {
- ExecuteCallbackFunction(CB_ONSELCHANGE);
- }
-#endif//NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_COMPONENTPAGE
-
- if (lParam)
- {
- int i, cbi;
- int inst_type = GetInstType(hTreeItems);
- SetInstType(inst_type);
-
- for (i = 0, cbi = 0; i < inst_type; i++)
- {
- if (install_types[i])
- {
- cbi++;
- }
- }
-
- SendMessage(hwndCombo1, CB_SETCURSEL, cbi, 0);
-
- lParam = inst_type;
- uMsg = WM_NOTIFY_INSTTYPE_CHANGED;
- }
-
- RefreshSectionGroups();
- RefreshComponents(hwndTree1, hTreeItems);
-
- if (LANG_STR_TAB(LANG_SPACE_REQ)) {
- SetSizeText(IDC_SPACEREQUIRED,LANG_SPACE_REQ,sumsecsfield(size_kb));
- }
- }
-
- if (uMsg == WM_NOTIFY_INSTTYPE_CHANGED)
- {
- if (g_flags & CH_FLAGS_COMP_ONLY_ON_CUSTOM)
- {
- int c = (lParam == NSIS_MAX_INST_TYPES ? 1 : 0) << 3;// SW_SHOWNA=8, SW_HIDE=0
- ShowWindow(hwndTree1, c);
- ShowWindow(GetUIItem(IDC_TEXT2), c);
- }
- }
-
- return HandleStaticBkColor();
-}
-#endif//NSIS_CONFIG_COMPONENTPAGE
-
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
-
-void NSISCALL update_status_text(int strtab, const char *text) {
- static char tmp[NSIS_MAX_STRLEN*2];
- LVITEM new_item;
- HWND linsthwnd = insthwnd;
- if (linsthwnd)
- {
- int updateflag = g_exec_flags.status_update;
- int tmplen;
-
- if (!(updateflag & 1))
- GetNSISString(tmp, strtab);
-
- tmplen = mystrlen(tmp);
-
- if (text)
- {
- if (tmplen + mystrlen(text) >= sizeof(tmp)) return;
- mystrcat(tmp, text);
- }
-
- if ((updateflag & 4) == 0) my_SetWindowText(insthwnd2, tmp);
- if ((updateflag & 2) == 0)
- {
- new_item.mask = LVIF_TEXT;
- new_item.pszText = tmp;
- new_item.iItem = ListView_GetItemCount(linsthwnd) - (updateflag & 1);
- new_item.iSubItem = 0;
- // LVM_INSERTITEM - LVM_SETITEM = 1
- SendMessage(linsthwnd, LVM_INSERTITEM - (updateflag & 1), 0, (LPARAM) &new_item);
- ListView_EnsureVisible(linsthwnd, new_item.iItem, 0);
- }
-
- if (updateflag & 1)
- tmp[tmplen] = 0;
- }
-}
-
-static DWORD WINAPI install_thread(LPVOID p)
-{
- int m_inst_sec=num_sections;
- HWND progresswnd = (HWND)p;
- section *s = g_sections;
-
-#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
- {
- extern HRESULT g_hres;
- g_hres|=OleInitialize(NULL);
- }
-#endif
-
- // workaround for bug #1400995
- //
- // for an unexplained reason, MessageBox with MB_TOPMOST
- // will fail, if no other messages were sent from this
- // thread to the GUI thread before it.
- //
- // the source of the problem couldn't be found, so a
- // WM_NULL is sent to work around it.
-
- NotifyCurWnd(WM_NULL);
-
- while (m_inst_sec--)
- {
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- if (s->flags&SF_SELECTED)
-#endif
- {
- log_printf2("Section: \"%s\"",s->name);
- if (ExecuteCodeSegment(s->code,progresswnd))
- {
- g_exec_flags.abort++;
- break;
- }
- }
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- else
- {
- log_printf2("Skipping section: \"%s\"",s->name);
- }
-#endif
- s++;
- }
- NotifyCurWnd(WM_NOTIFY_INSTPROC_DONE);
-
-#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
- OleUninitialize();
-#endif
-
- return g_exec_flags.abort;
-}
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-
-static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- HWND linsthwnd=insthwnd;
- if (uMsg == WM_INITDIALOG)
- {
- RECT r;
- LVCOLUMN lvc = {LVCF_WIDTH, 0, -1, 0, 0, -1};
- int lb_bg=g_header->lb_bg,lb_fg=g_header->lb_fg;
-
- insthwndbutton=GetUIItem(IDC_SHOWDETAILS);
- insthwnd2=GetUIItem(IDC_INTROTEXT);
- linsthwnd=insthwnd=GetUIItem(IDC_LIST1);
-
- SetActiveCtl(insthwndbutton);
-
- progress_bar_len=sumsecsfield(code_size);
- progress_bar_pos=0;
-
- log_printf3("New install of \"%s\" to \"%s\"",GetNSISStringTT(LANG_NAME),state_install_directory);
-
- GetClientRect(linsthwnd, &r);
- lvc.cx = r.right - GetSystemMetrics(SM_CXHSCROLL);
- ListView_InsertColumn(linsthwnd, 0, &lvc);
-
- ListView_SetExtendedListViewStyleEx(linsthwnd, LVS_EX_LABELTIP, LVS_EX_LABELTIP);
- if (lb_bg >= 0) {
- ListView_SetBkColor(linsthwnd, lb_bg);
- ListView_SetTextBkColor(linsthwnd, lb_bg);
- }
- if (lb_fg >= 0) {
- ListView_SetTextColor(linsthwnd, lb_fg);
- }
- SetUITextFromLang(IDC_SHOWDETAILS,this_page->parms[1]);
- if (g_flags&(CH_FLAGS_DETAILS_SHOWDETAILS|CH_FLAGS_DETAILS_NEVERSHOW))
- {
- ShowWindow(insthwndbutton,SW_HIDE);
- if (!(g_flags&CH_FLAGS_DETAILS_NEVERSHOW)) ShowWindow(linsthwnd,SW_SHOWNA);
- else insthwndbutton=NULL;
- SetActiveCtl(insthwnd2);
- }
-
- {
- HWND progresswnd=GetUIItem(IDC_PROGRESS);
- SendMessage(progresswnd,PBM_SETRANGE,0,MAKELPARAM(0,30000));
- if (g_flags&CH_FLAGS_PROGRESS_COLORED)
- {
- SendMessage(progresswnd,PBM_SETBARCOLOR,0,lb_fg);
- SendMessage(progresswnd,PBM_SETBKCOLOR,0,lb_bg);
- }
- }
-
- return FALSE;
- }
- if (uMsg == WM_NOTIFY_START) {
- DWORD id;
- CloseHandle(CreateThread(NULL,0,install_thread,GetUIItem(IDC_PROGRESS),0,&id));
- }
- if (uMsg == WM_COMMAND && LOWORD(wParam) == IDC_SHOWDETAILS)
- {
- ShowWindow(insthwndbutton,SW_HIDE);
- ShowWindow(linsthwnd,SW_SHOWNA);
- SetActiveCtl(linsthwnd);
- }
- if (uMsg == WM_NOTIFY_INSTPROC_DONE)
- {
- if (g_quit_flag)
- {
- m_retcode=2;
- outernotify(NOTIFY_BYE_BYE);
- }
- else
- {
- ShowWindow(g_hwnd,SW_SHOWNA);
- if (!g_exec_flags.abort)
- update_status_text(g_this_page->parms[2],0);
- outernotify(1);
- }
- }
- //>>>Ximon Eighteen aka Sunjammer 30th August 2002
- //+++Popup "Copy Details To Clipboard" menu when RMB clicked in DetailView
- if (uMsg == WM_CONTEXTMENU && wParam == (WPARAM) linsthwnd)
- {
- int count = ListView_GetItemCount(linsthwnd);
- if (count > 0)
- {
- HMENU menu = CreatePopupMenu();
- POINT pt;
- AppendMenu(menu,MF_STRING,1,GetNSISStringTT(LANG_COPYDETAILS));
- if (lParam == ((UINT)-1))
- {
- RECT r;
- GetWindowRect(linsthwnd, &r);
- pt.x = r.left;
- pt.y = r.top;
- }
- else
- {
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
- }
- if (1==TrackPopupMenu(
- menu,
- TPM_NONOTIFY|TPM_RETURNCMD,
- pt.x,
- pt.y,
- 0,hwndDlg,0))
- {
- int i,total = 1; // 1 for the null char
- LVITEM item;
- HGLOBAL memory;
- LPTSTR ptr;//,endPtr;
-
- // 1st pass - determine clipboard memory required.
- item.iSubItem = 0;
- item.pszText = g_tmp;
- item.cchTextMax = sizeof(g_tmp) - 1;
- i = count;
- while (i--)
- // Add 2 for the CR/LF combination that must follow every line.
- total += 2+SendMessage(linsthwnd,LVM_GETITEMTEXT,i,(LPARAM)&item);
-
- // 2nd pass - store detail view strings on the clipboard
- // Clipboard MSDN docs say mem must be GMEM_MOVEABLE
- OpenClipboard(0);
- EmptyClipboard();
- memory = GlobalAlloc(GHND,total);
- ptr = GlobalLock(memory);
- //endPtr = ptr+total-2; // -2 to allow for CR/LF
- i = 0;
- do {
- item.pszText = ptr;
- ptr += SendMessage(linsthwnd,LVM_GETITEMTEXT,i,(LPARAM)&item);
- *(WORD*)ptr = CHAR2_TO_WORD('\r','\n');
- ptr+=2;
- } while (++i < count);
- // memory is auto zeroed when allocated with GHND - *ptr = 0;
- GlobalUnlock(memory);
- SetClipboardData(CF_TEXT,memory);
- CloseClipboard();
- }
- }
- return FALSE;
- }
- //<<<
- return HandleStaticBkColor();
-}
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+/*
+ * Ui.c
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft, Jeff Doozan and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include <windowsx.h>
+#include <shlobj.h>
+#include <shellapi.h>
+#include <shlwapi.h>
+
+#include "../Platform.h"
+
+#include "resource.h"
+
+#include "fileform.h"
+#include "state.h"
+#include "util.h"
+#include "ui.h"
+#include "exec.h"
+#include "lang.h"
+#include "components.h"
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+HICON g_hIcon;
+#endif
+
+int dlg_offset;
+int ui_dlg_visible=0; // At start main window is not visible
+int g_quit_flag; // set when Quit has been called (meaning bail out ASAP)
+
+#if NSIS_MAX_INST_TYPES > 32 || NSIS_MAX_INST_TYPES < 1
+#error invalid value for NSIS_MAX_INST_TYPES
+#endif
+
+int progress_bar_pos, progress_bar_len;
+
+#if NSIS_MAX_STRLEN < 1024
+static char g_tmp[4096];
+#else
+static char g_tmp[NSIS_MAX_STRLEN * 4];
+#endif
+
+static int m_page=-1,m_retcode,m_delta;
+static page *g_this_page;
+
+#define NOTIFY_BYE_BYE 'x'
+
+static void NSISCALL outernotify(int delta) {
+ if (delta==NOTIFY_BYE_BYE)
+ g_quit_flag++;
+ SendMessage(g_hwnd,WM_NOTIFY_OUTER_NEXT,(WPARAM)delta,0);
+}
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+static int CALLBACK WINAPI BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData);
+#ifdef NSIS_CONFIG_LICENSEPAGE
+static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#endif
+static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+static BOOL CALLBACK UninstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+
+static DWORD WINAPI install_thread(LPVOID p);
+
+void NSISCALL CleanUp();
+
+HWND insthwnd, insthwnd2, insthwndbutton;
+
+HWND m_curwnd;
+static HWND m_bgwnd, m_hwndOK, m_hwndCancel;
+
+static BOOL NSISCALL SetDlgItemTextFromLang_(HWND dlg, int id, int lid) {
+ return my_SetDialogItemText(dlg,id+1000,GetNSISStringTT(lid));
+}
+
+static void NSISCALL SetNextDef()
+{
+ SendMessage(g_exec_flags.abort ? m_hwndCancel : m_hwndOK, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
+}
+
+static void NSISCALL EnableNext(BOOL e)
+{
+ EnableWindow(m_hwndOK, e);
+}
+
+static void NSISCALL SetActiveCtl(HWND hCtl)
+{
+ SendMessage(g_hwnd, WM_NEXTDLGCTL, (WPARAM) hCtl, TRUE);
+}
+
+static void NSISCALL NotifyCurWnd(UINT uNotifyCode)
+{
+ if (m_curwnd)
+ SendMessage(m_curwnd, uNotifyCode, 0, 0);
+}
+
+#define SetDlgItemTextFromLang(dlg,id,lid) SetDlgItemTextFromLang_(dlg,(id)-1000,lid)
+
+#define SetUITextFromLang(it,la) SetDlgItemTextFromLang_(hwndDlg,(it)-1000,la)
+#define SetUITextNT(it,text) my_SetDialogItemText(hwndDlg,it,text)
+#define GetUIText(it,s) my_GetDialogItemText(it,s)
+#define GetUIItem(it) GetDlgItem(hwndDlg,it)
+
+#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+#define HandleStaticBkColor() _HandleStaticBkColor(uMsg, wParam, lParam)
+static BOOL NSISCALL _HandleStaticBkColor(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if ((uMsg - WM_CTLCOLOREDIT) <= (WM_CTLCOLORSTATIC - WM_CTLCOLOREDIT))
+ {
+ ctlcolors *c = (ctlcolors *)GetWindowLong((HWND)lParam, GWL_USERDATA);
+
+ if (c) {
+ COLORREF text;
+ LOGBRUSH lh;
+
+ text = c->text;
+ if (c->flags & CC_TEXT_SYS)
+ text = GetSysColor(text);
+ if (c->flags & CC_TEXT)
+ SetTextColor((HDC)wParam, text);
+
+ SetBkMode((HDC)wParam, c->bkmode);
+
+ lh.lbColor = c->bkc;
+ if (c->flags & CC_BK_SYS)
+ lh.lbColor = GetSysColor(lh.lbColor);
+ if (c->flags & CC_BK)
+ SetBkColor((HDC)wParam, lh.lbColor);
+
+ if (c->flags & CC_BKB)
+ {
+ lh.lbStyle = c->lbStyle;
+ if (c->bkb)
+ DeleteObject(c->bkb);
+ c->bkb = CreateBrushIndirect(&lh);
+ }
+
+ return (BOOL)c->bkb;
+ }
+ }
+ return 0;
+}
+#else
+#define HandleStaticBkColor() 0
+#endif//!NSIS_CONFIG_ENHANCEDUI_SUPPORT
+
+#ifdef NSIS_CONFIG_LOG
+#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
+void NSISCALL build_g_logfile()
+{
+ mystrcat(addtrailingslash(mystrcpy(g_log_file,state_install_directory)),"install.log");
+}
+#endif
+#endif
+
+int *cur_langtable;
+
+static void NSISCALL set_language()
+{
+ LANGID lang_mask=(LANGID)~0;
+ LANGID lang=myatoi(state_language);
+ char *language_table=0;
+ int lang_num;
+ int *selected_langtable=0;
+
+lang_again:
+ lang_num=g_blocks[NB_LANGTABLES].num;
+ while (lang_num--) {
+ language_table=((char*)g_blocks[NB_LANGTABLES].offset)+lang_num*g_header->langtable_size;
+ if (!((lang ^ *(LANGID*)language_table) & lang_mask)) {
+ dlg_offset=*(int*)(language_table+sizeof(LANGID));
+ g_exec_flags.rtl=*(int*)(language_table+sizeof(LANGID)+sizeof(int));
+ selected_langtable=(int*)(language_table+sizeof(LANGID)+2*sizeof(int));
+ break;
+ }
+ }
+ if (!selected_langtable) {
+ if (lang_mask == (LANGID)~0)
+ lang_mask=0x3ff; // primary lang
+ else // we already tried once and we still don't have a language table
+ lang_mask=0; // first lang
+ goto lang_again;
+ }
+
+ cur_langtable = selected_langtable;
+
+ myitoa(state_language, *(LANGID*)language_table);
+ {
+ char *caption = GetNSISString(g_caption,LANG_CAPTION);
+#ifdef NSIS_SUPPORT_BGBG
+ my_SetWindowText(m_bgwnd, caption);
+#endif
+ }
+
+ // reload section names
+ {
+ section *sec = g_sections;
+ int x = num_sections;
+
+ while (x--)
+ {
+ if (sec->name_ptr)
+ {
+ GetNSISString(sec->name, sec->name_ptr);
+ }
+ sec++;
+ }
+ }
+}
+
+FORCE_INLINE int NSISCALL ui_doinstall(void)
+{
+ header *header = g_header;
+ static WNDCLASS wc; // richedit subclassing and bgbg creation
+
+ // detect default language
+ // more information at:
+ // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_0xrn.asp
+
+ LANGID (WINAPI *GUDUIL)();
+
+ GUDUIL = myGetProcAddress(MGA_GetUserDefaultUILanguage);
+ if (GUDUIL)
+ {
+ // Windows ME/2000+
+ myitoa(state_language, GUDUIL());
+ }
+ else
+ {
+ static const char reg_9x_locale[] = "Control Panel\\Desktop\\ResourceLocale";
+ static const char reg_nt_locale_key[] = ".DEFAULT\\Control Panel\\International";
+ const char *reg_nt_locale_val = &reg_9x_locale[30]; // = "Locale" with opt
+
+ *(DWORD*)state_language = CHAR4_TO_DWORD('0', 'x', 0, 0);
+
+ {
+ // Windows 9x
+ myRegGetStr(HKEY_CURRENT_USER, reg_9x_locale, NULL, g_tmp, 0);
+ }
+
+ if (!g_tmp[0])
+ {
+ // Windows NT
+ // This key exists on 9x as well, so it's only read if ResourceLocale wasn't found
+ myRegGetStr(HKEY_USERS, reg_nt_locale_key, reg_nt_locale_val, g_tmp, 0);
+ }
+
+ mystrcat(state_language, g_tmp);
+ }
+
+ // set default language
+ set_language();
+
+ // initialize auto close flag
+ g_exec_flags.autoclose=g_flags&CH_FLAGS_AUTO_CLOSE;
+
+ // read install directory from registry
+ if (!is_valid_instpath(state_install_directory))
+ {
+ if (header->install_reg_key_ptr)
+ {
+ myRegGetStr(
+ (HKEY)header->install_reg_rootkey,
+ GetNSISStringNP(header->install_reg_key_ptr),
+ GetNSISStringNP(header->install_reg_value_ptr),
+ ps_tmpbuf,
+ 0
+ );
+ if (ps_tmpbuf[0])
+ {
+ char *p=ps_tmpbuf;
+ char *e;
+ if (p[0]=='\"')
+ {
+ char *p2;
+ p++;
+ p2 = findchar(p, '"');
+ *p2 = 0;
+ }
+ // p is the path now, check for .exe extension
+
+ e=p+mystrlen(p)-4;
+ if (e > p)
+ {
+ // if filename ends in .exe, and is not a directory, remove the filename
+ if (!lstrcmpi(e, ".exe")) // check extension
+ {
+ DWORD d;
+ d=GetFileAttributes(p);
+ if (d == INVALID_FILE_ATTRIBUTES || !(d&FILE_ATTRIBUTE_DIRECTORY))
+ {
+ // if there is no back-slash, the string will become empty, but that's ok because
+ // it would make an invalid instdir anyway
+ trimslashtoend(p);
+ }
+ }
+ }
+
+ mystrcpy(state_install_directory,addtrailingslash(p));
+ }
+ }
+ }
+ if (!is_valid_instpath(state_install_directory))
+ {
+ GetNSISString(state_install_directory,header->install_directory_ptr);
+ }
+
+#ifdef NSIS_CONFIG_LOG
+ if (g_flags & CH_FLAGS_SILENT_LOG && !g_is_uninstaller)
+ {
+#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
+ build_g_logfile();
+#endif
+ log_dolog=1;
+ }
+#endif
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ g_hIcon=LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED);
+#ifdef NSIS_SUPPORT_BGBG
+ if (header->bg_color1 != -1)
+ {
+ DWORD cn = CHAR4_TO_DWORD('_', 'N', 'b', 0);
+ RECT vp;
+ extern LRESULT CALLBACK BG_WndProc(HWND, UINT, WPARAM, LPARAM);
+ wc.lpfnWndProc = BG_WndProc;
+ wc.hInstance = g_hInstance;
+ wc.hIcon = g_hIcon;
+ //wc.hCursor = LoadCursor(NULL,IDC_ARROW);
+ wc.lpszClassName = (LPCSTR)&cn;
+
+ if (!RegisterClass(&wc)) return 0;
+
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0);
+
+ m_bgwnd = CreateWindowEx(WS_EX_TOOLWINDOW,(LPCSTR)&cn,0,WS_POPUP,
+ vp.left,vp.top,vp.right-vp.left,vp.bottom-vp.top,0,NULL,g_hInstance,NULL);
+ }
+
+#endif//NSIS_SUPPORT_BGBG
+
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ // Select language
+ if (ExecuteCallbackFunction(CB_ONINIT)) return 2;
+ set_language();
+#endif
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ if (!g_exec_flags.silent)
+#endif//NSIS_CONFIG_SILENT_SUPPORT
+ {
+#ifdef NSIS_SUPPORT_BGBG
+ ShowWindow(m_bgwnd, SW_SHOW);
+#endif//NSIS_SUPPORT_BGBG
+
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ { // load richedit DLL
+ static const char riched20[]="RichEd20";
+ static const char riched32[]="RichEd32";
+ static const char richedit20a[]="RichEdit20A";
+ static const char richedit[]="RichEdit";
+ if (!LoadLibrary(riched20))
+ {
+ LoadLibrary(riched32);
+ }
+
+ // make richedit20a point to RICHEDIT
+ if (!GetClassInfo(NULL,richedit20a,&wc))
+ {
+ GetClassInfo(NULL,richedit,&wc);
+ wc.lpszClassName = richedit20a;
+ RegisterClass(&wc);
+ }
+ }
+#endif
+
+ {
+ int ret=DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST+dlg_offset),0,DialogProc);
+#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
+ ExecuteCallbackFunction(CB_ONGUIEND);
+#endif
+ return ret;
+ }
+ }
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ else
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+ {
+ if (install_thread(NULL))
+ {
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ if (!g_quit_flag) ExecuteCallbackFunction(CB_ONINSTFAILED);
+#endif//NSIS_SUPPORT_CODECALLBACKS
+ return 2;
+ }
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ ExecuteCallbackFunction(CB_ONINSTSUCCESS);
+#endif//NSIS_SUPPORT_CODECALLBACKS
+
+ return 0;
+ }
+#endif//NSIS_CONFIG_SILENT_SUPPORT
+}
+
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+static int CALLBACK WINAPI BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
+{
+ if (uMsg==BFFM_INITIALIZED)
+ {
+ my_GetDialogItemText(IDC_DIR,(char*)lpData);
+ SendMessage(hwnd,BFFM_SETSELECTION,(WPARAM)1,lpData);
+ }
+ if (uMsg==BFFM_SELCHANGED)
+ {
+ SendMessage(
+ hwnd,
+ BFFM_ENABLEOK,
+ 0,
+ SHGetPathFromIDList((LPITEMIDLIST)lParam,(char*)lpData)
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ && !ExecuteCallbackFunction(CB_ONVERIFYINSTDIR)
+#endif
+ );
+ }
+ return 0;
+}
+
+BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg == WM_INITDIALOG || uMsg == WM_NOTIFY_OUTER_NEXT)
+ {
+ page *this_page;
+ static DLGPROC winprocs[]=
+ {
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ LicenseProc,
+#endif
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ SelProc,
+#endif
+ DirProc,
+ InstProc,
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ UninstProc
+#endif
+ };
+
+ m_delta = wParam;
+
+ if (uMsg == WM_INITDIALOG)
+ {
+ g_hwnd=hwndDlg;
+ m_hwndOK=GetDlgItem(hwndDlg,IDOK);
+ m_hwndCancel=GetDlgItem(hwndDlg,IDCANCEL);
+ SetDlgItemTextFromLang(hwndDlg,IDC_VERSTR,LANG_BRANDING);
+ SetClassLong(hwndDlg,GCL_HICON,(long)g_hIcon);
+ // use the following line instead of the above, if .rdata needs shirking
+ //SendMessage(hwndDlg,WM_SETICON,ICON_BIG,(LPARAM)g_hIcon);
+#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
+ g_quit_flag = ExecuteCallbackFunction(CB_ONGUIINIT);
+#endif
+ //ShowWindow(hwndDlg, SW_SHOW);
+ m_delta = 1;
+ }
+
+ this_page=g_pages+m_page;
+
+ if (m_page>=0) {
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ // Call leave function. If Abort used don't move to the next page.
+ // But if quit called we must exit now
+ if (m_delta==1) if (ExecuteCodeSegment(this_page->leavefunc,NULL)) {
+ SendMessage(m_curwnd, WM_IN_UPDATEMSG, 0, 1);
+ return !g_quit_flag;
+ }
+#endif
+
+ // if the last page was a custom page, wait for it to finish by itself.
+ // if it doesn't, it's a BAD plugin.
+ // plugins should react to WM_NOTIFY_OUTER_NEXT.
+ if (!this_page->dlg_id) return 0;
+ }
+
+ NotifyCurWnd(WM_NOTIFY_INIGO_MONTOYA);
+
+nextPage:
+ m_page+=m_delta;
+ this_page+=m_delta;
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ if (m_page==g_blocks[NB_PAGES].num) ExecuteCallbackFunction(CB_ONINSTSUCCESS);
+#endif//NSIS_SUPPORT_CODECALLBACKS
+
+ if (g_quit_flag || (unsigned int)m_page >= (unsigned int)g_blocks[NB_PAGES].num)
+ {
+ DestroyWindow(m_curwnd);
+ g_hwnd = 0;
+ EndDialog(hwndDlg,m_retcode);
+ }
+ else
+ {
+ HWND hwndtmp;
+
+ int pflags = this_page->flags;
+
+ GetNSISString(state_click_next, this_page->clicknext);
+ SetDlgItemTextFromLang(hwndDlg, IDOK, this_page->next);
+ SetDlgItemTextFromLang(hwndDlg, IDC_BACK, this_page->back);
+ SetDlgItemTextFromLang(hwndDlg, IDCANCEL, this_page->cancel);
+
+ hwndtmp = GetDlgItem(hwndDlg, IDC_BACK);
+
+ if (g_exec_flags.abort)
+ {
+ pflags &= ~(PF_BACK_ENABLE | PF_NEXT_ENABLE);
+ pflags |= PF_CANCEL_ENABLE;
+ }
+
+ ShowWindow(hwndtmp, pflags & PF_BACK_SHOW);// SW_HIDE = 0, PF_BACK_SHOW = SW_SHOWNA = 8
+ EnableWindow(hwndtmp, pflags & PF_BACK_ENABLE);
+ EnableNext(pflags & PF_NEXT_ENABLE);
+ EnableWindow(m_hwndCancel, pflags & PF_CANCEL_ENABLE);
+
+ if (pflags & PF_CANCEL_ENABLE)
+ EnableMenuItem(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND | MF_ENABLED);
+ else
+ EnableMenuItem(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
+
+ SendMessage(hwndtmp, BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
+
+ if (g_exec_flags.abort)
+ {
+ SendMessage(hwndDlg, DM_SETDEFID, IDCANCEL, 0);
+ SetActiveCtl(m_hwndCancel);
+ }
+ else
+ {
+ SetActiveCtl(m_hwndOK);
+ }
+
+ mystrcpy(g_tmp,g_caption);
+ GetNSISString(g_tmp+mystrlen(g_tmp),this_page->caption);
+ my_SetWindowText(hwndDlg,g_tmp);
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ // custom page or user used abort in prefunc
+ if (ExecuteCodeSegment(this_page->prefunc, NULL) || !this_page->dlg_id) {
+ goto nextPage;
+ }
+#endif //NSIS_SUPPORT_CODECALLBACKS
+
+ if (this_page->wndproc_id != PWP_COMPLETED)
+ {
+ DestroyWindow(m_curwnd);
+ }
+ else {
+ if (!g_exec_flags.abort && g_exec_flags.autoclose)
+ goto nextPage;
+ // no need to go to skipPage because PWP_COMPLETED always follows PWP_INSTFILES
+ return FALSE;
+ }
+
+ // update g_this_page for the dialog proc
+ g_this_page=this_page;
+
+ if (this_page->dlg_id > 0) // NSIS page
+ {
+ m_curwnd=CreateDialogParam(
+ g_hInstance,
+ MAKEINTRESOURCE(this_page->dlg_id+dlg_offset),
+ hwndDlg,winprocs[this_page->wndproc_id],(LPARAM)this_page
+ );
+ if (m_curwnd)
+ {
+ RECT r;
+
+ SetDlgItemTextFromLang(m_curwnd,IDC_INTROTEXT,this_page->parms[0]);
+
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_CHILDRECT),&r);
+ ScreenToClient(hwndDlg,(LPPOINT)&r);
+ SetWindowPos(m_curwnd,0,r.left,r.top,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ ExecuteCodeSegment(this_page->showfunc,NULL);
+ if (g_quit_flag)
+ return FALSE;
+#endif //NSIS_SUPPORT_CODECALLBACKS
+ ShowWindow(m_curwnd,SW_SHOWNA);
+ NotifyCurWnd(WM_NOTIFY_START);
+ }
+ }
+ }
+
+skipPage:
+
+ if (!ui_dlg_visible && m_curwnd)
+ {
+ ShowWindow(hwndDlg, SW_SHOWDEFAULT);
+ ui_dlg_visible = 1;
+ }
+
+ return FALSE;
+ }
+
+#ifdef NSIS_SUPPORT_BGBG
+ if (uMsg == WM_WINDOWPOSCHANGED)
+ {
+ SetWindowPos(m_bgwnd, hwndDlg, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+ }
+ if (uMsg == WM_SIZE) {
+ ShowWindow(m_bgwnd, wParam == SIZE_MINIMIZED ? SW_HIDE : SW_SHOW);
+ }
+#endif //NSIS_SUPPORT_BGBG
+
+ if (uMsg == WM_NOTIFY_CUSTOM_READY) {
+ DestroyWindow(m_curwnd);
+ m_curwnd = (HWND)wParam;
+ goto skipPage;
+ }
+ if (uMsg == WM_QUERYENDSESSION)
+ {
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, FALSE);
+ return TRUE;
+ }
+ if (uMsg == WM_COMMAND)
+ {
+ int id = LOWORD(wParam);
+ HWND hCtl = GetDlgItem(hwndDlg, id); // lParam might be NULL
+ if (hCtl)
+ {
+ SendMessage(hCtl, BM_SETSTATE, FALSE, 0);
+ if (!IsWindowEnabled(hCtl))
+ return 0;
+ }
+
+ if (id == IDOK)
+ {
+ outernotify(1);
+ }
+ else if (id == IDC_BACK && m_page>0)
+ {
+ outernotify(-1);
+ }
+ else if (id == IDCANCEL)
+ {
+ if (g_exec_flags.abort)
+ {
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ ExecuteCallbackFunction(CB_ONINSTFAILED);
+#endif//NSIS_SUPPORT_CODECALLBACKS
+ m_retcode=2;
+ outernotify(NOTIFY_BYE_BYE);
+ }
+ else
+ {
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ if (!ExecuteCallbackFunction(CB_ONUSERABORT))
+#endif//NSIS_SUPPORT_CODECALLBACKS
+ {
+ m_retcode=1;
+ outernotify(NOTIFY_BYE_BYE);
+ }
+ }
+ }
+ else
+ {
+ // Forward WM_COMMANDs to inner dialogs, can be custom ones.
+ // Without this, enter on buttons in inner dialogs won't work.
+ SendMessage(m_curwnd, WM_COMMAND, wParam, lParam);
+ }
+ }
+ return HandleStaticBkColor();
+}
+
+#define this_page ((page*)lParam)
+
+#ifdef NSIS_CONFIG_LICENSEPAGE
+
+#define _RICHEDIT_VER 0x0200
+#include <richedit.h>
+#undef _RICHEDIT_VER
+static DWORD dwRead;
+DWORD CALLBACK StreamLicense(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
+{
+ lstrcpyn(pbBuff,(char*)dwCookie+dwRead,cb);
+ *pcb=mystrlen(pbBuff);
+ dwRead+=*pcb;
+ return 0;
+}
+
+static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ page *m_this_page=g_this_page;
+ HWND hwLicense;
+ static int ignoreWMCommand;
+
+ if (uMsg == WM_INITDIALOG)
+ {
+ char *l = (char *)GetNSISStringNP(GetNSISTab(this_page->parms[1]));
+ int lt = *l;
+ EDITSTREAM es = {
+ (DWORD)(++l),
+ 0,
+ StreamLicense
+ };
+
+ int selected = (this_page->flags & PF_LICENSE_SELECTED) | !(this_page->flags & PF_LICENSE_FORCE_SELECTION);
+
+ SetUITextFromLang(IDC_LICENSEAGREE,this_page->parms[2]);
+ SetUITextFromLang(IDC_LICENSEDISAGREE,this_page->parms[3]);
+ CheckDlgButton(hwndDlg,IDC_LICENSEAGREE+!selected,BST_CHECKED);
+ EnableNext(selected);
+
+ hwLicense=GetUIItem(IDC_EDIT1);
+ SetActiveCtl(hwLicense);
+ SendMessage(hwLicense,EM_AUTOURLDETECT,TRUE,0);
+#define lbg g_header->license_bg
+ SendMessage(hwLicense,EM_SETBKGNDCOLOR,0,lbg>=0?lbg:GetSysColor(-lbg));
+#undef lbg
+ SendMessage(hwLicense,EM_SETEVENTMASK,0,ENM_LINK|ENM_KEYEVENTS); //XGE 8th September 2002 Or'd in ENM_KEYEVENTS
+ dwRead=0;
+ SendMessage(hwLicense,EM_EXLIMITTEXT,0,mystrlen(l));
+ SendMessage(hwLicense,EM_STREAMIN,lt,(LPARAM)&es);
+ ignoreWMCommand = 0;
+ return FALSE;
+ }
+ if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && !ignoreWMCommand) {
+ if (m_this_page->flags & PF_LICENSE_FORCE_SELECTION) {
+ int is = SendMessage(GetUIItem(IDC_LICENSEAGREE), BM_GETCHECK, 0, 0) & BST_CHECKED;
+ m_this_page->flags &= ~PF_LICENSE_SELECTED;
+ m_this_page->flags |= is;
+ EnableNext(is);
+ SetNextDef();
+ }
+ }
+ if (uMsg == WM_NOTIFY) {
+ hwLicense=GetUIItem(IDC_EDIT1);
+ #define nmhdr ((NMHDR *)lParam)
+ #define enlink ((ENLINK *)lParam)
+ #define msgfilter ((MSGFILTER *)lParam)
+ if (nmhdr->code==EN_LINK) {
+ if (enlink->msg==WM_LBUTTONDOWN) {
+ TEXTRANGE tr = {
+ {
+ enlink->chrg.cpMin,
+ enlink->chrg.cpMax,
+ },
+ ps_tmpbuf
+ };
+ if (tr.chrg.cpMax-tr.chrg.cpMin < sizeof(ps_tmpbuf)) {
+ SendMessage(hwLicense,EM_GETTEXTRANGE,0,(LPARAM)&tr);
+ SetCursor(LoadCursor(0, IDC_WAIT));
+ ShellExecute(hwndDlg,"open",tr.lpstrText,NULL,NULL,SW_SHOWNORMAL);
+ SetCursor(LoadCursor(0, IDC_ARROW));
+ }
+ }
+ }
+ //Ximon Eighteen 8th September 2002 Capture return key presses in the rich
+ //edit control now that the control gets the focus rather than the default
+ //push button. When the user presses return ask the outer dialog to move
+ //the installer onto the next page. MSDN docs say return non-zero if the
+ //rich edit control should NOT process this message, hence the return 1.
+ //
+ //This is required because the RichEdit control is eating all the key hits.
+ //It does try to release some and convert VK_ESCAPE to WM_CLOSE, VK_ENTER
+ //to a push on the default button and VM_TAB to WM_NEXTDLGCTL. But sadly it
+ //it sends all of these messages to its parent instead of just letting the
+ //dialog manager handle them. Instead of properly handling WM_GETDLGCODE,
+ //it mimics the dialog manager.
+ if (nmhdr->code==EN_MSGFILTER)
+ {
+ if (msgfilter->msg==WM_KEYDOWN)
+ {
+ if (msgfilter->wParam==VK_RETURN) {
+ SendMessage(g_hwnd, WM_COMMAND, IDOK, 0);
+ }
+ if (msgfilter->wParam==VK_ESCAPE) {
+ SendMessage(g_hwnd, WM_CLOSE, 0, 0);
+ }
+ return 1;
+ }
+ }
+ #undef nmhdr
+ #undef enlink
+ #undef msgfilter
+ }
+ if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
+ {
+ ignoreWMCommand++;
+ }
+ return HandleStaticBkColor();
+}
+#endif
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+static BOOL CALLBACK UninstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg == WM_INITDIALOG)
+ {
+ SetUITextFromLang(IDC_UNINSTFROM,this_page->parms[1]);
+ SetUITextNT(IDC_EDIT1,g_usrvars[this_page->parms[4]]);
+ }
+ return HandleStaticBkColor();
+}
+#endif
+
+
+static void NSISCALL SetSizeText(int dlgItem, int prefix, unsigned kb)
+{
+ char scalestr[32], byte[32];
+ unsigned sh = 20;
+ int scale = LANG_GIGA;
+
+ if (kb < 1024 * 1024) { sh = 10; scale = LANG_MEGA; }
+ if (kb < 1024) { sh = 0; scale = LANG_KILO; }
+
+ if (kb < (0xFFFFFFFF - ((1 << 20) / 20))) // check for overflow
+ kb += (1 << sh) / 20; // round numbers for better display (e.g. 1.59 => 1.6)
+
+ wsprintf(
+ GetNSISString(g_tmp, prefix) + mystrlen(g_tmp),
+ "%u.%u%s%s",
+ kb >> sh,
+ (((kb & 0x00FFFFFF) * 10) >> sh) % 10, // 0x00FFFFFF mask is used to
+ // prevent overflow that causes
+ // bad results
+ GetNSISString(scalestr, scale),
+ GetNSISString(byte, LANG_BYTE)
+ );
+
+ my_SetDialogItemText(m_curwnd,dlgItem,g_tmp);
+}
+
+static int NSISCALL _sumsecsfield(int idx)
+{
+ int total = 0;
+ int x = num_sections;
+ section *s = g_sections;
+ while (x--)
+ {
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ if (s->flags & SF_SELECTED)
+#endif
+ total += ((int *)s)[idx];
+ s++;
+ }
+ return total;
+}
+
+#define sumsecsfield(x) _sumsecsfield(SECTION_OFFSET(x))
+
+static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static int dontsetdefstyle;
+ page *thispage = g_this_page;
+ char *dir = g_usrvars[thispage->parms[4]];
+ int browse_text = thispage->parms[3];
+ if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
+ {
+ GetUIText(IDC_DIR,dir);
+ validate_filename(dir);
+#ifdef NSIS_CONFIG_LOG
+#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
+ build_g_logfile();
+#endif
+ if (GetUIItem(IDC_CHECK1) != NULL)
+ log_dolog = IsDlgButtonChecked(hwndDlg,IDC_CHECK1);
+#endif
+ }
+ if (uMsg == WM_INITDIALOG)
+ {
+ HWND hDir = GetUIItem(IDC_DIR);
+
+#ifdef NSIS_CONFIG_LOG
+ if (GetAsyncKeyState(VK_SHIFT)&0x8000)
+ {
+ HWND h=GetUIItem(IDC_CHECK1);
+ SetUITextFromLang(IDC_CHECK1,LANG_LOG_INSTALL_PROCESS);
+ ShowWindow(h,SW_SHOWNA);
+ }
+#endif
+ if (validpathspec(dir) && !skip_root(dir))
+ addtrailingslash(dir);
+
+ // workaround for bug #1209843
+ //
+ // m_curwnd is only updated once WM_INITDIALOG returns.
+ // my_SetWindowText triggers an EN_CHANGE message that
+ // triggers a WM_IN_UPDATEMSG message that uses m_curwnd
+ // to get the selected directory (GetUIText).
+ // because m_curwnd is still outdated, dir varialble is
+ // filled with an empty string. by default, dir points
+ // to $INSTDIR.
+ //
+ // to solve this, m_curwnd is manually set to the correct
+ // window handle.
+
+ m_curwnd=hwndDlg;
+
+ my_SetWindowText(hDir,dir);
+ SetUITextFromLang(IDC_BROWSE,this_page->parms[2]);
+ SetUITextFromLang(IDC_SELDIRTEXT,this_page->parms[1]);
+ SetActiveCtl(hDir);
+
+ {
+ typedef HRESULT (WINAPI *SHAutoCompletePtr)(HWND, DWORD);
+ SHAutoCompletePtr fSHAutoComplete;
+ fSHAutoComplete = (SHAutoCompletePtr) myGetProcAddress(MGA_SHAutoComplete);
+ if (fSHAutoComplete)
+ {
+ fSHAutoComplete(hDir, SHACF_FILESYSTEM);
+ }
+ }
+ }
+ if (uMsg == WM_COMMAND)
+ {
+ int id=LOWORD(wParam);
+ if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE)
+ {
+ uMsg = WM_IN_UPDATEMSG;
+ }
+ if (id == IDC_BROWSE)
+ {
+ static char bt[NSIS_MAX_STRLEN];
+ BROWSEINFO bi = {0,};
+ ITEMIDLIST *idlist;
+ bi.hwndOwner = hwndDlg;
+ bi.pszDisplayName = g_tmp;
+ bi.lpfn = BrowseCallbackProc;
+ bi.lParam = (LPARAM)dir;
+ bi.lpszTitle = GetNSISString(bt, browse_text);
+ bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
+ idlist = SHBrowseForFolder(&bi);
+ if (idlist)
+ {
+ // free idlist
+ CoTaskMemFree(idlist);
+
+ addtrailingslash(dir);
+
+ if (g_header->install_directory_auto_append &&
+ dir == state_install_directory) // only append to $INSTDIR (bug #1174184)
+ {
+ const char *post_str = ps_tmpbuf;
+ GetNSISStringTT(g_header->install_directory_auto_append);
+ // display name gives just the folder name
+ if (lstrcmpi(post_str, g_tmp))
+ {
+ mystrcat(dir, post_str);
+ }
+ }
+
+ dontsetdefstyle++;
+ SetUITextNT(IDC_DIR,dir);
+ }
+ else
+ {
+ uMsg = WM_IN_UPDATEMSG;
+ }
+ }
+ }
+ if (uMsg == WM_IN_UPDATEMSG || uMsg == WM_NOTIFY_START)
+ {
+ static char s[NSIS_MAX_STRLEN];
+ char *p;
+ int error = 0;
+ int available_set = 0;
+ unsigned total, available = 0xFFFFFFFF;
+
+ GetUIText(IDC_DIR,dir);
+ if (!is_valid_instpath(dir))
+ error = NSIS_INSTDIR_INVALID;
+
+ mystrcpy(s,dir);
+ p=skip_root(s);
+ if (p)
+ *p=0;
+
+ // Test for and use the GetDiskFreeSpaceEx API
+ {
+ BOOL (WINAPI *GDFSE)(LPCSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
+ myGetProcAddress(MGA_GetDiskFreeSpaceExA);
+ if (GDFSE)
+ {
+ ULARGE_INTEGER available64;
+ ULARGE_INTEGER a, b;
+ if (GDFSE(s, &available64, &a, &b))
+ {
+#ifndef _NSIS_NO_INT64_SHR
+ available = (int)(available64.QuadPart >> 10);
+#else
+ available = (int)(Int64ShrlMod32(available64.QuadPart, 10));
+#endif
+ available_set++;
+ }
+ }
+ }
+
+ if (!available_set)
+ {
+ // GetDiskFreeSpaceEx is not available
+ DWORD spc, bps, fc, tc;
+ if (GetDiskFreeSpace(s, &spc, &bps, &fc, &tc))
+ {
+ available = (int)MulDiv(bps * spc, fc, 1 << 10);
+ available_set++;
+ }
+ }
+
+ total = (unsigned) sumsecsfield(size_kb);
+
+ if (available < total)
+ error = NSIS_INSTDIR_NOT_ENOUGH_SPACE;
+
+ if (LANG_STR_TAB(LANG_SPACE_REQ)) {
+ SetSizeText(IDC_SPACEREQUIRED,LANG_SPACE_REQ,total);
+ if (available_set)
+ SetSizeText(IDC_SPACEAVAILABLE,LANG_SPACE_AVAIL,available);
+ else
+ SetUITextNT(IDC_SPACEAVAILABLE,"");
+ }
+
+ g_exec_flags.instdir_error = error;
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ if (!error)
+ error = ExecuteCallbackFunction(CB_ONVERIFYINSTDIR);
+#endif
+
+ if (thispage->flags & PF_DIR_NO_BTN_DISABLE)
+ error = 0;
+
+ EnableNext(!error);
+ if (!error && !dontsetdefstyle)
+ SetNextDef();
+ dontsetdefstyle = 0;
+ }
+ return HandleStaticBkColor();
+}
+
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+
+static void FORCE_INLINE NSISCALL RefreshComponents(HWND hwTree, HTREEITEM *items)
+{
+ TVITEM item;
+ int i, flags, state;
+ section *sec;
+
+ item.stateMask = TVIS_STATEIMAGEMASK | TVIS_EXPANDED | TVIS_BOLD;
+
+ for (i = 0, sec = g_sections; i < num_sections; i++, sec++)
+ {
+ if (!items[i])
+ {
+ continue;
+ }
+
+ flags = sec->flags;
+
+ item.hItem = items[i];
+
+ item.mask = TVIF_STATE;
+
+ if (flags & SF_NAMECHG)
+ {
+ item.mask |= TVIF_TEXT;
+ item.pszText = sec->name;
+ sec->flags &= ~SF_NAMECHG;
+ }
+
+ if (flags & SF_PSELECTED)
+ {
+ state = 3;
+ }
+ else
+ {
+ state = 1 + (flags & SF_SELECTED); // SF_SELECTED == 1
+ if (flags & SF_RO) state += 3;
+ }
+
+ item.state = (flags & SF_BOLD) << 1; // (SF_BOLD << 1) == 16 == TVIS_BOLD
+ item.state |= flags & SF_EXPAND; // TVIS_EXPANDED == SF_EXPAND
+ item.state |= INDEXTOSTATEIMAGEMASK(state);
+
+ // TVE_COLLAPSE = 1, TVE_EXPAND = 2
+ TreeView_Expand(hwTree, item.hItem, TVE_COLLAPSE + ((flags & SF_EXPAND) / SF_EXPAND));
+
+ TreeView_SetItem(hwTree, &item);
+ }
+
+ // workaround for bug #1397031
+ //
+ // windows 95 doesn't erase the background of the state image
+ // before it draws a new one. because of this parts of the old
+ // state image will show where the new state image is masked.
+ //
+ // to solve this, the following line forces the background to
+ // be erased. sadly, this redraws the entire control. it might
+ // be a good idea to figure out where the state images are and
+ // redraw only those.
+
+ InvalidateRect(hwTree, NULL, TRUE);
+}
+
+int NSISCALL TreeGetSelectedSection(HWND tree, BOOL mouse)
+{
+ HTREEITEM hItem = TreeView_GetSelection(tree);
+ TVITEM item;
+
+ if (mouse)
+ {
+ TVHITTESTINFO ht;
+ DWORD dwpos = GetMessagePos();
+
+ ht.pt.x = GET_X_LPARAM(dwpos);
+ ht.pt.y = GET_Y_LPARAM(dwpos);
+ ScreenToClient(tree, &ht.pt);
+
+ TreeView_HitTest(tree, &ht);
+
+#ifdef NSIS_CONFIG_COMPONENTPAGE_ALTERNATIVE
+ if (!(ht.flags & TVHT_ONITEMSTATEICON))
+#else
+ if (!(ht.flags & (TVHT_ONITEMSTATEICON|TVHT_ONITEMLABEL|TVHT_ONITEMRIGHT|TVHT_ONITEM)))
+#endif
+ return -1;
+
+ hItem = ht.hItem;
+ }
+
+ item.mask = TVIF_PARAM;
+ item.hItem = hItem;
+ TreeView_GetItem(tree, &item);
+
+ return (int) item.lParam;
+}
+
+static LONG oldTreeWndProc;
+static LPARAM last_selected_tree_item;
+static DWORD WINAPI newTreeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg == WM_CHAR && wParam == VK_SPACE) {
+ NotifyCurWnd(WM_TREEVIEW_KEYHACK);
+ return 0;
+ }
+#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
+#ifndef NSIS_CONFIG_COMPONENTPAGE_ALTERNATIVE
+ if (uMsg == WM_MOUSEMOVE) {
+ if (IsWindowVisible(hwnd)) {
+ lParam = TreeGetSelectedSection(hwnd, TRUE);
+ uMsg = WM_NOTIFY_SELCHANGE;
+ }
+ }
+#endif
+ if (uMsg == WM_NOTIFY_SELCHANGE) {
+ if (last_selected_tree_item != lParam)
+ {
+ last_selected_tree_item = lParam;
+
+ mystrcpy(g_tmp, g_usrvars[0]);
+
+ myitoa(g_usrvars[0], lParam);
+
+ ExecuteCallbackFunction(CB_ONMOUSEOVERSECTION);
+
+ mystrcpy(g_usrvars[0], g_tmp);
+ }
+ }
+#endif//NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ return CallWindowProc((WNDPROC)oldTreeWndProc,hwnd,uMsg,wParam,lParam);
+}
+
+static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static HTREEITEM *hTreeItems;
+ static HIMAGELIST hImageList;
+ HWND hwndCombo1 = GetUIItem(IDC_COMBO1);
+ HWND hwndTree1 = GetUIItem(IDC_TREE1);
+ extern HWND g_SectionHack;
+ section *sections=g_sections;
+ int *install_types=g_header->install_types;
+ if (uMsg == WM_INITDIALOG)
+ {
+ int doLines=0;
+ HTREEITEM Par;
+ HBITMAP hBMcheck1;
+ int x, lastGoodX, i, noCombo=2;
+
+ g_SectionHack=hwndDlg;
+
+ hTreeItems=(HTREEITEM*)GlobalAlloc(GPTR,sizeof(HTREEITEM)*num_sections);
+
+ hBMcheck1=LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
+
+ last_selected_tree_item=-1;
+ oldTreeWndProc=SetWindowLong(hwndTree1,GWL_WNDPROC,(long)newTreeWndProc);
+
+ hImageList = ImageList_Create(16,16, ILC_COLOR32|ILC_MASK, 6, 0);
+ ImageList_AddMasked(hImageList,hBMcheck1,RGB(255,0,255));
+
+ TreeView_SetImageList(hwndTree1, hImageList, TVSIL_STATE);
+
+ if (TreeView_GetItemHeight(hwndTree1) < 16)
+ TreeView_SetItemHeight(hwndTree1, 16);
+
+ DeleteObject(hBMcheck1);
+
+ for (i = 0; i < NSIS_MAX_INST_TYPES+1; i++)
+ {
+ if (install_types[i])
+ {
+ int j;
+ if (i != NSIS_MAX_INST_TYPES) noCombo = 0;
+ j=SendMessage(hwndCombo1,CB_ADDSTRING,0,(LPARAM)GetNSISStringTT(install_types[i]));
+ SendMessage(hwndCombo1,CB_SETITEMDATA,j,i);
+ }
+ }
+
+ SetUITextFromLang(IDC_TEXT1,this_page->parms[1+noCombo]);
+ SetUITextFromLang(IDC_TEXT2,this_page->parms[2+noCombo]);
+
+ Par=NULL;
+
+ for (lastGoodX = x = 0; x < num_sections; x ++)
+ {
+ section *sec=sections+x;
+
+ if (sec->name[0])
+ {
+ TVINSERTSTRUCT tv;
+
+ tv.hParent = Par;
+ tv.hInsertAfter = TVI_LAST;
+ tv.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE;
+ tv.item.stateMask = TVIS_EXPANDED;
+ tv.item.lParam = x;
+ tv.item.pszText = sec->name;
+
+ tv.item.state = sec->flags & SF_EXPAND; // TVIS_EXPANDED == SF_EXPAND
+
+ if (sec->flags & SF_SECGRP)
+ {
+ tv.item.mask |= TVIF_CHILDREN;
+ tv.item.cChildren = 1;
+ Par = hTreeItems[x] = TreeView_InsertItem(hwndTree1, &tv);
+ doLines = 1;
+ }
+ else if (sec->flags & SF_SECGRPEND)
+ {
+ Par = TreeView_GetParent(hwndTree1, Par);
+ }
+ else
+ {
+ lastGoodX = x;
+ hTreeItems[x] = TreeView_InsertItem(hwndTree1, &tv);
+ }
+ }
+ }
+
+ if (!doLines)
+ {
+ SetWindowLong(hwndTree1,GWL_STYLE,GetWindowLong(hwndTree1,GWL_STYLE)&~(TVS_LINESATROOT));
+ }
+
+ if (!noCombo)
+ {
+ ShowWindow(hwndCombo1, SW_SHOW);
+ SetActiveCtl(hwndCombo1);
+ }
+ else
+ SetActiveCtl(hwndTree1);
+ }
+
+ if (uMsg == WM_NOTIFY_START)
+ {
+ wParam = 0;
+ lParam = 1;
+ uMsg = WM_IN_UPDATEMSG;
+ }
+
+ if (uMsg == WM_NOTIFY || uMsg == WM_TREEVIEW_KEYHACK)
+ {
+ LPNMHDR lpnmh = (LPNMHDR) lParam;
+ if (uMsg == WM_TREEVIEW_KEYHACK || lpnmh->idFrom == IDC_TREE1)
+ {
+ if (!(g_flags&CH_FLAGS_NO_CUSTOM) && (uMsg == WM_TREEVIEW_KEYHACK || lpnmh->code == NM_CLICK))
+ {
+ int secid = TreeGetSelectedSection(hwndTree1, uMsg != WM_TREEVIEW_KEYHACK);
+
+ if (secid >= 0)
+ {
+ int flags = sections[secid].flags;
+
+ if ((flags & SF_RO) == 0)
+ {
+ if ((flags & SF_PSELECTED))
+ {
+ flags ^= SF_TOGGLED;
+
+ if (flags & SF_TOGGLED)
+ {
+ flags |= SF_SELECTED;
+ }
+ else
+ {
+ flags &= ~SF_SELECTED;
+ }
+ }
+ else
+ {
+ flags ^= SF_SELECTED;
+ }
+
+ sections[secid].flags = flags;
+
+ SectionFlagsChanged(secid);
+
+ wParam = 1;
+ lParam = !(g_flags & CH_FLAGS_COMP_ONLY_ON_CUSTOM);
+ uMsg = WM_IN_UPDATEMSG;
+ }
+ } // was valid click
+ } // was click or hack
+#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
+ if (lpnmh)
+ {
+ if (lpnmh->code == TVN_SELCHANGED)
+ {
+ SendMessage(hwndTree1, WM_NOTIFY_SELCHANGE, 0, ((LPNMTREEVIEW)lpnmh)->itemNew.lParam);
+ }
+ if (lpnmh->code == TVN_ITEMEXPANDED)
+ {
+ LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lpnmh;
+ if (pnmtv->action == TVE_EXPAND)
+ sections[pnmtv->itemNew.lParam].flags |= SF_EXPAND;
+ else
+ sections[pnmtv->itemNew.lParam].flags &= ~SF_EXPAND;
+ }
+ }
+#endif//NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ }
+ }
+
+ if (uMsg == WM_COMMAND && LOWORD(wParam) == IDC_COMBO1 && HIWORD(wParam) == CBN_SELCHANGE)
+ {
+ int t = SendMessage(hwndCombo1,CB_GETCURSEL,0,0);
+ if (t != CB_ERR)
+ {
+ int whichcfg = SendMessage(hwndCombo1, CB_GETITEMDATA, t, 0);
+
+ if (whichcfg == CB_ERR || !install_types[whichcfg])
+ whichcfg = NSIS_MAX_INST_TYPES;
+
+ SetInstType(whichcfg);
+
+ SendMessage(hwndDlg, WM_NOTIFY_INSTTYPE_CHANGED, 0, whichcfg);
+
+ wParam = 1;
+ lParam = 0;
+ uMsg = WM_IN_UPDATEMSG;
+ }
+ }
+
+ if (uMsg == WM_MOUSEMOVE)
+ {
+ SendMessage(hwndTree1, WM_MOUSEMOVE, 0, 0);
+ }
+
+ if (uMsg == WM_NOTIFY_INIGO_MONTOYA)
+ {
+ if (hImageList) ImageList_Destroy(hImageList);
+ if (hTreeItems) GlobalFree(hTreeItems);
+ hImageList = NULL;
+ hTreeItems = NULL;
+ g_SectionHack = NULL;
+ }
+
+ if (uMsg == WM_IN_UPDATEMSG)
+ {
+ RefreshSectionGroups();
+
+#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_COMPONENTPAGE)
+ if (wParam)
+ {
+ ExecuteCallbackFunction(CB_ONSELCHANGE);
+ }
+#endif//NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_COMPONENTPAGE
+
+ if (lParam)
+ {
+ int i, cbi;
+ int inst_type = GetInstType(hTreeItems);
+ SetInstType(inst_type);
+
+ for (i = 0, cbi = 0; i < inst_type; i++)
+ {
+ if (install_types[i])
+ {
+ cbi++;
+ }
+ }
+
+ SendMessage(hwndCombo1, CB_SETCURSEL, cbi, 0);
+
+ lParam = inst_type;
+ uMsg = WM_NOTIFY_INSTTYPE_CHANGED;
+ }
+
+ RefreshSectionGroups();
+ RefreshComponents(hwndTree1, hTreeItems);
+
+ if (LANG_STR_TAB(LANG_SPACE_REQ)) {
+ SetSizeText(IDC_SPACEREQUIRED,LANG_SPACE_REQ,sumsecsfield(size_kb));
+ }
+ }
+
+ if (uMsg == WM_NOTIFY_INSTTYPE_CHANGED)
+ {
+ if (g_flags & CH_FLAGS_COMP_ONLY_ON_CUSTOM)
+ {
+ int c = (lParam == NSIS_MAX_INST_TYPES ? 1 : 0) << 3;// SW_SHOWNA=8, SW_HIDE=0
+ ShowWindow(hwndTree1, c);
+ ShowWindow(GetUIItem(IDC_TEXT2), c);
+ }
+ }
+
+ return HandleStaticBkColor();
+}
+#endif//NSIS_CONFIG_COMPONENTPAGE
+
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+
+void NSISCALL update_status_text(int strtab, const char *text) {
+ static char tmp[NSIS_MAX_STRLEN*2];
+ LVITEM new_item;
+ HWND linsthwnd = insthwnd;
+ if (linsthwnd)
+ {
+ int updateflag = g_exec_flags.status_update;
+ int tmplen;
+
+ if (!(updateflag & 1))
+ GetNSISString(tmp, strtab);
+
+ tmplen = mystrlen(tmp);
+
+ if (text)
+ {
+ if (tmplen + mystrlen(text) >= sizeof(tmp)) return;
+ mystrcat(tmp, text);
+ }
+
+ if ((updateflag & 4) == 0) my_SetWindowText(insthwnd2, tmp);
+ if ((updateflag & 2) == 0)
+ {
+ new_item.mask = LVIF_TEXT;
+ new_item.pszText = tmp;
+ new_item.iItem = ListView_GetItemCount(linsthwnd) - (updateflag & 1);
+ new_item.iSubItem = 0;
+ // LVM_INSERTITEM - LVM_SETITEM = 1
+ SendMessage(linsthwnd, LVM_INSERTITEM - (updateflag & 1), 0, (LPARAM) &new_item);
+ ListView_EnsureVisible(linsthwnd, new_item.iItem, 0);
+ }
+
+ if (updateflag & 1)
+ tmp[tmplen] = 0;
+ }
+}
+
+static DWORD WINAPI install_thread(LPVOID p)
+{
+ int m_inst_sec=num_sections;
+ HWND progresswnd = (HWND)p;
+ section *s = g_sections;
+
+#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
+ {
+ extern HRESULT g_hres;
+ g_hres|=OleInitialize(NULL);
+ }
+#endif
+
+ // workaround for bug #1400995
+ //
+ // for an unexplained reason, MessageBox with MB_TOPMOST
+ // will fail, if no other messages were sent from this
+ // thread to the GUI thread before it.
+ //
+ // the source of the problem couldn't be found, so a
+ // WM_NULL is sent to work around it.
+
+ NotifyCurWnd(WM_NULL);
+
+ while (m_inst_sec--)
+ {
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ if (s->flags&SF_SELECTED)
+#endif
+ {
+ log_printf2("Section: \"%s\"",s->name);
+ if (ExecuteCodeSegment(s->code,progresswnd))
+ {
+ g_exec_flags.abort++;
+ break;
+ }
+ }
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ else
+ {
+ log_printf2("Skipping section: \"%s\"",s->name);
+ }
+#endif
+ s++;
+ }
+ NotifyCurWnd(WM_NOTIFY_INSTPROC_DONE);
+
+#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
+ OleUninitialize();
+#endif
+
+ return g_exec_flags.abort;
+}
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+
+static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ HWND linsthwnd=insthwnd;
+ if (uMsg == WM_INITDIALOG)
+ {
+ RECT r;
+ LVCOLUMN lvc = {LVCF_WIDTH, 0, -1, 0, 0, -1};
+ int lb_bg=g_header->lb_bg,lb_fg=g_header->lb_fg;
+
+ insthwndbutton=GetUIItem(IDC_SHOWDETAILS);
+ insthwnd2=GetUIItem(IDC_INTROTEXT);
+ linsthwnd=insthwnd=GetUIItem(IDC_LIST1);
+
+ SetActiveCtl(insthwndbutton);
+
+ progress_bar_len=sumsecsfield(code_size);
+ progress_bar_pos=0;
+
+ log_printf3("New install of \"%s\" to \"%s\"",GetNSISStringTT(LANG_NAME),state_install_directory);
+
+ GetClientRect(linsthwnd, &r);
+ lvc.cx = r.right - GetSystemMetrics(SM_CXHSCROLL);
+ ListView_InsertColumn(linsthwnd, 0, &lvc);
+
+ ListView_SetExtendedListViewStyleEx(linsthwnd, LVS_EX_LABELTIP, LVS_EX_LABELTIP);
+ if (lb_bg >= 0) {
+ ListView_SetBkColor(linsthwnd, lb_bg);
+ ListView_SetTextBkColor(linsthwnd, lb_bg);
+ }
+ if (lb_fg >= 0) {
+ ListView_SetTextColor(linsthwnd, lb_fg);
+ }
+ SetUITextFromLang(IDC_SHOWDETAILS,this_page->parms[1]);
+ if (g_flags&(CH_FLAGS_DETAILS_SHOWDETAILS|CH_FLAGS_DETAILS_NEVERSHOW))
+ {
+ ShowWindow(insthwndbutton,SW_HIDE);
+ if (!(g_flags&CH_FLAGS_DETAILS_NEVERSHOW)) ShowWindow(linsthwnd,SW_SHOWNA);
+ else insthwndbutton=NULL;
+ SetActiveCtl(insthwnd2);
+ }
+
+ {
+ HWND progresswnd=GetUIItem(IDC_PROGRESS);
+ SendMessage(progresswnd,PBM_SETRANGE,0,MAKELPARAM(0,30000));
+ if (g_flags&CH_FLAGS_PROGRESS_COLORED)
+ {
+ SendMessage(progresswnd,PBM_SETBARCOLOR,0,lb_fg);
+ SendMessage(progresswnd,PBM_SETBKCOLOR,0,lb_bg);
+ }
+ }
+
+ return FALSE;
+ }
+ if (uMsg == WM_NOTIFY_START) {
+ DWORD id;
+ CloseHandle(CreateThread(NULL,0,install_thread,GetUIItem(IDC_PROGRESS),0,&id));
+ }
+ if (uMsg == WM_COMMAND && LOWORD(wParam) == IDC_SHOWDETAILS)
+ {
+ ShowWindow(insthwndbutton,SW_HIDE);
+ ShowWindow(linsthwnd,SW_SHOWNA);
+ SetActiveCtl(linsthwnd);
+ }
+ if (uMsg == WM_NOTIFY_INSTPROC_DONE)
+ {
+ if (g_quit_flag)
+ {
+ m_retcode=2;
+ outernotify(NOTIFY_BYE_BYE);
+ }
+ else
+ {
+ ShowWindow(g_hwnd,SW_SHOWNA);
+ if (!g_exec_flags.abort)
+ update_status_text(g_this_page->parms[2],0);
+ outernotify(1);
+ }
+ }
+ //>>>Ximon Eighteen aka Sunjammer 30th August 2002
+ //+++Popup "Copy Details To Clipboard" menu when RMB clicked in DetailView
+ if (uMsg == WM_CONTEXTMENU && wParam == (WPARAM) linsthwnd)
+ {
+ int count = ListView_GetItemCount(linsthwnd);
+ if (count > 0)
+ {
+ HMENU menu = CreatePopupMenu();
+ POINT pt;
+ AppendMenu(menu,MF_STRING,1,GetNSISStringTT(LANG_COPYDETAILS));
+ if (lParam == ((UINT)-1))
+ {
+ RECT r;
+ GetWindowRect(linsthwnd, &r);
+ pt.x = r.left;
+ pt.y = r.top;
+ }
+ else
+ {
+ pt.x = GET_X_LPARAM(lParam);
+ pt.y = GET_Y_LPARAM(lParam);
+ }
+ if (1==TrackPopupMenu(
+ menu,
+ TPM_NONOTIFY|TPM_RETURNCMD,
+ pt.x,
+ pt.y,
+ 0,hwndDlg,0))
+ {
+ int i,total = 1; // 1 for the null char
+ LVITEM item;
+ HGLOBAL memory;
+ LPTSTR ptr;//,endPtr;
+
+ // 1st pass - determine clipboard memory required.
+ item.iSubItem = 0;
+ item.pszText = g_tmp;
+ item.cchTextMax = sizeof(g_tmp) - 1;
+ i = count;
+ while (i--)
+ // Add 2 for the CR/LF combination that must follow every line.
+ total += 2+SendMessage(linsthwnd,LVM_GETITEMTEXT,i,(LPARAM)&item);
+
+ // 2nd pass - store detail view strings on the clipboard
+ // Clipboard MSDN docs say mem must be GMEM_MOVEABLE
+ OpenClipboard(0);
+ EmptyClipboard();
+ memory = GlobalAlloc(GHND,total);
+ ptr = GlobalLock(memory);
+ //endPtr = ptr+total-2; // -2 to allow for CR/LF
+ i = 0;
+ do {
+ item.pszText = ptr;
+ ptr += SendMessage(linsthwnd,LVM_GETITEMTEXT,i,(LPARAM)&item);
+ *(WORD*)ptr = CHAR2_TO_WORD('\r','\n');
+ ptr+=2;
+ } while (++i < count);
+ // memory is auto zeroed when allocated with GHND - *ptr = 0;
+ GlobalUnlock(memory);
+ SetClipboardData(CF_TEXT,memory);
+ CloseClipboard();
+ }
+ }
+ return FALSE;
+ }
+ //<<<
+ return HandleStaticBkColor();
+}
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
diff --git a/Source/exehead/afxres.h b/Source/exehead/afxres.h
index 7a74b25..70bd1e4 100755
--- a/Source/exehead/afxres.h
+++ b/Source/exehead/afxres.h
@@ -1,21 +1,21 @@
-/*
- * afxres.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "../Platform.h"
-
-#ifndef IDC_STATIC
-#define IDC_STATIC -1
-#endif
+/*
+ * afxres.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "../Platform.h"
+
+#ifndef IDC_STATIC
+#define IDC_STATIC -1
+#endif
diff --git a/Source/exehead/bgbg.c b/Source/exehead/bgbg.c
index 9851f2b..42da5e1 100755
--- a/Source/exehead/bgbg.c
+++ b/Source/exehead/bgbg.c
@@ -1,99 +1,99 @@
-/*
- * bgbg.c
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "../Platform.h"
-#include "resource.h"
-#include "config.h"
-#include "fileform.h"
-#include "state.h"
-#include "ui.h"
-#include "util.h"
-
-#ifdef NSIS_SUPPORT_BGBG
-
-#define c1 header->bg_color1
-#define c2 header->bg_color2
-
-LRESULT CALLBACK BG_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- switch (uMsg)
- {
- case WM_WINDOWPOSCHANGING:
- {
- LPWINDOWPOS wp = (LPWINDOWPOS) lParam;
- wp->flags |= SWP_NOACTIVATE;
- wp->hwndInsertAfter = g_hwnd;
- break;
- }
- case WM_PAINT:
- {
- header *header = g_header;
-
- PAINTSTRUCT ps;
- HDC hdc=BeginPaint(hwnd,&ps);
- RECT r;
- LOGBRUSH lh;
- int ry;
-
- lh.lbStyle = BS_SOLID;
-
- GetClientRect(hwnd,&r);
- // this portion by Drew Davidson, drewdavidson@mindspring.com
- ry=r.bottom;
- r.bottom=0;
-
- // JF: made slower, reduced to 4 pixels high, because I like how it looks better/
- while (r.top < ry)
- {
- int rv,gv,bv;
- HBRUSH brush;
- rv = (GetRValue(c2) * r.top + GetRValue(c1) * (ry-r.top)) / ry;
- gv = (GetGValue(c2) * r.top + GetGValue(c1) * (ry-r.top)) / ry;
- bv = (GetBValue(c2) * r.top + GetBValue(c1) * (ry-r.top)) / ry;
- lh.lbColor = RGB(rv,gv,bv);
- brush = CreateBrushIndirect(&lh);
- // note that we don't need to do "SelectObject(hdc, brush)"
- // because FillRect lets us specify the brush as a parameter.
- r.bottom+=4;
- FillRect(hdc, &r, brush);
- DeleteObject(brush);
- r.top+=4;
- }
-
- if (header->bg_textcolor != -1)
- {
- HFONT newFont = CreateFontIndirect((LOGFONT *) header->blocks[NB_BGFONT].offset);
- if (newFont)
- {
- HFONT oldFont;
- r.left=16;
- r.top=8;
- SetBkMode(hdc,TRANSPARENT);
- SetTextColor(hdc,header->bg_textcolor);
- oldFont = SelectObject(hdc,newFont);
- DrawText(hdc,g_caption,-1,&r,DT_TOP|DT_LEFT|DT_SINGLELINE|DT_NOPREFIX);
- SelectObject(hdc,oldFont);
- DeleteObject(newFont);
- }
- }
- EndPaint(hwnd,&ps);
- }
- return 0;
- }
- return DefWindowProc(hwnd,uMsg,wParam,lParam);
-}
-
-#endif //NSIS_SUPPORT_BGBG
+/*
+ * bgbg.c
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "../Platform.h"
+#include "resource.h"
+#include "config.h"
+#include "fileform.h"
+#include "state.h"
+#include "ui.h"
+#include "util.h"
+
+#ifdef NSIS_SUPPORT_BGBG
+
+#define c1 header->bg_color1
+#define c2 header->bg_color2
+
+LRESULT CALLBACK BG_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_WINDOWPOSCHANGING:
+ {
+ LPWINDOWPOS wp = (LPWINDOWPOS) lParam;
+ wp->flags |= SWP_NOACTIVATE;
+ wp->hwndInsertAfter = g_hwnd;
+ break;
+ }
+ case WM_PAINT:
+ {
+ header *header = g_header;
+
+ PAINTSTRUCT ps;
+ HDC hdc=BeginPaint(hwnd,&ps);
+ RECT r;
+ LOGBRUSH lh;
+ int ry;
+
+ lh.lbStyle = BS_SOLID;
+
+ GetClientRect(hwnd,&r);
+ // this portion by Drew Davidson, drewdavidson@mindspring.com
+ ry=r.bottom;
+ r.bottom=0;
+
+ // JF: made slower, reduced to 4 pixels high, because I like how it looks better/
+ while (r.top < ry)
+ {
+ int rv,gv,bv;
+ HBRUSH brush;
+ rv = (GetRValue(c2) * r.top + GetRValue(c1) * (ry-r.top)) / ry;
+ gv = (GetGValue(c2) * r.top + GetGValue(c1) * (ry-r.top)) / ry;
+ bv = (GetBValue(c2) * r.top + GetBValue(c1) * (ry-r.top)) / ry;
+ lh.lbColor = RGB(rv,gv,bv);
+ brush = CreateBrushIndirect(&lh);
+ // note that we don't need to do "SelectObject(hdc, brush)"
+ // because FillRect lets us specify the brush as a parameter.
+ r.bottom+=4;
+ FillRect(hdc, &r, brush);
+ DeleteObject(brush);
+ r.top+=4;
+ }
+
+ if (header->bg_textcolor != -1)
+ {
+ HFONT newFont = CreateFontIndirect((LOGFONT *) header->blocks[NB_BGFONT].offset);
+ if (newFont)
+ {
+ HFONT oldFont;
+ r.left=16;
+ r.top=8;
+ SetBkMode(hdc,TRANSPARENT);
+ SetTextColor(hdc,header->bg_textcolor);
+ oldFont = SelectObject(hdc,newFont);
+ DrawText(hdc,g_caption,-1,&r,DT_TOP|DT_LEFT|DT_SINGLELINE|DT_NOPREFIX);
+ SelectObject(hdc,oldFont);
+ DeleteObject(newFont);
+ }
+ }
+ EndPaint(hwnd,&ps);
+ }
+ return 0;
+ }
+ return DefWindowProc(hwnd,uMsg,wParam,lParam);
+}
+
+#endif //NSIS_SUPPORT_BGBG
diff --git a/Source/exehead/components.c b/Source/exehead/components.c
index 8b494c4..f7643e4 100755
--- a/Source/exehead/components.c
+++ b/Source/exehead/components.c
@@ -1,164 +1,164 @@
-/*
- * components.c
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "../Platform.h"
-#include "config.h"
-#include "ui.h"
-#include "fileform.h"
-
-void NSISCALL SectionFlagsChanged(unsigned int index) {
- section *sections = g_sections;
-
- int flags = sections[index].flags;
-
- if (flags & SF_SECGRP) {
- unsigned int i = index + 1;
- unsigned int level = 0;
-
- for (; i < (unsigned int) num_sections; i++) {
- if (sections[i].flags & SF_SECGRP) {
- level++;
- continue;
- }
-
- if (sections[i].flags & SF_SECGRPEND) {
- if (level-- == 0) {
- break;
- }
-
- continue;
- }
-
- if ((sections[i].flags & SF_RO) == 0) {
- sections[i].flags &= ~SF_SELECTED;
- sections[i].flags |= (flags & SF_SELECTED);
- }
- }
- }
-}
-
-unsigned int NSISCALL _RefreshSectionGroups(unsigned int i, int not_first_call) {
- unsigned int selected = 0;
- unsigned int not_selected = 0;
-
- section *sections = g_sections;
-
- section *sec = &sections[i];
-
- if (sec->flags & SF_SECGRP) {
- if (not_first_call) {
- sec->flags &= ~(SF_SELECTED | SF_PSELECTED);
- i++;
- }
- }
-
- while (i < (unsigned int) num_sections) {
- int flags = sections[i].flags;
- int ni = i + 1;
-
- if (flags & SF_SECGRP) {
- ni = _RefreshSectionGroups(i, 1);
- flags = sections[i].flags;
- }
-
- if (flags & SF_SECGRPEND) {
- if (selected) {
- if (not_selected) {
- sec->flags |= SF_PSELECTED;
- } else {
- sec->flags |= SF_SELECTED;
- sec->flags &= ~SF_TOGGLED;
- }
- }
-
- return ni;
- }
-
- if (flags & SF_PSELECTED) {
- selected++;
- }
-
- if (flags & SF_SELECTED) {
- selected++;
- } else {
- not_selected++;
- }
-
- i = ni;
- }
-
- return 0;
-}
-
-#ifdef NSIS_CONFIG_COMPONENTPAGE
-
-void NSISCALL SetInstType(int inst_type) {
- unsigned int i = 0;
-
- section *sections = g_sections;
-
- if ((unsigned int) inst_type >= NSIS_MAX_INST_TYPES) {
- return;
- }
-
- for (; i < (unsigned int) num_sections; i++) {
- if (sections[i].flags & (SF_SECGRP | SF_SECGRPEND)) {
- continue;
- }
-
- if (sections[i].install_types & (1 << inst_type)) {
- sections[i].flags |= SF_SELECTED;
- } else {
- sections[i].flags &= ~SF_SELECTED;
- }
- }
-}
-
-unsigned int NSISCALL GetInstType(HTREEITEM *items) {
- unsigned int i, j;
-
- section *sections = g_sections;
-
- for (i = 0; i < NSIS_MAX_INST_TYPES; i++) {
- if (!g_header->install_types[i]) {
- continue;
- }
-
- for (j = 0; j < (unsigned int) num_sections; j++) {
- if (sections[j].flags & (SF_SECGRP | SF_SECGRPEND)) {
- continue;
- }
-
- if (items && !items[j]) {
- continue;
- }
-
- if ((sections[j].install_types & (1 << i)) == ((sections[j].flags & SF_SELECTED) << i)) {
- continue;
- } else {
- break;
- }
- }
-
- if (j == (unsigned int) num_sections) {
- break;
- }
- }
-
- return i;
-}
-
-#endif//NSIS_CONFIG_COMPONENTPAGE
+/*
+ * components.c
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "../Platform.h"
+#include "config.h"
+#include "ui.h"
+#include "fileform.h"
+
+void NSISCALL SectionFlagsChanged(unsigned int index) {
+ section *sections = g_sections;
+
+ int flags = sections[index].flags;
+
+ if (flags & SF_SECGRP) {
+ unsigned int i = index + 1;
+ unsigned int level = 0;
+
+ for (; i < (unsigned int) num_sections; i++) {
+ if (sections[i].flags & SF_SECGRP) {
+ level++;
+ continue;
+ }
+
+ if (sections[i].flags & SF_SECGRPEND) {
+ if (level-- == 0) {
+ break;
+ }
+
+ continue;
+ }
+
+ if ((sections[i].flags & SF_RO) == 0) {
+ sections[i].flags &= ~SF_SELECTED;
+ sections[i].flags |= (flags & SF_SELECTED);
+ }
+ }
+ }
+}
+
+unsigned int NSISCALL _RefreshSectionGroups(unsigned int i, int not_first_call) {
+ unsigned int selected = 0;
+ unsigned int not_selected = 0;
+
+ section *sections = g_sections;
+
+ section *sec = &sections[i];
+
+ if (sec->flags & SF_SECGRP) {
+ if (not_first_call) {
+ sec->flags &= ~(SF_SELECTED | SF_PSELECTED);
+ i++;
+ }
+ }
+
+ while (i < (unsigned int) num_sections) {
+ int flags = sections[i].flags;
+ int ni = i + 1;
+
+ if (flags & SF_SECGRP) {
+ ni = _RefreshSectionGroups(i, 1);
+ flags = sections[i].flags;
+ }
+
+ if (flags & SF_SECGRPEND) {
+ if (selected) {
+ if (not_selected) {
+ sec->flags |= SF_PSELECTED;
+ } else {
+ sec->flags |= SF_SELECTED;
+ sec->flags &= ~SF_TOGGLED;
+ }
+ }
+
+ return ni;
+ }
+
+ if (flags & SF_PSELECTED) {
+ selected++;
+ }
+
+ if (flags & SF_SELECTED) {
+ selected++;
+ } else {
+ not_selected++;
+ }
+
+ i = ni;
+ }
+
+ return 0;
+}
+
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+
+void NSISCALL SetInstType(int inst_type) {
+ unsigned int i = 0;
+
+ section *sections = g_sections;
+
+ if ((unsigned int) inst_type >= NSIS_MAX_INST_TYPES) {
+ return;
+ }
+
+ for (; i < (unsigned int) num_sections; i++) {
+ if (sections[i].flags & (SF_SECGRP | SF_SECGRPEND)) {
+ continue;
+ }
+
+ if (sections[i].install_types & (1 << inst_type)) {
+ sections[i].flags |= SF_SELECTED;
+ } else {
+ sections[i].flags &= ~SF_SELECTED;
+ }
+ }
+}
+
+unsigned int NSISCALL GetInstType(HTREEITEM *items) {
+ unsigned int i, j;
+
+ section *sections = g_sections;
+
+ for (i = 0; i < NSIS_MAX_INST_TYPES; i++) {
+ if (!g_header->install_types[i]) {
+ continue;
+ }
+
+ for (j = 0; j < (unsigned int) num_sections; j++) {
+ if (sections[j].flags & (SF_SECGRP | SF_SECGRPEND)) {
+ continue;
+ }
+
+ if (items && !items[j]) {
+ continue;
+ }
+
+ if ((sections[j].install_types & (1 << i)) == ((sections[j].flags & SF_SELECTED) << i)) {
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ if (j == (unsigned int) num_sections) {
+ break;
+ }
+ }
+
+ return i;
+}
+
+#endif//NSIS_CONFIG_COMPONENTPAGE
diff --git a/Source/exehead/components.h b/Source/exehead/components.h
index 35b78c6..6d77bea 100755
--- a/Source/exehead/components.h
+++ b/Source/exehead/components.h
@@ -1,28 +1,28 @@
-/*
- * components.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef ___COMPONENTS_H___
-#define ___COMPONENTS_H___
-
-void NSISCALL SectionFlagsChanged(unsigned int index);
-#define RefreshSectionGroups() _RefreshSectionGroups(0, 0)
-unsigned int NSISCALL _RefreshSectionGroups(unsigned int i, int not_first_call);
-#ifdef NSIS_CONFIG_COMPONENTPAGE
-void NSISCALL SetInstType(int inst_type);
-unsigned int NSISCALL GetInstType(HTREEITEM *items);
-#endif//NSIS_CONFIG_COMPONENTPAGE
-
-#endif//!___COMPONENTS_H___
+/*
+ * components.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef ___COMPONENTS_H___
+#define ___COMPONENTS_H___
+
+void NSISCALL SectionFlagsChanged(unsigned int index);
+#define RefreshSectionGroups() _RefreshSectionGroups(0, 0)
+unsigned int NSISCALL _RefreshSectionGroups(unsigned int i, int not_first_call);
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+void NSISCALL SetInstType(int inst_type);
+unsigned int NSISCALL GetInstType(HTREEITEM *items);
+#endif//NSIS_CONFIG_COMPONENTPAGE
+
+#endif//!___COMPONENTS_H___
diff --git a/Source/exehead/config.h b/Source/exehead/config.h
index 03a2afd..4f50e79 100755
--- a/Source/exehead/config.h
+++ b/Source/exehead/config.h
@@ -1,161 +1,161 @@
-/*
- * config.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef NSIS_CONFIG_H
-#define NSIS_CONFIG_H
-
-#ifndef APSTUDIO_INVOKED // keep msdev's resource editor from mangling the .rc file
-
-#include "sconf.h"
-
-#ifndef NSIS_CONFIG_VISIBLE_SUPPORT
- #ifdef NSIS_CONFIG_LICENSEPAGE
- #undef NSIS_CONFIG_LICENSEPAGE
- #endif
- #ifdef NSIS_CONFIG_COMPONENTPAGE
- #undef NSIS_CONFIG_COMPONENTPAGE
- #endif
- #ifdef NSIS_SUPPORT_BGBG
- #undef NSIS_SUPPORT_BGBG
- #endif
- #ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
- #undef NSIS_CONFIG_ENHANCEDUI_SUPPORT
- #endif
-#endif
-
-#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
- #ifndef NSIS_SUPPORT_HWNDS
- #define NSIS_SUPPORT_HWNDS
- #endif
-#endif
-
-#ifdef NSIS_CONFIG_LOG_ODS
- #ifndef NSIS_CONFIG_LOG
- #error NSIS_CONFIG_LOG_ODS relies on NSIS_CONFIG_LOG, but NSIS_CONFIG_LOG is not defined
- #endif
-#endif
-
-#ifdef NSIS_CONFIG_LOG_STDOUT
- #ifndef NSIS_CONFIG_LOG
- #error NSIS_CONFIG_LOG_STDOUT relies on NSIS_CONFIG_LOG, but NSIS_CONFIG_LOG is not defined
- #endif
-#endif
-
-#ifdef NSIS_CONFIG_LOG_TIMESTAMP
- #ifndef NSIS_CONFIG_LOG
- #error NSIS_CONFIG_LOG_TIMESTAMP relies on NSIS_CONFIG_LOG, but NSIS_CONFIG_LOG is not defined
- #endif
-#endif
-
-#if defined(NSIS_CONFIG_CRC_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
- #define _NSIS_CONFIG_VERIFYDIALOG
-#endif
-
-#if defined(NSIS_CONFIG_UNINSTALL_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
- #define _NSIS_CONFIG_UNINSTDLG
-#endif
-
-#if defined(NSIS_CONFIG_UNINSTALL_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
- #define _NSIS_CONFIG_UNINSTDLG
-#endif
-
-#ifdef EXEHEAD
- #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- #ifndef NSIS_COMPRESS_USE_ZLIB
- #ifndef NSIS_COMPRESS_USE_BZIP2
- #ifndef NSIS_COMPRESS_USE_LZMA
- #error compression is enabled but zlib, bzip2 and lzma are disabled.
- #endif
- #endif
- #endif
- #endif
-
- #ifdef NSIS_COMPRESS_USE_ZLIB
- #ifdef NSIS_COMPRESS_USE_BZIP2
- #error both zlib and bzip2 are enabled.
- #endif
- #ifdef NSIS_COMPRESS_USE_LZMA
- #error both zlib and lzma are enabled.
- #endif
- #endif
- #ifdef NSIS_COMPRESS_USE_BZIP2
- #ifdef NSIS_COMPRESS_USE_LZMA
- #error both bzip2 and lzma are enabled.
- #endif
- #endif
-
- #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- #ifdef NSIS_COMPRESS_WHOLE
- #ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- #ifndef _NSIS_CONFIG_VERIFYDIALOG
- #define _NSIS_CONFIG_VERIFYDIALOG
- #endif
- #endif
- #endif
- #endif
-#endif // EXEHEAD
-
-#ifdef NSIS_COMPRESS_WHOLE
- #ifndef NSIS_CONFIG_COMPRESSION_SUPPORT
- #error NSIS_COMPRESS_WHOLE defined, NSIS_CONFIG_COMPRESSION_SUPPORT not
- #endif
-#endif
-
-#ifdef NSIS_CONFIG_CRC_ANAL
- #ifndef NSIS_CONFIG_CRC_SUPPORT
- #error NSIS_CONFIG_CRC_ANAL defined but NSIS_CONFIG_CRC_SUPPORT not
- #endif
-#endif
-
-#ifndef NSIS_COMPRESS_BZIP2_LEVEL
- #define NSIS_COMPRESS_BZIP2_LEVEL 9
-#endif
-
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
- #ifndef NSIS_SUPPORT_RMDIR
- #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_RMDIR, but NSIS_SUPPORT_RMDIR is not defined
- #endif
- #ifndef NSIS_SUPPORT_FILE
- #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_FILE, but NSIS_SUPPORT_FILE is not defined
- #endif
- #ifndef NSIS_SUPPORT_ACTIVEXREG
- #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_ACTIVEXREG, but NSIS_SUPPORT_ACTIVEXREG is not defined
- #endif
- #ifndef NSIS_SUPPORT_STACK
- #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_STACK, but NSIS_SUPPORT_STACK is not defined
- #endif
- #ifndef NSIS_SUPPORT_FNUTIL
- #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_FNUTIL, but NSIS_SUPPORT_FNUTIL is not defined
- #endif
- #ifndef NSIS_SUPPORT_DELETE
- #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_DELETE, but NSIS_SUPPORT_DELETE is not defined
- #endif
- #ifndef NSIS_SUPPORT_MESSAGEBOX
- #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_MESSAGEBOX, but NSIS_SUPPORT_MESSAGEBOX is not defined
- #endif
-#endif
-
-#if NSIS_MAX_INST_TYPES > 32
- #error NSIS_MAX_INST_TYPES > 32
-#endif
-
-#ifndef NSIS_DEFAULT_LANG
- #define NSIS_DEFAULT_LANG 1033
-#endif
-
-#endif//!APSTUDIO_INVOKED
-
-#endif // NSIS_CONFIG_H
+/*
+ * config.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef NSIS_CONFIG_H
+#define NSIS_CONFIG_H
+
+#ifndef APSTUDIO_INVOKED // keep msdev's resource editor from mangling the .rc file
+
+#include "sconf.h"
+
+#ifndef NSIS_CONFIG_VISIBLE_SUPPORT
+ #ifdef NSIS_CONFIG_LICENSEPAGE
+ #undef NSIS_CONFIG_LICENSEPAGE
+ #endif
+ #ifdef NSIS_CONFIG_COMPONENTPAGE
+ #undef NSIS_CONFIG_COMPONENTPAGE
+ #endif
+ #ifdef NSIS_SUPPORT_BGBG
+ #undef NSIS_SUPPORT_BGBG
+ #endif
+ #ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ #undef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ #endif
+#endif
+
+#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ #ifndef NSIS_SUPPORT_HWNDS
+ #define NSIS_SUPPORT_HWNDS
+ #endif
+#endif
+
+#ifdef NSIS_CONFIG_LOG_ODS
+ #ifndef NSIS_CONFIG_LOG
+ #error NSIS_CONFIG_LOG_ODS relies on NSIS_CONFIG_LOG, but NSIS_CONFIG_LOG is not defined
+ #endif
+#endif
+
+#ifdef NSIS_CONFIG_LOG_STDOUT
+ #ifndef NSIS_CONFIG_LOG
+ #error NSIS_CONFIG_LOG_STDOUT relies on NSIS_CONFIG_LOG, but NSIS_CONFIG_LOG is not defined
+ #endif
+#endif
+
+#ifdef NSIS_CONFIG_LOG_TIMESTAMP
+ #ifndef NSIS_CONFIG_LOG
+ #error NSIS_CONFIG_LOG_TIMESTAMP relies on NSIS_CONFIG_LOG, but NSIS_CONFIG_LOG is not defined
+ #endif
+#endif
+
+#if defined(NSIS_CONFIG_CRC_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
+ #define _NSIS_CONFIG_VERIFYDIALOG
+#endif
+
+#if defined(NSIS_CONFIG_UNINSTALL_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
+ #define _NSIS_CONFIG_UNINSTDLG
+#endif
+
+#if defined(NSIS_CONFIG_UNINSTALL_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
+ #define _NSIS_CONFIG_UNINSTDLG
+#endif
+
+#ifdef EXEHEAD
+ #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ #ifndef NSIS_COMPRESS_USE_ZLIB
+ #ifndef NSIS_COMPRESS_USE_BZIP2
+ #ifndef NSIS_COMPRESS_USE_LZMA
+ #error compression is enabled but zlib, bzip2 and lzma are disabled.
+ #endif
+ #endif
+ #endif
+ #endif
+
+ #ifdef NSIS_COMPRESS_USE_ZLIB
+ #ifdef NSIS_COMPRESS_USE_BZIP2
+ #error both zlib and bzip2 are enabled.
+ #endif
+ #ifdef NSIS_COMPRESS_USE_LZMA
+ #error both zlib and lzma are enabled.
+ #endif
+ #endif
+ #ifdef NSIS_COMPRESS_USE_BZIP2
+ #ifdef NSIS_COMPRESS_USE_LZMA
+ #error both bzip2 and lzma are enabled.
+ #endif
+ #endif
+
+ #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ #ifdef NSIS_COMPRESS_WHOLE
+ #ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ #ifndef _NSIS_CONFIG_VERIFYDIALOG
+ #define _NSIS_CONFIG_VERIFYDIALOG
+ #endif
+ #endif
+ #endif
+ #endif
+#endif // EXEHEAD
+
+#ifdef NSIS_COMPRESS_WHOLE
+ #ifndef NSIS_CONFIG_COMPRESSION_SUPPORT
+ #error NSIS_COMPRESS_WHOLE defined, NSIS_CONFIG_COMPRESSION_SUPPORT not
+ #endif
+#endif
+
+#ifdef NSIS_CONFIG_CRC_ANAL
+ #ifndef NSIS_CONFIG_CRC_SUPPORT
+ #error NSIS_CONFIG_CRC_ANAL defined but NSIS_CONFIG_CRC_SUPPORT not
+ #endif
+#endif
+
+#ifndef NSIS_COMPRESS_BZIP2_LEVEL
+ #define NSIS_COMPRESS_BZIP2_LEVEL 9
+#endif
+
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+ #ifndef NSIS_SUPPORT_RMDIR
+ #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_RMDIR, but NSIS_SUPPORT_RMDIR is not defined
+ #endif
+ #ifndef NSIS_SUPPORT_FILE
+ #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_FILE, but NSIS_SUPPORT_FILE is not defined
+ #endif
+ #ifndef NSIS_SUPPORT_ACTIVEXREG
+ #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_ACTIVEXREG, but NSIS_SUPPORT_ACTIVEXREG is not defined
+ #endif
+ #ifndef NSIS_SUPPORT_STACK
+ #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_STACK, but NSIS_SUPPORT_STACK is not defined
+ #endif
+ #ifndef NSIS_SUPPORT_FNUTIL
+ #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_FNUTIL, but NSIS_SUPPORT_FNUTIL is not defined
+ #endif
+ #ifndef NSIS_SUPPORT_DELETE
+ #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_DELETE, but NSIS_SUPPORT_DELETE is not defined
+ #endif
+ #ifndef NSIS_SUPPORT_MESSAGEBOX
+ #error NSIS_CONFIG_PLUGIN_SUPPORT relies on NSIS_SUPPORT_MESSAGEBOX, but NSIS_SUPPORT_MESSAGEBOX is not defined
+ #endif
+#endif
+
+#if NSIS_MAX_INST_TYPES > 32
+ #error NSIS_MAX_INST_TYPES > 32
+#endif
+
+#ifndef NSIS_DEFAULT_LANG
+ #define NSIS_DEFAULT_LANG 1033
+#endif
+
+#endif//!APSTUDIO_INVOKED
+
+#endif // NSIS_CONFIG_H
diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c
index 3b22e29..1566ffc 100755
--- a/Source/exehead/exec.c
+++ b/Source/exehead/exec.c
@@ -1,1626 +1,1626 @@
-/*
- * exec.c
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "../Platform.h"
-#include <shlobj.h>
-#include <shellapi.h>
-#include "fileform.h"
-#include "util.h"
-#include "state.h"
-#include "ui.h"
-#include "components.h"
-#include "exec.h"
-#include "lang.h"
-#include "resource.h"
-
-#define EXEC_ERROR 0x7FFFFFFF
-
-#ifdef NSIS_CONFIG_COMPONENTPAGE
-HWND g_SectionHack;
-#endif
-
-#ifdef NSIS_SUPPORT_STACK
-typedef struct _stack_t {
- struct _stack_t *next;
- char text[NSIS_MAX_STRLEN];
-} stack_t;
-
-static stack_t *g_st;
-#endif
-
-exec_flags g_exec_flags;
-exec_flags g_exec_flags_last_used;
-
-struct {
- exec_flags *flags;
- void *ExecuteCodeSegment;
- void *validate_filename;
-} plugin_extra_parameters = {
- &g_exec_flags,
- &ExecuteCodeSegment,
- &validate_filename
-};
-
-#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
-HRESULT g_hres;
-#endif
-
-static int NSISCALL ExecuteEntry(entry *entry_);
-
-int NSISCALL resolveaddr(int v)
-{
- if (v < 0)
- {
- return myatoi(g_usrvars[-(v+1)]);
- }
- return v;
-}
-
-int NSISCALL ExecuteCodeSegment(int pos, HWND hwndProgress)
-{
- while (pos >= 0)
- {
- int rv;
- if (g_entries[pos].which == EW_RET) return 0;
- rv=ExecuteEntry(g_entries + pos);
- if (rv == EXEC_ERROR) return EXEC_ERROR;
-
- rv=resolveaddr(rv);
-
- if (!rv) { rv++; pos++; }
- else
- {
- int t=pos;
- rv--; // rv is decremented here by 1, since it was +1 on the other end.
- pos=rv; // set new position
- rv-=t; // set rv to delta for progress adjustment
- }
-
- if (hwndProgress)
- {
- extern int progress_bar_pos, progress_bar_len;
- progress_bar_pos+=rv;
- SendMessage(hwndProgress,PBM_SETPOS,MulDiv(progress_bar_pos,30000,progress_bar_len),0);
- }
- }
- return 0;
-}
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
-
-int NSISCALL ExecuteCallbackFunction(int num)
-{
- return ExecuteCodeSegment(*(&g_header->code_onInit + num), NULL);
-}
-
-#endif
-
-static char bufs[5][NSIS_MAX_STRLEN];
-static int *parms;
-
-void NSISCALL update_status_text_buf1(int strtab)
-{
- update_status_text(strtab, bufs[1]);
-}
-
-static int NSISCALL GetIntFromParm(int id_)
-{
- return myatoi(GetNSISStringTT(parms[id_]));
-}
-
-// NB - USE CAUTION when rearranging code to make use of the new return value of
-// this function - be sure the parm being accessed is not modified before the call.
-// Use a negative number to get the string validated as a file name
-static char * NSISCALL GetStringFromParm(int id_)
-{
- int id = id_ < 0 ? -id_ : id_;
- char *result = GetNSISString(bufs[id >> 4], parms[id & 0xF]);
- if (id_ < 0) validate_filename(result);
- return result;
-}
-
-#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
-
-#define AlterRegistrySAM(sam) (sam | g_exec_flags.alter_reg_view)
-
-// based loosely on code from Tim Kosse
-// in win9x this isn't necessary (RegDeleteKey() can delete a tree of keys),
-// but in win2k you need to do this manually.
-static LONG NSISCALL myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey, int onlyifempty)
-{
- HKEY key;
- int retval=RegOpenKeyEx(thiskey,lpSubKey,0,AlterRegistrySAM(KEY_ENUMERATE_SUB_KEYS),&key);
- if (retval==ERROR_SUCCESS)
- {
- // NB - don't change this to static (recursive function)
- char buffer[MAX_PATH+1];
- while (RegEnumKey(key,0,buffer,MAX_PATH+1)==ERROR_SUCCESS)
- {
- if (onlyifempty)
- {
- RegCloseKey(key);
- return !ERROR_SUCCESS;
- }
- if ((retval=myRegDeleteKeyEx(key,buffer,0)) != ERROR_SUCCESS) break;
- }
- RegCloseKey(key);
- {
- typedef LONG (WINAPI * RegDeleteKeyExAPtr)(HKEY, LPCTSTR, REGSAM, DWORD);
- RegDeleteKeyExAPtr RDKE = (RegDeleteKeyExAPtr)
- myGetProcAddress(MGA_RegDeleteKeyExA);
-
- if (RDKE)
- retval=RDKE(thiskey,lpSubKey,AlterRegistrySAM(0),0);
- else
- retval=g_exec_flags.alter_reg_view||RegDeleteKey(thiskey,lpSubKey);
- }
- }
- return retval;
-}
-
-static HKEY NSISCALL GetRegRootKey(int hRootKey)
-{
- if (hRootKey)
- return (HKEY) hRootKey;
-
- // HKEY_LOCAL_MACHINE - HKEY_CURRENT_USER == 1
- return (HKEY) ((int) HKEY_CURRENT_USER + g_exec_flags.all_user_var);
-}
-
-static HKEY NSISCALL myRegOpenKey(REGSAM samDesired)
-{
- HKEY hKey;
- if (RegOpenKeyEx(GetRegRootKey(parms[1]), GetStringFromParm(0x22), 0, AlterRegistrySAM(samDesired), &hKey) == ERROR_SUCCESS)
- {
- return hKey;
- }
- return NULL;
-}
-#endif//NSIS_SUPPORT_REGISTRYFUNCTIONS
-
-// returns EXEC_ERROR on error
-// returns 0, advance position by 1
-// otherwise, returns new_position+1
-static int NSISCALL ExecuteEntry(entry *entry_)
-{
- char *buf0 = bufs[0];
- char *buf1 = bufs[1];
- char *buf2 = bufs[2];
- char *buf3 = bufs[3];
- //char *buf4 = bufs[4];
-
- char *var0;
- char *var1;
- //char *var2;
- //char *var3;
- //char *var4;
- //char *var5;
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- // Saves 8 bytes
- HWND mainHwnd = g_hwnd;
-#define g_hwnd mainHwnd
-#endif
-
- int exec_error = 0;
-
- entry lent = *entry_;
-
-#define which (lent.which)
-#define parm0 (lent.offsets[0])
-#define parm1 (lent.offsets[1])
-#define parm2 (lent.offsets[2])
-#define parm3 (lent.offsets[3])
-#define parm4 (lent.offsets[4])
-#define parm5 (lent.offsets[5])
-
- var0 = g_usrvars[parm0];
- var1 = g_usrvars[parm1];
- // not used yet
- //var2 = g_usrvars[parm2];
- //var3 = g_usrvars[parm3];
- //var4 = g_usrvars[parm4];
- //var5 = g_usrvars[parm5];
-
- parms = lent.offsets;
-
- switch (which)
- {
- case EW_NOP:
- log_printf2("Jump: %d",parm0);
- return parm0;
- case EW_ABORT:
- {
- log_printf2("Aborting: \"%s\"",GetStringFromParm(0x00));
- update_status_text(parm0,0);
- }
- return EXEC_ERROR;
- case EW_QUIT:
- g_quit_flag++;
- if (g_hwnd) PostQuitMessage(0); // make sure we bail out fast.
- return EXEC_ERROR;
- case EW_CALL:
- {
- int v=resolveaddr(parm0)-1; // address is -1, since we encode it as +1
- log_printf2("Call: %d",v);
- return ExecuteCodeSegment(v,NULL);
- }
- case EW_UPDATETEXT:
- log_printf2("detailprint: %s",GetStringFromParm(0x00));
- update_status_text(parm0,0);
- break;
- case EW_SLEEP:
- {
- int x=GetIntFromParm(0);
- log_printf2("Sleep(%d)",x);
- Sleep(max(x,1));
- }
- break;
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- case EW_BRINGTOFRONT:
- log_printf("BringToFront");
- SetForegroundWindow(g_hwnd);
- break;
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
- case EW_SETFLAG:
- if (!parm2)
- {
- FIELDN(g_exec_flags_last_used,parm0)=FIELDN(g_exec_flags,parm0);
- FIELDN(g_exec_flags,parm0)=GetIntFromParm(1);
- }
- else
- {
- FIELDN(g_exec_flags,parm0)=FIELDN(g_exec_flags_last_used,parm0);
- }
- break;
- case EW_IFFLAG:
- {
- int f=lent.offsets[!FIELDN(g_exec_flags,parm2)];
- FIELDN(g_exec_flags,parm2)&=parm3;
- return f;
- }
- case EW_GETFLAG:
- myitoa(var0,FIELDN(g_exec_flags,parm1));
- break;
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- case EW_CHDETAILSVIEW:
- if (insthwndbutton) ShowWindow(insthwndbutton,parm1);
- if (insthwnd) ShowWindow(insthwnd,parm0);
- break;
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
- case EW_SETFILEATTRIBUTES:
- {
- char *buf1=GetStringFromParm(-0x10);
- log_printf3("SetFileAttributes: \"%s\":%08X",buf1,parm1);
- if (!SetFileAttributes(buf1,parm1))
- {
- exec_error++;
- log_printf("SetFileAttributes failed.");
- }
- }
- break;
- case EW_CREATEDIR: {
- char *buf1=GetStringFromParm(-0x10);
- log_printf3("CreateDirectory: \"%s\" (%d)",buf1,parm1);
- {
- char *p = skip_root(buf1);
- char c = 'c';
- if (p)
- {
- while (c)
- {
- p = findchar(p, '\\');
- c = *p;
- *p = 0;
- if (!CreateDirectory(buf1, NULL))
- {
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- {
- log_printf3("CreateDirectory: can't create \"%s\" (err=%d)",buf1,GetLastError());
- exec_error++;
- }
- else if ((GetFileAttributes(buf1) & FILE_ATTRIBUTE_DIRECTORY) == 0)
- {
- log_printf2("CreateDirectory: can't create \"%s\" - a file already exists",buf1);
- exec_error++;
- }
- }
- *p++ = c;
- }
- }
- }
- if (parm1)
- {
- update_status_text_buf1(LANG_OUTPUTDIR);
- mystrcpy(state_output_directory,buf1);
- SetCurrentDirectory(buf1);
- }
- else update_status_text_buf1(LANG_CREATEDIR);
- }
- break;
- case EW_IFFILEEXISTS:
- {
- char *buf0=GetStringFromParm(0x00);
- if (file_exists(buf0))
- {
- log_printf3("IfFileExists: file \"%s\" exists, jumping %d",buf0,parm1);
- return parm1;
- }
- log_printf3("IfFileExists: file \"%s\" does not exist, jumping %d",buf0,parm2);
- }
- return parm2;
-#ifdef NSIS_SUPPORT_RENAME
- case EW_RENAME:
- {
- char *buf3=GetStringFromParm(-0x30);
- char *buf2=GetStringFromParm(-0x21);
- char *buf1=GetStringFromParm(0x13);
- log_printf2("Rename: %s",buf1);
- if (MoveFile(buf3,buf2))
- {
- update_status_text_buf1(LANG_RENAME);
- }
- else
- {
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
- if (parm2 && file_exists(buf3))
- {
- MoveFileOnReboot(buf3,buf2);
- update_status_text_buf1(LANG_RENAMEONREBOOT);
- log_printf2("Rename on reboot: %s",buf1);
- }
- else
-#endif
- {
- exec_error++;
- log_printf2("Rename failed: %s",buf1);
- }
- }
- }
- break;
-#endif//NSIS_SUPPORT_RENAME
-#ifdef NSIS_SUPPORT_FNUTIL
- case EW_GETFULLPATHNAME:
- {
- char *fp;
- char *p=var1;
- char *buf0=GetStringFromParm(0x00);
- if (!GetFullPathName(buf0,NSIS_MAX_STRLEN,p,&fp))
- {
- exec_error++;
- *p=0;
- }
- else if (fp>buf0 && *fp)
- {
- WIN32_FIND_DATA *fd=file_exists(buf0);
- if (fd)
- {
- mystrcpy(fp,fd->cFileName);
- }
- else
- {
- exec_error++;
- *p=0;
- }
- }
- if (!parm2) GetShortPathName(p,p,NSIS_MAX_STRLEN);
- }
- break;
- case EW_SEARCHPATH:
- {
- char *fp;
- char *p=var0;
- char *buf0=GetStringFromParm(-0x01);
- if (!SearchPath(NULL,buf0,NULL,NSIS_MAX_STRLEN,p,&fp))
- {
- exec_error++;
- p[0]=0;
- }
- }
- break;
- case EW_GETTEMPFILENAME:
- {
- char *textout=var0;
- if (!my_GetTempFileName(textout, GetStringFromParm(-0x11)))
- exec_error++;
- }
- break;
-#endif
-#ifdef NSIS_SUPPORT_FILE
- case EW_EXTRACTFILE:
- {
- HANDLE hOut;
- int ret;
- char *buf3 = GetStringFromParm(0x31);
- int overwriteflag = parm0 & 7;
-
- log_printf4("File: overwriteflag=%d, allowskipfilesflag=%d, name=\"%s\"",overwriteflag,(parm0>>3)&MB_ABORTRETRYIGNORE,buf3);
- if (validpathspec(buf3))
- {
- mystrcpy(buf0,buf3);
- }
- else mystrcat(addtrailingslash(mystrcpy(buf0,state_output_directory)),buf3);
- validate_filename(buf0);
- _tryagain:
- if (overwriteflag >= 3) // check date and time
- {
- WIN32_FIND_DATA *ffd=file_exists(buf0);
- // if it doesn't exist, overwrite flag will be off (though it doesn't really matter)
- int cmp=0;
- if (ffd)
- {
- cmp=CompareFileTime(&ffd->ftLastWriteTime, (FILETIME*)(lent.offsets + 3));
- }
- overwriteflag=!(cmp & (0x80000000 | (overwriteflag - 3)));
- }
- // remove read only flag if overwrite mode is on
- if (!overwriteflag)
- {
- remove_ro_attr(buf0);
- }
- hOut=myOpenFile(buf0,GENERIC_WRITE,(overwriteflag==1)?CREATE_NEW:CREATE_ALWAYS);
- if (hOut == INVALID_HANDLE_VALUE)
- {
- if (overwriteflag)
- {
- update_status_text(LANG_SKIPPED,buf3);
- if (overwriteflag==2) exec_error++;
- log_printf3("File: skipped: \"%s\" (overwriteflag=%d)",buf0,overwriteflag);
- break;
- }
- log_printf2("File: error creating \"%s\"",buf0);
-
- mystrcpy(buf2,g_usrvars[0]); // save $0
- mystrcpy(g_usrvars[0],buf0); // copy file name to $0
- GetNSISString(buf1,parm5); // use $0
- mystrcpy(g_usrvars[0],buf2); // restore $0
-
- // Modified by ramon 23 May 2003
- switch (my_MessageBox(buf1, parm0>>3))
- {
- case IDRETRY:
- log_printf("File: error, user retry");
- goto _tryagain;
- case IDIGNORE:
- log_printf("File: error, user cancel");
- g_exec_flags.exec_error++;
- return 0;
- default:
- log_printf("File: error, user abort");
- update_status_text(LANG_CANTWRITE,buf0);
- return EXEC_ERROR;
- }
- }
-
- update_status_text(LANG_EXTRACT,buf3);
- {
- g_exec_flags.status_update++;
- ret=GetCompressedDataFromDataBlock(parm2,hOut);
- g_exec_flags.status_update--;
- }
-
- log_printf3("File: wrote %d to \"%s\"",ret,buf0);
-
- if (parm3 != 0xffffffff || parm4 != 0xffffffff)
- SetFileTime(hOut,(FILETIME*)(lent.offsets+3),NULL,(FILETIME*)(lent.offsets+3));
-
- CloseHandle(hOut);
-
- if (ret < 0)
- {
- if (ret == -2)
- {
- GetNSISString(buf0,LANG_ERRORWRITING);
- mystrcat(buf0,buf3);
- }
- else
- {
- GetNSISString(buf0,LANG_ERRORDECOMPRESSING);
- }
- log_printf2("%s",buf0);
- my_MessageBox(buf0,MB_OK|MB_ICONSTOP|(IDOK<<21));
- return EXEC_ERROR;
- }
- }
- break;
-#endif//NSIS_SUPPORT_FILE
-#ifdef NSIS_SUPPORT_DELETE
- case EW_DELETEFILE:
- {
- char *buf0=GetStringFromParm(0x00);
- log_printf2("Delete: \"%s\"",buf0);
- myDelete(buf0,parm1);
- }
- break;
-#endif//NSIS_SUPPORT_DELETE
-#ifdef NSIS_SUPPORT_MESSAGEBOX
- case EW_MESSAGEBOX: // MessageBox
- {
- int v;
- char *buf3=GetStringFromParm(0x31);
- log_printf3("MessageBox: %d,\"%s\"",parm0,buf3);
- v=my_MessageBox(buf3,parm0);
- if (v)
- {
- if (v==parm2)
- {
- return parm3;
- }
- if (v==parm4)
- {
- return parm5;
- }
- }
- else exec_error++;
- }
- break;
-#endif//NSIS_SUPPORT_MESSAGEBOX
-#ifdef NSIS_SUPPORT_RMDIR
- case EW_RMDIR:
- {
- char *buf1=GetStringFromParm(-0x10);
- log_printf2("RMDir: \"%s\"",buf1);
-
- myDelete(buf1,parm1);
- }
- break;
-#endif//NSIS_SUPPORT_RMDIR
-#ifdef NSIS_SUPPORT_STROPTS
- case EW_STRLEN:
- {
- char *buf0=GetStringFromParm(0x01);
- myitoa(var0,mystrlen(buf0));
- }
- break;
- case EW_ASSIGNVAR:
- {
- int newlen=GetIntFromParm(2);
- int start=GetIntFromParm(3);
- int l;
- char *p=var0;
- char *buf0=GetStringFromParm(0x01);
- *p=0;
- if (!parm2 || newlen)
- {
- l=mystrlen(buf0);
-
- if (start<0) start=l+start;
- if (start>=0)
- {
- if (start>l) start=l;
- mystrcpy(p,buf0+start);
- if (newlen)
- {
- if (newlen<0) newlen=mystrlen(p)+newlen;
- if (newlen<0) newlen=0;
- if (newlen < NSIS_MAX_STRLEN) p[newlen]=0;
- }
- }
- }
- }
- break;
- case EW_STRCMP:
- {
- char *buf2=GetStringFromParm(0x20);
- char *buf3=GetStringFromParm(0x31);
- if (!parm4) {
- // case insensitive
- if (!lstrcmpi(buf2,buf3)) return parm2;
- }
- else {
- // case sensitive
- if (!lstrcmp(buf2,buf3)) return parm2;
- }
- }
- return parm3;
-#endif//NSIS_SUPPORT_STROPTS
-#ifdef NSIS_SUPPORT_ENVIRONMENT
- case EW_READENVSTR:
- {
- char *p=var0;
- char *buf0=GetStringFromParm(0x01);
- if (!ExpandEnvironmentStrings(buf0,p,NSIS_MAX_STRLEN)
- || (parm2 && !lstrcmp(buf0, p)))
- {
- exec_error++;
- *p=0;
- }
- p[NSIS_MAX_STRLEN-1]=0;
- }
- break;
-#endif//NSIS_SUPPORT_ENVIRONMENT
-#ifdef NSIS_SUPPORT_INTOPTS
- case EW_INTCMP:
- {
- int v,v2;
- v=GetIntFromParm(0);
- v2=GetIntFromParm(1);
- if (!parm5) {
- // signed
- if (v<v2) return parm3;
- if (v>v2) return parm4;
- }
- else {
- // unsigned
- if ((unsigned int)v<(unsigned int)v2) return parm3;
- if ((unsigned int)v>(unsigned int)v2) return parm4;
- }
- }
- return parm2;
- case EW_INTOP:
- {
- int v,v2;
- char *p=var0;
- v=GetIntFromParm(1);
- v2=GetIntFromParm(2);
- switch (parm3)
- {
- case 0: v+=v2; break;
- case 1: v-=v2; break;
- case 2: v*=v2; break;
- case 3: if (v2) v/=v2; else { v=0; exec_error++; } break;
- case 4: v|=v2; break;
- case 5: v&=v2; break;
- case 6: v^=v2; break;
- case 7: v=!v; break;
- case 8: v=v||v2; break;
- case 9: v=v&&v2; break;
- case 10: if (v2) v%=v2; else { v=0; exec_error++; } break;
- case 11: v=v<<v2; break;
- case 12: v=v>>v2; break;
- }
- myitoa(p,v);
- }
- break;
- case EW_INTFMT: {
- char *buf0=GetStringFromParm(0x01);
- wsprintf(var0,
- buf0,
- GetIntFromParm(2));
- }
- break;
-#endif//NSIS_SUPPORT_INTOPTS
-#ifdef NSIS_SUPPORT_STACK
- case EW_PUSHPOP:
- {
- stack_t *s=g_st;
- int cnt=parm2;
- if (cnt) //Exch contributed by Fritz Elfert
- {
- while (cnt--&&s) s=s->next;
- if (!s)
- {
- log_printf2("Exch: stack < %d elements",parm2);
- my_MessageBox(GetNSISStringTT(LANG_INSTCORRUPTED),MB_OK|MB_ICONSTOP|(IDOK<<21));
- return EXEC_ERROR;
- }
- mystrcpy(buf0,s->text);
- mystrcpy(s->text,g_st->text);
- mystrcpy(g_st->text,buf0);
- }
- else if (parm1)
- {
- if (!s)
- {
- log_printf("Pop: stack empty");
- exec_error++;
- break;
- }
- mystrcpy(var0,s->text);
- g_st=s->next;
- GlobalFree((HGLOBAL)s);
- }
- else
- {
- s=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t));
- GetNSISString(s->text,parm0);
- s->next=g_st;
- g_st=s;
- }
- }
- break;
-#endif//NSIS_SUPPORT_STACK
-#ifdef NSIS_SUPPORT_HWNDS
- case EW_FINDWINDOW:
- case EW_SENDMESSAGE:
- {
- int v;
- int b3=GetIntFromParm(3);
- int b4=GetIntFromParm(4);
- if (parm5&1) b3=(int)GetStringFromParm(0x33);
- if (parm5&2) b4=(int)GetStringFromParm(0x44);
-
- if (which == EW_SENDMESSAGE)
- {
- HWND hwnd=(HWND)GetIntFromParm(1);
- int msg=GetIntFromParm(2);
-
- if (parm5>>2) exec_error += !SendMessageTimeout(hwnd,msg,b3,b4,SMTO_NORMAL,parm5>>2,(LPDWORD)&v);
- else v=SendMessage(hwnd,msg,b3,b4);
- }
- else
- {
- char *buf0=GetStringFromParm(0x01);
- char *buf1=GetStringFromParm(0x12);
- v=(int)FindWindowEx((HWND)b3,(HWND)b4,buf0[0]?buf0:NULL,buf1[0]?buf1:NULL);
- }
-
- if (parm0>=0)
- myitoa(var0,v);
- }
- break;
- case EW_ISWINDOW:
- if (IsWindow((HWND)GetIntFromParm(0))) return parm1;
- return parm2;
-#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
- case EW_GETDLGITEM:
- myitoa(
- var0,
- (int)GetDlgItem(
- (HWND)GetIntFromParm(1),
- GetIntFromParm(2)
- )
- );
- break;
- case EW_SETCTLCOLORS:
- {
- ctlcolors *c = (ctlcolors *)(g_blocks[NB_CTLCOLORS].offset + parm1);
- SetWindowLong((HWND) GetIntFromParm(0), GWL_USERDATA, (long) c);
- }
- break;
- case EW_SETBRANDINGIMAGE:
- {
- RECT r;
- HANDLE hImage;
- HWND hwImage=GetDlgItem(g_hwnd, parm1);
- GetClientRect(hwImage, &r);
- hImage=LoadImage(
- 0,
- GetStringFromParm(0x00),
- IMAGE_BITMAP,
- parm2*r.right,
- parm2*r.bottom,
- LR_LOADFROMFILE
- );
- hImage = (HANDLE)SendMessage(
- hwImage,
- STM_SETIMAGE,
- IMAGE_BITMAP,
- (LPARAM)hImage
- );
- // delete old image
- if (hImage) DeleteObject(hImage);
- }
- break;
- case EW_CREATEFONT:
- {
- static LOGFONT f;
- f.lfHeight=-MulDiv(GetIntFromParm(2),GetDeviceCaps(GetDC(g_hwnd),LOGPIXELSY),72);
- f.lfWeight=GetIntFromParm(3);
- f.lfItalic=parm4&1;
- f.lfUnderline=parm4&2;
- f.lfStrikeOut=parm4&4;
- f.lfCharSet=DEFAULT_CHARSET;
- GetNSISString(f.lfFaceName,parm1);
- myitoa(var0,(int)CreateFontIndirect(&f));
- }
- break;
- case EW_SHOWWINDOW:
- {
- HWND hw=(HWND)GetIntFromParm(0);
- int a=GetIntFromParm(1);
- if (parm2) log_printf("HideWindow");
- if (!parm3)
- ShowWindow(hw,a);
- else
- EnableWindow(hw,a);
- }
- break;
-#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
-#endif//NSIS_SUPPORT_HWNDS
-#ifdef NSIS_SUPPORT_SHELLEXECUTE
- case EW_SHELLEXEC: // this uses improvements of Andras Varga
- {
- int x;
- char *buf0=GetStringFromParm(0x00);
- char *buf3=GetStringFromParm(0x31);
- char *buf2=GetStringFromParm(0x22);
- char *buf1=GetStringFromParm(0x15);
- update_status_text_buf1(LANG_EXECSHELL);
- x=(int)ShellExecute(g_hwnd,buf0[0]?buf0:NULL,buf3,buf2[0]?buf2:NULL,state_output_directory,parm3);
- if (x < 33)
- {
- log_printf5("ExecShell: warning: error (\"%s\": file:\"%s\" params:\"%s\")=%d",buf0,buf3,buf2,x);
- exec_error++;
- }
- else
- {
- log_printf4("ExecShell: success (\"%s\": file:\"%s\" params:\"%s\")",buf0,buf3,buf2);
- }
- }
- break;
-#endif//NSIS_SUPPORT_SHELLEXECUTE
-#ifdef NSIS_SUPPORT_EXECUTE
- case EW_EXECUTE:
- {
- HANDLE hProc;
- char *buf0=GetStringFromParm(0x00);
- log_printf2("Exec: command=\"%s\"",buf0);
- update_status_text(LANG_EXECUTE,buf0);
-
- hProc=myCreateProcess(buf0);
-
- if (hProc)
- {
- log_printf2("Exec: success (\"%s\")",buf0);
- if (parm2)
- {
- DWORD lExitCode;
- while (WaitForSingleObject(hProc,100) == WAIT_TIMEOUT)
- {
- MessageLoop(WM_PAINT);
- }
- GetExitCodeProcess(hProc, &lExitCode);
-
- if (parm1>=0) myitoa(var1,lExitCode);
- else if (lExitCode) exec_error++;
- }
- CloseHandle( hProc );
- }
- else
- {
- exec_error++;
- log_printf2("Exec: failed createprocess (\"%s\")",buf0);
- }
- }
- break;
-#endif//NSIS_SUPPORT_EXECUTE
-#ifdef NSIS_SUPPORT_GETFILETIME
- case EW_GETFILETIME:
- // this new implementation based on one by Dave Bau
- // used FindFirstFile instead of GetFileTime to better handle files that are locked.
- // also allows GetFileTime to be passed a wildcard.
- {
- WIN32_FIND_DATA *ffd;
- char *highout=var0;
- char *lowout=var1;
- char *buf0=GetStringFromParm(0x02);
-
- ffd=file_exists(buf0);
- if (ffd)
- {
- myitoa(lowout,ffd->ftLastWriteTime.dwLowDateTime);
- myitoa(highout,ffd->ftLastWriteTime.dwHighDateTime);
- }
- else
- {
- *lowout=*highout=0;
- exec_error++;
- }
- }
- break;
-#endif//NSIS_SUPPORT_GETFILETIME
-#ifdef NSIS_SUPPORT_GETDLLVERSION
- case EW_GETDLLVERSION:
- {
- char *highout=var0;
- char *lowout=var1;
- DWORD s1;
- VS_FIXEDFILEINFO *pvsf1;
- DWORD d;
- char *buf1=GetStringFromParm(-0x12);
- s1=GetFileVersionInfoSize(buf1,&d);
- *lowout=*highout=0;
- exec_error++;
- if (s1)
- {
- void *b1;
- b1=GlobalAlloc(GPTR,s1);
- if (b1)
- {
- UINT uLen;
- if (GetFileVersionInfo(buf1,0,s1,b1) && VerQueryValue(b1,"\\",(void*)&pvsf1,&uLen))
- {
- myitoa(highout,pvsf1->dwFileVersionMS);
- myitoa(lowout,pvsf1->dwFileVersionLS);
-
- exec_error--;
- }
- GlobalFree(b1);
- }
- }
- }
- break;
-#endif//NSIS_SUPPORT_GETDLLVERSION
-#ifdef NSIS_SUPPORT_ACTIVEXREG
- case EW_REGISTERDLL:
- {
- exec_error++;
- if (SUCCEEDED(g_hres))
- {
- HANDLE h=NULL;
- char *buf1=GetStringFromParm(-0x10);
- char *buf0=GetStringFromParm(0x01);
-
- if (parm4)
- h=GetModuleHandle(buf1);
- if (!h)
- h=LoadLibraryEx(buf1, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
- if (h)
- {
- FARPROC funke = GetProcAddress(h,buf0);
- if (funke)
- {
- exec_error--;
- if (parm2)
- {
- update_status_text_buf1(parm2);
- if (funke()) exec_error++;
- }
- else
- {
- void (*func)(HWND,int,char*,void*,void*);
- func=(void*)funke;
- func(
- g_hwnd,
- NSIS_MAX_STRLEN,
- (char*)g_usrvars,
-#ifdef NSIS_SUPPORT_STACK
- (void*)&g_st,
-#else
- NULL,
-#endif//NSIS_SUPPORT_STACK
- &plugin_extra_parameters
- );
- }
- }
- else
- {
- update_status_text(LANG_CANNOTFINDSYMBOL,buf0);
- log_printf3("Error registering DLL: %s not found in %s",buf0,buf1);
- }
- if (!parm3) FreeLibrary(h);
- }
- else
- {
- update_status_text_buf1(LANG_COULDNOTLOAD);
- log_printf2("Error registering DLL: Could not load %s",buf1);
- }
- }
- else
- {
- update_status_text_buf1(LANG_NOOLE);
- log_printf("Error registering DLL: Could not initialize OLE");
- }
- }
- break;
-#endif
-#ifdef NSIS_SUPPORT_CREATESHORTCUT
- case EW_CREATESHORTCUT:
- {
- char *buf1=GetStringFromParm(-0x10);
- char *buf2=GetStringFromParm(-0x21);
- char *buf0=GetStringFromParm(0x02);
- char *buf3=GetStringFromParm(-0x33);
- char *buf4=GetStringFromParm(0x45);
-
- HRESULT hres;
- IShellLink* psl;
-
- if (!validpathspec(buf2))
- GetStringFromParm(0x21);
-
- log_printf8("CreateShortCut: out: \"%s\", in: \"%s %s\", icon: %s,%d, sw=%d, hk=%d",
- buf1,buf2,buf0,buf3,parm4&0xff,(parm4&0xff00)>>8,parm4>>16);
-
- hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
- &IID_IShellLink, (void **) &psl);
- if (SUCCEEDED(hres))
- {
- IPersistFile* ppf;
-
- hres = psl->lpVtbl->QueryInterface(psl,&IID_IPersistFile, (void **) &ppf);
- if (SUCCEEDED(hres))
- {
- hres = psl->lpVtbl->SetPath(psl,buf2);
- psl->lpVtbl->SetWorkingDirectory(psl,state_output_directory);
- if ((parm4&0xff00)>>8) psl->lpVtbl->SetShowCmd(psl,(parm4&0xff00)>>8);
- psl->lpVtbl->SetHotkey(psl,(unsigned short)(parm4>>16));
- if (buf3[0]) psl->lpVtbl->SetIconLocation(psl,buf3,parm4&0xff);
- psl->lpVtbl->SetArguments(psl,buf0);
- psl->lpVtbl->SetDescription(psl,buf4);
-
- if (SUCCEEDED(hres))
- {
- static WCHAR wsz[1024];
- hres=E_FAIL;
- if (MultiByteToWideChar(CP_ACP, 0, buf1, -1, wsz, 1024))
- hres=ppf->lpVtbl->Save(ppf,(const WCHAR*)wsz,TRUE);
- }
- ppf->lpVtbl->Release(ppf);
- }
- psl->lpVtbl->Release(psl);
- }
-
- if (FAILED(hres))
- {
- exec_error++;
- update_status_text_buf1(LANG_ERRORCREATINGSHORTCUT);
- }
- else
- {
- update_status_text_buf1(LANG_CREATESHORTCUT);
- }
- }
- break;
-#endif//NSIS_SUPPORT_CREATESHORTCUT
-#ifdef NSIS_SUPPORT_COPYFILES
- case EW_COPYFILES: // CopyFile (added by NOP)
- {
- int res;
- SHFILEOPSTRUCT op;
- char *buf0=GetStringFromParm(0x00);
- char *buf1=GetStringFromParm(0x11);
- char *buf2=GetStringFromParm(0x23); // LANG_COPYTO + buf1
- log_printf3("CopyFiles \"%s\"->\"%s\"",buf0,buf1);
-
- if (!file_exists(buf0))
- {
- // workaround for bug #774966
- //
- // on nt4, SHFileOperation silently fails if the source
- // file doesn't exist. do a manual check instead.
-
- update_status_text(LANG_COPYFAILED,0);
- exec_error++;
- break;
- }
-
- op.hwnd=g_hwnd;
- op.wFunc=FO_COPY;
- buf0[mystrlen(buf0)+1]=0;
- buf1[mystrlen(buf1)+1]=0;
-
- op.pFrom=buf0;
- op.pTo=buf1;
- op.lpszProgressTitle=buf2;
- op.fFlags=parm2;
- update_status_text(0,buf2);
- res=SHFileOperation(&op);
- if (res)
- { // some of these changes were from Edgewise (wiked_edge@yahoo.com)
- update_status_text(LANG_COPYFAILED,0);
- exec_error++;
- }
- }
- break;
-#endif//NSIS_SUPPORT_COPYFILES
-#ifdef NSIS_SUPPORT_REBOOT
- case EW_REBOOT:
- if (parm0!=0xbadf00d)
- {
- my_MessageBox(GetNSISStringTT(LANG_INSTCORRUPTED),MB_OK|MB_ICONSTOP|(IDOK<<21));
- return EXEC_ERROR;
- }
-
- g_exec_flags.reboot_called++;
- // a following EW_QUIT will make sure the installer quits right away
-
- break;
-#endif//NSIS_SUPPORT_REBOOT
-#ifdef NSIS_SUPPORT_INIFILES
- case EW_WRITEINI:
- {
- char *sec=0, *key=0, *str=0;
-#ifdef NSIS_CONFIG_LOG
- mystrcpy(buf1,"<RM>");
- mystrcpy(buf2,buf1);
-#endif
- if (parm0)
- {
- sec=GetStringFromParm(0x00);
- }
- if (parm1)
- {
- key=GetStringFromParm(0x11);
- }
- if (parm4)
- {
- str=GetStringFromParm(0x22);
- }
- buf3=GetStringFromParm(-0x33);
- log_printf5("WriteINIStr: wrote [%s] %s=%s in %s",buf0,buf1,buf2,buf3);
- if (!WritePrivateProfileString(sec,key,str,buf3)) exec_error++;
- }
- break;
- case EW_READINISTR:
- {
- DWORD errstr = CHAR4_TO_DWORD('!', 'N', '~', 0);
- char *p=var0;
- char *buf0=GetStringFromParm(0x01);
- char *buf1=GetStringFromParm(0x12);
- char *buf2=GetStringFromParm(-0x23);
- GetPrivateProfileString(buf0,buf1,(LPCSTR)&errstr,p,NSIS_MAX_STRLEN-1,buf2);
- if (*(DWORD*)p == errstr)
- {
- exec_error++;
- p[0]=0;
- }
- }
- break;
-#endif//NSIS_SUPPORT_INIFILES
-#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
- case EW_DELREG:
- {
- long res=!ERROR_SUCCESS;
- const char *rkn UNUSED=RegKeyHandleToName((HKEY)parm1);
- if (!parm4)
- {
- HKEY hKey=myRegOpenKey(KEY_SET_VALUE);
- if (hKey)
- {
- char *buf3=GetStringFromParm(0x33);
- res = RegDeleteValue(hKey,buf3);
- log_printf4("DeleteRegValue: \"%s\\%s\" \"%s\"",rkn,buf2,buf3);
- RegCloseKey(hKey);
- }
- }
- else
- {
- char *buf2=GetStringFromParm(0x22);
- log_printf3("DeleteRegKey: \"%s\\%s\"",rkn,buf2);
- res = myRegDeleteKeyEx(GetRegRootKey(parm1),buf2,parm4&2);
- }
- if (res != ERROR_SUCCESS)
- exec_error++;
- }
- break;
- case EW_WRITEREG: // write registry value
- {
- HKEY hKey;
- HKEY rootkey=GetRegRootKey(parm0);
- int type=parm4;
- int rtype=parm5;
- char *buf0=GetStringFromParm(0x02);
- char *buf1=GetStringFromParm(0x11);
- const char *rkn UNUSED=RegKeyHandleToName(rootkey);
-
- exec_error++;
- if (RegCreateKeyEx(rootkey,buf1,0,0,0,AlterRegistrySAM(KEY_SET_VALUE),0,&hKey,0) == ERROR_SUCCESS)
- {
- LPBYTE data = (LPBYTE) buf2;
- DWORD size = 0;
- if (type == REG_SZ)
- {
- GetStringFromParm(0x23);
- size = mystrlen((char *) data) + 1;
- if (rtype == REG_SZ)
- {
- log_printf5("WriteRegStr: \"%s\\%s\" \"%s\"=\"%s\"",rkn,buf1,buf0,data);
- }
- else
- {
- log_printf5("WriteRegExpandStr: \"%s\\%s\" \"%s\"=\"%s\"",rkn,buf1,buf0,data);
- }
- }
- if (type == REG_DWORD)
- {
- *(LPDWORD) data = GetIntFromParm(3);
- size = sizeof(DWORD);
- log_printf5("WriteRegDWORD: \"%s\\%s\" \"%s\"=\"0x%08x\"",rkn,buf1,buf0,*(LPDWORD) data);
- }
- if (type == REG_BINARY)
- {
-#ifdef NSIS_CONFIG_LOG
- char binbuf[128];
-#endif
- // use buf2, buf3 and buf4
- size = GetCompressedDataFromDataBlockToMemory(parm3, data, 3 * NSIS_MAX_STRLEN);
- LogData2Hex(binbuf, sizeof(binbuf), data, size);
- log_printf5("WriteRegBin: \"%s\\%s\" \"%s\"=\"%s\"",rkn,buf1,buf0,binbuf);
- }
-
- if (size >= 0 && RegSetValueEx(hKey,buf0,0,rtype,data,size) == ERROR_SUCCESS)
- {
- exec_error--;
- }
- else
- {
- log_printf4("WriteReg: error writing into \"%s\\%s\" \"%s\"",rkn,buf1,buf0);
- }
-
- RegCloseKey(hKey);
- }
- else { log_printf3("WriteReg: error creating key \"%s\\%s\"",rkn,buf1); }
- }
- break;
- case EW_READREGSTR: // read registry string
- {
- HKEY hKey=myRegOpenKey(KEY_READ);
- char *p=var0;
- char *buf3=GetStringFromParm(0x33); // buf3 == key name
- p[0]=0;
- if (hKey)
- {
- DWORD l = NSIS_MAX_STRLEN - 1;
- DWORD t;
-
- if (RegQueryValueEx(hKey,buf3,NULL,&t,p,&l) != ERROR_SUCCESS ||
- (t != REG_DWORD && t != REG_SZ && t != REG_EXPAND_SZ))
- {
- p[0]=0;
- exec_error++;
- }
- else
- {
- if (t==REG_DWORD)
- {
- exec_error += !parm4;
- myitoa(p,*((DWORD*)p));
- }
- else
- {
- exec_error += parm4;
- p[l]=0;
- }
- }
- RegCloseKey(hKey);
- }
- else exec_error++;
- }
- break;
- case EW_REGENUM:
- {
- HKEY key=myRegOpenKey(KEY_READ);
- char *p=var0;
- int b=GetIntFromParm(3);
- p[0]=0;
- if (key)
- {
- DWORD d=NSIS_MAX_STRLEN-1;
- if (parm4) RegEnumKey(key,b,p,d);
- else if (RegEnumValue(key,b,p,&d,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS)
- {
- exec_error++;
- break;
- }
- p[NSIS_MAX_STRLEN-1]=0;
- RegCloseKey(key);
- }
- else exec_error++;
- }
-
- break;
-#endif//NSIS_SUPPORT_REGISTRYFUNCTIONS
-#ifdef NSIS_SUPPORT_FILEFUNCTIONS
- case EW_FCLOSE:
- {
- char *t=var0;
- if (*t) CloseHandle((HANDLE)myatoi(t));
- }
- break;
- case EW_FOPEN:
- {
- HANDLE h;
- char *handleout=var0;
- char *buf1=GetStringFromParm(-0x13);
- h=myOpenFile(buf1,parm1,parm2);
- if (h == INVALID_HANDLE_VALUE)
- {
- *handleout=0;
- exec_error++;
- }
- else
- {
- myitoa(handleout,(int)h);
- }
- }
- break;
- case EW_FPUTS:
- {
- DWORD dw;
- int l;
- char *t=var0;
- if (parm2)
- {
- ((unsigned char *)buf1)[0]=GetIntFromParm(1)&0xff;
- l=1;
- }
- else
- {
- l=mystrlen(GetStringFromParm(0x11));
- }
- if (!*t || !WriteFile((HANDLE)myatoi(t),buf1,l,&dw,NULL))
- {
- exec_error++;
- }
- }
- break;
- case EW_FGETS:
- {
- char *textout=var1;
- DWORD dw;
- int rpos=0;
- char *hptr=var0;
- int maxlen=GetIntFromParm(2);
- if (maxlen<1) break;
- if (maxlen > NSIS_MAX_STRLEN-1) maxlen=NSIS_MAX_STRLEN-1;
- if (*hptr)
- {
- char lc=0;
- HANDLE h=(HANDLE)myatoi(hptr);
- while (rpos<maxlen)
- {
- char c;
- if (!ReadFile(h,&c,1,&dw,NULL) || dw != 1) break;
- if (parm3)
- {
- myitoa(textout,(unsigned int)(unsigned char)c);
- return 0;
- }
- if (lc == '\r' || lc == '\n')
- {
- if (lc == c || (c != '\r' && c != '\n')) SetFilePointer(h,-1,NULL,FILE_CURRENT);
- else textout[rpos++]=c;
- break;
- }
- textout[rpos++]=c;
- lc=c;
- if (!c) break;
- }
- }
- textout[rpos]=0;
- if (!rpos) exec_error++;
- }
- break;
- case EW_FSEEK:
- {
- char *t=var0;
- if (*t)
- {
- DWORD v=SetFilePointer((HANDLE)myatoi(t),GetIntFromParm(2),NULL,parm3);
-
- if (parm1>=0)
- {
- myitoa(var1,v);
- }
- }
- }
- break;
-#endif//NSIS_SUPPORT_FILEFUNCTIONS
-#ifdef NSIS_SUPPORT_FINDFIRST
- case EW_FINDCLOSE:
- {
- char *t=var0;
- if (*t) FindClose((HANDLE)myatoi(t));
- }
- break;
- case EW_FINDNEXT:
- {
- char *textout=var0;
- char *t=var1;
- WIN32_FIND_DATA fd;
- if (*t && FindNextFile((HANDLE)myatoi(t),&fd))
- {
- mystrcpy(textout,fd.cFileName);
- }
- else
- {
- exec_error++;
- *textout=0;
- }
-
- }
- break;
- case EW_FINDFIRST:
- {
- char *textout=var0;
- char *handleout=var1;
- HANDLE h;
- WIN32_FIND_DATA fd;
- char *buf0=GetStringFromParm(0x02);
- h=FindFirstFile(buf0,&fd);
- if (h == INVALID_HANDLE_VALUE)
- {
- *handleout=0;
- *textout=0;
- exec_error++;
- }
- else
- {
- myitoa(handleout,(int)h);
- mystrcpy(textout,fd.cFileName);
- }
- }
- break;
-#endif//NSIS_SUPPORT_FINDFIRST
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- case EW_WRITEUNINSTALLER:
- {
- int ret=-666;
- HANDLE hFile;
- char *buf1=GetStringFromParm(-0x10);
-
- if (!validpathspec(buf1))
- GetStringFromParm(-0x13);
-
- remove_ro_attr(buf1);
- hFile=myOpenFile(buf1,GENERIC_WRITE,CREATE_ALWAYS);
- if (hFile != INVALID_HANDLE_VALUE)
- {
- unsigned char *filebuf;
- int filehdrsize = g_filehdrsize;
- filebuf=(unsigned char *)GlobalAlloc(GPTR,filehdrsize);
- if (filebuf)
- {
- DWORD lout;
- SetSelfFilePointer(0);
- ReadSelfFile((char*)filebuf,filehdrsize);
- {
- unsigned char* seeker;
- unsigned char* unicon_data = seeker = (unsigned char*)GlobalAlloc(GPTR,parm2);
- if (unicon_data) {
- GetCompressedDataFromDataBlockToMemory(parm1,unicon_data,parm2);
- while (*seeker) {
- struct icondata {
- DWORD dwSize;
- DWORD dwOffset;
- } id = *(struct icondata *) seeker;
- seeker += sizeof(struct icondata);
- mini_memcpy(filebuf+id.dwOffset, seeker, id.dwSize);
- seeker += id.dwSize;
- }
- GlobalFree(unicon_data);
- }
- }
- WriteFile(hFile,(char*)filebuf,filehdrsize,&lout,NULL);
- GlobalFree(filebuf);
- ret=GetCompressedDataFromDataBlock(-1,hFile);
- }
- CloseHandle(hFile);
- }
- log_printf3("created uninstaller: %d, \"%s\"",ret,buf1);
- {
- int str = LANG_CREATEDUNINST;
- if (ret < 0)
- {
- str = LANG_ERRORCREATING;
- DeleteFile(buf1);
- exec_error++;
- }
- update_status_text_buf1(str);
- }
- }
- break;
-#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
-#ifdef NSIS_CONFIG_LOG
- case EW_LOG:
- if (parm0)
- {
- log_printf2("settings logging to %d",parm1);
- log_dolog=parm1;
- log_printf2("logging set to %d",parm1);
-#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
- if (parm1) build_g_logfile();
-#endif
- }
- else
- {
- char *buf0=GetStringFromParm(0x01);
- log_printf2("%s",buf0);
- }
- break;
-#endif//NSIS_CONFIG_LOG
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- case EW_SECTIONSET:
- {
- int x=GetIntFromParm(0);
- if ((unsigned int)x < (unsigned int)num_sections)
- {
- section *sec=g_sections+x;
- if (parm2>=0) // get something
- {
- int res=((int*)sec)[parm2];
- if (!parm2)
- {
- // getting text
- mystrcpy(var1,sec->name);
- }
- else
- {
- // getting number
- myitoa(var1,res);
- }
- }
- else // set something
- {
- parm2=-parm2-1;
- if (parm2)
- {
- // not setting text, get int
- parm1=GetIntFromParm(1);
- }
- else
- {
- // setting text
- GetNSISString(sec->name,parm4);
- sec->flags|=SF_NAMECHG;
- // parm1 is zero so name_ptr will be set to zero
- // if name_ptr is zero, it won't be used after .onInit
- }
-
- ((int*)sec)[parm2]=parm1;
-
- if (parm3) // update flags
- {
- SectionFlagsChanged(x);
- }
- }
- }
- else exec_error++;
- }
- break;
- case EW_INSTTYPESET:
- {
- int x = GetIntFromParm(0);
-
- if ((unsigned int)x < (unsigned int)NSIS_MAX_INST_TYPES)
- {
- if (parm3) // current install type
- {
- if (parm2) // set install type
- {
- SetInstType(x);
- RefreshSectionGroups();
- }
- else // get install type
- {
- myitoa(var1, GetInstType(0));
- }
- }
- else // install type text
- {
- if (parm2) // set text
- {
- g_header->install_types[x] = parm1;
- }
- else // get text
- {
- GetNSISString(var1,g_header->install_types[x]);
- }
- }
- }
- else exec_error++;
- }
- break;
-#endif//NSIS_CONFIG_COMPONENTPAGE
-
-#ifdef NSIS_LOCKWINDOW_SUPPORT
- case EW_LOCKWINDOW:
- {
- // ui_dlg_visible is 1 or 0, so is parm0
- SendMessage(g_hwnd, WM_SETREDRAW, parm0 & ui_dlg_visible, 0);
- if ( parm0 )
- InvalidateRect(g_hwnd, NULL, FALSE);
- break;
- }
-#endif //NSIS_LOCKWINDOW_SUPPORT
- }
-
- g_exec_flags.exec_error += exec_error;
-
- return 0;
-}
+/*
+ * exec.c
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "../Platform.h"
+#include <shlobj.h>
+#include <shellapi.h>
+#include "fileform.h"
+#include "util.h"
+#include "state.h"
+#include "ui.h"
+#include "components.h"
+#include "exec.h"
+#include "lang.h"
+#include "resource.h"
+
+#define EXEC_ERROR 0x7FFFFFFF
+
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+HWND g_SectionHack;
+#endif
+
+#ifdef NSIS_SUPPORT_STACK
+typedef struct _stack_t {
+ struct _stack_t *next;
+ char text[NSIS_MAX_STRLEN];
+} stack_t;
+
+static stack_t *g_st;
+#endif
+
+exec_flags g_exec_flags;
+exec_flags g_exec_flags_last_used;
+
+struct {
+ exec_flags *flags;
+ void *ExecuteCodeSegment;
+ void *validate_filename;
+} plugin_extra_parameters = {
+ &g_exec_flags,
+ &ExecuteCodeSegment,
+ &validate_filename
+};
+
+#if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
+HRESULT g_hres;
+#endif
+
+static int NSISCALL ExecuteEntry(entry *entry_);
+
+int NSISCALL resolveaddr(int v)
+{
+ if (v < 0)
+ {
+ return myatoi(g_usrvars[-(v+1)]);
+ }
+ return v;
+}
+
+int NSISCALL ExecuteCodeSegment(int pos, HWND hwndProgress)
+{
+ while (pos >= 0)
+ {
+ int rv;
+ if (g_entries[pos].which == EW_RET) return 0;
+ rv=ExecuteEntry(g_entries + pos);
+ if (rv == EXEC_ERROR) return EXEC_ERROR;
+
+ rv=resolveaddr(rv);
+
+ if (!rv) { rv++; pos++; }
+ else
+ {
+ int t=pos;
+ rv--; // rv is decremented here by 1, since it was +1 on the other end.
+ pos=rv; // set new position
+ rv-=t; // set rv to delta for progress adjustment
+ }
+
+ if (hwndProgress)
+ {
+ extern int progress_bar_pos, progress_bar_len;
+ progress_bar_pos+=rv;
+ SendMessage(hwndProgress,PBM_SETPOS,MulDiv(progress_bar_pos,30000,progress_bar_len),0);
+ }
+ }
+ return 0;
+}
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+
+int NSISCALL ExecuteCallbackFunction(int num)
+{
+ return ExecuteCodeSegment(*(&g_header->code_onInit + num), NULL);
+}
+
+#endif
+
+static char bufs[5][NSIS_MAX_STRLEN];
+static int *parms;
+
+void NSISCALL update_status_text_buf1(int strtab)
+{
+ update_status_text(strtab, bufs[1]);
+}
+
+static int NSISCALL GetIntFromParm(int id_)
+{
+ return myatoi(GetNSISStringTT(parms[id_]));
+}
+
+// NB - USE CAUTION when rearranging code to make use of the new return value of
+// this function - be sure the parm being accessed is not modified before the call.
+// Use a negative number to get the string validated as a file name
+static char * NSISCALL GetStringFromParm(int id_)
+{
+ int id = id_ < 0 ? -id_ : id_;
+ char *result = GetNSISString(bufs[id >> 4], parms[id & 0xF]);
+ if (id_ < 0) validate_filename(result);
+ return result;
+}
+
+#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
+
+#define AlterRegistrySAM(sam) (sam | g_exec_flags.alter_reg_view)
+
+// based loosely on code from Tim Kosse
+// in win9x this isn't necessary (RegDeleteKey() can delete a tree of keys),
+// but in win2k you need to do this manually.
+static LONG NSISCALL myRegDeleteKeyEx(HKEY thiskey, LPCTSTR lpSubKey, int onlyifempty)
+{
+ HKEY key;
+ int retval=RegOpenKeyEx(thiskey,lpSubKey,0,AlterRegistrySAM(KEY_ENUMERATE_SUB_KEYS),&key);
+ if (retval==ERROR_SUCCESS)
+ {
+ // NB - don't change this to static (recursive function)
+ char buffer[MAX_PATH+1];
+ while (RegEnumKey(key,0,buffer,MAX_PATH+1)==ERROR_SUCCESS)
+ {
+ if (onlyifempty)
+ {
+ RegCloseKey(key);
+ return !ERROR_SUCCESS;
+ }
+ if ((retval=myRegDeleteKeyEx(key,buffer,0)) != ERROR_SUCCESS) break;
+ }
+ RegCloseKey(key);
+ {
+ typedef LONG (WINAPI * RegDeleteKeyExAPtr)(HKEY, LPCTSTR, REGSAM, DWORD);
+ RegDeleteKeyExAPtr RDKE = (RegDeleteKeyExAPtr)
+ myGetProcAddress(MGA_RegDeleteKeyExA);
+
+ if (RDKE)
+ retval=RDKE(thiskey,lpSubKey,AlterRegistrySAM(0),0);
+ else
+ retval=g_exec_flags.alter_reg_view||RegDeleteKey(thiskey,lpSubKey);
+ }
+ }
+ return retval;
+}
+
+static HKEY NSISCALL GetRegRootKey(int hRootKey)
+{
+ if (hRootKey)
+ return (HKEY) hRootKey;
+
+ // HKEY_LOCAL_MACHINE - HKEY_CURRENT_USER == 1
+ return (HKEY) ((int) HKEY_CURRENT_USER + g_exec_flags.all_user_var);
+}
+
+static HKEY NSISCALL myRegOpenKey(REGSAM samDesired)
+{
+ HKEY hKey;
+ if (RegOpenKeyEx(GetRegRootKey(parms[1]), GetStringFromParm(0x22), 0, AlterRegistrySAM(samDesired), &hKey) == ERROR_SUCCESS)
+ {
+ return hKey;
+ }
+ return NULL;
+}
+#endif//NSIS_SUPPORT_REGISTRYFUNCTIONS
+
+// returns EXEC_ERROR on error
+// returns 0, advance position by 1
+// otherwise, returns new_position+1
+static int NSISCALL ExecuteEntry(entry *entry_)
+{
+ char *buf0 = bufs[0];
+ char *buf1 = bufs[1];
+ char *buf2 = bufs[2];
+ char *buf3 = bufs[3];
+ //char *buf4 = bufs[4];
+
+ char *var0;
+ char *var1;
+ //char *var2;
+ //char *var3;
+ //char *var4;
+ //char *var5;
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ // Saves 8 bytes
+ HWND mainHwnd = g_hwnd;
+#define g_hwnd mainHwnd
+#endif
+
+ int exec_error = 0;
+
+ entry lent = *entry_;
+
+#define which (lent.which)
+#define parm0 (lent.offsets[0])
+#define parm1 (lent.offsets[1])
+#define parm2 (lent.offsets[2])
+#define parm3 (lent.offsets[3])
+#define parm4 (lent.offsets[4])
+#define parm5 (lent.offsets[5])
+
+ var0 = g_usrvars[parm0];
+ var1 = g_usrvars[parm1];
+ // not used yet
+ //var2 = g_usrvars[parm2];
+ //var3 = g_usrvars[parm3];
+ //var4 = g_usrvars[parm4];
+ //var5 = g_usrvars[parm5];
+
+ parms = lent.offsets;
+
+ switch (which)
+ {
+ case EW_NOP:
+ log_printf2("Jump: %d",parm0);
+ return parm0;
+ case EW_ABORT:
+ {
+ log_printf2("Aborting: \"%s\"",GetStringFromParm(0x00));
+ update_status_text(parm0,0);
+ }
+ return EXEC_ERROR;
+ case EW_QUIT:
+ g_quit_flag++;
+ if (g_hwnd) PostQuitMessage(0); // make sure we bail out fast.
+ return EXEC_ERROR;
+ case EW_CALL:
+ {
+ int v=resolveaddr(parm0)-1; // address is -1, since we encode it as +1
+ log_printf2("Call: %d",v);
+ return ExecuteCodeSegment(v,NULL);
+ }
+ case EW_UPDATETEXT:
+ log_printf2("detailprint: %s",GetStringFromParm(0x00));
+ update_status_text(parm0,0);
+ break;
+ case EW_SLEEP:
+ {
+ int x=GetIntFromParm(0);
+ log_printf2("Sleep(%d)",x);
+ Sleep(max(x,1));
+ }
+ break;
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ case EW_BRINGTOFRONT:
+ log_printf("BringToFront");
+ SetForegroundWindow(g_hwnd);
+ break;
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+ case EW_SETFLAG:
+ if (!parm2)
+ {
+ FIELDN(g_exec_flags_last_used,parm0)=FIELDN(g_exec_flags,parm0);
+ FIELDN(g_exec_flags,parm0)=GetIntFromParm(1);
+ }
+ else
+ {
+ FIELDN(g_exec_flags,parm0)=FIELDN(g_exec_flags_last_used,parm0);
+ }
+ break;
+ case EW_IFFLAG:
+ {
+ int f=lent.offsets[!FIELDN(g_exec_flags,parm2)];
+ FIELDN(g_exec_flags,parm2)&=parm3;
+ return f;
+ }
+ case EW_GETFLAG:
+ myitoa(var0,FIELDN(g_exec_flags,parm1));
+ break;
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ case EW_CHDETAILSVIEW:
+ if (insthwndbutton) ShowWindow(insthwndbutton,parm1);
+ if (insthwnd) ShowWindow(insthwnd,parm0);
+ break;
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+ case EW_SETFILEATTRIBUTES:
+ {
+ char *buf1=GetStringFromParm(-0x10);
+ log_printf3("SetFileAttributes: \"%s\":%08X",buf1,parm1);
+ if (!SetFileAttributes(buf1,parm1))
+ {
+ exec_error++;
+ log_printf("SetFileAttributes failed.");
+ }
+ }
+ break;
+ case EW_CREATEDIR: {
+ char *buf1=GetStringFromParm(-0x10);
+ log_printf3("CreateDirectory: \"%s\" (%d)",buf1,parm1);
+ {
+ char *p = skip_root(buf1);
+ char c = 'c';
+ if (p)
+ {
+ while (c)
+ {
+ p = findchar(p, '\\');
+ c = *p;
+ *p = 0;
+ if (!CreateDirectory(buf1, NULL))
+ {
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ log_printf3("CreateDirectory: can't create \"%s\" (err=%d)",buf1,GetLastError());
+ exec_error++;
+ }
+ else if ((GetFileAttributes(buf1) & FILE_ATTRIBUTE_DIRECTORY) == 0)
+ {
+ log_printf2("CreateDirectory: can't create \"%s\" - a file already exists",buf1);
+ exec_error++;
+ }
+ }
+ *p++ = c;
+ }
+ }
+ }
+ if (parm1)
+ {
+ update_status_text_buf1(LANG_OUTPUTDIR);
+ mystrcpy(state_output_directory,buf1);
+ SetCurrentDirectory(buf1);
+ }
+ else update_status_text_buf1(LANG_CREATEDIR);
+ }
+ break;
+ case EW_IFFILEEXISTS:
+ {
+ char *buf0=GetStringFromParm(0x00);
+ if (file_exists(buf0))
+ {
+ log_printf3("IfFileExists: file \"%s\" exists, jumping %d",buf0,parm1);
+ return parm1;
+ }
+ log_printf3("IfFileExists: file \"%s\" does not exist, jumping %d",buf0,parm2);
+ }
+ return parm2;
+#ifdef NSIS_SUPPORT_RENAME
+ case EW_RENAME:
+ {
+ char *buf3=GetStringFromParm(-0x30);
+ char *buf2=GetStringFromParm(-0x21);
+ char *buf1=GetStringFromParm(0x13);
+ log_printf2("Rename: %s",buf1);
+ if (MoveFile(buf3,buf2))
+ {
+ update_status_text_buf1(LANG_RENAME);
+ }
+ else
+ {
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+ if (parm2 && file_exists(buf3))
+ {
+ MoveFileOnReboot(buf3,buf2);
+ update_status_text_buf1(LANG_RENAMEONREBOOT);
+ log_printf2("Rename on reboot: %s",buf1);
+ }
+ else
+#endif
+ {
+ exec_error++;
+ log_printf2("Rename failed: %s",buf1);
+ }
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_RENAME
+#ifdef NSIS_SUPPORT_FNUTIL
+ case EW_GETFULLPATHNAME:
+ {
+ char *fp;
+ char *p=var1;
+ char *buf0=GetStringFromParm(0x00);
+ if (!GetFullPathName(buf0,NSIS_MAX_STRLEN,p,&fp))
+ {
+ exec_error++;
+ *p=0;
+ }
+ else if (fp>buf0 && *fp)
+ {
+ WIN32_FIND_DATA *fd=file_exists(buf0);
+ if (fd)
+ {
+ mystrcpy(fp,fd->cFileName);
+ }
+ else
+ {
+ exec_error++;
+ *p=0;
+ }
+ }
+ if (!parm2) GetShortPathName(p,p,NSIS_MAX_STRLEN);
+ }
+ break;
+ case EW_SEARCHPATH:
+ {
+ char *fp;
+ char *p=var0;
+ char *buf0=GetStringFromParm(-0x01);
+ if (!SearchPath(NULL,buf0,NULL,NSIS_MAX_STRLEN,p,&fp))
+ {
+ exec_error++;
+ p[0]=0;
+ }
+ }
+ break;
+ case EW_GETTEMPFILENAME:
+ {
+ char *textout=var0;
+ if (!my_GetTempFileName(textout, GetStringFromParm(-0x11)))
+ exec_error++;
+ }
+ break;
+#endif
+#ifdef NSIS_SUPPORT_FILE
+ case EW_EXTRACTFILE:
+ {
+ HANDLE hOut;
+ int ret;
+ char *buf3 = GetStringFromParm(0x31);
+ int overwriteflag = parm0 & 7;
+
+ log_printf4("File: overwriteflag=%d, allowskipfilesflag=%d, name=\"%s\"",overwriteflag,(parm0>>3)&MB_ABORTRETRYIGNORE,buf3);
+ if (validpathspec(buf3))
+ {
+ mystrcpy(buf0,buf3);
+ }
+ else mystrcat(addtrailingslash(mystrcpy(buf0,state_output_directory)),buf3);
+ validate_filename(buf0);
+ _tryagain:
+ if (overwriteflag >= 3) // check date and time
+ {
+ WIN32_FIND_DATA *ffd=file_exists(buf0);
+ // if it doesn't exist, overwrite flag will be off (though it doesn't really matter)
+ int cmp=0;
+ if (ffd)
+ {
+ cmp=CompareFileTime(&ffd->ftLastWriteTime, (FILETIME*)(lent.offsets + 3));
+ }
+ overwriteflag=!(cmp & (0x80000000 | (overwriteflag - 3)));
+ }
+ // remove read only flag if overwrite mode is on
+ if (!overwriteflag)
+ {
+ remove_ro_attr(buf0);
+ }
+ hOut=myOpenFile(buf0,GENERIC_WRITE,(overwriteflag==1)?CREATE_NEW:CREATE_ALWAYS);
+ if (hOut == INVALID_HANDLE_VALUE)
+ {
+ if (overwriteflag)
+ {
+ update_status_text(LANG_SKIPPED,buf3);
+ if (overwriteflag==2) exec_error++;
+ log_printf3("File: skipped: \"%s\" (overwriteflag=%d)",buf0,overwriteflag);
+ break;
+ }
+ log_printf2("File: error creating \"%s\"",buf0);
+
+ mystrcpy(buf2,g_usrvars[0]); // save $0
+ mystrcpy(g_usrvars[0],buf0); // copy file name to $0
+ GetNSISString(buf1,parm5); // use $0
+ mystrcpy(g_usrvars[0],buf2); // restore $0
+
+ // Modified by ramon 23 May 2003
+ switch (my_MessageBox(buf1, parm0>>3))
+ {
+ case IDRETRY:
+ log_printf("File: error, user retry");
+ goto _tryagain;
+ case IDIGNORE:
+ log_printf("File: error, user cancel");
+ g_exec_flags.exec_error++;
+ return 0;
+ default:
+ log_printf("File: error, user abort");
+ update_status_text(LANG_CANTWRITE,buf0);
+ return EXEC_ERROR;
+ }
+ }
+
+ update_status_text(LANG_EXTRACT,buf3);
+ {
+ g_exec_flags.status_update++;
+ ret=GetCompressedDataFromDataBlock(parm2,hOut);
+ g_exec_flags.status_update--;
+ }
+
+ log_printf3("File: wrote %d to \"%s\"",ret,buf0);
+
+ if (parm3 != 0xffffffff || parm4 != 0xffffffff)
+ SetFileTime(hOut,(FILETIME*)(lent.offsets+3),NULL,(FILETIME*)(lent.offsets+3));
+
+ CloseHandle(hOut);
+
+ if (ret < 0)
+ {
+ if (ret == -2)
+ {
+ GetNSISString(buf0,LANG_ERRORWRITING);
+ mystrcat(buf0,buf3);
+ }
+ else
+ {
+ GetNSISString(buf0,LANG_ERRORDECOMPRESSING);
+ }
+ log_printf2("%s",buf0);
+ my_MessageBox(buf0,MB_OK|MB_ICONSTOP|(IDOK<<21));
+ return EXEC_ERROR;
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_FILE
+#ifdef NSIS_SUPPORT_DELETE
+ case EW_DELETEFILE:
+ {
+ char *buf0=GetStringFromParm(0x00);
+ log_printf2("Delete: \"%s\"",buf0);
+ myDelete(buf0,parm1);
+ }
+ break;
+#endif//NSIS_SUPPORT_DELETE
+#ifdef NSIS_SUPPORT_MESSAGEBOX
+ case EW_MESSAGEBOX: // MessageBox
+ {
+ int v;
+ char *buf3=GetStringFromParm(0x31);
+ log_printf3("MessageBox: %d,\"%s\"",parm0,buf3);
+ v=my_MessageBox(buf3,parm0);
+ if (v)
+ {
+ if (v==parm2)
+ {
+ return parm3;
+ }
+ if (v==parm4)
+ {
+ return parm5;
+ }
+ }
+ else exec_error++;
+ }
+ break;
+#endif//NSIS_SUPPORT_MESSAGEBOX
+#ifdef NSIS_SUPPORT_RMDIR
+ case EW_RMDIR:
+ {
+ char *buf1=GetStringFromParm(-0x10);
+ log_printf2("RMDir: \"%s\"",buf1);
+
+ myDelete(buf1,parm1);
+ }
+ break;
+#endif//NSIS_SUPPORT_RMDIR
+#ifdef NSIS_SUPPORT_STROPTS
+ case EW_STRLEN:
+ {
+ char *buf0=GetStringFromParm(0x01);
+ myitoa(var0,mystrlen(buf0));
+ }
+ break;
+ case EW_ASSIGNVAR:
+ {
+ int newlen=GetIntFromParm(2);
+ int start=GetIntFromParm(3);
+ int l;
+ char *p=var0;
+ char *buf0=GetStringFromParm(0x01);
+ *p=0;
+ if (!parm2 || newlen)
+ {
+ l=mystrlen(buf0);
+
+ if (start<0) start=l+start;
+ if (start>=0)
+ {
+ if (start>l) start=l;
+ mystrcpy(p,buf0+start);
+ if (newlen)
+ {
+ if (newlen<0) newlen=mystrlen(p)+newlen;
+ if (newlen<0) newlen=0;
+ if (newlen < NSIS_MAX_STRLEN) p[newlen]=0;
+ }
+ }
+ }
+ }
+ break;
+ case EW_STRCMP:
+ {
+ char *buf2=GetStringFromParm(0x20);
+ char *buf3=GetStringFromParm(0x31);
+ if (!parm4) {
+ // case insensitive
+ if (!lstrcmpi(buf2,buf3)) return parm2;
+ }
+ else {
+ // case sensitive
+ if (!lstrcmp(buf2,buf3)) return parm2;
+ }
+ }
+ return parm3;
+#endif//NSIS_SUPPORT_STROPTS
+#ifdef NSIS_SUPPORT_ENVIRONMENT
+ case EW_READENVSTR:
+ {
+ char *p=var0;
+ char *buf0=GetStringFromParm(0x01);
+ if (!ExpandEnvironmentStrings(buf0,p,NSIS_MAX_STRLEN)
+ || (parm2 && !lstrcmp(buf0, p)))
+ {
+ exec_error++;
+ *p=0;
+ }
+ p[NSIS_MAX_STRLEN-1]=0;
+ }
+ break;
+#endif//NSIS_SUPPORT_ENVIRONMENT
+#ifdef NSIS_SUPPORT_INTOPTS
+ case EW_INTCMP:
+ {
+ int v,v2;
+ v=GetIntFromParm(0);
+ v2=GetIntFromParm(1);
+ if (!parm5) {
+ // signed
+ if (v<v2) return parm3;
+ if (v>v2) return parm4;
+ }
+ else {
+ // unsigned
+ if ((unsigned int)v<(unsigned int)v2) return parm3;
+ if ((unsigned int)v>(unsigned int)v2) return parm4;
+ }
+ }
+ return parm2;
+ case EW_INTOP:
+ {
+ int v,v2;
+ char *p=var0;
+ v=GetIntFromParm(1);
+ v2=GetIntFromParm(2);
+ switch (parm3)
+ {
+ case 0: v+=v2; break;
+ case 1: v-=v2; break;
+ case 2: v*=v2; break;
+ case 3: if (v2) v/=v2; else { v=0; exec_error++; } break;
+ case 4: v|=v2; break;
+ case 5: v&=v2; break;
+ case 6: v^=v2; break;
+ case 7: v=!v; break;
+ case 8: v=v||v2; break;
+ case 9: v=v&&v2; break;
+ case 10: if (v2) v%=v2; else { v=0; exec_error++; } break;
+ case 11: v=v<<v2; break;
+ case 12: v=v>>v2; break;
+ }
+ myitoa(p,v);
+ }
+ break;
+ case EW_INTFMT: {
+ char *buf0=GetStringFromParm(0x01);
+ wsprintf(var0,
+ buf0,
+ GetIntFromParm(2));
+ }
+ break;
+#endif//NSIS_SUPPORT_INTOPTS
+#ifdef NSIS_SUPPORT_STACK
+ case EW_PUSHPOP:
+ {
+ stack_t *s=g_st;
+ int cnt=parm2;
+ if (cnt) //Exch contributed by Fritz Elfert
+ {
+ while (cnt--&&s) s=s->next;
+ if (!s)
+ {
+ log_printf2("Exch: stack < %d elements",parm2);
+ my_MessageBox(GetNSISStringTT(LANG_INSTCORRUPTED),MB_OK|MB_ICONSTOP|(IDOK<<21));
+ return EXEC_ERROR;
+ }
+ mystrcpy(buf0,s->text);
+ mystrcpy(s->text,g_st->text);
+ mystrcpy(g_st->text,buf0);
+ }
+ else if (parm1)
+ {
+ if (!s)
+ {
+ log_printf("Pop: stack empty");
+ exec_error++;
+ break;
+ }
+ mystrcpy(var0,s->text);
+ g_st=s->next;
+ GlobalFree((HGLOBAL)s);
+ }
+ else
+ {
+ s=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t));
+ GetNSISString(s->text,parm0);
+ s->next=g_st;
+ g_st=s;
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_STACK
+#ifdef NSIS_SUPPORT_HWNDS
+ case EW_FINDWINDOW:
+ case EW_SENDMESSAGE:
+ {
+ int v;
+ int b3=GetIntFromParm(3);
+ int b4=GetIntFromParm(4);
+ if (parm5&1) b3=(int)GetStringFromParm(0x33);
+ if (parm5&2) b4=(int)GetStringFromParm(0x44);
+
+ if (which == EW_SENDMESSAGE)
+ {
+ HWND hwnd=(HWND)GetIntFromParm(1);
+ int msg=GetIntFromParm(2);
+
+ if (parm5>>2) exec_error += !SendMessageTimeout(hwnd,msg,b3,b4,SMTO_NORMAL,parm5>>2,(LPDWORD)&v);
+ else v=SendMessage(hwnd,msg,b3,b4);
+ }
+ else
+ {
+ char *buf0=GetStringFromParm(0x01);
+ char *buf1=GetStringFromParm(0x12);
+ v=(int)FindWindowEx((HWND)b3,(HWND)b4,buf0[0]?buf0:NULL,buf1[0]?buf1:NULL);
+ }
+
+ if (parm0>=0)
+ myitoa(var0,v);
+ }
+ break;
+ case EW_ISWINDOW:
+ if (IsWindow((HWND)GetIntFromParm(0))) return parm1;
+ return parm2;
+#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ case EW_GETDLGITEM:
+ myitoa(
+ var0,
+ (int)GetDlgItem(
+ (HWND)GetIntFromParm(1),
+ GetIntFromParm(2)
+ )
+ );
+ break;
+ case EW_SETCTLCOLORS:
+ {
+ ctlcolors *c = (ctlcolors *)(g_blocks[NB_CTLCOLORS].offset + parm1);
+ SetWindowLong((HWND) GetIntFromParm(0), GWL_USERDATA, (long) c);
+ }
+ break;
+ case EW_SETBRANDINGIMAGE:
+ {
+ RECT r;
+ HANDLE hImage;
+ HWND hwImage=GetDlgItem(g_hwnd, parm1);
+ GetClientRect(hwImage, &r);
+ hImage=LoadImage(
+ 0,
+ GetStringFromParm(0x00),
+ IMAGE_BITMAP,
+ parm2*r.right,
+ parm2*r.bottom,
+ LR_LOADFROMFILE
+ );
+ hImage = (HANDLE)SendMessage(
+ hwImage,
+ STM_SETIMAGE,
+ IMAGE_BITMAP,
+ (LPARAM)hImage
+ );
+ // delete old image
+ if (hImage) DeleteObject(hImage);
+ }
+ break;
+ case EW_CREATEFONT:
+ {
+ static LOGFONT f;
+ f.lfHeight=-MulDiv(GetIntFromParm(2),GetDeviceCaps(GetDC(g_hwnd),LOGPIXELSY),72);
+ f.lfWeight=GetIntFromParm(3);
+ f.lfItalic=parm4&1;
+ f.lfUnderline=parm4&2;
+ f.lfStrikeOut=parm4&4;
+ f.lfCharSet=DEFAULT_CHARSET;
+ GetNSISString(f.lfFaceName,parm1);
+ myitoa(var0,(int)CreateFontIndirect(&f));
+ }
+ break;
+ case EW_SHOWWINDOW:
+ {
+ HWND hw=(HWND)GetIntFromParm(0);
+ int a=GetIntFromParm(1);
+ if (parm2) log_printf("HideWindow");
+ if (!parm3)
+ ShowWindow(hw,a);
+ else
+ EnableWindow(hw,a);
+ }
+ break;
+#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
+#endif//NSIS_SUPPORT_HWNDS
+#ifdef NSIS_SUPPORT_SHELLEXECUTE
+ case EW_SHELLEXEC: // this uses improvements of Andras Varga
+ {
+ int x;
+ char *buf0=GetStringFromParm(0x00);
+ char *buf3=GetStringFromParm(0x31);
+ char *buf2=GetStringFromParm(0x22);
+ char *buf1=GetStringFromParm(0x15);
+ update_status_text_buf1(LANG_EXECSHELL);
+ x=(int)ShellExecute(g_hwnd,buf0[0]?buf0:NULL,buf3,buf2[0]?buf2:NULL,state_output_directory,parm3);
+ if (x < 33)
+ {
+ log_printf5("ExecShell: warning: error (\"%s\": file:\"%s\" params:\"%s\")=%d",buf0,buf3,buf2,x);
+ exec_error++;
+ }
+ else
+ {
+ log_printf4("ExecShell: success (\"%s\": file:\"%s\" params:\"%s\")",buf0,buf3,buf2);
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_SHELLEXECUTE
+#ifdef NSIS_SUPPORT_EXECUTE
+ case EW_EXECUTE:
+ {
+ HANDLE hProc;
+ char *buf0=GetStringFromParm(0x00);
+ log_printf2("Exec: command=\"%s\"",buf0);
+ update_status_text(LANG_EXECUTE,buf0);
+
+ hProc=myCreateProcess(buf0);
+
+ if (hProc)
+ {
+ log_printf2("Exec: success (\"%s\")",buf0);
+ if (parm2)
+ {
+ DWORD lExitCode;
+ while (WaitForSingleObject(hProc,100) == WAIT_TIMEOUT)
+ {
+ MessageLoop(WM_PAINT);
+ }
+ GetExitCodeProcess(hProc, &lExitCode);
+
+ if (parm1>=0) myitoa(var1,lExitCode);
+ else if (lExitCode) exec_error++;
+ }
+ CloseHandle( hProc );
+ }
+ else
+ {
+ exec_error++;
+ log_printf2("Exec: failed createprocess (\"%s\")",buf0);
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_EXECUTE
+#ifdef NSIS_SUPPORT_GETFILETIME
+ case EW_GETFILETIME:
+ // this new implementation based on one by Dave Bau
+ // used FindFirstFile instead of GetFileTime to better handle files that are locked.
+ // also allows GetFileTime to be passed a wildcard.
+ {
+ WIN32_FIND_DATA *ffd;
+ char *highout=var0;
+ char *lowout=var1;
+ char *buf0=GetStringFromParm(0x02);
+
+ ffd=file_exists(buf0);
+ if (ffd)
+ {
+ myitoa(lowout,ffd->ftLastWriteTime.dwLowDateTime);
+ myitoa(highout,ffd->ftLastWriteTime.dwHighDateTime);
+ }
+ else
+ {
+ *lowout=*highout=0;
+ exec_error++;
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_GETFILETIME
+#ifdef NSIS_SUPPORT_GETDLLVERSION
+ case EW_GETDLLVERSION:
+ {
+ char *highout=var0;
+ char *lowout=var1;
+ DWORD s1;
+ VS_FIXEDFILEINFO *pvsf1;
+ DWORD d;
+ char *buf1=GetStringFromParm(-0x12);
+ s1=GetFileVersionInfoSize(buf1,&d);
+ *lowout=*highout=0;
+ exec_error++;
+ if (s1)
+ {
+ void *b1;
+ b1=GlobalAlloc(GPTR,s1);
+ if (b1)
+ {
+ UINT uLen;
+ if (GetFileVersionInfo(buf1,0,s1,b1) && VerQueryValue(b1,"\\",(void*)&pvsf1,&uLen))
+ {
+ myitoa(highout,pvsf1->dwFileVersionMS);
+ myitoa(lowout,pvsf1->dwFileVersionLS);
+
+ exec_error--;
+ }
+ GlobalFree(b1);
+ }
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_GETDLLVERSION
+#ifdef NSIS_SUPPORT_ACTIVEXREG
+ case EW_REGISTERDLL:
+ {
+ exec_error++;
+ if (SUCCEEDED(g_hres))
+ {
+ HANDLE h=NULL;
+ char *buf1=GetStringFromParm(-0x10);
+ char *buf0=GetStringFromParm(0x01);
+
+ if (parm4)
+ h=GetModuleHandle(buf1);
+ if (!h)
+ h=LoadLibraryEx(buf1, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (h)
+ {
+ FARPROC funke = GetProcAddress(h,buf0);
+ if (funke)
+ {
+ exec_error--;
+ if (parm2)
+ {
+ update_status_text_buf1(parm2);
+ if (funke()) exec_error++;
+ }
+ else
+ {
+ void (*func)(HWND,int,char*,void*,void*);
+ func=(void*)funke;
+ func(
+ g_hwnd,
+ NSIS_MAX_STRLEN,
+ (char*)g_usrvars,
+#ifdef NSIS_SUPPORT_STACK
+ (void*)&g_st,
+#else
+ NULL,
+#endif//NSIS_SUPPORT_STACK
+ &plugin_extra_parameters
+ );
+ }
+ }
+ else
+ {
+ update_status_text(LANG_CANNOTFINDSYMBOL,buf0);
+ log_printf3("Error registering DLL: %s not found in %s",buf0,buf1);
+ }
+ if (!parm3) FreeLibrary(h);
+ }
+ else
+ {
+ update_status_text_buf1(LANG_COULDNOTLOAD);
+ log_printf2("Error registering DLL: Could not load %s",buf1);
+ }
+ }
+ else
+ {
+ update_status_text_buf1(LANG_NOOLE);
+ log_printf("Error registering DLL: Could not initialize OLE");
+ }
+ }
+ break;
+#endif
+#ifdef NSIS_SUPPORT_CREATESHORTCUT
+ case EW_CREATESHORTCUT:
+ {
+ char *buf1=GetStringFromParm(-0x10);
+ char *buf2=GetStringFromParm(-0x21);
+ char *buf0=GetStringFromParm(0x02);
+ char *buf3=GetStringFromParm(-0x33);
+ char *buf4=GetStringFromParm(0x45);
+
+ HRESULT hres;
+ IShellLink* psl;
+
+ if (!validpathspec(buf2))
+ GetStringFromParm(0x21);
+
+ log_printf8("CreateShortCut: out: \"%s\", in: \"%s %s\", icon: %s,%d, sw=%d, hk=%d",
+ buf1,buf2,buf0,buf3,parm4&0xff,(parm4&0xff00)>>8,parm4>>16);
+
+ hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IShellLink, (void **) &psl);
+ if (SUCCEEDED(hres))
+ {
+ IPersistFile* ppf;
+
+ hres = psl->lpVtbl->QueryInterface(psl,&IID_IPersistFile, (void **) &ppf);
+ if (SUCCEEDED(hres))
+ {
+ hres = psl->lpVtbl->SetPath(psl,buf2);
+ psl->lpVtbl->SetWorkingDirectory(psl,state_output_directory);
+ if ((parm4&0xff00)>>8) psl->lpVtbl->SetShowCmd(psl,(parm4&0xff00)>>8);
+ psl->lpVtbl->SetHotkey(psl,(unsigned short)(parm4>>16));
+ if (buf3[0]) psl->lpVtbl->SetIconLocation(psl,buf3,parm4&0xff);
+ psl->lpVtbl->SetArguments(psl,buf0);
+ psl->lpVtbl->SetDescription(psl,buf4);
+
+ if (SUCCEEDED(hres))
+ {
+ static WCHAR wsz[1024];
+ hres=E_FAIL;
+ if (MultiByteToWideChar(CP_ACP, 0, buf1, -1, wsz, 1024))
+ hres=ppf->lpVtbl->Save(ppf,(const WCHAR*)wsz,TRUE);
+ }
+ ppf->lpVtbl->Release(ppf);
+ }
+ psl->lpVtbl->Release(psl);
+ }
+
+ if (FAILED(hres))
+ {
+ exec_error++;
+ update_status_text_buf1(LANG_ERRORCREATINGSHORTCUT);
+ }
+ else
+ {
+ update_status_text_buf1(LANG_CREATESHORTCUT);
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_CREATESHORTCUT
+#ifdef NSIS_SUPPORT_COPYFILES
+ case EW_COPYFILES: // CopyFile (added by NOP)
+ {
+ int res;
+ SHFILEOPSTRUCT op;
+ char *buf0=GetStringFromParm(0x00);
+ char *buf1=GetStringFromParm(0x11);
+ char *buf2=GetStringFromParm(0x23); // LANG_COPYTO + buf1
+ log_printf3("CopyFiles \"%s\"->\"%s\"",buf0,buf1);
+
+ if (!file_exists(buf0))
+ {
+ // workaround for bug #774966
+ //
+ // on nt4, SHFileOperation silently fails if the source
+ // file doesn't exist. do a manual check instead.
+
+ update_status_text(LANG_COPYFAILED,0);
+ exec_error++;
+ break;
+ }
+
+ op.hwnd=g_hwnd;
+ op.wFunc=FO_COPY;
+ buf0[mystrlen(buf0)+1]=0;
+ buf1[mystrlen(buf1)+1]=0;
+
+ op.pFrom=buf0;
+ op.pTo=buf1;
+ op.lpszProgressTitle=buf2;
+ op.fFlags=parm2;
+ update_status_text(0,buf2);
+ res=SHFileOperation(&op);
+ if (res)
+ { // some of these changes were from Edgewise (wiked_edge@yahoo.com)
+ update_status_text(LANG_COPYFAILED,0);
+ exec_error++;
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_COPYFILES
+#ifdef NSIS_SUPPORT_REBOOT
+ case EW_REBOOT:
+ if (parm0!=0xbadf00d)
+ {
+ my_MessageBox(GetNSISStringTT(LANG_INSTCORRUPTED),MB_OK|MB_ICONSTOP|(IDOK<<21));
+ return EXEC_ERROR;
+ }
+
+ g_exec_flags.reboot_called++;
+ // a following EW_QUIT will make sure the installer quits right away
+
+ break;
+#endif//NSIS_SUPPORT_REBOOT
+#ifdef NSIS_SUPPORT_INIFILES
+ case EW_WRITEINI:
+ {
+ char *sec=0, *key=0, *str=0;
+#ifdef NSIS_CONFIG_LOG
+ mystrcpy(buf1,"<RM>");
+ mystrcpy(buf2,buf1);
+#endif
+ if (parm0)
+ {
+ sec=GetStringFromParm(0x00);
+ }
+ if (parm1)
+ {
+ key=GetStringFromParm(0x11);
+ }
+ if (parm4)
+ {
+ str=GetStringFromParm(0x22);
+ }
+ buf3=GetStringFromParm(-0x33);
+ log_printf5("WriteINIStr: wrote [%s] %s=%s in %s",buf0,buf1,buf2,buf3);
+ if (!WritePrivateProfileString(sec,key,str,buf3)) exec_error++;
+ }
+ break;
+ case EW_READINISTR:
+ {
+ DWORD errstr = CHAR4_TO_DWORD('!', 'N', '~', 0);
+ char *p=var0;
+ char *buf0=GetStringFromParm(0x01);
+ char *buf1=GetStringFromParm(0x12);
+ char *buf2=GetStringFromParm(-0x23);
+ GetPrivateProfileString(buf0,buf1,(LPCSTR)&errstr,p,NSIS_MAX_STRLEN-1,buf2);
+ if (*(DWORD*)p == errstr)
+ {
+ exec_error++;
+ p[0]=0;
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_INIFILES
+#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
+ case EW_DELREG:
+ {
+ long res=!ERROR_SUCCESS;
+ const char *rkn UNUSED=RegKeyHandleToName((HKEY)parm1);
+ if (!parm4)
+ {
+ HKEY hKey=myRegOpenKey(KEY_SET_VALUE);
+ if (hKey)
+ {
+ char *buf3=GetStringFromParm(0x33);
+ res = RegDeleteValue(hKey,buf3);
+ log_printf4("DeleteRegValue: \"%s\\%s\" \"%s\"",rkn,buf2,buf3);
+ RegCloseKey(hKey);
+ }
+ }
+ else
+ {
+ char *buf2=GetStringFromParm(0x22);
+ log_printf3("DeleteRegKey: \"%s\\%s\"",rkn,buf2);
+ res = myRegDeleteKeyEx(GetRegRootKey(parm1),buf2,parm4&2);
+ }
+ if (res != ERROR_SUCCESS)
+ exec_error++;
+ }
+ break;
+ case EW_WRITEREG: // write registry value
+ {
+ HKEY hKey;
+ HKEY rootkey=GetRegRootKey(parm0);
+ int type=parm4;
+ int rtype=parm5;
+ char *buf0=GetStringFromParm(0x02);
+ char *buf1=GetStringFromParm(0x11);
+ const char *rkn UNUSED=RegKeyHandleToName(rootkey);
+
+ exec_error++;
+ if (RegCreateKeyEx(rootkey,buf1,0,0,0,AlterRegistrySAM(KEY_SET_VALUE),0,&hKey,0) == ERROR_SUCCESS)
+ {
+ LPBYTE data = (LPBYTE) buf2;
+ DWORD size = 0;
+ if (type == REG_SZ)
+ {
+ GetStringFromParm(0x23);
+ size = mystrlen((char *) data) + 1;
+ if (rtype == REG_SZ)
+ {
+ log_printf5("WriteRegStr: \"%s\\%s\" \"%s\"=\"%s\"",rkn,buf1,buf0,data);
+ }
+ else
+ {
+ log_printf5("WriteRegExpandStr: \"%s\\%s\" \"%s\"=\"%s\"",rkn,buf1,buf0,data);
+ }
+ }
+ if (type == REG_DWORD)
+ {
+ *(LPDWORD) data = GetIntFromParm(3);
+ size = sizeof(DWORD);
+ log_printf5("WriteRegDWORD: \"%s\\%s\" \"%s\"=\"0x%08x\"",rkn,buf1,buf0,*(LPDWORD) data);
+ }
+ if (type == REG_BINARY)
+ {
+#ifdef NSIS_CONFIG_LOG
+ char binbuf[128];
+#endif
+ // use buf2, buf3 and buf4
+ size = GetCompressedDataFromDataBlockToMemory(parm3, data, 3 * NSIS_MAX_STRLEN);
+ LogData2Hex(binbuf, sizeof(binbuf), data, size);
+ log_printf5("WriteRegBin: \"%s\\%s\" \"%s\"=\"%s\"",rkn,buf1,buf0,binbuf);
+ }
+
+ if (size >= 0 && RegSetValueEx(hKey,buf0,0,rtype,data,size) == ERROR_SUCCESS)
+ {
+ exec_error--;
+ }
+ else
+ {
+ log_printf4("WriteReg: error writing into \"%s\\%s\" \"%s\"",rkn,buf1,buf0);
+ }
+
+ RegCloseKey(hKey);
+ }
+ else { log_printf3("WriteReg: error creating key \"%s\\%s\"",rkn,buf1); }
+ }
+ break;
+ case EW_READREGSTR: // read registry string
+ {
+ HKEY hKey=myRegOpenKey(KEY_READ);
+ char *p=var0;
+ char *buf3=GetStringFromParm(0x33); // buf3 == key name
+ p[0]=0;
+ if (hKey)
+ {
+ DWORD l = NSIS_MAX_STRLEN - 1;
+ DWORD t;
+
+ if (RegQueryValueEx(hKey,buf3,NULL,&t,p,&l) != ERROR_SUCCESS ||
+ (t != REG_DWORD && t != REG_SZ && t != REG_EXPAND_SZ))
+ {
+ p[0]=0;
+ exec_error++;
+ }
+ else
+ {
+ if (t==REG_DWORD)
+ {
+ exec_error += !parm4;
+ myitoa(p,*((DWORD*)p));
+ }
+ else
+ {
+ exec_error += parm4;
+ p[l]=0;
+ }
+ }
+ RegCloseKey(hKey);
+ }
+ else exec_error++;
+ }
+ break;
+ case EW_REGENUM:
+ {
+ HKEY key=myRegOpenKey(KEY_READ);
+ char *p=var0;
+ int b=GetIntFromParm(3);
+ p[0]=0;
+ if (key)
+ {
+ DWORD d=NSIS_MAX_STRLEN-1;
+ if (parm4) RegEnumKey(key,b,p,d);
+ else if (RegEnumValue(key,b,p,&d,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS)
+ {
+ exec_error++;
+ break;
+ }
+ p[NSIS_MAX_STRLEN-1]=0;
+ RegCloseKey(key);
+ }
+ else exec_error++;
+ }
+
+ break;
+#endif//NSIS_SUPPORT_REGISTRYFUNCTIONS
+#ifdef NSIS_SUPPORT_FILEFUNCTIONS
+ case EW_FCLOSE:
+ {
+ char *t=var0;
+ if (*t) CloseHandle((HANDLE)myatoi(t));
+ }
+ break;
+ case EW_FOPEN:
+ {
+ HANDLE h;
+ char *handleout=var0;
+ char *buf1=GetStringFromParm(-0x13);
+ h=myOpenFile(buf1,parm1,parm2);
+ if (h == INVALID_HANDLE_VALUE)
+ {
+ *handleout=0;
+ exec_error++;
+ }
+ else
+ {
+ myitoa(handleout,(int)h);
+ }
+ }
+ break;
+ case EW_FPUTS:
+ {
+ DWORD dw;
+ int l;
+ char *t=var0;
+ if (parm2)
+ {
+ ((unsigned char *)buf1)[0]=GetIntFromParm(1)&0xff;
+ l=1;
+ }
+ else
+ {
+ l=mystrlen(GetStringFromParm(0x11));
+ }
+ if (!*t || !WriteFile((HANDLE)myatoi(t),buf1,l,&dw,NULL))
+ {
+ exec_error++;
+ }
+ }
+ break;
+ case EW_FGETS:
+ {
+ char *textout=var1;
+ DWORD dw;
+ int rpos=0;
+ char *hptr=var0;
+ int maxlen=GetIntFromParm(2);
+ if (maxlen<1) break;
+ if (maxlen > NSIS_MAX_STRLEN-1) maxlen=NSIS_MAX_STRLEN-1;
+ if (*hptr)
+ {
+ char lc=0;
+ HANDLE h=(HANDLE)myatoi(hptr);
+ while (rpos<maxlen)
+ {
+ char c;
+ if (!ReadFile(h,&c,1,&dw,NULL) || dw != 1) break;
+ if (parm3)
+ {
+ myitoa(textout,(unsigned int)(unsigned char)c);
+ return 0;
+ }
+ if (lc == '\r' || lc == '\n')
+ {
+ if (lc == c || (c != '\r' && c != '\n')) SetFilePointer(h,-1,NULL,FILE_CURRENT);
+ else textout[rpos++]=c;
+ break;
+ }
+ textout[rpos++]=c;
+ lc=c;
+ if (!c) break;
+ }
+ }
+ textout[rpos]=0;
+ if (!rpos) exec_error++;
+ }
+ break;
+ case EW_FSEEK:
+ {
+ char *t=var0;
+ if (*t)
+ {
+ DWORD v=SetFilePointer((HANDLE)myatoi(t),GetIntFromParm(2),NULL,parm3);
+
+ if (parm1>=0)
+ {
+ myitoa(var1,v);
+ }
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_FILEFUNCTIONS
+#ifdef NSIS_SUPPORT_FINDFIRST
+ case EW_FINDCLOSE:
+ {
+ char *t=var0;
+ if (*t) FindClose((HANDLE)myatoi(t));
+ }
+ break;
+ case EW_FINDNEXT:
+ {
+ char *textout=var0;
+ char *t=var1;
+ WIN32_FIND_DATA fd;
+ if (*t && FindNextFile((HANDLE)myatoi(t),&fd))
+ {
+ mystrcpy(textout,fd.cFileName);
+ }
+ else
+ {
+ exec_error++;
+ *textout=0;
+ }
+
+ }
+ break;
+ case EW_FINDFIRST:
+ {
+ char *textout=var0;
+ char *handleout=var1;
+ HANDLE h;
+ WIN32_FIND_DATA fd;
+ char *buf0=GetStringFromParm(0x02);
+ h=FindFirstFile(buf0,&fd);
+ if (h == INVALID_HANDLE_VALUE)
+ {
+ *handleout=0;
+ *textout=0;
+ exec_error++;
+ }
+ else
+ {
+ myitoa(handleout,(int)h);
+ mystrcpy(textout,fd.cFileName);
+ }
+ }
+ break;
+#endif//NSIS_SUPPORT_FINDFIRST
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ case EW_WRITEUNINSTALLER:
+ {
+ int ret=-666;
+ HANDLE hFile;
+ char *buf1=GetStringFromParm(-0x10);
+
+ if (!validpathspec(buf1))
+ GetStringFromParm(-0x13);
+
+ remove_ro_attr(buf1);
+ hFile=myOpenFile(buf1,GENERIC_WRITE,CREATE_ALWAYS);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ unsigned char *filebuf;
+ int filehdrsize = g_filehdrsize;
+ filebuf=(unsigned char *)GlobalAlloc(GPTR,filehdrsize);
+ if (filebuf)
+ {
+ DWORD lout;
+ SetSelfFilePointer(0);
+ ReadSelfFile((char*)filebuf,filehdrsize);
+ {
+ unsigned char* seeker;
+ unsigned char* unicon_data = seeker = (unsigned char*)GlobalAlloc(GPTR,parm2);
+ if (unicon_data) {
+ GetCompressedDataFromDataBlockToMemory(parm1,unicon_data,parm2);
+ while (*seeker) {
+ struct icondata {
+ DWORD dwSize;
+ DWORD dwOffset;
+ } id = *(struct icondata *) seeker;
+ seeker += sizeof(struct icondata);
+ mini_memcpy(filebuf+id.dwOffset, seeker, id.dwSize);
+ seeker += id.dwSize;
+ }
+ GlobalFree(unicon_data);
+ }
+ }
+ WriteFile(hFile,(char*)filebuf,filehdrsize,&lout,NULL);
+ GlobalFree(filebuf);
+ ret=GetCompressedDataFromDataBlock(-1,hFile);
+ }
+ CloseHandle(hFile);
+ }
+ log_printf3("created uninstaller: %d, \"%s\"",ret,buf1);
+ {
+ int str = LANG_CREATEDUNINST;
+ if (ret < 0)
+ {
+ str = LANG_ERRORCREATING;
+ DeleteFile(buf1);
+ exec_error++;
+ }
+ update_status_text_buf1(str);
+ }
+ }
+ break;
+#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
+#ifdef NSIS_CONFIG_LOG
+ case EW_LOG:
+ if (parm0)
+ {
+ log_printf2("settings logging to %d",parm1);
+ log_dolog=parm1;
+ log_printf2("logging set to %d",parm1);
+#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
+ if (parm1) build_g_logfile();
+#endif
+ }
+ else
+ {
+ char *buf0=GetStringFromParm(0x01);
+ log_printf2("%s",buf0);
+ }
+ break;
+#endif//NSIS_CONFIG_LOG
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ case EW_SECTIONSET:
+ {
+ int x=GetIntFromParm(0);
+ if ((unsigned int)x < (unsigned int)num_sections)
+ {
+ section *sec=g_sections+x;
+ if (parm2>=0) // get something
+ {
+ int res=((int*)sec)[parm2];
+ if (!parm2)
+ {
+ // getting text
+ mystrcpy(var1,sec->name);
+ }
+ else
+ {
+ // getting number
+ myitoa(var1,res);
+ }
+ }
+ else // set something
+ {
+ parm2=-parm2-1;
+ if (parm2)
+ {
+ // not setting text, get int
+ parm1=GetIntFromParm(1);
+ }
+ else
+ {
+ // setting text
+ GetNSISString(sec->name,parm4);
+ sec->flags|=SF_NAMECHG;
+ // parm1 is zero so name_ptr will be set to zero
+ // if name_ptr is zero, it won't be used after .onInit
+ }
+
+ ((int*)sec)[parm2]=parm1;
+
+ if (parm3) // update flags
+ {
+ SectionFlagsChanged(x);
+ }
+ }
+ }
+ else exec_error++;
+ }
+ break;
+ case EW_INSTTYPESET:
+ {
+ int x = GetIntFromParm(0);
+
+ if ((unsigned int)x < (unsigned int)NSIS_MAX_INST_TYPES)
+ {
+ if (parm3) // current install type
+ {
+ if (parm2) // set install type
+ {
+ SetInstType(x);
+ RefreshSectionGroups();
+ }
+ else // get install type
+ {
+ myitoa(var1, GetInstType(0));
+ }
+ }
+ else // install type text
+ {
+ if (parm2) // set text
+ {
+ g_header->install_types[x] = parm1;
+ }
+ else // get text
+ {
+ GetNSISString(var1,g_header->install_types[x]);
+ }
+ }
+ }
+ else exec_error++;
+ }
+ break;
+#endif//NSIS_CONFIG_COMPONENTPAGE
+
+#ifdef NSIS_LOCKWINDOW_SUPPORT
+ case EW_LOCKWINDOW:
+ {
+ // ui_dlg_visible is 1 or 0, so is parm0
+ SendMessage(g_hwnd, WM_SETREDRAW, parm0 & ui_dlg_visible, 0);
+ if ( parm0 )
+ InvalidateRect(g_hwnd, NULL, FALSE);
+ break;
+ }
+#endif //NSIS_LOCKWINDOW_SUPPORT
+ }
+
+ g_exec_flags.exec_error += exec_error;
+
+ return 0;
+}
diff --git a/Source/exehead/exec.h b/Source/exehead/exec.h
index b49b91d..6af6603 100755
--- a/Source/exehead/exec.h
+++ b/Source/exehead/exec.h
@@ -1,26 +1,26 @@
-/*
- * exec.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef _EXEC_H_
-#define _EXEC_H_
-
-extern exec_flags g_exec_flags;
-extern exec_flags g_exec_flags_last_used;
-
-int NSISCALL ExecuteCodeSegment(int pos, HWND hwndProgress); // returns 0 on success
-int NSISCALL ExecuteCallbackFunction(int num); // returns 0 on success
-
-#endif//_EXEC_H_
+/*
+ * exec.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef _EXEC_H_
+#define _EXEC_H_
+
+extern exec_flags g_exec_flags;
+extern exec_flags g_exec_flags_last_used;
+
+int NSISCALL ExecuteCodeSegment(int pos, HWND hwndProgress); // returns 0 on success
+int NSISCALL ExecuteCallbackFunction(int num); // returns 0 on success
+
+#endif//_EXEC_H_
diff --git a/Source/exehead/fileform.c b/Source/exehead/fileform.c
index 43f7706..cb2618f 100755
--- a/Source/exehead/fileform.c
+++ b/Source/exehead/fileform.c
@@ -1,564 +1,576 @@
-/*
- * fileform.c
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "../Platform.h"
-#include "fileform.h"
-#include "util.h"
-#include "state.h"
-#include "resource.h"
-#include "lang.h"
-#include "ui.h"
-#include "exec.h"
-#include "../crc32.h"
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
-#ifdef NSIS_COMPRESS_USE_ZLIB
-#include "../zlib/ZLIB.H"
-#endif
-
-#ifdef NSIS_COMPRESS_USE_LZMA
-#include "../7zip/LZMADecode.h"
-#define z_stream lzma_stream
-#define inflateInit(x) lzmaInit(x)
-#define inflateReset(x) lzmaInit(x)
-#define inflate(x) lzmaDecode(x)
-#define Z_OK LZMA_OK
-#define Z_STREAM_END LZMA_STREAM_END
-#endif
-
-#ifdef NSIS_COMPRESS_USE_BZIP2
-#include "../bzip2/bzlib.h"
-
-#define z_stream DState
-#define inflateInit(x) BZ2_bzDecompressInit(x)
-#define inflateReset(x) BZ2_bzDecompressInit(x)
-
-#define inflate(x) BZ2_bzDecompress(x)
-#define Z_OK BZ_OK
-#define Z_STREAM_END BZ_STREAM_END
-#endif//NSIS_COMPRESS_USE_BZIP2
-#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
-
-struct block_header g_blocks[BLOCKS_NUM];
-header *g_header;
-int g_flags;
-int g_filehdrsize;
-int g_is_uninstaller;
-
-HANDLE g_db_hFile=INVALID_HANDLE_VALUE;
-
-#if defined(NSIS_CONFIG_COMPRESSION_SUPPORT) && defined(NSIS_COMPRESS_WHOLE)
-HANDLE dbd_hFile=INVALID_HANDLE_VALUE;
-static int dbd_size, dbd_pos, dbd_srcpos, dbd_fulllen;
-#endif//NSIS_COMPRESS_WHOLE
-
-static int m_length;
-static int m_pos;
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-#if defined(NSIS_CONFIG_CRC_SUPPORT) || defined(NSIS_COMPRESS_WHOLE)
-BOOL CALLBACK verProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- static char *msg;
- if (uMsg == WM_INITDIALOG)
- {
- SetTimer(hwndDlg,1,250,NULL);
- msg = (char *) lParam;
- uMsg = WM_TIMER;
- }
- if (uMsg == WM_TIMER)
- {
- static char bt[64];
- int percent=MulDiv(min(m_pos,m_length),100,m_length);
-#ifdef NSIS_COMPRESS_WHOLE
- if (msg)
-#endif
- {
- wsprintf(bt,msg,percent);
-
- my_SetWindowText(hwndDlg,bt);
- my_SetDialogItemText(hwndDlg,IDC_STR,bt);
-
- ShowWindow(hwndDlg, SW_SHOW);
- }
-
-#ifdef NSIS_COMPRESS_WHOLE
- if (g_exec_flags.status_update & 1)
- {
- wsprintf(bt, "... %d%%", percent);
- update_status_text(0, bt);
- }
-#endif
- }
- return 0;
-}
-#endif//NSIS_CONFIG_CRC_SUPPORT || NSIS_COMPRESS_WHOLE
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
-static z_stream g_inflate_stream;
-#endif
-
-const char * NSISCALL loadHeaders(int cl_flags)
-{
-#ifdef NSIS_CONFIG_CRC_SUPPORT
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- HWND hwnd = 0;
- unsigned int verify_time = GetTickCount() + 1000;
-#endif
- crc32_t crc = 0;
- int do_crc = 0;
-#endif//NSIS_CONFIG_CRC_SUPPORT
- int left;
-
- void *data;
- firstheader h;
- header *header;
-
- HANDLE db_hFile;
-
- GetModuleFileName(NULL, state_exe_path, NSIS_MAX_STRLEN);
-
- g_db_hFile = db_hFile = myOpenFile(state_exe_path, GENERIC_READ, OPEN_EXISTING);
- if (db_hFile == INVALID_HANDLE_VALUE)
- {
- return _LANG_CANTOPENSELF;
- }
-
- mystrcpy(state_exe_directory, state_exe_path);
- mystrcpy(state_exe_file, trimslashtoend(state_exe_directory));
-
- left = m_length = GetFileSize(db_hFile,NULL);
- while (left > 0)
- {
- static char temp[32768];
- DWORD l = min(left, (g_filehdrsize ? 32768 : 512));
- if (!ReadSelfFile(temp, l))
- {
-#if defined(NSIS_CONFIG_CRC_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
- if (hwnd) DestroyWindow(hwnd);
-#endif//NSIS_CONFIG_CRC_SUPPORT
- return _LANG_INVALIDCRC;
- }
-
- if (!g_filehdrsize)
- {
- mini_memcpy(&h, temp, sizeof(firstheader));
- if (
- (h.flags & (~FH_FLAGS_MASK)) == 0 &&
- h.siginfo == FH_SIG &&
- h.nsinst[2] == FH_INT3 &&
- h.nsinst[1] == FH_INT2 &&
- h.nsinst[0] == FH_INT1
- )
- {
- g_filehdrsize = m_pos;
-
-#if defined(NSIS_CONFIG_CRC_SUPPORT) || defined(NSIS_CONFIG_SILENT_SUPPORT)
- cl_flags |= h.flags;
-#endif
-
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- g_exec_flags.silent |= cl_flags & FH_FLAGS_SILENT;
-#endif
-
- if (h.length_of_all_following_data > left)
- return _LANG_INVALIDCRC;
-
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- if ((cl_flags & FH_FLAGS_FORCE_CRC) == 0)
- {
- if (cl_flags & FH_FLAGS_NO_CRC)
- break;
- }
-
- do_crc++;
-
-#ifndef NSIS_CONFIG_CRC_ANAL
- left = h.length_of_all_following_data - 4;
- // end crc checking at crc :) this means you can tack shit on the end and it'll still work.
-#else //!NSIS_CONFIG_CRC_ANAL
- left -= 4;
-#endif//NSIS_CONFIG_CRC_ANAL
- // this is in case the end part is < 512 bytes.
- if (l > (DWORD)left) l=(DWORD)left;
-
-#else//!NSIS_CONFIG_CRC_SUPPORT
- // no crc support, no need to keep on reading
- break;
-#endif//!NSIS_CONFIG_CRC_SUPPORT
- }
- }
-#ifdef NSIS_CONFIG_CRC_SUPPORT
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- else if ((cl_flags & FH_FLAGS_SILENT) == 0)
-#endif//NSIS_CONFIG_SILENT_SUPPORT
- {
- if (hwnd)
- {
- MessageLoop(0);
- }
- else if (GetTickCount() > verify_time)
- hwnd = CreateDialogParam(
- g_hInstance,
- MAKEINTRESOURCE(IDD_VERIFY),
- 0,
- verProc,
- (LPARAM)_LANG_VERIFYINGINST
- );
- }
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
-
-#ifndef NSIS_CONFIG_CRC_ANAL
- if (left < m_length)
-#endif//NSIS_CONFIG_CRC_ANAL
- crc = CRC32(crc, temp, l);
-
-#endif//NSIS_CONFIG_CRC_SUPPORT
- m_pos += l;
- left -= l;
- }
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- if (hwnd)
- {
- DestroyWindow(hwnd);
- }
-#endif//NSIS_CONFIG_CRC_SUPPORT
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
- if (!g_filehdrsize)
- return _LANG_INVALIDCRC;
-
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- if (do_crc)
- {
- crc32_t fcrc;
- SetSelfFilePointer(m_pos);
- if (!ReadSelfFile(&fcrc, sizeof(crc32_t)) || crc != fcrc)
- return _LANG_INVALIDCRC;
- }
-#endif//NSIS_CONFIG_CRC_SUPPORT
-
- data = (void *)GlobalAlloc(GPTR,h.length_of_header);
-
-#ifdef NSIS_COMPRESS_WHOLE
- inflateReset(&g_inflate_stream);
-
- {
- char fno[MAX_PATH];
- my_GetTempFileName(fno, state_temp_dir);
- dbd_hFile=CreateFile(fno,GENERIC_WRITE|GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,NULL);
- if (dbd_hFile == INVALID_HANDLE_VALUE)
- return _LANG_ERRORWRITINGTEMP;
- }
- dbd_srcpos = SetSelfFilePointer(g_filehdrsize + sizeof(firstheader));
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data - ((h.flags & FH_FLAGS_NO_CRC) ? 0 : sizeof(crc32_t));
-#else
- dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data;
-#endif//NSIS_CONFIG_CRC_SUPPORT
-#else
- SetSelfFilePointer(g_filehdrsize + sizeof(firstheader));
-#endif//NSIS_COMPRESS_WHOLE
-
- if (GetCompressedDataFromDataBlockToMemory(-1, data, h.length_of_header) != h.length_of_header)
- {
- return _LANG_INVALIDCRC;
- }
-
- header = g_header = data;
-
- g_flags = header->flags;
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (h.flags & FH_FLAGS_UNINSTALL)
- g_is_uninstaller++;
-#endif
-
- // set offsets to real memory offsets rather than installer's header offset
- left = BLOCKS_NUM;
- while (left--)
- header->blocks[left].offset += (int)data;
-
-#ifdef NSIS_COMPRESS_WHOLE
- header->blocks[NB_DATA].offset = dbd_pos;
-#else
- header->blocks[NB_DATA].offset = SetFilePointer(db_hFile,0,NULL,FILE_CURRENT);
-#endif
-
- mini_memcpy(&g_blocks, &header->blocks, sizeof(g_blocks));
-
- return 0;
-}
-
-#define IBUFSIZE 16384
-#define OBUFSIZE 32768
-
-// returns -3 if compression error/eof/etc
-
-#if !defined(NSIS_COMPRESS_WHOLE) || !defined(NSIS_CONFIG_COMPRESSION_SUPPORT)
-
-int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen)
-{
- static char inbuffer[IBUFSIZE+OBUFSIZE];
- char *outbuffer;
- int outbuffer_len=outbuf?outbuflen:OBUFSIZE;
- int retval=0;
- int input_len;
-
- outbuffer = outbuf?outbuf:(inbuffer+IBUFSIZE);
-
- if (offset>=0)
- {
- SetSelfFilePointer(g_blocks[NB_DATA].offset+offset);
- }
-
- if (!ReadSelfFile((LPVOID)&input_len,sizeof(int))) return -3;
-
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- if (input_len & 0x80000000) // compressed
- {
- char progress[64];
- int input_len_total;
- DWORD ltc = GetTickCount(), tc;
-
- inflateReset(&g_inflate_stream);
- input_len_total = input_len &= 0x7fffffff; // take off top bit.
-
- while (input_len > 0)
- {
- int l=min(input_len,IBUFSIZE);
- int err;
-
- if (!ReadSelfFile((LPVOID)inbuffer,l))
- return -3;
-
- g_inflate_stream.next_in = inbuffer;
- g_inflate_stream.avail_in = l;
- input_len-=l;
-
- for (;;)
- {
- int u;
-
- g_inflate_stream.next_out = outbuffer;
- g_inflate_stream.avail_out = (unsigned int)outbuffer_len;
-
- err=inflate(&g_inflate_stream);
-
- if (err<0) return -4;
-
- u=(char*)g_inflate_stream.next_out - outbuffer;
-
- tc = GetTickCount();
- if (g_exec_flags.status_update & 1 && (tc - ltc > 200 || !input_len))
- {
- wsprintf(progress, "... %d%%", MulDiv(input_len_total - input_len, 100, input_len_total));
- update_status_text(0, progress);
- ltc = tc;
- }
-
- // if there's no output, more input is needed
- if (!u)
- break;
-
- if (!outbuf)
- {
- DWORD r;
- if (!WriteFile(hFileOut,outbuffer,u,&r,NULL) || (int)r != u) return -2;
- retval+=u;
- }
- else
- {
- retval+=u;
- outbuffer_len-=u;
- outbuffer=g_inflate_stream.next_out;
- if (outbuffer_len < 1) return retval;
- }
- if (err==Z_STREAM_END) return retval;
- }
- }
- }
- else
-#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
- {
- if (!outbuf)
- {
- while (input_len > 0)
- {
- DWORD l=min(input_len,outbuffer_len);
- DWORD t;
- if (!ReadSelfFile((LPVOID)inbuffer,l)) return -3;
- if (!WriteFile(hFileOut,inbuffer,l,&t,NULL) || l!=t) return -2;
- retval+=l;
- input_len-=l;
- }
- }
- else
- {
- int l=min(input_len,outbuflen);
- if (!ReadSelfFile((LPVOID)outbuf,l)) return -3;
- retval=l;
- }
- }
- return retval;
-}
-#else//NSIS_COMPRESS_WHOLE
-
-static char _inbuffer[IBUFSIZE];
-static char _outbuffer[OBUFSIZE];
-extern int m_length;
-extern int m_pos;
-extern BOOL CALLBACK verProc(HWND, UINT, WPARAM, LPARAM);
-extern BOOL CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
-static int NSISCALL __ensuredata(int amount)
-{
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- HWND hwnd=NULL;
- unsigned int verify_time=GetTickCount()+500;
-#endif
- int needed=amount-(dbd_size-dbd_pos);
- if (needed>0)
- {
- SetSelfFilePointer(dbd_srcpos);
- SetFilePointer(dbd_hFile,dbd_size,NULL,FILE_BEGIN);
- m_length=needed;
- m_pos=0;
- for (;;)
- {
- int err;
- int l=min(IBUFSIZE,dbd_fulllen-dbd_srcpos);
- if (!ReadSelfFile((LPVOID)_inbuffer,l)) return -1;
- dbd_srcpos+=l;
- g_inflate_stream.next_in=_inbuffer;
- g_inflate_stream.avail_in=l;
- do
- {
- DWORD r,t;
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- if (g_header)
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- if (!g_exec_flags.silent)
-#endif
- {
- if (hwnd)
- {
- m_pos=m_length-(amount-(dbd_size-dbd_pos));
- MessageLoop(0);
- }
- else if (GetTickCount() > verify_time)
- {
- hwnd = CreateDialogParam(
- g_hInstance,
- MAKEINTRESOURCE(IDD_VERIFY),
- 0,
- verProc,
- g_hwnd ? 0 : (LPARAM)_LANG_UNPACKING
- );
- }
- }
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
- g_inflate_stream.next_out=_outbuffer;
- g_inflate_stream.avail_out=OBUFSIZE;
- err=inflate(&g_inflate_stream);
- if (err<0)
- {
- return -3;
- }
- r=(DWORD)g_inflate_stream.next_out-(DWORD)_outbuffer;
- if (r)
- {
- if (!WriteFile(dbd_hFile,_outbuffer,r,&t,NULL) || r != t)
- {
- return -2;
- }
- dbd_size+=r;
- }
- else if (g_inflate_stream.avail_in || !l) return -3;
- else break;
- }
- while (g_inflate_stream.avail_in);
- if (amount-(dbd_size-dbd_pos) <= 0) break;
- }
- SetFilePointer(dbd_hFile,dbd_pos,NULL,FILE_BEGIN);
- }
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- if (hwnd)
- {
- m_pos=m_length;
- SendMessage(hwnd,WM_TIMER,0,0);
- DestroyWindow(hwnd);
- }
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
- return 0;
-}
-
-
-int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen)
-{
- DWORD r;
- int input_len;
- int retval;
- if (offset>=0)
- {
- dbd_pos=g_blocks[NB_DATA].offset+offset;
- SetFilePointer(dbd_hFile,dbd_pos,NULL,FILE_BEGIN);
- }
- retval=__ensuredata(sizeof(int));
- if (retval<0) return retval;
-
- if (!ReadFile(dbd_hFile,(LPVOID)&input_len,sizeof(int),&r,NULL) || r!=sizeof(int)) return -3;
- dbd_pos+=sizeof(int);
-
- retval=__ensuredata(input_len);
- if (retval < 0) return retval;
-
- if (!outbuf)
- {
- while (input_len > 0)
- {
- DWORD t;
- DWORD l=min(input_len,IBUFSIZE);
- if (!ReadFile(dbd_hFile,(LPVOID)_inbuffer,l,&r,NULL) || l != r) return -3;
- if (!WriteFile(hFileOut,_inbuffer,r,&t,NULL) || t != l) return -2;
- retval+=r;
- input_len-=r;
- dbd_pos+=r;
- }
- }
- else
- {
- if (!ReadFile(dbd_hFile,(LPVOID)outbuf,min(input_len,outbuflen),&r,NULL)) return -3;
- retval=r;
- dbd_pos+=r;
- }
- return retval;
-}
-#endif//NSIS_COMPRESS_WHOLE
-
-BOOL NSISCALL ReadSelfFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead)
-{
- DWORD rd;
- return ReadFile(g_db_hFile,lpBuffer,nNumberOfBytesToRead,&rd,NULL) && (rd == nNumberOfBytesToRead);
-}
-
-DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove)
-{
- return SetFilePointer(g_db_hFile,lDistanceToMove,NULL,FILE_BEGIN);
-}
+/*
+ * fileform.c
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "../Platform.h"
+#include "fileform.h"
+#include "util.h"
+#include "state.h"
+#include "resource.h"
+#include "lang.h"
+#include "ui.h"
+#include "exec.h"
+#include "../crc32.h"
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+#ifdef NSIS_COMPRESS_USE_ZLIB
+#include "../zlib/ZLIB.H"
+#endif
+
+#ifdef NSIS_COMPRESS_USE_LZMA
+#include "../7zip/LZMADecode.h"
+#define z_stream lzma_stream
+#define inflateInit(x) lzmaInit(x)
+#define inflateReset(x) lzmaInit(x)
+#define inflate(x) lzmaDecode(x)
+#define Z_OK LZMA_OK
+#define Z_STREAM_END LZMA_STREAM_END
+#endif
+
+#ifdef NSIS_COMPRESS_USE_BZIP2
+#include "../bzip2/bzlib.h"
+
+#define z_stream DState
+#define inflateInit(x) BZ2_bzDecompressInit(x)
+#define inflateReset(x) BZ2_bzDecompressInit(x)
+
+#define inflate(x) BZ2_bzDecompress(x)
+#define Z_OK BZ_OK
+#define Z_STREAM_END BZ_STREAM_END
+#endif//NSIS_COMPRESS_USE_BZIP2
+#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
+
+struct block_header g_blocks[BLOCKS_NUM];
+header *g_header;
+int g_flags;
+int g_filehdrsize;
+int g_is_uninstaller;
+
+HANDLE g_db_hFile=INVALID_HANDLE_VALUE;
+
+#if defined(NSIS_CONFIG_COMPRESSION_SUPPORT) && defined(NSIS_COMPRESS_WHOLE)
+HANDLE dbd_hFile=INVALID_HANDLE_VALUE;
+static int dbd_size, dbd_pos, dbd_srcpos, dbd_fulllen;
+#endif//NSIS_COMPRESS_WHOLE
+
+static int m_length;
+static int m_pos;
+
+#define _calc_percent() (MulDiv(min(m_pos,m_length),100,m_length))
+#ifdef NSIS_COMPRESS_WHOLE
+static int NSISCALL calc_percent()
+{
+ return _calc_percent();
+}
+#else
+#define calc_percent() _calc_percent()
+#endif
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+#if defined(NSIS_CONFIG_CRC_SUPPORT) || defined(NSIS_COMPRESS_WHOLE)
+BOOL CALLBACK verProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg == WM_INITDIALOG)
+ {
+ SetTimer(hwndDlg,1,250,NULL);
+ uMsg = WM_TIMER;
+ }
+ if (uMsg == WM_TIMER)
+ {
+ char bt[64];
+ int percent=calc_percent();
+#ifdef NSIS_COMPRESS_WHOLE
+ char *msg=g_header?_LANG_UNPACKING:_LANG_VERIFYINGINST;
+#else
+ char *msg=_LANG_VERIFYINGINST;
+#endif
+
+ wsprintf(bt,msg,percent);
+
+ my_SetWindowText(hwndDlg,bt);
+ my_SetDialogItemText(hwndDlg,IDC_STR,bt);
+ }
+ return 0;
+}
+
+DWORD verify_time;
+
+void handle_ver_dlg(BOOL kill)
+{
+ static HWND hwnd;
+
+ if (kill)
+ {
+ if (hwnd) DestroyWindow(hwnd);
+ hwnd = NULL;
+
+ return;
+ }
+
+ if (hwnd)
+ {
+ MessageLoop(0);
+ }
+ else if (GetTickCount() > verify_time)
+ {
+#ifdef NSIS_COMPRESS_WHOLE
+ if (g_hwnd)
+ {
+ if (g_exec_flags.status_update & 1)
+ {
+ char bt[64];
+ wsprintf(bt, "... %d%%", calc_percent());
+ update_status_text(0, bt);
+ }
+ }
+ else
+#endif
+ {
+ hwnd = CreateDialog(
+ g_hInstance,
+ MAKEINTRESOURCE(IDD_VERIFY),
+ 0,
+ verProc
+ );
+ }
+ }
+}
+#endif//NSIS_CONFIG_CRC_SUPPORT || NSIS_COMPRESS_WHOLE
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+static z_stream g_inflate_stream;
+#endif
+
+const char * NSISCALL loadHeaders(int cl_flags)
+{
+ int left;
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ crc32_t crc = 0;
+ int do_crc = 0;
+#endif//NSIS_CONFIG_CRC_SUPPORT
+
+ void *data;
+ firstheader h;
+ header *header;
+
+ HANDLE db_hFile;
+
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ verify_time = GetTickCount() + 1000;
+#endif
+#endif//NSIS_CONFIG_CRC_SUPPORT
+
+ GetModuleFileName(NULL, state_exe_path, NSIS_MAX_STRLEN);
+
+ g_db_hFile = db_hFile = myOpenFile(state_exe_path, GENERIC_READ, OPEN_EXISTING);
+ if (db_hFile == INVALID_HANDLE_VALUE)
+ {
+ return _LANG_CANTOPENSELF;
+ }
+
+ mystrcpy(state_exe_directory, state_exe_path);
+ mystrcpy(state_exe_file, trimslashtoend(state_exe_directory));
+
+ left = m_length = GetFileSize(db_hFile,NULL);
+ while (left > 0)
+ {
+ static char temp[32768];
+ DWORD l = min(left, (g_filehdrsize ? 32768 : 512));
+ if (!ReadSelfFile(temp, l))
+ {
+#if defined(NSIS_CONFIG_CRC_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
+ handle_ver_dlg(TRUE);
+#endif//NSIS_CONFIG_CRC_SUPPORT
+ return _LANG_INVALIDCRC;
+ }
+
+ if (!g_filehdrsize)
+ {
+ mini_memcpy(&h, temp, sizeof(firstheader));
+ if (
+ (h.flags & (~FH_FLAGS_MASK)) == 0 &&
+ h.siginfo == FH_SIG &&
+ h.nsinst[2] == FH_INT3 &&
+ h.nsinst[1] == FH_INT2 &&
+ h.nsinst[0] == FH_INT1
+ )
+ {
+ g_filehdrsize = m_pos;
+
+#if defined(NSIS_CONFIG_CRC_SUPPORT) || defined(NSIS_CONFIG_SILENT_SUPPORT)
+ cl_flags |= h.flags;
+#endif
+
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ g_exec_flags.silent |= cl_flags & FH_FLAGS_SILENT;
+#endif
+
+ if (h.length_of_all_following_data > left)
+ return _LANG_INVALIDCRC;
+
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ if ((cl_flags & FH_FLAGS_FORCE_CRC) == 0)
+ {
+ if (cl_flags & FH_FLAGS_NO_CRC)
+ break;
+ }
+
+ do_crc++;
+
+#ifndef NSIS_CONFIG_CRC_ANAL
+ left = h.length_of_all_following_data - 4;
+ // end crc checking at crc :) this means you can tack shit on the end and it'll still work.
+#else //!NSIS_CONFIG_CRC_ANAL
+ left -= 4;
+#endif//NSIS_CONFIG_CRC_ANAL
+ // this is in case the end part is < 512 bytes.
+ if (l > (DWORD)left) l=(DWORD)left;
+
+#else//!NSIS_CONFIG_CRC_SUPPORT
+ // no crc support, no need to keep on reading
+ break;
+#endif//!NSIS_CONFIG_CRC_SUPPORT
+ }
+ }
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ else if ((cl_flags & FH_FLAGS_SILENT) == 0)
+#endif//NSIS_CONFIG_SILENT_SUPPORT
+ {
+ handle_ver_dlg(FALSE);
+ }
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+
+#ifndef NSIS_CONFIG_CRC_ANAL
+ if (left < m_length)
+#endif//NSIS_CONFIG_CRC_ANAL
+ crc = CRC32(crc, temp, l);
+
+#endif//NSIS_CONFIG_CRC_SUPPORT
+ m_pos += l;
+ left -= l;
+ }
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ handle_ver_dlg(TRUE);
+#endif//NSIS_CONFIG_CRC_SUPPORT
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+ if (!g_filehdrsize)
+ return _LANG_INVALIDCRC;
+
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ if (do_crc)
+ {
+ crc32_t fcrc;
+ SetSelfFilePointer(m_pos);
+ if (!ReadSelfFile(&fcrc, sizeof(crc32_t)) || crc != fcrc)
+ return _LANG_INVALIDCRC;
+ }
+#endif//NSIS_CONFIG_CRC_SUPPORT
+
+ data = (void *)GlobalAlloc(GPTR,h.length_of_header);
+
+#ifdef NSIS_COMPRESS_WHOLE
+ inflateReset(&g_inflate_stream);
+
+ {
+ char fno[MAX_PATH];
+ my_GetTempFileName(fno, state_temp_dir);
+ dbd_hFile=CreateFile(fno,GENERIC_WRITE|GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,NULL);
+ if (dbd_hFile == INVALID_HANDLE_VALUE)
+ return _LANG_ERRORWRITINGTEMP;
+ }
+ dbd_srcpos = SetSelfFilePointer(g_filehdrsize + sizeof(firstheader));
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data - ((h.flags & FH_FLAGS_NO_CRC) ? 0 : sizeof(crc32_t));
+#else
+ dbd_fulllen = dbd_srcpos - sizeof(h) + h.length_of_all_following_data;
+#endif//NSIS_CONFIG_CRC_SUPPORT
+#else
+ SetSelfFilePointer(g_filehdrsize + sizeof(firstheader));
+#endif//NSIS_COMPRESS_WHOLE
+
+ if (GetCompressedDataFromDataBlockToMemory(-1, data, h.length_of_header) != h.length_of_header)
+ {
+ return _LANG_INVALIDCRC;
+ }
+
+ header = g_header = data;
+
+ g_flags = header->flags;
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (h.flags & FH_FLAGS_UNINSTALL)
+ g_is_uninstaller++;
+#endif
+
+ // set offsets to real memory offsets rather than installer's header offset
+ left = BLOCKS_NUM;
+ while (left--)
+ header->blocks[left].offset += (int)data;
+
+#ifdef NSIS_COMPRESS_WHOLE
+ header->blocks[NB_DATA].offset = dbd_pos;
+#else
+ header->blocks[NB_DATA].offset = SetFilePointer(db_hFile,0,NULL,FILE_CURRENT);
+#endif
+
+ mini_memcpy(&g_blocks, &header->blocks, sizeof(g_blocks));
+
+ return 0;
+}
+
+#define IBUFSIZE 16384
+#define OBUFSIZE 32768
+
+// returns -3 if compression error/eof/etc
+
+#if !defined(NSIS_COMPRESS_WHOLE) || !defined(NSIS_CONFIG_COMPRESSION_SUPPORT)
+
+int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen)
+{
+ static char inbuffer[IBUFSIZE+OBUFSIZE];
+ char *outbuffer;
+ int outbuffer_len=outbuf?outbuflen:OBUFSIZE;
+ int retval=0;
+ int input_len;
+
+ outbuffer = outbuf?outbuf:(inbuffer+IBUFSIZE);
+
+ if (offset>=0)
+ {
+ SetSelfFilePointer(g_blocks[NB_DATA].offset+offset);
+ }
+
+ if (!ReadSelfFile((LPVOID)&input_len,sizeof(int))) return -3;
+
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ if (input_len & 0x80000000) // compressed
+ {
+ char progress[64];
+ int input_len_total;
+ DWORD ltc = GetTickCount(), tc;
+
+ inflateReset(&g_inflate_stream);
+ input_len_total = input_len &= 0x7fffffff; // take off top bit.
+
+ while (input_len > 0)
+ {
+ int l=min(input_len,IBUFSIZE);
+ int err;
+
+ if (!ReadSelfFile((LPVOID)inbuffer,l))
+ return -3;
+
+ g_inflate_stream.next_in = inbuffer;
+ g_inflate_stream.avail_in = l;
+ input_len-=l;
+
+ for (;;)
+ {
+ int u;
+
+ g_inflate_stream.next_out = outbuffer;
+ g_inflate_stream.avail_out = (unsigned int)outbuffer_len;
+
+ err=inflate(&g_inflate_stream);
+
+ if (err<0) return -4;
+
+ u=(char*)g_inflate_stream.next_out - outbuffer;
+
+ tc = GetTickCount();
+ if (g_exec_flags.status_update & 1 && (tc - ltc > 200 || !input_len))
+ {
+ wsprintf(progress, "... %d%%", MulDiv(input_len_total - input_len, 100, input_len_total));
+ update_status_text(0, progress);
+ ltc = tc;
+ }
+
+ // if there's no output, more input is needed
+ if (!u)
+ break;
+
+ if (!outbuf)
+ {
+ DWORD r;
+ if (!WriteFile(hFileOut,outbuffer,u,&r,NULL) || (int)r != u) return -2;
+ retval+=u;
+ }
+ else
+ {
+ retval+=u;
+ outbuffer_len-=u;
+ outbuffer=g_inflate_stream.next_out;
+ if (outbuffer_len < 1) return retval;
+ }
+ if (err==Z_STREAM_END) return retval;
+ }
+ }
+ }
+ else
+#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
+ {
+ if (!outbuf)
+ {
+ while (input_len > 0)
+ {
+ DWORD l=min(input_len,outbuffer_len);
+ DWORD t;
+ if (!ReadSelfFile((LPVOID)inbuffer,l)) return -3;
+ if (!WriteFile(hFileOut,inbuffer,l,&t,NULL) || l!=t) return -2;
+ retval+=l;
+ input_len-=l;
+ }
+ }
+ else
+ {
+ int l=min(input_len,outbuflen);
+ if (!ReadSelfFile((LPVOID)outbuf,l)) return -3;
+ retval=l;
+ }
+ }
+ return retval;
+}
+#else//NSIS_COMPRESS_WHOLE
+
+static char _inbuffer[IBUFSIZE];
+static char _outbuffer[OBUFSIZE];
+extern int m_length;
+extern int m_pos;
+extern BOOL CALLBACK verProc(HWND, UINT, WPARAM, LPARAM);
+extern BOOL CALLBACK DialogProc(HWND, UINT, WPARAM, LPARAM);
+static int NSISCALL __ensuredata(int amount)
+{
+ int needed=amount-(dbd_size-dbd_pos);
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ verify_time=GetTickCount()+500;
+#endif
+ if (needed>0)
+ {
+ SetSelfFilePointer(dbd_srcpos);
+ SetFilePointer(dbd_hFile,dbd_size,NULL,FILE_BEGIN);
+ m_length=needed;
+ m_pos=0;
+ for (;;)
+ {
+ int err;
+ int l=min(IBUFSIZE,dbd_fulllen-dbd_srcpos);
+ if (!ReadSelfFile((LPVOID)_inbuffer,l)) return -1;
+ dbd_srcpos+=l;
+ g_inflate_stream.next_in=_inbuffer;
+ g_inflate_stream.avail_in=l;
+ do
+ {
+ DWORD r,t;
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ if (g_header)
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ if (!g_exec_flags.silent)
+#endif
+ {
+ m_pos=m_length-(amount-(dbd_size-dbd_pos));
+
+ handle_ver_dlg(FALSE);
+ }
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+ g_inflate_stream.next_out=_outbuffer;
+ g_inflate_stream.avail_out=OBUFSIZE;
+ err=inflate(&g_inflate_stream);
+ if (err<0)
+ {
+ return -3;
+ }
+ r=(DWORD)g_inflate_stream.next_out-(DWORD)_outbuffer;
+ if (r)
+ {
+ if (!WriteFile(dbd_hFile,_outbuffer,r,&t,NULL) || r != t)
+ {
+ return -2;
+ }
+ dbd_size+=r;
+ }
+ else if (g_inflate_stream.avail_in || !l) return -3;
+ else break;
+ }
+ while (g_inflate_stream.avail_in);
+ if (amount-(dbd_size-dbd_pos) <= 0) break;
+ }
+ SetFilePointer(dbd_hFile,dbd_pos,NULL,FILE_BEGIN);
+ }
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ handle_ver_dlg(TRUE);
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+ return 0;
+}
+
+
+int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen)
+{
+ DWORD r;
+ int input_len;
+ int retval;
+ if (offset>=0)
+ {
+ dbd_pos=g_blocks[NB_DATA].offset+offset;
+ SetFilePointer(dbd_hFile,dbd_pos,NULL,FILE_BEGIN);
+ }
+ retval=__ensuredata(sizeof(int));
+ if (retval<0) return retval;
+
+ if (!ReadFile(dbd_hFile,(LPVOID)&input_len,sizeof(int),&r,NULL) || r!=sizeof(int)) return -3;
+ dbd_pos+=sizeof(int);
+
+ retval=__ensuredata(input_len);
+ if (retval < 0) return retval;
+
+ if (!outbuf)
+ {
+ while (input_len > 0)
+ {
+ DWORD t;
+ DWORD l=min(input_len,IBUFSIZE);
+ if (!ReadFile(dbd_hFile,(LPVOID)_inbuffer,l,&r,NULL) || l != r) return -3;
+ if (!WriteFile(hFileOut,_inbuffer,r,&t,NULL) || t != l) return -2;
+ retval+=r;
+ input_len-=r;
+ dbd_pos+=r;
+ }
+ }
+ else
+ {
+ if (!ReadFile(dbd_hFile,(LPVOID)outbuf,min(input_len,outbuflen),&r,NULL)) return -3;
+ retval=r;
+ dbd_pos+=r;
+ }
+ return retval;
+}
+#endif//NSIS_COMPRESS_WHOLE
+
+BOOL NSISCALL ReadSelfFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead)
+{
+ DWORD rd;
+ return ReadFile(g_db_hFile,lpBuffer,nNumberOfBytesToRead,&rd,NULL) && (rd == nNumberOfBytesToRead);
+}
+
+DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove)
+{
+ return SetFilePointer(g_db_hFile,lDistanceToMove,NULL,FILE_BEGIN);
+}
diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h
index 982be84..66391f9 100755
--- a/Source/exehead/fileform.h
+++ b/Source/exehead/fileform.h
@@ -1,553 +1,553 @@
-/*
- * fileform.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "config.h"
-#include "../Platform.h"
-
-#ifndef _FILEFORM_H_
-#define _FILEFORM_H_
-
-
-// * the installer is compsed of the following parts:
-// exehead (~34kb)
-// firstheader (struct firstheader)
-// * headers (compressed together):
-// header (struct header)
-// * nsis blocks (described in header->blocks)
-// pages (struct page)
-// section headers (struct section)
-// entries/instructions (struct entry)
-// strings (null seperated)
-// language tables (language id, dialog offset, language strings)
-// colors (struct color)
-// data block (files and uninstaller data)
-// * not compressed
-// CRC (optional - 4 bytes)
-//
-// headers + datablock is at least 512 bytes if CRC enabled
-
-
-#define MAX_ENTRY_OFFSETS 6
-
-
-// if you want people to not be able to decompile your installers as easily,
-// reorder the lines following EW_INVALID_OPCODE randomly.
-
-enum
-{
- EW_INVALID_OPCODE, // zero is invalid. useful for catching errors. (otherwise an all zeroes instruction
- // does nothing, which is easily ignored but means something is wrong.
- EW_RET, // return from function call
- EW_NOP, // Nop/Jump, do nothing: 1, [?new address+1:advance one]
- EW_ABORT, // Abort: 1 [status]
- EW_QUIT, // Quit: 0
- EW_CALL, // Call: 1 [new address+1]
- EW_UPDATETEXT, // Update status text: 2 [update str, ui_st_updateflag=?ui_st_updateflag:this]
- EW_SLEEP, // Sleep: 1 [sleep time in milliseconds]
- EW_BRINGTOFRONT, // BringToFront: 0
- EW_CHDETAILSVIEW, // SetDetailsView: 2 [listaction,buttonaction]
- EW_SETFILEATTRIBUTES, // SetFileAttributes: 2 [filename, attributes]
- EW_CREATEDIR, // Create directory: 2, [path, ?update$INSTDIR]
- EW_IFFILEEXISTS, // IfFileExists: 3, [file name, jump amount if exists, jump amount if not exists]
- EW_SETFLAG, // Sets a flag: 2 [id, data]
- EW_IFFLAG, // If a flag: 4 [on, off, id, new value mask]
- EW_GETFLAG, // Gets a flag: 2 [output, id]
-#ifdef NSIS_SUPPORT_RENAME
- EW_RENAME, // Rename: 3 [old, new, rebootok]
-#endif
-#ifdef NSIS_SUPPORT_FNUTIL
- EW_GETFULLPATHNAME, // GetFullPathName: 2 [output, input, ?lfn:sfn]
- EW_SEARCHPATH, // SearchPath: 2 [output, filename]
- EW_GETTEMPFILENAME, // GetTempFileName: 2 [output, base_dir]
-#endif
-#ifdef NSIS_SUPPORT_FILE
- EW_EXTRACTFILE, // File to extract: 6 [overwriteflag, output filename, compressed filedata, filedatetimelow, filedatetimehigh, allow ignore]
- // overwriteflag: 0x1 = no. 0x0=force, 0x2=try, 0x3=if date is newer
-#endif
-#ifdef NSIS_SUPPORT_DELETE
- EW_DELETEFILE, // Delete File: 2, [filename, rebootok]
-#endif
-#ifdef NSIS_SUPPORT_MESSAGEBOX
- EW_MESSAGEBOX, // MessageBox: 5,[MB_flags,text,retv1:retv2,moveonretv1:moveonretv2]
-#endif
-#ifdef NSIS_SUPPORT_RMDIR
- EW_RMDIR, // RMDir: 2 [path, recursiveflag]
-#endif
-#ifdef NSIS_SUPPORT_STROPTS
- EW_STRLEN, // StrLen: 2 [output, input]
- EW_ASSIGNVAR, // Assign: 4 [variable (0-9) to assign, string to assign, maxlen, startpos]
- EW_STRCMP, // StrCmp: 5 [str1, str2, jump_if_equal, jump_if_not_equal, case-sensitive?]
-#endif
-#ifdef NSIS_SUPPORT_ENVIRONMENT
- EW_READENVSTR, // ReadEnvStr/ExpandEnvStrings: 3 [output, string_with_env_variables, IsRead]
-#endif
-#ifdef NSIS_SUPPORT_INTOPTS
- EW_INTCMP, // IntCmp: 6 [val1, val2, equal, val1<val2, val1>val2, unsigned?]
- EW_INTOP, // IntOp: 4 [output, input1, input2, op] where op: 0=add, 1=sub, 2=mul, 3=div, 4=bor, 5=band, 6=bxor, 7=bnot input1, 8=lnot input1, 9=lor, 10=land], 11=1%2
- EW_INTFMT, // IntFmt: [output, format, input]
-#endif
-#ifdef NSIS_SUPPORT_STACK
- EW_PUSHPOP, // Push/Pop/Exchange: 3 [variable/string, ?pop:push, ?exch]
-#endif
-#ifdef NSIS_SUPPORT_HWNDS
- EW_FINDWINDOW, // FindWindow: 5, [outputvar, window class,window name, window_parent, window_after]
- EW_SENDMESSAGE, // SendMessage: 6 [output, hwnd, msg, wparam, lparam, [wparamstring?1:0 | lparamstring?2:0 | timeout<<2]
- EW_ISWINDOW, // IsWindow: 3 [hwnd, jump_if_window, jump_if_notwindow]
-#endif
-
-#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
- EW_GETDLGITEM, // GetDlgItem: 3: [outputvar, dialog, item_id]
- EW_SETCTLCOLORS, // SerCtlColors: 3: [hwnd, pointer to struct colors]
- EW_SETBRANDINGIMAGE, // SetBrandingImage: 1: [Bitmap file]
- EW_CREATEFONT, // CreateFont: 5: [handle output, face name, height, weight, flags]
- EW_SHOWWINDOW, // ShowWindow: 2: [hwnd, show state]
-#endif
-
-#ifdef NSIS_SUPPORT_SHELLEXECUTE
- EW_SHELLEXEC, // ShellExecute program: 4, [shell action, complete commandline, parameters, showwindow]
-#endif
-
-#ifdef NSIS_SUPPORT_EXECUTE
- EW_EXECUTE, // Execute program: 3,[complete command line,waitflag,>=0?output errorcode]
-#endif
-
-#ifdef NSIS_SUPPORT_GETFILETIME
- EW_GETFILETIME, // GetFileTime; 3 [file highout lowout]
-#endif
-
-#ifdef NSIS_SUPPORT_GETDLLVERSION
- EW_GETDLLVERSION, // GetDLLVersion: 3 [file highout lowout]
-#endif
-
-#ifdef NSIS_SUPPORT_ACTIVEXREG
- EW_REGISTERDLL, // Register DLL: 3,[DLL file name, string ptr of function to call, text to put in display (<0 if none/pass parms), 1 - no unload, 0 - unload]
-#endif
-
-#ifdef NSIS_SUPPORT_CREATESHORTCUT
- EW_CREATESHORTCUT, // Make Shortcut: 5, [link file, target file, parameters, icon file, iconindex|show mode<<8|hotkey<<16]
-#endif
-
-#ifdef NSIS_SUPPORT_COPYFILES
- EW_COPYFILES, // CopyFiles: 3 [source mask, destination location, flags]
-#endif
-
-#ifdef NSIS_SUPPORT_REBOOT
- EW_REBOOT, // Reboot: 0
-#endif
-
-#ifdef NSIS_SUPPORT_INIFILES
- EW_WRITEINI, // Write INI String: 4, [Section, Name, Value, INI File]
- EW_READINISTR, // ReadINIStr: 4 [output, section, name, ini_file]
-#endif
-
-#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
- EW_DELREG, // DeleteRegValue/DeleteRegKey: 4, [root key(int), KeyName, ValueName, delkeyonlyifempty]. ValueName is -1 if delete key
- EW_WRITEREG, // Write Registry value: 5, [RootKey(int),KeyName,ItemName,ItemData,typelen]
- // typelen=1 for str, 2 for dword, 3 for binary, 0 for expanded str
- EW_READREGSTR, // ReadRegStr: 5 [output, rootkey(int), keyname, itemname, ==1?int::str]
- EW_REGENUM, // RegEnum: 5 [output, rootkey, keyname, index, ?key:value]
-#endif
-
-#ifdef NSIS_SUPPORT_FILEFUNCTIONS
- EW_FCLOSE, // FileClose: 1 [handle]
- EW_FOPEN, // FileOpen: 4 [name, openmode, createmode, outputhandle]
- EW_FPUTS, // FileWrite: 3 [handle, string, ?int:string]
- EW_FGETS, // FileRead: 4 [handle, output, maxlen, ?getchar:gets]
- EW_FSEEK, // FileSeek: 4 [handle, offset, mode, >=0?positionoutput]
-#endif//NSIS_SUPPORT_FILEFUNCTIONS
-
-#ifdef NSIS_SUPPORT_FINDFIRST
- EW_FINDCLOSE, // FindClose: 1 [handle]
- EW_FINDNEXT, // FindNext: 2 [output, handle]
- EW_FINDFIRST, // FindFirst: 2 [filespec, output, handleoutput]
-#endif
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- EW_WRITEUNINSTALLER, // WriteUninstaller: 3 [name, offset, icon_size]
-#endif
-
-#ifdef NSIS_CONFIG_LOG
- EW_LOG, // LogText: 2 [0, text] / LogSet: [1, logstate]
-#endif
-
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- EW_SECTIONSET, // SectionSetText: 3: [idx, 0, text]
- // SectionGetText: 3: [idx, 1, output]
- // SectionSetFlags: 3: [idx, 2, flags]
- // SectionGetFlags: 3: [idx, 3, output]
- EW_INSTTYPESET, // InstTypeSetFlags: 3: [idx, 0, flags]
- // InstTypeGetFlags: 3: [idx, 1, output]
-#endif
-
- // instructions not actually implemented in exehead, but used in compiler.
- EW_GETLABELADDR, // both of these get converted to EW_ASSIGNVAR
- EW_GETFUNCTIONADDR,
-
-#ifdef NSIS_LOCKWINDOW_SUPPORT
- EW_LOCKWINDOW,
-#endif
-};
-
-#define FH_FLAGS_MASK 15
-#define FH_FLAGS_UNINSTALL 1
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
-# define FH_FLAGS_SILENT 2
-#endif
-#ifdef NSIS_CONFIG_CRC_SUPPORT
-# define FH_FLAGS_NO_CRC 4
-# define FH_FLAGS_FORCE_CRC 8
-#endif
-
-#define FH_SIG 0xDEADBEEF
-
-// neato surprise signature that goes in firstheader. :)
-#define FH_INT1 0x6C6C754E
-#define FH_INT2 0x74666F73
-#define FH_INT3 0x74736E49
-
-typedef struct
-{
- int flags; // FH_FLAGS_*
- int siginfo; // FH_SIG
-
- int nsinst[3]; // FH_INT1,FH_INT2,FH_INT3
-
- // these point to the header+sections+entries+stringtable in the datablock
- int length_of_header;
-
- // this specifies the length of all the data (including the firstheader and CRC)
- int length_of_all_following_data;
-} firstheader;
-
-// Flags for common_header.flags
-#define CH_FLAGS_DETAILS_SHOWDETAILS 1
-#define CH_FLAGS_DETAILS_NEVERSHOW 2
-#define CH_FLAGS_PROGRESS_COLORED 4
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- #define CH_FLAGS_SILENT 8
- #define CH_FLAGS_SILENT_LOG 16
-#endif
-#define CH_FLAGS_AUTO_CLOSE 32
-#define CH_FLAGS_DIR_NO_SHOW 64
-#define CH_FLAGS_NO_ROOT_DIR 128
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- #define CH_FLAGS_COMP_ONLY_ON_CUSTOM 256
- #define CH_FLAGS_NO_CUSTOM 512
-#endif
-
-// nsis blocks
-struct block_header {
- int offset;
- int num;
-};
-
-enum {
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- NB_PAGES,
-#endif
- NB_SECTIONS,
- NB_ENTRIES,
- NB_STRINGS,
- NB_LANGTABLES,
- NB_CTLCOLORS,
-#ifdef NSIS_SUPPORT_BGBG
- NB_BGFONT,
-#endif
- NB_DATA,
-
- BLOCKS_NUM
-};
-
-// nsis strings
-
-typedef char NSIS_STRING[NSIS_MAX_STRLEN];
-
-// Settings common to both installers and uninstallers
-typedef struct
-{
- int flags; // CH_FLAGS_*
- struct block_header blocks[BLOCKS_NUM];
-
- // InstallDirRegKey stuff
- int install_reg_rootkey;
- // these two are not processed!
- int install_reg_key_ptr, install_reg_value_ptr;
-
-#ifdef NSIS_SUPPORT_BGBG
- int bg_color1, bg_color2, bg_textcolor;
-#endif
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- // installation log window colors
- int lb_bg, lb_fg;
-#endif
-
- // langtable size
- int langtable_size;
-
-#ifdef NSIS_CONFIG_LICENSEPAGE
- // license background color
- int license_bg;
-#endif//NSIS_CONFIG_LICENSEPAGE
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- // .on* calls
- int code_onInit;
- int code_onInstSuccess;
- int code_onInstFailed;
- int code_onUserAbort;
-#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
- int code_onGUIInit;
- int code_onGUIEnd;
- int code_onMouseOverSection;
-#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
- int code_onVerifyInstDir;
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- int code_onSelChange;
-#endif//NSIS_CONFIG_COMPONENTPAGE
-#ifdef NSIS_SUPPORT_REBOOT
- int code_onRebootFailed;
-#endif//NSIS_SUPPORT_REBOOT
-#endif//NSIS_SUPPORT_CODECALLBACKS
-
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- int install_types[NSIS_MAX_INST_TYPES+1];
-#endif
-
- int install_directory_ptr; // default install dir.
- int install_directory_auto_append; // auto append part
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- int str_uninstchild;
- int str_uninstcmd;
-#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
- int str_wininit;
-#endif//NSIS_SUPPORT_MOVEONREBOOT
-} header;
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
-// callback indices
-enum
-{
- CB_ONINIT,
- CB_ONINSTSUCCESS,
- CB_ONINSTFAILED,
- CB_ONUSERABORT,
-#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
- CB_ONGUIINIT,
- CB_ONGUIEND,
- CB_ONMOUSEOVERSECTION,
-#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
- CB_ONVERIFYINSTDIR,
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- CB_ONSELCHANGE,
-#endif//NSIS_CONFIG_COMPONENTPAGE
-#ifdef NSIS_SUPPORT_REBOOT
- CB_ONREBOOTFAILED
-#endif//NSIS_SUPPORT_REBOOT
-};
-#endif//NSIS_SUPPORT_CODECALLBACKS
-
-// used for section->flags
-#define SF_SELECTED 1
-#define SF_SECGRP 2
-#define SF_SECGRPEND 4
-#define SF_BOLD 8
-#define SF_RO 16
-#define SF_EXPAND 32
-#define SF_PSELECTED 64
-#define SF_TOGGLED 128
-#define SF_NAMECHG 256
-
-typedef struct
-{
- int name_ptr; // initial name pointer
- int install_types; // bits set for each of the different install_types, if any.
- int flags; // SF_* - defined above
- int code;
- int code_size;
- int size_kb;
- char name[NSIS_MAX_STRLEN]; // '' for invisible sections
-} section;
-
-#define SECTION_OFFSET(field) (FIELD_OFFSET(section, field)/sizeof(int))
-
-typedef struct
-{
- int which;
- int offsets[MAX_ENTRY_OFFSETS]; // count and meaning of offsets depend on 'which'
-} entry;
-
-// page window proc
-enum
-{
-#ifdef NSIS_CONFIG_LICENSEPAGE
- PWP_LICENSE,
-#endif
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- PWP_SELCOM,
-#endif
- PWP_DIR,
- PWP_INSTFILES,
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- PWP_UNINST,
-#endif
- PWP_COMPLETED,
- PWP_CUSTOM
-};
-
-// page flags
-#define PF_BACK_ENABLE 256
-#define PF_NEXT_ENABLE 2
-#define PF_CANCEL_ENABLE 4
-#define PF_BACK_SHOW 8 // must be SW_SHOWNA, don't change
-#define PF_LICENSE_STREAM 16
-#define PF_LICENSE_FORCE_SELECTION 32
-#define PF_LICENSE_NO_FORCE_SELECTION 64
-#define PF_LICENSE_SELECTED 1 // must be 1
-#define PF_NO_NEXT_FOCUS 128
-#define PF_PAGE_EX 512
-#define PF_DIR_NO_BTN_DISABLE 1024
-
-typedef struct
-{
- int dlg_id; // dialog resource id
- int wndproc_id;
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- // called before the page is created, or if custom to show the page
- // use Abort to skip the page
- int prefunc;
- // called right before page is shown
- int showfunc;
- // called when the user leaves to the next page
- // use Abort to force the user to stay on this page
- int leavefunc;
-#endif //NSIS_SUPPORT_CODECALLBACKS
-
- int flags;
-
- int caption;
- int back;
- int next;
- int clicknext;
- int cancel;
-
- int parms[5];
-} page;
-
-// text/bg color
-#define CC_TEXT 1
-#define CC_TEXT_SYS 2
-#define CC_BK 4
-#define CC_BK_SYS 8
-#define CC_BKB 16
-
-typedef struct {
- COLORREF text;
- COLORREF bkc;
- UINT lbStyle;
- HBRUSH bkb;
- int bkmode;
- int flags;
-} ctlcolors;
-
-// constants for myDelete (util.c)
-#define DEL_DIR 1
-#define DEL_RECURSE 2
-#define DEL_REBOOT 4
-#define DEL_SIMPLE 8
-
-// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value.
-// Added by ramon 3 jun 2003
-#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
-
-#define CODE_SHORT(x) (WORD)((((WORD)x & 0x7F) | (((WORD)x & 0x3F80) << 1) | 0x8080))
-#define MAX_CODED 16383
-
-#define NSIS_INSTDIR_INVALID 1
-#define NSIS_INSTDIR_NOT_ENOUGH_SPACE 2
-
-typedef struct
-{
- int autoclose;
- int all_user_var;
- int exec_error;
- int abort;
-#ifdef NSIS_SUPPORT_REBOOT
- int exec_reboot;
- int reboot_called;
-#else
- int _;
- int __;
-#endif
- int XXX_cur_insttype; // depreacted
- int XXX_insttype_changed; // deprecated
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- int silent;
-#else
- int ___;
-#endif
- int instdir_error;
- int rtl;
- int errlvl;
- int alter_reg_view;
- int status_update;
-} exec_flags;
-
-#define FIELDN(x, y) (((int *)&x)[y])
-
-#ifdef EXEHEAD
-
-// the following are only used/implemented in exehead, not makensis.
-
-int NSISCALL isheader(firstheader *h); // returns 0 on not header, length_of_datablock on success
-
-// returns nonzero on error
-// returns 0 on success
-// on success, m_header will be set to a pointer that should eventually be GlobalFree()'d.
-// (or m_uninstheader)
-const char * NSISCALL loadHeaders(int cl_flags);
-
-int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen);
-
-#define GetCompressedDataFromDataBlock(offset, hFileOut) _dodecomp(offset,hFileOut,NULL,0)
-#define GetCompressedDataFromDataBlockToMemory(offset, out, out_len) _dodecomp(offset,NULL,out,out_len)
-
-extern HANDLE g_db_hFile;
-extern int g_quit_flag;
-
-BOOL NSISCALL ReadSelfFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead);
-DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove);
-
-extern struct block_header g_blocks[BLOCKS_NUM];
-extern header *g_header;
-extern int g_flags;
-extern int g_filehdrsize;
-extern int g_is_uninstaller;
-
-#define g_pages ((page*)g_blocks[NB_PAGES].offset)
-#define g_sections ((section*)g_blocks[NB_SECTIONS].offset)
-#define num_sections (g_blocks[NB_SECTIONS].num)
-#define g_entries ((entry*)g_blocks[NB_ENTRIES].offset)
-#endif
-
-#endif //_FILEFORM_H_
+/*
+ * fileform.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "config.h"
+#include "../Platform.h"
+
+#ifndef _FILEFORM_H_
+#define _FILEFORM_H_
+
+
+// * the installer is compsed of the following parts:
+// exehead (~34kb)
+// firstheader (struct firstheader)
+// * headers (compressed together):
+// header (struct header)
+// * nsis blocks (described in header->blocks)
+// pages (struct page)
+// section headers (struct section)
+// entries/instructions (struct entry)
+// strings (null seperated)
+// language tables (language id, dialog offset, language strings)
+// colors (struct color)
+// data block (files and uninstaller data)
+// * not compressed
+// CRC (optional - 4 bytes)
+//
+// headers + datablock is at least 512 bytes if CRC enabled
+
+
+#define MAX_ENTRY_OFFSETS 6
+
+
+// if you want people to not be able to decompile your installers as easily,
+// reorder the lines following EW_INVALID_OPCODE randomly.
+
+enum
+{
+ EW_INVALID_OPCODE, // zero is invalid. useful for catching errors. (otherwise an all zeroes instruction
+ // does nothing, which is easily ignored but means something is wrong.
+ EW_RET, // return from function call
+ EW_NOP, // Nop/Jump, do nothing: 1, [?new address+1:advance one]
+ EW_ABORT, // Abort: 1 [status]
+ EW_QUIT, // Quit: 0
+ EW_CALL, // Call: 1 [new address+1]
+ EW_UPDATETEXT, // Update status text: 2 [update str, ui_st_updateflag=?ui_st_updateflag:this]
+ EW_SLEEP, // Sleep: 1 [sleep time in milliseconds]
+ EW_BRINGTOFRONT, // BringToFront: 0
+ EW_CHDETAILSVIEW, // SetDetailsView: 2 [listaction,buttonaction]
+ EW_SETFILEATTRIBUTES, // SetFileAttributes: 2 [filename, attributes]
+ EW_CREATEDIR, // Create directory: 2, [path, ?update$INSTDIR]
+ EW_IFFILEEXISTS, // IfFileExists: 3, [file name, jump amount if exists, jump amount if not exists]
+ EW_SETFLAG, // Sets a flag: 2 [id, data]
+ EW_IFFLAG, // If a flag: 4 [on, off, id, new value mask]
+ EW_GETFLAG, // Gets a flag: 2 [output, id]
+#ifdef NSIS_SUPPORT_RENAME
+ EW_RENAME, // Rename: 3 [old, new, rebootok]
+#endif
+#ifdef NSIS_SUPPORT_FNUTIL
+ EW_GETFULLPATHNAME, // GetFullPathName: 2 [output, input, ?lfn:sfn]
+ EW_SEARCHPATH, // SearchPath: 2 [output, filename]
+ EW_GETTEMPFILENAME, // GetTempFileName: 2 [output, base_dir]
+#endif
+#ifdef NSIS_SUPPORT_FILE
+ EW_EXTRACTFILE, // File to extract: 6 [overwriteflag, output filename, compressed filedata, filedatetimelow, filedatetimehigh, allow ignore]
+ // overwriteflag: 0x1 = no. 0x0=force, 0x2=try, 0x3=if date is newer
+#endif
+#ifdef NSIS_SUPPORT_DELETE
+ EW_DELETEFILE, // Delete File: 2, [filename, rebootok]
+#endif
+#ifdef NSIS_SUPPORT_MESSAGEBOX
+ EW_MESSAGEBOX, // MessageBox: 5,[MB_flags,text,retv1:retv2,moveonretv1:moveonretv2]
+#endif
+#ifdef NSIS_SUPPORT_RMDIR
+ EW_RMDIR, // RMDir: 2 [path, recursiveflag]
+#endif
+#ifdef NSIS_SUPPORT_STROPTS
+ EW_STRLEN, // StrLen: 2 [output, input]
+ EW_ASSIGNVAR, // Assign: 4 [variable (0-9) to assign, string to assign, maxlen, startpos]
+ EW_STRCMP, // StrCmp: 5 [str1, str2, jump_if_equal, jump_if_not_equal, case-sensitive?]
+#endif
+#ifdef NSIS_SUPPORT_ENVIRONMENT
+ EW_READENVSTR, // ReadEnvStr/ExpandEnvStrings: 3 [output, string_with_env_variables, IsRead]
+#endif
+#ifdef NSIS_SUPPORT_INTOPTS
+ EW_INTCMP, // IntCmp: 6 [val1, val2, equal, val1<val2, val1>val2, unsigned?]
+ EW_INTOP, // IntOp: 4 [output, input1, input2, op] where op: 0=add, 1=sub, 2=mul, 3=div, 4=bor, 5=band, 6=bxor, 7=bnot input1, 8=lnot input1, 9=lor, 10=land], 11=1%2
+ EW_INTFMT, // IntFmt: [output, format, input]
+#endif
+#ifdef NSIS_SUPPORT_STACK
+ EW_PUSHPOP, // Push/Pop/Exchange: 3 [variable/string, ?pop:push, ?exch]
+#endif
+#ifdef NSIS_SUPPORT_HWNDS
+ EW_FINDWINDOW, // FindWindow: 5, [outputvar, window class,window name, window_parent, window_after]
+ EW_SENDMESSAGE, // SendMessage: 6 [output, hwnd, msg, wparam, lparam, [wparamstring?1:0 | lparamstring?2:0 | timeout<<2]
+ EW_ISWINDOW, // IsWindow: 3 [hwnd, jump_if_window, jump_if_notwindow]
+#endif
+
+#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ EW_GETDLGITEM, // GetDlgItem: 3: [outputvar, dialog, item_id]
+ EW_SETCTLCOLORS, // SerCtlColors: 3: [hwnd, pointer to struct colors]
+ EW_SETBRANDINGIMAGE, // SetBrandingImage: 1: [Bitmap file]
+ EW_CREATEFONT, // CreateFont: 5: [handle output, face name, height, weight, flags]
+ EW_SHOWWINDOW, // ShowWindow: 2: [hwnd, show state]
+#endif
+
+#ifdef NSIS_SUPPORT_SHELLEXECUTE
+ EW_SHELLEXEC, // ShellExecute program: 4, [shell action, complete commandline, parameters, showwindow]
+#endif
+
+#ifdef NSIS_SUPPORT_EXECUTE
+ EW_EXECUTE, // Execute program: 3,[complete command line,waitflag,>=0?output errorcode]
+#endif
+
+#ifdef NSIS_SUPPORT_GETFILETIME
+ EW_GETFILETIME, // GetFileTime; 3 [file highout lowout]
+#endif
+
+#ifdef NSIS_SUPPORT_GETDLLVERSION
+ EW_GETDLLVERSION, // GetDLLVersion: 3 [file highout lowout]
+#endif
+
+#ifdef NSIS_SUPPORT_ACTIVEXREG
+ EW_REGISTERDLL, // Register DLL: 3,[DLL file name, string ptr of function to call, text to put in display (<0 if none/pass parms), 1 - no unload, 0 - unload]
+#endif
+
+#ifdef NSIS_SUPPORT_CREATESHORTCUT
+ EW_CREATESHORTCUT, // Make Shortcut: 5, [link file, target file, parameters, icon file, iconindex|show mode<<8|hotkey<<16]
+#endif
+
+#ifdef NSIS_SUPPORT_COPYFILES
+ EW_COPYFILES, // CopyFiles: 3 [source mask, destination location, flags]
+#endif
+
+#ifdef NSIS_SUPPORT_REBOOT
+ EW_REBOOT, // Reboot: 0
+#endif
+
+#ifdef NSIS_SUPPORT_INIFILES
+ EW_WRITEINI, // Write INI String: 4, [Section, Name, Value, INI File]
+ EW_READINISTR, // ReadINIStr: 4 [output, section, name, ini_file]
+#endif
+
+#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
+ EW_DELREG, // DeleteRegValue/DeleteRegKey: 4, [root key(int), KeyName, ValueName, delkeyonlyifempty]. ValueName is -1 if delete key
+ EW_WRITEREG, // Write Registry value: 5, [RootKey(int),KeyName,ItemName,ItemData,typelen]
+ // typelen=1 for str, 2 for dword, 3 for binary, 0 for expanded str
+ EW_READREGSTR, // ReadRegStr: 5 [output, rootkey(int), keyname, itemname, ==1?int::str]
+ EW_REGENUM, // RegEnum: 5 [output, rootkey, keyname, index, ?key:value]
+#endif
+
+#ifdef NSIS_SUPPORT_FILEFUNCTIONS
+ EW_FCLOSE, // FileClose: 1 [handle]
+ EW_FOPEN, // FileOpen: 4 [name, openmode, createmode, outputhandle]
+ EW_FPUTS, // FileWrite: 3 [handle, string, ?int:string]
+ EW_FGETS, // FileRead: 4 [handle, output, maxlen, ?getchar:gets]
+ EW_FSEEK, // FileSeek: 4 [handle, offset, mode, >=0?positionoutput]
+#endif//NSIS_SUPPORT_FILEFUNCTIONS
+
+#ifdef NSIS_SUPPORT_FINDFIRST
+ EW_FINDCLOSE, // FindClose: 1 [handle]
+ EW_FINDNEXT, // FindNext: 2 [output, handle]
+ EW_FINDFIRST, // FindFirst: 2 [filespec, output, handleoutput]
+#endif
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ EW_WRITEUNINSTALLER, // WriteUninstaller: 3 [name, offset, icon_size]
+#endif
+
+#ifdef NSIS_CONFIG_LOG
+ EW_LOG, // LogText: 2 [0, text] / LogSet: [1, logstate]
+#endif
+
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ EW_SECTIONSET, // SectionSetText: 3: [idx, 0, text]
+ // SectionGetText: 3: [idx, 1, output]
+ // SectionSetFlags: 3: [idx, 2, flags]
+ // SectionGetFlags: 3: [idx, 3, output]
+ EW_INSTTYPESET, // InstTypeSetFlags: 3: [idx, 0, flags]
+ // InstTypeGetFlags: 3: [idx, 1, output]
+#endif
+
+ // instructions not actually implemented in exehead, but used in compiler.
+ EW_GETLABELADDR, // both of these get converted to EW_ASSIGNVAR
+ EW_GETFUNCTIONADDR,
+
+#ifdef NSIS_LOCKWINDOW_SUPPORT
+ EW_LOCKWINDOW,
+#endif
+};
+
+#define FH_FLAGS_MASK 15
+#define FH_FLAGS_UNINSTALL 1
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+# define FH_FLAGS_SILENT 2
+#endif
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+# define FH_FLAGS_NO_CRC 4
+# define FH_FLAGS_FORCE_CRC 8
+#endif
+
+#define FH_SIG 0xDEADBEEF
+
+// neato surprise signature that goes in firstheader. :)
+#define FH_INT1 0x6C6C754E
+#define FH_INT2 0x74666F73
+#define FH_INT3 0x74736E49
+
+typedef struct
+{
+ int flags; // FH_FLAGS_*
+ int siginfo; // FH_SIG
+
+ int nsinst[3]; // FH_INT1,FH_INT2,FH_INT3
+
+ // these point to the header+sections+entries+stringtable in the datablock
+ int length_of_header;
+
+ // this specifies the length of all the data (including the firstheader and CRC)
+ int length_of_all_following_data;
+} firstheader;
+
+// Flags for common_header.flags
+#define CH_FLAGS_DETAILS_SHOWDETAILS 1
+#define CH_FLAGS_DETAILS_NEVERSHOW 2
+#define CH_FLAGS_PROGRESS_COLORED 4
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ #define CH_FLAGS_SILENT 8
+ #define CH_FLAGS_SILENT_LOG 16
+#endif
+#define CH_FLAGS_AUTO_CLOSE 32
+#define CH_FLAGS_DIR_NO_SHOW 64
+#define CH_FLAGS_NO_ROOT_DIR 128
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ #define CH_FLAGS_COMP_ONLY_ON_CUSTOM 256
+ #define CH_FLAGS_NO_CUSTOM 512
+#endif
+
+// nsis blocks
+struct block_header {
+ int offset;
+ int num;
+};
+
+enum {
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ NB_PAGES,
+#endif
+ NB_SECTIONS,
+ NB_ENTRIES,
+ NB_STRINGS,
+ NB_LANGTABLES,
+ NB_CTLCOLORS,
+#ifdef NSIS_SUPPORT_BGBG
+ NB_BGFONT,
+#endif
+ NB_DATA,
+
+ BLOCKS_NUM
+};
+
+// nsis strings
+
+typedef char NSIS_STRING[NSIS_MAX_STRLEN];
+
+// Settings common to both installers and uninstallers
+typedef struct
+{
+ int flags; // CH_FLAGS_*
+ struct block_header blocks[BLOCKS_NUM];
+
+ // InstallDirRegKey stuff
+ int install_reg_rootkey;
+ // these two are not processed!
+ int install_reg_key_ptr, install_reg_value_ptr;
+
+#ifdef NSIS_SUPPORT_BGBG
+ int bg_color1, bg_color2, bg_textcolor;
+#endif
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ // installation log window colors
+ int lb_bg, lb_fg;
+#endif
+
+ // langtable size
+ int langtable_size;
+
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ // license background color
+ int license_bg;
+#endif//NSIS_CONFIG_LICENSEPAGE
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ // .on* calls
+ int code_onInit;
+ int code_onInstSuccess;
+ int code_onInstFailed;
+ int code_onUserAbort;
+#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ int code_onGUIInit;
+ int code_onGUIEnd;
+ int code_onMouseOverSection;
+#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ int code_onVerifyInstDir;
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ int code_onSelChange;
+#endif//NSIS_CONFIG_COMPONENTPAGE
+#ifdef NSIS_SUPPORT_REBOOT
+ int code_onRebootFailed;
+#endif//NSIS_SUPPORT_REBOOT
+#endif//NSIS_SUPPORT_CODECALLBACKS
+
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ int install_types[NSIS_MAX_INST_TYPES+1];
+#endif
+
+ int install_directory_ptr; // default install dir.
+ int install_directory_auto_append; // auto append part
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ int str_uninstchild;
+ int str_uninstcmd;
+#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+ int str_wininit;
+#endif//NSIS_SUPPORT_MOVEONREBOOT
+} header;
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+// callback indices
+enum
+{
+ CB_ONINIT,
+ CB_ONINSTSUCCESS,
+ CB_ONINSTFAILED,
+ CB_ONUSERABORT,
+#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ CB_ONGUIINIT,
+ CB_ONGUIEND,
+ CB_ONMOUSEOVERSECTION,
+#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ CB_ONVERIFYINSTDIR,
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ CB_ONSELCHANGE,
+#endif//NSIS_CONFIG_COMPONENTPAGE
+#ifdef NSIS_SUPPORT_REBOOT
+ CB_ONREBOOTFAILED
+#endif//NSIS_SUPPORT_REBOOT
+};
+#endif//NSIS_SUPPORT_CODECALLBACKS
+
+// used for section->flags
+#define SF_SELECTED 1
+#define SF_SECGRP 2
+#define SF_SECGRPEND 4
+#define SF_BOLD 8
+#define SF_RO 16
+#define SF_EXPAND 32
+#define SF_PSELECTED 64
+#define SF_TOGGLED 128
+#define SF_NAMECHG 256
+
+typedef struct
+{
+ int name_ptr; // initial name pointer
+ int install_types; // bits set for each of the different install_types, if any.
+ int flags; // SF_* - defined above
+ int code;
+ int code_size;
+ int size_kb;
+ char name[NSIS_MAX_STRLEN]; // '' for invisible sections
+} section;
+
+#define SECTION_OFFSET(field) (FIELD_OFFSET(section, field)/sizeof(int))
+
+typedef struct
+{
+ int which;
+ int offsets[MAX_ENTRY_OFFSETS]; // count and meaning of offsets depend on 'which'
+} entry;
+
+// page window proc
+enum
+{
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ PWP_LICENSE,
+#endif
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ PWP_SELCOM,
+#endif
+ PWP_DIR,
+ PWP_INSTFILES,
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ PWP_UNINST,
+#endif
+ PWP_COMPLETED,
+ PWP_CUSTOM
+};
+
+// page flags
+#define PF_BACK_ENABLE 256
+#define PF_NEXT_ENABLE 2
+#define PF_CANCEL_ENABLE 4
+#define PF_BACK_SHOW 8 // must be SW_SHOWNA, don't change
+#define PF_LICENSE_STREAM 16
+#define PF_LICENSE_FORCE_SELECTION 32
+#define PF_LICENSE_NO_FORCE_SELECTION 64
+#define PF_LICENSE_SELECTED 1 // must be 1
+#define PF_NO_NEXT_FOCUS 128
+#define PF_PAGE_EX 512
+#define PF_DIR_NO_BTN_DISABLE 1024
+
+typedef struct
+{
+ int dlg_id; // dialog resource id
+ int wndproc_id;
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ // called before the page is created, or if custom to show the page
+ // use Abort to skip the page
+ int prefunc;
+ // called right before page is shown
+ int showfunc;
+ // called when the user leaves to the next page
+ // use Abort to force the user to stay on this page
+ int leavefunc;
+#endif //NSIS_SUPPORT_CODECALLBACKS
+
+ int flags;
+
+ int caption;
+ int back;
+ int next;
+ int clicknext;
+ int cancel;
+
+ int parms[5];
+} page;
+
+// text/bg color
+#define CC_TEXT 1
+#define CC_TEXT_SYS 2
+#define CC_BK 4
+#define CC_BK_SYS 8
+#define CC_BKB 16
+
+typedef struct {
+ COLORREF text;
+ COLORREF bkc;
+ UINT lbStyle;
+ HBRUSH bkb;
+ int bkmode;
+ int flags;
+} ctlcolors;
+
+// constants for myDelete (util.c)
+#define DEL_DIR 1
+#define DEL_RECURSE 2
+#define DEL_REBOOT 4
+#define DEL_SIMPLE 8
+
+// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value.
+// Added by ramon 3 jun 2003
+#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
+
+#define CODE_SHORT(x) (WORD)((((WORD)x & 0x7F) | (((WORD)x & 0x3F80) << 1) | 0x8080))
+#define MAX_CODED 16383
+
+#define NSIS_INSTDIR_INVALID 1
+#define NSIS_INSTDIR_NOT_ENOUGH_SPACE 2
+
+typedef struct
+{
+ int autoclose;
+ int all_user_var;
+ int exec_error;
+ int abort;
+#ifdef NSIS_SUPPORT_REBOOT
+ int exec_reboot;
+ int reboot_called;
+#else
+ int _;
+ int __;
+#endif
+ int XXX_cur_insttype; // depreacted
+ int XXX_insttype_changed; // deprecated
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ int silent;
+#else
+ int ___;
+#endif
+ int instdir_error;
+ int rtl;
+ int errlvl;
+ int alter_reg_view;
+ int status_update;
+} exec_flags;
+
+#define FIELDN(x, y) (((int *)&x)[y])
+
+#ifdef EXEHEAD
+
+// the following are only used/implemented in exehead, not makensis.
+
+int NSISCALL isheader(firstheader *h); // returns 0 on not header, length_of_datablock on success
+
+// returns nonzero on error
+// returns 0 on success
+// on success, m_header will be set to a pointer that should eventually be GlobalFree()'d.
+// (or m_uninstheader)
+const char * NSISCALL loadHeaders(int cl_flags);
+
+int NSISCALL _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen);
+
+#define GetCompressedDataFromDataBlock(offset, hFileOut) _dodecomp(offset,hFileOut,NULL,0)
+#define GetCompressedDataFromDataBlockToMemory(offset, out, out_len) _dodecomp(offset,NULL,out,out_len)
+
+extern HANDLE g_db_hFile;
+extern int g_quit_flag;
+
+BOOL NSISCALL ReadSelfFile(LPVOID lpBuffer, DWORD nNumberOfBytesToRead);
+DWORD NSISCALL SetSelfFilePointer(LONG lDistanceToMove);
+
+extern struct block_header g_blocks[BLOCKS_NUM];
+extern header *g_header;
+extern int g_flags;
+extern int g_filehdrsize;
+extern int g_is_uninstaller;
+
+#define g_pages ((page*)g_blocks[NB_PAGES].offset)
+#define g_sections ((section*)g_blocks[NB_SECTIONS].offset)
+#define num_sections (g_blocks[NB_SECTIONS].num)
+#define g_entries ((entry*)g_blocks[NB_ENTRIES].offset)
+#endif
+
+#endif //_FILEFORM_H_
diff --git a/Source/exehead/lang.h b/Source/exehead/lang.h
index db5b26b..4c6d425 100755
--- a/Source/exehead/lang.h
+++ b/Source/exehead/lang.h
@@ -1,85 +1,85 @@
-/*
- * lang.c
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef _NSIS_LANG_H_
-#define _NSIS_LANG_H_
-
-
-// generic startup strings (these will never be overridable)
-#ifdef NSIS_CONFIG_CRC_SUPPORT
-#define _LANG_INVALIDCRC "The installer you are trying to use is corrupted or incomplete.\n" \
- "This could be the result of a damaged disk, a failed download or a virus.\n\n" \
- "You may want to contact the author of this installer to obtain a new copy.\n\n" \
- "It may be possible to skip this check using the /NCRC command line switch\n" \
- "(NOT RECOMMENDED)."
-#else
-#define _LANG_INVALIDCRC "The installer you are trying to use is corrupted or incomplete.\n" \
- "This could be the result of a damaged disk, a failed download or a virus.\n\n" \
- "You may want to contact the author of this installer to obtain a new copy."
-#endif
-
-#define _LANG_ERRORWRITINGTEMP "Error writing temporary file. Make sure your temp folder is valid."
-
-#define _LANG_UNINSTINITERROR "Error launching installer"
-
-#define _LANG_VERIFYINGINST "verifying installer: %d%%"
-
-#define _LANG_UNPACKING "unpacking data: %d%%"
-
-#define _LANG_CANTOPENSELF "Error launching installer" // same as uninstiniterror for size
-
-#define _LANG_GENERIC_ERROR "NSIS Error"
-
-#define LANG_STR_TAB(x) cur_langtable[-((int)x+1)]
-
-#define LANG_BRANDING -1
-#define LANG_CAPTION -2
-#define LANG_NAME -3
-#define LANG_SPACE_AVAIL -4
-#define LANG_SPACE_REQ -5
-#define LANG_CANTWRITE -6
-#define LANG_COPYFAILED -7
-#define LANG_COPYTO -8
-#define LANG_CANNOTFINDSYMBOL -9
-#define LANG_COULDNOTLOAD -10
-#define LANG_CREATEDIR -11
-#define LANG_CREATESHORTCUT -12
-#define LANG_CREATEDUNINST -13
-#define LANG_DELETEFILE -14
-#define LANG_DELETEONREBOOT -15
-#define LANG_ERRORCREATINGSHORTCUT -16
-#define LANG_ERRORCREATING -17
-#define LANG_ERRORDECOMPRESSING -18
-#define LANG_DLLREGERROR -19
-#define LANG_EXECSHELL -20
-#define LANG_EXECUTE -21
-#define LANG_EXTRACT -22
-#define LANG_ERRORWRITING -23
-#define LANG_INSTCORRUPTED -24
-#define LANG_NOOLE -25
-#define LANG_OUTPUTDIR -26
-#define LANG_REMOVEDIR -27
-#define LANG_RENAMEONREBOOT -28
-#define LANG_RENAME -29
-#define LANG_SKIPPED -30
-#define LANG_COPYDETAILS -31
-#define LANG_LOG_INSTALL_PROCESS -32
-#define LANG_BYTE -33
-#define LANG_KILO -34
-#define LANG_MEGA -35
-#define LANG_GIGA -36
-
-#endif//_NSIS_LANG_H_
+/*
+ * lang.c
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef _NSIS_LANG_H_
+#define _NSIS_LANG_H_
+
+
+// generic startup strings (these will never be overridable)
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+#define _LANG_INVALIDCRC "The installer you are trying to use is corrupted or incomplete.\n" \
+ "This could be the result of a damaged disk, a failed download or a virus.\n\n" \
+ "You may want to contact the author of this installer to obtain a new copy.\n\n" \
+ "It may be possible to skip this check using the /NCRC command line switch\n" \
+ "(NOT RECOMMENDED)."
+#else
+#define _LANG_INVALIDCRC "The installer you are trying to use is corrupted or incomplete.\n" \
+ "This could be the result of a damaged disk, a failed download or a virus.\n\n" \
+ "You may want to contact the author of this installer to obtain a new copy."
+#endif
+
+#define _LANG_ERRORWRITINGTEMP "Error writing temporary file. Make sure your temp folder is valid."
+
+#define _LANG_UNINSTINITERROR "Error launching installer"
+
+#define _LANG_VERIFYINGINST "verifying installer: %d%%"
+
+#define _LANG_UNPACKING "unpacking data: %d%%"
+
+#define _LANG_CANTOPENSELF "Error launching installer" // same as uninstiniterror for size
+
+#define _LANG_GENERIC_ERROR "NSIS Error"
+
+#define LANG_STR_TAB(x) cur_langtable[-((int)x+1)]
+
+#define LANG_BRANDING -1
+#define LANG_CAPTION -2
+#define LANG_NAME -3
+#define LANG_SPACE_AVAIL -4
+#define LANG_SPACE_REQ -5
+#define LANG_CANTWRITE -6
+#define LANG_COPYFAILED -7
+#define LANG_COPYTO -8
+#define LANG_CANNOTFINDSYMBOL -9
+#define LANG_COULDNOTLOAD -10
+#define LANG_CREATEDIR -11
+#define LANG_CREATESHORTCUT -12
+#define LANG_CREATEDUNINST -13
+#define LANG_DELETEFILE -14
+#define LANG_DELETEONREBOOT -15
+#define LANG_ERRORCREATINGSHORTCUT -16
+#define LANG_ERRORCREATING -17
+#define LANG_ERRORDECOMPRESSING -18
+#define LANG_DLLREGERROR -19
+#define LANG_EXECSHELL -20
+#define LANG_EXECUTE -21
+#define LANG_EXTRACT -22
+#define LANG_ERRORWRITING -23
+#define LANG_INSTCORRUPTED -24
+#define LANG_NOOLE -25
+#define LANG_OUTPUTDIR -26
+#define LANG_REMOVEDIR -27
+#define LANG_RENAMEONREBOOT -28
+#define LANG_RENAME -29
+#define LANG_SKIPPED -30
+#define LANG_COPYDETAILS -31
+#define LANG_LOG_INSTALL_PROCESS -32
+#define LANG_BYTE -33
+#define LANG_KILO -34
+#define LANG_MEGA -35
+#define LANG_GIGA -36
+
+#endif//_NSIS_LANG_H_
diff --git a/Source/exehead/resource.h b/Source/exehead/resource.h
index 53b2fb5..df080c8 100755
--- a/Source/exehead/resource.h
+++ b/Source/exehead/resource.h
@@ -1,56 +1,56 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by resource.rc
-//
-#ifndef DS_SHELLFONT
-#define DS_SHELLFONT (DS_SETFONT | DS_FIXEDSYS)
-#endif
-
-#define IDC_BACK 3
-#define IDD_LICENSE 102
-#define IDD_LICENSE_FSRB 108
-#define IDD_LICENSE_FSCB 109
-#define IDI_ICON2 103
-#define IDD_DIR 103
-#define IDD_SELCOM 104
-#define IDD_INST 105
-#define IDD_INSTFILES 106
-#define IDD_UNINST 107
-#define IDD_VERIFY 111
-#define IDB_BITMAP1 110
-#define IDC_EDIT1 1000
-#define IDC_BROWSE 1001
-#define IDC_PROGRESS 1004
-#define IDC_INTROTEXT 1006
-#define IDC_CHECK1 1008
-#define IDC_LIST1 1016
-#define IDC_COMBO1 1017
-#define IDC_CHILDRECT 1018
-#define IDC_DIR 1019
-#define IDC_SELDIRTEXT 1020
-#define IDC_TEXT1 1021
-#define IDC_TEXT2 1022
-#define IDC_SPACEREQUIRED 1023
-#define IDC_SPACEAVAILABLE 1024
-#define IDC_SHOWDETAILS 1027
-#define IDC_VERSTR 1028
-#define IDC_UNINSTFROM 1029
-#define IDC_STR 1030
-#define IDC_ULICON 1031
-#define IDC_TREE1 1032
-#define IDC_BRANDIMAGE 1033
-#define IDC_LICENSEAGREE 1034
-#define IDC_LICENSEDISAGREE 1035
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 112
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1036
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
-
-
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#ifndef DS_SHELLFONT
+#define DS_SHELLFONT (DS_SETFONT | DS_FIXEDSYS)
+#endif
+
+#define IDC_BACK 3
+#define IDD_LICENSE 102
+#define IDD_LICENSE_FSRB 108
+#define IDD_LICENSE_FSCB 109
+#define IDI_ICON2 103
+#define IDD_DIR 103
+#define IDD_SELCOM 104
+#define IDD_INST 105
+#define IDD_INSTFILES 106
+#define IDD_UNINST 107
+#define IDD_VERIFY 111
+#define IDB_BITMAP1 110
+#define IDC_EDIT1 1000
+#define IDC_BROWSE 1001
+#define IDC_PROGRESS 1004
+#define IDC_INTROTEXT 1006
+#define IDC_CHECK1 1008
+#define IDC_LIST1 1016
+#define IDC_COMBO1 1017
+#define IDC_CHILDRECT 1018
+#define IDC_DIR 1019
+#define IDC_SELDIRTEXT 1020
+#define IDC_TEXT1 1021
+#define IDC_TEXT2 1022
+#define IDC_SPACEREQUIRED 1023
+#define IDC_SPACEAVAILABLE 1024
+#define IDC_SHOWDETAILS 1027
+#define IDC_VERSTR 1028
+#define IDC_UNINSTFROM 1029
+#define IDC_STR 1030
+#define IDC_ULICON 1031
+#define IDC_TREE1 1032
+#define IDC_BRANDIMAGE 1033
+#define IDC_LICENSEAGREE 1034
+#define IDC_LICENSEDISAGREE 1035
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 112
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1036
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
+
+
diff --git a/Source/exehead/resource.rc b/Source/exehead/resource.rc
index e3b83e1..245927e 100755
--- a/Source/exehead/resource.rc
+++ b/Source/exehead/resource.rc
@@ -1,282 +1,282 @@
-//Microsoft Developer Studio generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "afxres.h"
-#include "config.h"
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_LICENSEPAGE)
-#if defined(APSTUDIO_INVOKED)
-IDD_LICENSE$(NSIS_CONFIG_LICENSEPAGE) DIALOGEX 0, 0, 266, 130
-#else
-IDD_LICENSE DIALOGEX 0, 0, 266, 130
-#endif
-STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- ICON IDI_ICON2,IDC_ULICON,0,0,22,20
- LTEXT "",IDC_INTROTEXT,25,0,241,23
- CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL |
- WS_TABSTOP | 0x804,0,24,266,105
-END
-#endif
-
-#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_LICENSEPAGE)
-#if defined(APSTUDIO_INVOKED)
-IDD_LICENSE_FSRB$(NSIS_CONFIG_LICENSEPAGE) DIALOG DISCARDABLE 0, 0, 266, 130
-#else
-IDD_LICENSE_FSRB DIALOG DISCARDABLE 0, 0, 266, 130
-#endif
-STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
-FONT 8, "MS Shell Dlg"
-BEGIN
- ICON IDI_ICON2,1031,0,0,22,20
- LTEXT "",IDC_INTROTEXT,25,0,241,23
- CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL |
- WS_TABSTOP | 0x804,0,24,266,85
- CONTROL "",IDC_LICENSEAGREE,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,0,110,266,9
- CONTROL "",IDC_LICENSEDISAGREE,"Button",BS_AUTORADIOBUTTON |
- WS_TABSTOP,0,120,266,9
-END
-#endif
-
-#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_LICENSEPAGE)
-#if defined(APSTUDIO_INVOKED)
-IDD_LICENSE_FSCB$(NSIS_CONFIG_LICENSEPAGE) DIALOG DISCARDABLE 0, 0, 266, 130
-#else
-IDD_LICENSE_FSCB DIALOG DISCARDABLE 0, 0, 266, 130
-#endif
-STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
-FONT 8, "MS Shell Dlg"
-BEGIN
- ICON IDI_ICON2,1031,0,0,22,20
- LTEXT "",IDC_INTROTEXT,25,0,241,23
- CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL |
- WS_TABSTOP | 0x804,0,24,266,95
- CONTROL "",IDC_LICENSEAGREE,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,0,120,266,9
-END
-#endif
-
-#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_VISIBLE_SUPPORT)
-#if defined(APSTUDIO_INVOKED)
-IDD_DIR$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX 0, 0, 266, 130
-#else
-IDD_DIR DIALOGEX 0, 0, 266, 130
-#endif
-STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- EDITTEXT IDC_DIR,8,49,187,12,ES_AUTOHSCROLL
- PUSHBUTTON "",IDC_BROWSE,202,48,55,14
- ICON IDI_ICON2,IDC_ULICON,0,0,22,20
- CONTROL "",IDC_SPACEAVAILABLE,"Static",SS_LEFTNOWORDWRAP,0,122,
- 265,8
- CONTROL "",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE |
- WS_TABSTOP,8,71,118,10
- CONTROL "",IDC_SPACEREQUIRED,"Static",SS_LEFTNOWORDWRAP,0,111,
- 265,8
- LTEXT "",IDC_INTROTEXT,25,0,241,34
- GROUPBOX "",IDC_SELDIRTEXT,1,38,264,30
-END
-#endif
-
-#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_COMPONENTPAGE)
-#if defined(APSTUDIO_INVOKED)
-IDD_SELCOM$(NSIS_CONFIG_COMPONENTPAGE) DIALOGEX 0, 0, 266, 130
-#else
-IDD_SELCOM DIALOGEX 0, 0, 266, 130
-#endif
-STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- COMBOBOX IDC_COMBO1,114,25,152,102,CBS_DROPDOWNLIST | NOT
- WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
- ICON IDI_ICON2,IDC_ULICON,0,0,22,20
- LTEXT "",IDC_TEXT2,0,40,108,65
- CONTROL "",IDC_TEXT1,"Static",SS_LEFTNOWORDWRAP,0,27,108,8
- LTEXT "",IDC_SPACEREQUIRED,0,111,111,18,NOT WS_GROUP
- LTEXT "",IDC_INTROTEXT,25,0,241,25
- CONTROL "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS |
- TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP |
- WS_BORDER | WS_TABSTOP,114,39,151,90
-END
-#endif
-
-#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_VISIBLE_SUPPORT)
-#if defined(APSTUDIO_INVOKED)
-IDD_INST$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX 0, 0, 280, 162
-#else
-IDD_INST DIALOGEX 0, 0, 280, 162
-#endif
-STYLE DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION |
- WS_SYSMENU
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- PUSHBUTTON "",IDC_BACK,171,142,50,14,NOT WS_VISIBLE | WS_GROUP
- PUSHBUTTON "",IDOK,223,142,50,14
- PUSHBUTTON "",IDCANCEL,7,142,50,14
- CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ | WS_GROUP,7,138,
- 267,1
- CONTROL "",IDC_CHILDRECT,"Static",SS_BLACKRECT | NOT WS_VISIBLE |
- WS_GROUP,7,6,266,130
- CTEXT "",IDC_VERSTR,59,145,108,8,WS_DISABLED
-END
-#endif
-
-#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_VISIBLE_SUPPORT)
-#if defined(APSTUDIO_INVOKED)
-IDD_INSTFILES$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX 0, 0, 266, 130
-#else
-IDD_INSTFILES DIALOGEX 0, 0, 266, 130
-#endif
-STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,24,10,241,
- 11
- CONTROL "",IDC_INTROTEXT,"Static",SS_LEFTNOWORDWRAP |
- SS_NOPREFIX,24,0,241,8
- CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL |
- LVS_NOCOLUMNHEADER | NOT WS_VISIBLE | WS_BORDER |
- WS_TABSTOP,0,25,265,104
- ICON IDI_ICON2,IDC_ULICON,0,0,22,20
- PUSHBUTTON "",IDC_SHOWDETAILS,0,28,60,14,NOT WS_TABSTOP
-END
-#endif
-
-#if defined(APSTUDIO_INVOKED) || defined(_NSIS_CONFIG_UNINSTDLG)
-#if defined(APSTUDIO_INVOKED)
-IDD_UNINST$(_NSIS_CONFIG_UNINSTDLG) DIALOGEX 0, 0, 266, 130
-#else
-IDD_UNINST DIALOGEX 0, 0, 266, 130
-#endif
-STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- ICON IDI_ICON2,IDC_ULICON,0,1,22,20
- LTEXT "",IDC_UNINSTFROM,0,45,55,8
- EDITTEXT IDC_EDIT1,56,43,209,12,ES_AUTOHSCROLL | ES_READONLY
- LTEXT "",IDC_INTROTEXT,25,0,241,34
-END
-#endif
-
-#if defined(APSTUDIO_INVOKED) || defined(_NSIS_CONFIG_VERIFYDIALOG)
-#if defined(APSTUDIO_INVOKED)
-IDD_VERIFY$(_NSIS_CONFIG_VERIFYDIALOG) DIALOGEX 0, 0, 162, 22
-#else
-IDD_VERIFY DIALOGEX 0, 0, 162, 22
-#endif
-STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- CTEXT "",IDC_STR,7,7,148,8
-END
-#endif
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// DESIGNINFO
-//
-
-#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO DISCARDABLE
-BEGIN
- "IDD_INST$(NSIS_CONFIG_VISIBLE_SUPPORT)", DIALOG
- BEGIN
- LEFTMARGIN, 7
- RIGHTMARGIN, 273
- TOPMARGIN, 6
- BOTTOMMARGIN, 156
- END
-
- "IDD_INSTFILES$(NSIS_CONFIG_VISIBLE_SUPPORT)", DIALOG
- BEGIN
- RIGHTMARGIN, 246
- BOTTOMMARGIN, 125
- END
-
- "IDD_VERIFY$(_NSIS_CONFIG_VERIFYDIALOG)", DIALOG
- BEGIN
- LEFTMARGIN, 7
- RIGHTMARGIN, 155
- TOPMARGIN, 7
- BOTTOMMARGIN, 15
- END
-END
-#endif // APSTUDIO_INVOKED
-
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE DISCARDABLE
-BEGIN
- "resource.h\0"
-END
-
-2 TEXTINCLUDE DISCARDABLE
-BEGIN
- "#include ""afxres.h""\r\n"
- "#include ""config.h""\0"
-END
-
-3 TEXTINCLUDE DISCARDABLE
-BEGIN
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-IDI_ICON2 ICON DISCARDABLE "nsis.ico"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Bitmap
-//
-
-#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_COMPONENTPAGE)
-#if defined(APSTUDIO_INVOKED)
-IDB_BITMAP1$(NSIS_CONFIG_COMPONENTPAGE) BITMAP DISCARDABLE "bitmap1.bmp"
-#else
-IDB_BITMAP1 BITMAP DISCARDABLE "bitmap1.bmp"
-#endif
-#endif
-#endif // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+#include "config.h"
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_LICENSEPAGE)
+#if defined(APSTUDIO_INVOKED)
+IDD_LICENSE$(NSIS_CONFIG_LICENSEPAGE) DIALOGEX 0, 0, 266, 130
+#else
+IDD_LICENSE DIALOGEX 0, 0, 266, 130
+#endif
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ ICON IDI_ICON2,IDC_ULICON,0,0,22,20
+ LTEXT "",IDC_INTROTEXT,25,0,241,23
+ CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL |
+ WS_TABSTOP | 0x804,0,24,266,105
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_LICENSEPAGE)
+#if defined(APSTUDIO_INVOKED)
+IDD_LICENSE_FSRB$(NSIS_CONFIG_LICENSEPAGE) DIALOG DISCARDABLE 0, 0, 266, 130
+#else
+IDD_LICENSE_FSRB DIALOG DISCARDABLE 0, 0, 266, 130
+#endif
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg"
+BEGIN
+ ICON IDI_ICON2,1031,0,0,22,20
+ LTEXT "",IDC_INTROTEXT,25,0,241,23
+ CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL |
+ WS_TABSTOP | 0x804,0,24,266,85
+ CONTROL "",IDC_LICENSEAGREE,"Button",BS_AUTORADIOBUTTON |
+ WS_TABSTOP,0,110,266,9
+ CONTROL "",IDC_LICENSEDISAGREE,"Button",BS_AUTORADIOBUTTON |
+ WS_TABSTOP,0,120,266,9
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_LICENSEPAGE)
+#if defined(APSTUDIO_INVOKED)
+IDD_LICENSE_FSCB$(NSIS_CONFIG_LICENSEPAGE) DIALOG DISCARDABLE 0, 0, 266, 130
+#else
+IDD_LICENSE_FSCB DIALOG DISCARDABLE 0, 0, 266, 130
+#endif
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg"
+BEGIN
+ ICON IDI_ICON2,1031,0,0,22,20
+ LTEXT "",IDC_INTROTEXT,25,0,241,23
+ CONTROL "",IDC_EDIT1,"RichEdit20A",WS_BORDER | WS_VSCROLL |
+ WS_TABSTOP | 0x804,0,24,266,95
+ CONTROL "",IDC_LICENSEAGREE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,0,120,266,9
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_VISIBLE_SUPPORT)
+#if defined(APSTUDIO_INVOKED)
+IDD_DIR$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX 0, 0, 266, 130
+#else
+IDD_DIR DIALOGEX 0, 0, 266, 130
+#endif
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_DIR,8,49,187,12,ES_AUTOHSCROLL
+ PUSHBUTTON "",IDC_BROWSE,202,48,55,14
+ ICON IDI_ICON2,IDC_ULICON,0,0,22,20
+ CONTROL "",IDC_SPACEAVAILABLE,"Static",SS_LEFTNOWORDWRAP,0,122,
+ 265,8
+ CONTROL "",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE |
+ WS_TABSTOP,8,71,118,10
+ CONTROL "",IDC_SPACEREQUIRED,"Static",SS_LEFTNOWORDWRAP,0,111,
+ 265,8
+ LTEXT "",IDC_INTROTEXT,25,0,241,34
+ GROUPBOX "",IDC_SELDIRTEXT,1,38,264,30
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_COMPONENTPAGE)
+#if defined(APSTUDIO_INVOKED)
+IDD_SELCOM$(NSIS_CONFIG_COMPONENTPAGE) DIALOGEX 0, 0, 266, 130
+#else
+IDD_SELCOM DIALOGEX 0, 0, 266, 130
+#endif
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ COMBOBOX IDC_COMBO1,114,25,152,102,CBS_DROPDOWNLIST | NOT
+ WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
+ ICON IDI_ICON2,IDC_ULICON,0,0,22,20
+ LTEXT "",IDC_TEXT2,0,40,108,65
+ CONTROL "",IDC_TEXT1,"Static",SS_LEFTNOWORDWRAP,0,27,108,8
+ LTEXT "",IDC_SPACEREQUIRED,0,111,111,18,NOT WS_GROUP
+ LTEXT "",IDC_INTROTEXT,25,0,241,25
+ CONTROL "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS |
+ TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP |
+ WS_BORDER | WS_TABSTOP,114,39,151,90
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_VISIBLE_SUPPORT)
+#if defined(APSTUDIO_INVOKED)
+IDD_INST$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX 0, 0, 280, 162
+#else
+IDD_INST DIALOGEX 0, 0, 280, 162
+#endif
+STYLE DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ PUSHBUTTON "",IDC_BACK,171,142,50,14,NOT WS_VISIBLE | WS_GROUP
+ PUSHBUTTON "",IDOK,223,142,50,14
+ PUSHBUTTON "",IDCANCEL,7,142,50,14
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ | WS_GROUP,7,138,
+ 267,1
+ CONTROL "",IDC_CHILDRECT,"Static",SS_BLACKRECT | NOT WS_VISIBLE |
+ WS_GROUP,7,6,266,130
+ CTEXT "",IDC_VERSTR,59,145,108,8,WS_DISABLED
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_VISIBLE_SUPPORT)
+#if defined(APSTUDIO_INVOKED)
+IDD_INSTFILES$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOGEX 0, 0, 266, 130
+#else
+IDD_INSTFILES DIALOGEX 0, 0, 266, 130
+#endif
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,24,10,241,
+ 11
+ CONTROL "",IDC_INTROTEXT,"Static",SS_LEFTNOWORDWRAP |
+ SS_NOPREFIX,24,0,241,8
+ CONTROL "",IDC_LIST1,"SysListView32",LVS_REPORT | LVS_SINGLESEL |
+ LVS_NOCOLUMNHEADER | NOT WS_VISIBLE | WS_BORDER |
+ WS_TABSTOP,0,25,265,104
+ ICON IDI_ICON2,IDC_ULICON,0,0,22,20
+ PUSHBUTTON "",IDC_SHOWDETAILS,0,28,60,14,NOT WS_TABSTOP
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(_NSIS_CONFIG_UNINSTDLG)
+#if defined(APSTUDIO_INVOKED)
+IDD_UNINST$(_NSIS_CONFIG_UNINSTDLG) DIALOGEX 0, 0, 266, 130
+#else
+IDD_UNINST DIALOGEX 0, 0, 266, 130
+#endif
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ ICON IDI_ICON2,IDC_ULICON,0,1,22,20
+ LTEXT "",IDC_UNINSTFROM,0,45,55,8
+ EDITTEXT IDC_EDIT1,56,43,209,12,ES_AUTOHSCROLL | ES_READONLY
+ LTEXT "",IDC_INTROTEXT,25,0,241,34
+END
+#endif
+
+#if defined(APSTUDIO_INVOKED) || defined(_NSIS_CONFIG_VERIFYDIALOG)
+#if defined(APSTUDIO_INVOKED)
+IDD_VERIFY$(_NSIS_CONFIG_VERIFYDIALOG) DIALOGEX 0, 0, 162, 22
+#else
+IDD_VERIFY DIALOGEX 0, 0, 162, 22
+#endif
+STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CTEXT "",IDC_STR,7,7,148,8
+END
+#endif
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ "IDD_INST$(NSIS_CONFIG_VISIBLE_SUPPORT)", DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 273
+ TOPMARGIN, 6
+ BOTTOMMARGIN, 156
+ END
+
+ "IDD_INSTFILES$(NSIS_CONFIG_VISIBLE_SUPPORT)", DIALOG
+ BEGIN
+ RIGHTMARGIN, 246
+ BOTTOMMARGIN, 125
+ END
+
+ "IDD_VERIFY$(_NSIS_CONFIG_VERIFYDIALOG)", DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 155
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 15
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "#include ""config.h""\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON2 ICON DISCARDABLE "nsis.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_COMPONENTPAGE)
+#if defined(APSTUDIO_INVOKED)
+IDB_BITMAP1$(NSIS_CONFIG_COMPONENTPAGE) BITMAP DISCARDABLE "bitmap1.bmp"
+#else
+IDB_BITMAP1 BITMAP DISCARDABLE "bitmap1.bmp"
+#endif
+#endif
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
diff --git a/Source/exehead/state.h b/Source/exehead/state.h
index 27730e4..8aa5020 100755
--- a/Source/exehead/state.h
+++ b/Source/exehead/state.h
@@ -1,42 +1,42 @@
-/*
- * fileform.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "fileform.h"
-
-extern NSIS_STRING g_usrvars[1];
-
-#define state_command_line g_usrvars[20]
-#define state_install_directory g_usrvars[21]
-#define state_output_directory g_usrvars[22]
-#define state_exe_directory g_usrvars[23]
-#define state_language g_usrvars[24]
-#define state_temp_dir g_usrvars[25]
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
-# define state_plugins_dir g_usrvars[26]
-#endif
-#define state_exe_path g_usrvars[27]
-#define state_exe_file g_usrvars[28]
-#define state_click_next g_usrvars[30]
-
-extern char g_caption[NSIS_MAX_STRLEN*2];
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
-extern HWND g_hwnd;
-extern HANDLE g_hInstance;
-extern HWND insthwnd,insthwndbutton;
-#else
-#define g_hwnd 0
-#define g_hInstance 0
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+/*
+ * fileform.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "fileform.h"
+
+extern NSIS_STRING g_usrvars[1];
+
+#define state_command_line g_usrvars[20]
+#define state_install_directory g_usrvars[21]
+#define state_output_directory g_usrvars[22]
+#define state_exe_directory g_usrvars[23]
+#define state_language g_usrvars[24]
+#define state_temp_dir g_usrvars[25]
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+# define state_plugins_dir g_usrvars[26]
+#endif
+#define state_exe_path g_usrvars[27]
+#define state_exe_file g_usrvars[28]
+#define state_click_next g_usrvars[30]
+
+extern char g_caption[NSIS_MAX_STRLEN*2];
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+extern HWND g_hwnd;
+extern HANDLE g_hInstance;
+extern HWND insthwnd,insthwndbutton;
+#else
+#define g_hwnd 0
+#define g_hInstance 0
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
diff --git a/Source/exehead/ui.h b/Source/exehead/ui.h
index 9160e3d..ae85609 100755
--- a/Source/exehead/ui.h
+++ b/Source/exehead/ui.h
@@ -1,60 +1,60 @@
-/*
- * ui.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-
-#ifndef _UI_H_
-#define _UI_H_
-
-extern int *cur_langtable;
-
-extern int NSISCALL ui_doinstall(void);
-void NSISCALL update_status_text(int strtab, const char *text2);
-
-extern int ui_dlg_visible;
-extern HWND m_curwnd;
-
-#ifdef NSIS_CONFIG_LOG
-void NSISCALL build_g_logfile(void);
-#endif
-
-// sent to the last child window to tell it that the install thread is done
-#define WM_NOTIFY_INSTPROC_DONE (WM_USER+0x4)
-
-// sent to every child window to tell it it can start executing NSIS code
-#define WM_NOTIFY_START (WM_USER+0x5)
-
-// sent to the outer window to tell it to go to the next inner window
-#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
-
-// sent to every child window to tell it it is closing soon
-#define WM_NOTIFY_INIGO_MONTOYA (WM_USER+0xb)
-
-// update message used by DirProc and SelProc for space display
-#define WM_IN_UPDATEMSG (WM_USER+0xf)
-
-// custom pages should send this message to let NSIS know they're ready
-#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
-
-// simulates clicking on the tree
-#define WM_TREEVIEW_KEYHACK (WM_USER+0x13)
-
-// notifies a component selection change (.onMouseOverSection)
-#define WM_NOTIFY_SELCHANGE (WM_USER+0x19)
-
-// Notifies the installation type has changed by the user
-#define WM_NOTIFY_INSTTYPE_CHANGED (WM_USER+0x20)
-
-#endif//_UI_H_
+/*
+ * ui.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+
+#ifndef _UI_H_
+#define _UI_H_
+
+extern int *cur_langtable;
+
+extern int NSISCALL ui_doinstall(void);
+void NSISCALL update_status_text(int strtab, const char *text2);
+
+extern int ui_dlg_visible;
+extern HWND m_curwnd;
+
+#ifdef NSIS_CONFIG_LOG
+void NSISCALL build_g_logfile(void);
+#endif
+
+// sent to the last child window to tell it that the install thread is done
+#define WM_NOTIFY_INSTPROC_DONE (WM_USER+0x4)
+
+// sent to every child window to tell it it can start executing NSIS code
+#define WM_NOTIFY_START (WM_USER+0x5)
+
+// sent to the outer window to tell it to go to the next inner window
+#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
+
+// sent to every child window to tell it it is closing soon
+#define WM_NOTIFY_INIGO_MONTOYA (WM_USER+0xb)
+
+// update message used by DirProc and SelProc for space display
+#define WM_IN_UPDATEMSG (WM_USER+0xf)
+
+// custom pages should send this message to let NSIS know they're ready
+#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
+
+// simulates clicking on the tree
+#define WM_TREEVIEW_KEYHACK (WM_USER+0x13)
+
+// notifies a component selection change (.onMouseOverSection)
+#define WM_NOTIFY_SELCHANGE (WM_USER+0x19)
+
+// Notifies the installation type has changed by the user
+#define WM_NOTIFY_INSTTYPE_CHANGED (WM_USER+0x20)
+
+#endif//_UI_H_
diff --git a/Source/exehead/util.c b/Source/exehead/util.c
index fe1481f..afaacc7 100755
--- a/Source/exehead/util.c
+++ b/Source/exehead/util.c
@@ -1,960 +1,960 @@
-/*
- * util.c
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "../Platform.h"
-#include <shellapi.h>
-#include "util.h"
-#include "state.h"
-#include "config.h"
-#include "lang.h"
-#include "fileform.h"
-#include "exec.h"
-#include "ui.h"
-#include "resource.h"
-
-#ifdef NSIS_CONFIG_LOG
-#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
-char g_log_file[1024];
-#endif
-#endif
-
-// *** DO NOT DECLARE MORE VARIABLES INSIDE THIS PRAGMAS ***
-// This will produce a special section called ".ndata" (stands for nsis data)
-// this way makensis during build time, can search for this section by name
-// and change the virtual size of this section
-// which result in extra memory for extra variables without code to do allocation :)
-// nsis then removes the "DISCARDABLE" style from section (for safe)
-#ifdef _MSC_VER
-# pragma bss_seg(NSIS_VARS_SECTION)
-NSIS_STRING g_usrvars[1];
-# pragma bss_seg()
-# pragma comment(linker, "/section:" NSIS_VARS_SECTION ",rwd")
-#else
-# ifdef __GNUC__
-NSIS_STRING g_usrvars[1] __attribute__((section (NSIS_VARS_SECTION)));
-# else
-# error Unknown compiler. You must implement the seperate PE section yourself.
-# endif
-#endif
-
-HANDLE NSISCALL myCreateProcess(char *cmd)
-{
- PROCESS_INFORMATION ProcInfo;
- static STARTUPINFO StartUp;
- StartUp.cb=sizeof(StartUp);
- if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &StartUp, &ProcInfo))
- return NULL;
- CloseHandle(ProcInfo.hThread);
- return ProcInfo.hProcess;
-}
-
-/*BOOL NSISCALL my_SetWindowText(HWND hWnd, const char *val)
-{
- return SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)val);
-}*/
-
-BOOL NSISCALL my_SetDialogItemText(HWND dlg, UINT idx, const char *val)
-{
- return SetDlgItemText(dlg,idx,val);
-// return my_SetWindowText(GetDlgItem(dlg, idx), val);
-}
-
-int NSISCALL my_GetDialogItemText(UINT idx, char *val)
-{
- extern HWND m_curwnd;
- return GetDlgItemText(m_curwnd, idx, val, NSIS_MAX_STRLEN);
-// return my_GetWindowText(GetDlgItem(m_curwnd, idx), val, NSIS_MAX_STRLEN);
-}
-
-int NSISCALL my_MessageBox(const char *text, UINT type) {
- int _type = type & 0x001FFFFF;
- static MSGBOXPARAMS mbp = {
- sizeof(MSGBOXPARAMS),
- 0,
- 0,
- 0,
- 0,
- 0,
- MAKEINTRESOURCE(IDI_ICON2),
- 0,
- 0,
- 0
- };
-
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- // default for silent installers
- if (g_exec_flags.silent && type >> 21)
- return type >> 21;
-#endif
- // no silent or no default, just show
- if (g_exec_flags.rtl)
- _type ^= MB_RIGHT | MB_RTLREADING;
-
- mbp.hwndOwner = g_hwnd;
- mbp.hInstance = g_hInstance;
- mbp.lpszText = text;
- mbp.lpszCaption = g_caption;
- mbp.dwStyle = _type;
-
- return MessageBoxIndirect(&mbp);
-}
-
-void NSISCALL myDelete(char *buf, int flags)
-{
- static char lbuf[NSIS_MAX_STRLEN];
-
- HANDLE h;
- WIN32_FIND_DATA fd;
- char *fn;
- int valid_dir=is_valid_instpath(buf);
-
- if ((flags & DEL_SIMPLE))
- {
- g_exec_flags.exec_error += !DeleteFile(buf);
- return;
- }
-
-#ifdef NSIS_SUPPORT_RMDIR
- if (!(flags & DEL_DIR) || (valid_dir && (flags & DEL_RECURSE)))
-#endif//NSIS_SUPPORT_RMDIR
- {
- mystrcpy(lbuf,buf);
-#ifdef NSIS_SUPPORT_RMDIR
- if (flags & DEL_DIR)
- mystrcat(lbuf,"\\*.*");
- else
-#endif//NSIS_SUPPORT_RMDIR
- trimslashtoend(buf);
-
- mystrcat(buf,"\\");
-
- fn=buf+mystrlen(buf);
-
- h = FindFirstFile(lbuf,&fd);
- if (h != INVALID_HANDLE_VALUE)
- {
- do
- {
- char *fdfn = fd.cFileName;
- if (*findchar(fdfn, '?') && *fd.cAlternateFileName)
- // name contains unicode, use short name
- fdfn = fd.cAlternateFileName;
-
-#ifdef NSIS_SUPPORT_RMDIR
- if (fdfn[0] == '.' && !fdfn[1]) continue;
- if (fdfn[0] == '.' && fdfn[1] == '.' && !fdfn[2]) continue;
-#endif//NSIS_SUPPORT_RMDIR
- {
- mystrcpy(fn,fdfn);
- if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
-#ifdef NSIS_SUPPORT_RMDIR
- if ((flags & (DEL_DIR | DEL_RECURSE)) == (DEL_DIR | DEL_RECURSE))
- {
- myDelete(buf,flags);
- }
-#endif//NSIS_SUPPORT_RMDIR
- }
- else
- {
- log_printf2("Delete: DeleteFile(\"%s\")",buf);
- remove_ro_attr(buf);
- if (!DeleteFile(buf))
- {
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
- if (flags & DEL_REBOOT)
- {
- log_printf2("Delete: DeleteFile on Reboot(\"%s\")",buf);
- update_status_text(LANG_DELETEONREBOOT,buf);
- MoveFileOnReboot(buf,NULL);
- }
- else
-#endif//NSIS_SUPPORT_MOVEONREBOOT
- {
- log_printf2("Delete: DeleteFile failed(\"%s\")",buf);
- g_exec_flags.exec_error++;
- }
- }
- else
- update_status_text(LANG_DELETEFILE,buf);
- }
- }
- } while (FindNextFile(h,&fd));
- FindClose(h);
- }
-
-#ifdef NSIS_SUPPORT_RMDIR
- if (flags & DEL_DIR)
- fn[-1]=0;
-#endif//NSIS_SUPPORT_RMDIR
- }
-
-#ifdef NSIS_SUPPORT_RMDIR
- if ((flags & DEL_DIR))
- {
- if (!valid_dir)
- {
- log_printf2("RMDir: RemoveDirectory invalid input(\"%s\")",buf);
- g_exec_flags.exec_error++;
- }
- else if (file_exists(buf))
- {
- addtrailingslash(buf);
- log_printf2("RMDir: RemoveDirectory(\"%s\")",buf);
- remove_ro_attr(buf);
- if (!RemoveDirectory(buf))
- {
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
- if (flags & DEL_REBOOT)
- {
- log_printf2("RMDir: RemoveDirectory on Reboot(\"%s\")",buf);
- update_status_text(LANG_DELETEONREBOOT,buf);
- MoveFileOnReboot(buf,NULL);
- }
- else
-#endif//NSIS_SUPPORT_MOVEONREBOOT
- {
- log_printf2("RMDir: RemoveDirectory failed(\"%s\")",buf);
- g_exec_flags.exec_error++;
- }
- }
- else
- {
- update_status_text(LANG_REMOVEDIR,buf);
- }
- }
- }
-#endif//NSIS_SUPPORT_RMDIR
-}
-
-char *NSISCALL addtrailingslash(char *str)
-{
- if (lastchar(str)!='\\') mystrcat(str,"\\");
- return str;
-}
-
-/*char NSISCALL lastchar(const char *str)
-{
- return *CharPrev(str,str+mystrlen(str));
-}*/
-
-char * NSISCALL findchar(char *str, char c)
-{
- while (*str && *str != c)
- {
- str = CharNext(str);
- }
- return str;
-}
-
-char * NSISCALL trimslashtoend(char *buf)
-{
- char *p = buf + mystrlen(buf);
- do
- {
- if (*p == '\\')
- break;
- p = CharPrev(buf, p);
- } while (p > buf);
-
- *p = 0;
-
- return p + 1;
-}
-
-int NSISCALL validpathspec(char *ubuf)
-{
- char dl = ubuf[0] | 0x20; // convert alleged drive letter to lower case
- return ((*(WORD*)ubuf==CHAR2_TO_WORD('\\','\\')) || (dl >= 'a' && dl <= 'z' && ubuf[1]==':'));
-}
-
-char * NSISCALL skip_root(char *path)
-{
- char *p = CharNext(path);
- char *p2 = CharNext(p);
-
- if (*path && *(WORD*)p == CHAR2_TO_WORD(':', '\\'))
- {
- return CharNext(p2);
- }
- else if (*(WORD*)path == CHAR2_TO_WORD('\\','\\'))
- {
- // skip host and share name
- int x = 2;
- while (x--)
- {
- p2 = findchar(p2, '\\');
- if (!*p2)
- return NULL;
- p2++; // skip backslash
- }
-
- return p2;
- }
- else
- return NULL;
-}
-
-int NSISCALL is_valid_instpath(char *s)
-{
- static char tmp[NSIS_MAX_STRLEN];
- char *root;
-
- mystrcpy(tmp, s);
-
- root = skip_root(tmp);
-
- if (!root)
- return 0;
-
- // must be called after skip_root or AllowRootDirInstall won't work.
- // validate_filename removes trailing blackslashes and so converts
- // "C:\" to "C:" which is not a valid directory. skip_root returns
- // NULL for "C:" so the above test returns 0.
- // validate_filename is called so directories such as "C:\ " will
- // not pass as a valid non-root directory.
- validate_filename(root);
-
- if ((g_flags & CH_FLAGS_NO_ROOT_DIR) && (!*root || *root == '\\'))
- return 0;
-
- while (mystrlen(tmp) > root - tmp)
- {
- WIN32_FIND_DATA *fd = file_exists(tmp);
- // if the directory bit not set then it's a file, which is not a valid inst dir...
- // GetFileAttributes is not used because it doesn't work with certain files (error 32)
- // as for concerns of the user using * or ?, that's invalid anyway...
- if (fd && !(fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
- return 0;
- trimslashtoend(tmp);
- }
-
- // if the root drive exists
- addtrailingslash(tmp); // don't check the current directory, check the root directory
- if (GetFileAttributes(tmp) == INVALID_FILE_ATTRIBUTES)
- return 0;
-
- return 1;
-}
-
-char * NSISCALL mystrstri(char *a, const char *b)
-{
- int l = mystrlen(b);
- while (mystrlen(a) >= l)
- {
- char c = a[l];
- a[l] = 0;
- if (!lstrcmpi(a, b))
- {
- a[l] = c;
- return a;
- }
- a[l] = c;
- a = CharNext(a);
- }
- return NULL;
-}
-
-void NSISCALL mini_memcpy(void *out, const void *in, int len)
-{
- char *c_out=(char*)out;
- char *c_in=(char *)in;
- while (len-- > 0)
- {
- *c_out++=*c_in++;
- }
-}
-
-void NSISCALL remove_ro_attr(char *file)
-{
- int attr = GetFileAttributes(file);
- if (attr != INVALID_FILE_ATTRIBUTES)
- SetFileAttributes(file,attr&(~FILE_ATTRIBUTE_READONLY));
-}
-
-HANDLE NSISCALL myOpenFile(const char *fn, DWORD da, DWORD cd)
-{
- int attr = GetFileAttributes(fn);
- return CreateFile(
- fn,
- da,
- FILE_SHARE_READ,
- NULL,
- cd,
- attr == INVALID_FILE_ATTRIBUTES ? 0 : attr,
- NULL
- );
-}
-
-char * NSISCALL my_GetTempFileName(char *buf, const char *dir)
-{
- int n = 100;
- while (n--)
- {
- char prefix[4];
- *(LPDWORD)prefix = CHAR4_TO_DWORD('n', 's', 'a', 0);
- prefix[2] += (char)(GetTickCount() % 26);
- if (GetTempFileName(dir, prefix, 0, buf))
- return buf;
- }
- *buf = 0;
- return 0;
-}
-
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
-void NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew)
-{
- BOOL fOk = 0;
- typedef BOOL (WINAPI *mfea_t)(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,DWORD dwFlags);
- mfea_t mfea;
- mfea=(mfea_t) myGetProcAddress(MGA_MoveFileExA);
- if (mfea)
- {
- fOk=mfea(pszExisting, pszNew, MOVEFILE_DELAY_UNTIL_REBOOT|MOVEFILE_REPLACE_EXISTING);
- }
-
- if (!fOk)
- {
- static char szRenameLine[1024];
- static char wininit[1024];
- static char tmpbuf[1024];
- int cchRenameLine;
- static const char szRenameSec[] = "[Rename]\r\n";
- HANDLE hfile;
- DWORD dwFileSize;
- DWORD dwBytes;
- DWORD dwRenameLinePos;
- char *pszWinInit;
-
- int spn;
-
- *(DWORD*)tmpbuf = CHAR4_TO_DWORD('N', 'U', 'L', 0);
-
- if (pszNew) {
- // create the file if it's not already there to prevent GetShortPathName from failing
- CloseHandle(myOpenFile(pszNew,0,CREATE_NEW));
- spn = GetShortPathName(pszNew,tmpbuf,1024);
- if (!spn || spn > 1024)
- return;
- }
- // wininit is used as a temporary here
- spn = GetShortPathName(pszExisting,wininit,1024);
- if (!spn || spn > 1024)
- return;
- cchRenameLine = wsprintf(szRenameLine,"%s=%s\r\n",tmpbuf,wininit);
-
- GetNSISString(wininit, g_header->str_wininit);
- hfile = myOpenFile(wininit, GENERIC_READ | GENERIC_WRITE, OPEN_ALWAYS);
-
- if (hfile != INVALID_HANDLE_VALUE)
- {
- dwFileSize = GetFileSize(hfile, NULL);
- pszWinInit = GlobalAlloc(GPTR, dwFileSize + cchRenameLine + 10);
-
- if (pszWinInit != NULL)
- {
- if (ReadFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL) && dwFileSize == dwBytes)
- {
- LPSTR pszRenameSecInFile = mystrstri(pszWinInit, szRenameSec);
- if (pszRenameSecInFile == NULL)
- {
- mystrcpy(pszWinInit+dwFileSize, szRenameSec);
- dwFileSize += 10;
- dwRenameLinePos = dwFileSize;
- }
- else
- {
- char *pszFirstRenameLine = pszRenameSecInFile+10;
- char *pszNextSec = mystrstri(pszFirstRenameLine,"\n[");
- if (pszNextSec)
- {
- char *p = ++pszNextSec;
- while (p < pszWinInit + dwFileSize) {
- p[cchRenameLine] = *p;
- p++;
- }
-
- dwRenameLinePos = pszNextSec - pszWinInit;
- }
- // rename section is last, stick item at end of file
- else dwRenameLinePos = dwFileSize;
- }
-
- mini_memcpy(&pszWinInit[dwRenameLinePos], szRenameLine, cchRenameLine);
- dwFileSize += cchRenameLine;
-
- SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
- WriteFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL);
-
- GlobalFree(pszWinInit);
- }
- }
-
- CloseHandle(hfile);
- }
- }
-
-#ifdef NSIS_SUPPORT_REBOOT
- g_exec_flags.exec_reboot++;
-#endif
-}
-#endif
-
-void NSISCALL myRegGetStr(HKEY root, const char *sub, const char *name, char *out, int x64)
-{
- HKEY hKey;
- *out=0;
- if (RegOpenKeyEx(root,sub,0,KEY_READ|(x64?KEY_WOW64_64KEY:0),&hKey) == ERROR_SUCCESS)
- {
- DWORD l = NSIS_MAX_STRLEN;
- DWORD t;
- if (RegQueryValueEx(hKey,name,NULL,&t,out,&l ) != ERROR_SUCCESS || (t != REG_SZ && t != REG_EXPAND_SZ)) *out=0;
- out[NSIS_MAX_STRLEN-1]=0;
- RegCloseKey(hKey);
- }
-}
-
-void NSISCALL myitoa(char *s, int d)
-{
- static const char c[] = "%d";
- wsprintf(s,c,d);
-}
-
-int NSISCALL myatoi(char *s)
-{
- unsigned int v=0;
- int sign=1; // sign of positive
- char m=10; // base of 10
- char t='9'; // cap top of numbers at 9
-
- if (*s == '-')
- {
- s++; //skip over -
- sign=-1; // sign flip
- }
-
- if (*s == '0')
- {
- s++; // skip over 0
- if (s[0] >= '0' && s[0] <= '7')
- {
- m=8; // base of 8
- t='7'; // cap top at 7
- }
- if ((s[0] & ~0x20) == 'X')
- {
- m=16; // base of 16
- s++; // advance over 'x'
- }
- }
-
- for (;;)
- {
- int c=*s++;
- if (c >= '0' && c <= t) c-='0';
- else if (m==16 && (c & ~0x20) >= 'A' && (c & ~0x20) <= 'F') c = (c & 7) + 9;
- else break;
- v*=m;
- v+=c;
- }
- return ((int)v)*sign;
-}
-
-// Straight copies of selected shell functions. Calling local functions
-// requires less code than DLL functions. For the savings to outweigh the cost
-// of a new function there should be about a couple of dozen or so calls.
-char * NSISCALL mystrcpy(char *out, const char *in)
-{
- return lstrcpyn(out, in, NSIS_MAX_STRLEN);
-}
-
-int NSISCALL mystrlen(const char *in)
-{
- return lstrlen(in);
-}
-
-char * NSISCALL mystrcat(char *out, const char *concat)
-{
- return lstrcat(out, concat);
-}
-
-char ps_tmpbuf[NSIS_MAX_STRLEN*2];
-
-const char SYSREGKEY[] = "Software\\Microsoft\\Windows\\CurrentVersion";
-const char QUICKLAUNCH[] = "\\Microsoft\\Internet Explorer\\Quick Launch";
-
-typedef HRESULT (__stdcall * PFNSHGETFOLDERPATHA)(HWND, int, HANDLE, DWORD, LPSTR);
-extern void *g_SHGetFolderPath;
-
-// Based on Dave Laundon's simplified process_string
-char * NSISCALL GetNSISString(char *outbuf, int strtab)
-{
- char *in = (char*)GetNSISStringNP(GetNSISTab(strtab));
- char *out = ps_tmpbuf;
- if ((unsigned int) (outbuf - ps_tmpbuf) < sizeof(ps_tmpbuf))
- {
- out = outbuf;
- outbuf = 0;
- }
- while (*in && out - ps_tmpbuf < NSIS_MAX_STRLEN)
- {
- unsigned char nVarIdx = (unsigned char)*in++;
- int nData;
- int fldrs[4];
- if (nVarIdx > NS_CODES_START)
- {
- nData = ((in[1] & 0x7F) << 7) | (in[0] & 0x7F);
- fldrs[0] = in[0]; // current user
- fldrs[1] = in[0] | CSIDL_FLAG_CREATE;
- fldrs[2] = in[1]; // all users
- fldrs[3] = in[1] | CSIDL_FLAG_CREATE;
- in += 2;
-
- if (nVarIdx == NS_SHELL_CODE)
- {
- LPITEMIDLIST idl;
-
- int x = 2;
- DWORD ver = GetVersion();
-
- /*
-
- SHGetFolderPath as provided by shfolder.dll is used to get special folders
- unless the installer is running on Windows 95/98. For 95/98 shfolder.dll is
- only used for the Application Data and Documents folder (if the DLL exists).
- Oherwise, the old SHGetSpecialFolderLocation API is called.
-
- There reason for not using shfolder.dll for all folders on 95/98 is that
- some unsupported folders (such as the Start Menu folder for all users) are
- simulated instead of returning an error so whe can fall back on the folder
- for the current user.
-
- SHGetFolderPath in shell32.dll could be called directly for Windows versions
- later than 95/98 but there is no need to do so, because shfolder.dll is still
- provided and calls shell32.dll.
-
- */
-
- BOOL use_shfolder =
- // Use shfolder if not on 95/98
- !((ver & 0x80000000) && (LOWORD(ver) != 0x5A04)) ||
-
- // Unless the Application Data or Documents folder is requested
- (
- (fldrs[2] == CSIDL_COMMON_APPDATA) ||
- (fldrs[2] == CSIDL_COMMON_DOCUMENTS)
- );
-
- /* Carry on... shfolder stuff is over. */
-
- if (g_exec_flags.all_user_var)
- {
- x = 4;
- }
-
- if (fldrs[0] & 0x80)
- {
- myRegGetStr(HKEY_LOCAL_MACHINE, SYSREGKEY, GetNSISStringNP(fldrs[0] & 0x3F), out, fldrs[0] & 0x40);
- if (!*out)
- GetNSISString(out, fldrs[2]);
- x = 0;
- }
- else if (fldrs[0] == CSIDL_SYSTEM)
- {
- GetSystemDirectory(out, NSIS_MAX_STRLEN);
- x = 0;
- }
- else if (fldrs[0] == CSIDL_WINDOWS)
- {
- GetWindowsDirectory(out, NSIS_MAX_STRLEN);
- x = 0;
- }
-
- while (x--)
- {
- if (g_SHGetFolderPath && use_shfolder)
- {
- PFNSHGETFOLDERPATHA SHGetFolderPathFunc = (PFNSHGETFOLDERPATHA) g_SHGetFolderPath;
- if (!SHGetFolderPathFunc(g_hwnd, fldrs[x], NULL, SHGFP_TYPE_CURRENT, out))
- {
- break;
- }
- }
-
- if (!SHGetSpecialFolderLocation(g_hwnd, fldrs[x], &idl))
- {
- BOOL res = SHGetPathFromIDList(idl, out);
- CoTaskMemFree(idl);
- if (res) break;
- }
-
- *out=0;
- }
-
- if (*out)
- {
- // all users' version is CSIDL_APPDATA only for $QUICKLAUNCH
- // for normal $APPDATA, it'd be CSIDL_APPDATA_COMMON
- if (fldrs[2] == CSIDL_APPDATA)
- {
- mystrcat(out, QUICKLAUNCH);
- }
- }
- validate_filename(out);
- }
- else if (nVarIdx == NS_VAR_CODE)
- {
- if (nData == 29) // $HWNDPARENT
- myitoa(out, (unsigned int) g_hwnd);
- else
- mystrcpy(out, g_usrvars[nData]);
- // validate the directory name
- if ((unsigned int)(nData - 21) < 7) {
- // validate paths for $INSTDIR, $OUTDIR, $EXEDIR, $LANGUAGE, $TEMP, $PLUGINSDIR and $EXEPATH
- // $LANGUAGE is just a number anyway...
- validate_filename(out);
- }
- } // == VAR_CODES_START
- else if (nVarIdx == NS_LANG_CODE)
- {
- GetNSISString(out, -nData-1);
- }
- out += mystrlen(out);
- }
- else if (nVarIdx == NS_SKIP_CODE)
- {
- *out++ = *in++;
- }
- else // Normal char
- {
- *out++ = nVarIdx;
- }
- } // while
- *out = 0;
- if (outbuf)
- return mystrcpy(outbuf, ps_tmpbuf);
- return ps_tmpbuf;
-}
-
-void NSISCALL validate_filename(char *in) {
- char *nono = "*?|<>/\":";
- char *out;
- char *out_save;
-
- // ignoring spaces is wrong, " C:\blah" is invalid
- //while (*in == ' ') in = CharNext(in);
-
- if (in[0] == '\\' && in[1] == '\\' && in[2] == '?' && in[3] == '\\')
- {
- // at least four bytes
- in += 4;
- }
- if (*in)
- {
- // at least two bytes
- if (validpathspec(in)) in += 2;
- }
- out = out_save = in;
- while (*in)
- {
- if ((unsigned char)*in > 31 && !*findchar(nono, *in))
- {
- mini_memcpy(out, in, CharNext(in) - in);
- out = CharNext(out);
- }
- in = CharNext(in);
- }
- *out = 0;
- do
- {
- out = CharPrev(out_save, out);
- if (*out == ' ' || *out == '\\')
- *out = 0;
- else
- break;
- } while (out_save < out);
-}
-
-#ifdef NSIS_CONFIG_LOG
-int log_dolog;
-char log_text[2048]; // 1024 for each wsprintf
-
-#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
-void NSISCALL log_write(int close)
-{
- static HANDLE fp=INVALID_HANDLE_VALUE;
- if (close)
- {
- if (fp!=INVALID_HANDLE_VALUE)
- {
- CloseHandle(fp);
- }
- fp=INVALID_HANDLE_VALUE;
- return;
- }
- if (log_dolog)
- {
- if (g_log_file[0] && fp==INVALID_HANDLE_VALUE)
- {
- fp = myOpenFile(g_log_file,GENERIC_WRITE,OPEN_ALWAYS);
- if (fp!=INVALID_HANDLE_VALUE)
- SetFilePointer(fp,0,NULL,FILE_END);
- }
- if (fp!=INVALID_HANDLE_VALUE)
- {
- DWORD d;
- mystrcat(log_text,"\r\n");
- WriteFile(fp,log_text,mystrlen(log_text),&d,NULL);
- }
- }
-}
-#endif//!NSIS_CONFIG_LOG_ODS && !NSIS_CONFIG_LOG_STDOUT
-
-const char * _RegKeyHandleToName(HKEY hKey)
-{
- if (hKey == HKEY_CLASSES_ROOT)
- return "HKEY_CLASSES_ROOT";
- else if (hKey == HKEY_CURRENT_USER)
- return "HKEY_CURRENT_USER";
- else if (hKey == HKEY_LOCAL_MACHINE)
- return "HKEY_LOCAL_MACHINE";
- else if (hKey == HKEY_USERS)
- return "HKEY_USERS";
- else if (hKey == HKEY_PERFORMANCE_DATA)
- return "HKEY_PERFORMANCE_DATA";
- else if (hKey == HKEY_CURRENT_CONFIG)
- return "HKEY_CURRENT_CONFIG";
- else if (hKey == HKEY_DYN_DATA)
- return "HKEY_DYN_DATA";
- else
- return "invalid registry key";
-}
-
-void _LogData2Hex(char *buf, size_t buflen, unsigned char *data, size_t datalen)
-{
- char *p = buf;
-
- size_t i;
-
- int dots = 0;
- size_t bufbytes = buflen / 3; // 2 hex digits, one space/null
-
- if (datalen > bufbytes)
- {
- bufbytes--;
- dots = 1;
- }
- else
- bufbytes = datalen;
-
- for (i = 0; i < bufbytes; i++)
- {
- wsprintf(p, "%02x%c", data[i], (i == bufbytes - 1) ? '\0' : ' ');
- p += 3;
- }
-
- if (dots)
- mystrcat(buf, "...");
-}
-
-#ifdef NSIS_CONFIG_LOG_TIMESTAMP
-void log_timestamp(char *buf)
-{
- SYSTEMTIME st;
- GetLocalTime(&st);
- wsprintf(buf,"[%04hu/%02hu/%02hu %02hu:%02hu:%02hu] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
-}
-#else
-# define log_timestamp(x)
-#endif//NSIS_CONFIG_LOG_TIMESTAMP
-
-void log_printf(char *format, ...)
-{
- va_list val;
- va_start(val,format);
-
- log_text[0] = '\0';
- log_timestamp(log_text);
- wvsprintf(log_text+mystrlen(log_text),format,val);
-
- va_end(val);
-#ifdef NSIS_CONFIG_LOG_ODS
- if (log_dolog)
- OutputDebugString(log_text);
-#endif
-#ifdef NSIS_CONFIG_LOG_STDOUT
- if (log_dolog && GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE)
- {
- DWORD dwBytes;
- WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), log_text, lstrlen(log_text), &dwBytes, NULL);
- WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\n", 1, &dwBytes, NULL);
- }
-#endif
-#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
- log_write(0);
-#endif
-}
-#endif//NSIS_CONFIG_LOG
-
-WIN32_FIND_DATA * NSISCALL file_exists(char *buf)
-{
- HANDLE h;
- static WIN32_FIND_DATA fd;
- h = FindFirstFile(buf,&fd);
- if (h != INVALID_HANDLE_VALUE)
- {
- FindClose(h);
- return &fd;
- }
- return NULL;
-}
-
-struct MGA_FUNC
-{
- const char *dll;
- const char *func;
-};
-
-struct MGA_FUNC MGA_FUNCS[] = {
- {"KERNEL32", "GetDiskFreeSpaceExA"},
- {"KERNEL32", "MoveFileExA"},
- {"ADVAPI32", "RegDeleteKeyExA"},
- {"ADVAPI32", "OpenProcessToken"},
- {"ADVAPI32", "LookupPrivilegeValueA"},
- {"ADVAPI32", "AdjustTokenPrivileges"},
- {"KERNEL32", "GetUserDefaultUILanguage"},
- {"SHLWAPI", "SHAutoComplete"},
- {"SHFOLDER", "SHGetFolderPathA"}
-};
-
-void * NSISCALL myGetProcAddress(const enum myGetProcAddressFunctions func)
-{
- const char *dll = MGA_FUNCS[func].dll;
- HMODULE hModule = GetModuleHandle(dll);
- if (!hModule)
- hModule = LoadLibrary(dll);
- if (!hModule)
- return NULL;
-
- return GetProcAddress(hModule, MGA_FUNCS[func].func);
-}
-
-void NSISCALL MessageLoop(UINT uCheckedMsg)
-{
- MSG msg;
- while (PeekMessage(&msg, NULL, uCheckedMsg, uCheckedMsg, PM_REMOVE))
- DispatchMessage(&msg);
-}
+/*
+ * util.c
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "../Platform.h"
+#include <shellapi.h>
+#include "util.h"
+#include "state.h"
+#include "config.h"
+#include "lang.h"
+#include "fileform.h"
+#include "exec.h"
+#include "ui.h"
+#include "resource.h"
+
+#ifdef NSIS_CONFIG_LOG
+#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
+char g_log_file[1024];
+#endif
+#endif
+
+// *** DO NOT DECLARE MORE VARIABLES INSIDE THIS PRAGMAS ***
+// This will produce a special section called ".ndata" (stands for nsis data)
+// this way makensis during build time, can search for this section by name
+// and change the virtual size of this section
+// which result in extra memory for extra variables without code to do allocation :)
+// nsis then removes the "DISCARDABLE" style from section (for safe)
+#ifdef _MSC_VER
+# pragma bss_seg(NSIS_VARS_SECTION)
+NSIS_STRING g_usrvars[1];
+# pragma bss_seg()
+# pragma comment(linker, "/section:" NSIS_VARS_SECTION ",rwd")
+#else
+# ifdef __GNUC__
+NSIS_STRING g_usrvars[1] __attribute__((section (NSIS_VARS_SECTION)));
+# else
+# error Unknown compiler. You must implement the seperate PE section yourself.
+# endif
+#endif
+
+HANDLE NSISCALL myCreateProcess(char *cmd)
+{
+ PROCESS_INFORMATION ProcInfo;
+ static STARTUPINFO StartUp;
+ StartUp.cb=sizeof(StartUp);
+ if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &StartUp, &ProcInfo))
+ return NULL;
+ CloseHandle(ProcInfo.hThread);
+ return ProcInfo.hProcess;
+}
+
+/*BOOL NSISCALL my_SetWindowText(HWND hWnd, const char *val)
+{
+ return SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)val);
+}*/
+
+BOOL NSISCALL my_SetDialogItemText(HWND dlg, UINT idx, const char *val)
+{
+ return SetDlgItemText(dlg,idx,val);
+// return my_SetWindowText(GetDlgItem(dlg, idx), val);
+}
+
+int NSISCALL my_GetDialogItemText(UINT idx, char *val)
+{
+ extern HWND m_curwnd;
+ return GetDlgItemText(m_curwnd, idx, val, NSIS_MAX_STRLEN);
+// return my_GetWindowText(GetDlgItem(m_curwnd, idx), val, NSIS_MAX_STRLEN);
+}
+
+int NSISCALL my_MessageBox(const char *text, UINT type) {
+ int _type = type & 0x001FFFFF;
+ static MSGBOXPARAMS mbp = {
+ sizeof(MSGBOXPARAMS),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ MAKEINTRESOURCE(IDI_ICON2),
+ 0,
+ 0,
+ 0
+ };
+
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ // default for silent installers
+ if (g_exec_flags.silent && type >> 21)
+ return type >> 21;
+#endif
+ // no silent or no default, just show
+ if (g_exec_flags.rtl)
+ _type ^= MB_RIGHT | MB_RTLREADING;
+
+ mbp.hwndOwner = g_hwnd;
+ mbp.hInstance = g_hInstance;
+ mbp.lpszText = text;
+ mbp.lpszCaption = g_caption;
+ mbp.dwStyle = _type;
+
+ return MessageBoxIndirect(&mbp);
+}
+
+void NSISCALL myDelete(char *buf, int flags)
+{
+ static char lbuf[NSIS_MAX_STRLEN];
+
+ HANDLE h;
+ WIN32_FIND_DATA fd;
+ char *fn;
+ int valid_dir=is_valid_instpath(buf);
+
+ if ((flags & DEL_SIMPLE))
+ {
+ g_exec_flags.exec_error += !DeleteFile(buf);
+ return;
+ }
+
+#ifdef NSIS_SUPPORT_RMDIR
+ if (!(flags & DEL_DIR) || (valid_dir && (flags & DEL_RECURSE)))
+#endif//NSIS_SUPPORT_RMDIR
+ {
+ mystrcpy(lbuf,buf);
+#ifdef NSIS_SUPPORT_RMDIR
+ if (flags & DEL_DIR)
+ mystrcat(lbuf,"\\*.*");
+ else
+#endif//NSIS_SUPPORT_RMDIR
+ trimslashtoend(buf);
+
+ mystrcat(buf,"\\");
+
+ fn=buf+mystrlen(buf);
+
+ h = FindFirstFile(lbuf,&fd);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ char *fdfn = fd.cFileName;
+ if (*findchar(fdfn, '?') && *fd.cAlternateFileName)
+ // name contains unicode, use short name
+ fdfn = fd.cAlternateFileName;
+
+#ifdef NSIS_SUPPORT_RMDIR
+ if (fdfn[0] == '.' && !fdfn[1]) continue;
+ if (fdfn[0] == '.' && fdfn[1] == '.' && !fdfn[2]) continue;
+#endif//NSIS_SUPPORT_RMDIR
+ {
+ mystrcpy(fn,fdfn);
+ if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+#ifdef NSIS_SUPPORT_RMDIR
+ if ((flags & (DEL_DIR | DEL_RECURSE)) == (DEL_DIR | DEL_RECURSE))
+ {
+ myDelete(buf,flags);
+ }
+#endif//NSIS_SUPPORT_RMDIR
+ }
+ else
+ {
+ log_printf2("Delete: DeleteFile(\"%s\")",buf);
+ remove_ro_attr(buf);
+ if (!DeleteFile(buf))
+ {
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+ if (flags & DEL_REBOOT)
+ {
+ log_printf2("Delete: DeleteFile on Reboot(\"%s\")",buf);
+ update_status_text(LANG_DELETEONREBOOT,buf);
+ MoveFileOnReboot(buf,NULL);
+ }
+ else
+#endif//NSIS_SUPPORT_MOVEONREBOOT
+ {
+ log_printf2("Delete: DeleteFile failed(\"%s\")",buf);
+ g_exec_flags.exec_error++;
+ }
+ }
+ else
+ update_status_text(LANG_DELETEFILE,buf);
+ }
+ }
+ } while (FindNextFile(h,&fd));
+ FindClose(h);
+ }
+
+#ifdef NSIS_SUPPORT_RMDIR
+ if (flags & DEL_DIR)
+ fn[-1]=0;
+#endif//NSIS_SUPPORT_RMDIR
+ }
+
+#ifdef NSIS_SUPPORT_RMDIR
+ if ((flags & DEL_DIR))
+ {
+ if (!valid_dir)
+ {
+ log_printf2("RMDir: RemoveDirectory invalid input(\"%s\")",buf);
+ g_exec_flags.exec_error++;
+ }
+ else if (file_exists(buf))
+ {
+ addtrailingslash(buf);
+ log_printf2("RMDir: RemoveDirectory(\"%s\")",buf);
+ remove_ro_attr(buf);
+ if (!RemoveDirectory(buf))
+ {
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+ if (flags & DEL_REBOOT)
+ {
+ log_printf2("RMDir: RemoveDirectory on Reboot(\"%s\")",buf);
+ update_status_text(LANG_DELETEONREBOOT,buf);
+ MoveFileOnReboot(buf,NULL);
+ }
+ else
+#endif//NSIS_SUPPORT_MOVEONREBOOT
+ {
+ log_printf2("RMDir: RemoveDirectory failed(\"%s\")",buf);
+ g_exec_flags.exec_error++;
+ }
+ }
+ else
+ {
+ update_status_text(LANG_REMOVEDIR,buf);
+ }
+ }
+ }
+#endif//NSIS_SUPPORT_RMDIR
+}
+
+char *NSISCALL addtrailingslash(char *str)
+{
+ if (lastchar(str)!='\\') mystrcat(str,"\\");
+ return str;
+}
+
+/*char NSISCALL lastchar(const char *str)
+{
+ return *CharPrev(str,str+mystrlen(str));
+}*/
+
+char * NSISCALL findchar(char *str, char c)
+{
+ while (*str && *str != c)
+ {
+ str = CharNext(str);
+ }
+ return str;
+}
+
+char * NSISCALL trimslashtoend(char *buf)
+{
+ char *p = buf + mystrlen(buf);
+ do
+ {
+ if (*p == '\\')
+ break;
+ p = CharPrev(buf, p);
+ } while (p > buf);
+
+ *p = 0;
+
+ return p + 1;
+}
+
+int NSISCALL validpathspec(char *ubuf)
+{
+ char dl = ubuf[0] | 0x20; // convert alleged drive letter to lower case
+ return ((*(WORD*)ubuf==CHAR2_TO_WORD('\\','\\')) || (dl >= 'a' && dl <= 'z' && ubuf[1]==':'));
+}
+
+char * NSISCALL skip_root(char *path)
+{
+ char *p = CharNext(path);
+ char *p2 = CharNext(p);
+
+ if (*path && *(WORD*)p == CHAR2_TO_WORD(':', '\\'))
+ {
+ return CharNext(p2);
+ }
+ else if (*(WORD*)path == CHAR2_TO_WORD('\\','\\'))
+ {
+ // skip host and share name
+ int x = 2;
+ while (x--)
+ {
+ p2 = findchar(p2, '\\');
+ if (!*p2)
+ return NULL;
+ p2++; // skip backslash
+ }
+
+ return p2;
+ }
+ else
+ return NULL;
+}
+
+int NSISCALL is_valid_instpath(char *s)
+{
+ static char tmp[NSIS_MAX_STRLEN];
+ char *root;
+
+ mystrcpy(tmp, s);
+
+ root = skip_root(tmp);
+
+ if (!root)
+ return 0;
+
+ // must be called after skip_root or AllowRootDirInstall won't work.
+ // validate_filename removes trailing blackslashes and so converts
+ // "C:\" to "C:" which is not a valid directory. skip_root returns
+ // NULL for "C:" so the above test returns 0.
+ // validate_filename is called so directories such as "C:\ " will
+ // not pass as a valid non-root directory.
+ validate_filename(root);
+
+ if ((g_flags & CH_FLAGS_NO_ROOT_DIR) && (!*root || *root == '\\'))
+ return 0;
+
+ while (mystrlen(tmp) > root - tmp)
+ {
+ WIN32_FIND_DATA *fd = file_exists(tmp);
+ // if the directory bit not set then it's a file, which is not a valid inst dir...
+ // GetFileAttributes is not used because it doesn't work with certain files (error 32)
+ // as for concerns of the user using * or ?, that's invalid anyway...
+ if (fd && !(fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ return 0;
+ trimslashtoend(tmp);
+ }
+
+ // if the root drive exists
+ addtrailingslash(tmp); // don't check the current directory, check the root directory
+ if (GetFileAttributes(tmp) == INVALID_FILE_ATTRIBUTES)
+ return 0;
+
+ return 1;
+}
+
+char * NSISCALL mystrstri(char *a, const char *b)
+{
+ int l = mystrlen(b);
+ while (mystrlen(a) >= l)
+ {
+ char c = a[l];
+ a[l] = 0;
+ if (!lstrcmpi(a, b))
+ {
+ a[l] = c;
+ return a;
+ }
+ a[l] = c;
+ a = CharNext(a);
+ }
+ return NULL;
+}
+
+void NSISCALL mini_memcpy(void *out, const void *in, int len)
+{
+ char *c_out=(char*)out;
+ char *c_in=(char *)in;
+ while (len-- > 0)
+ {
+ *c_out++=*c_in++;
+ }
+}
+
+void NSISCALL remove_ro_attr(char *file)
+{
+ int attr = GetFileAttributes(file);
+ if (attr != INVALID_FILE_ATTRIBUTES)
+ SetFileAttributes(file,attr&(~FILE_ATTRIBUTE_READONLY));
+}
+
+HANDLE NSISCALL myOpenFile(const char *fn, DWORD da, DWORD cd)
+{
+ int attr = GetFileAttributes(fn);
+ return CreateFile(
+ fn,
+ da,
+ FILE_SHARE_READ,
+ NULL,
+ cd,
+ attr == INVALID_FILE_ATTRIBUTES ? 0 : attr,
+ NULL
+ );
+}
+
+char * NSISCALL my_GetTempFileName(char *buf, const char *dir)
+{
+ int n = 100;
+ while (n--)
+ {
+ char prefix[4];
+ *(LPDWORD)prefix = CHAR4_TO_DWORD('n', 's', 'a', 0);
+ prefix[2] += (char)(GetTickCount() % 26);
+ if (GetTempFileName(dir, prefix, 0, buf))
+ return buf;
+ }
+ *buf = 0;
+ return 0;
+}
+
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+void NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew)
+{
+ BOOL fOk = 0;
+ typedef BOOL (WINAPI *mfea_t)(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,DWORD dwFlags);
+ mfea_t mfea;
+ mfea=(mfea_t) myGetProcAddress(MGA_MoveFileExA);
+ if (mfea)
+ {
+ fOk=mfea(pszExisting, pszNew, MOVEFILE_DELAY_UNTIL_REBOOT|MOVEFILE_REPLACE_EXISTING);
+ }
+
+ if (!fOk)
+ {
+ static char szRenameLine[1024];
+ static char wininit[1024];
+ static char tmpbuf[1024];
+ int cchRenameLine;
+ static const char szRenameSec[] = "[Rename]\r\n";
+ HANDLE hfile;
+ DWORD dwFileSize;
+ DWORD dwBytes;
+ DWORD dwRenameLinePos;
+ char *pszWinInit;
+
+ int spn;
+
+ *(DWORD*)tmpbuf = CHAR4_TO_DWORD('N', 'U', 'L', 0);
+
+ if (pszNew) {
+ // create the file if it's not already there to prevent GetShortPathName from failing
+ CloseHandle(myOpenFile(pszNew,0,CREATE_NEW));
+ spn = GetShortPathName(pszNew,tmpbuf,1024);
+ if (!spn || spn > 1024)
+ return;
+ }
+ // wininit is used as a temporary here
+ spn = GetShortPathName(pszExisting,wininit,1024);
+ if (!spn || spn > 1024)
+ return;
+ cchRenameLine = wsprintf(szRenameLine,"%s=%s\r\n",tmpbuf,wininit);
+
+ GetNSISString(wininit, g_header->str_wininit);
+ hfile = myOpenFile(wininit, GENERIC_READ | GENERIC_WRITE, OPEN_ALWAYS);
+
+ if (hfile != INVALID_HANDLE_VALUE)
+ {
+ dwFileSize = GetFileSize(hfile, NULL);
+ pszWinInit = GlobalAlloc(GPTR, dwFileSize + cchRenameLine + 10);
+
+ if (pszWinInit != NULL)
+ {
+ if (ReadFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL) && dwFileSize == dwBytes)
+ {
+ LPSTR pszRenameSecInFile = mystrstri(pszWinInit, szRenameSec);
+ if (pszRenameSecInFile == NULL)
+ {
+ mystrcpy(pszWinInit+dwFileSize, szRenameSec);
+ dwFileSize += 10;
+ dwRenameLinePos = dwFileSize;
+ }
+ else
+ {
+ char *pszFirstRenameLine = pszRenameSecInFile+10;
+ char *pszNextSec = mystrstri(pszFirstRenameLine,"\n[");
+ if (pszNextSec)
+ {
+ char *p = ++pszNextSec;
+ while (p < pszWinInit + dwFileSize) {
+ p[cchRenameLine] = *p;
+ p++;
+ }
+
+ dwRenameLinePos = pszNextSec - pszWinInit;
+ }
+ // rename section is last, stick item at end of file
+ else dwRenameLinePos = dwFileSize;
+ }
+
+ mini_memcpy(&pszWinInit[dwRenameLinePos], szRenameLine, cchRenameLine);
+ dwFileSize += cchRenameLine;
+
+ SetFilePointer(hfile, 0, NULL, FILE_BEGIN);
+ WriteFile(hfile, pszWinInit, dwFileSize, &dwBytes, NULL);
+
+ GlobalFree(pszWinInit);
+ }
+ }
+
+ CloseHandle(hfile);
+ }
+ }
+
+#ifdef NSIS_SUPPORT_REBOOT
+ g_exec_flags.exec_reboot++;
+#endif
+}
+#endif
+
+void NSISCALL myRegGetStr(HKEY root, const char *sub, const char *name, char *out, int x64)
+{
+ HKEY hKey;
+ *out=0;
+ if (RegOpenKeyEx(root,sub,0,KEY_READ|(x64?KEY_WOW64_64KEY:0),&hKey) == ERROR_SUCCESS)
+ {
+ DWORD l = NSIS_MAX_STRLEN;
+ DWORD t;
+ if (RegQueryValueEx(hKey,name,NULL,&t,out,&l ) != ERROR_SUCCESS || (t != REG_SZ && t != REG_EXPAND_SZ)) *out=0;
+ out[NSIS_MAX_STRLEN-1]=0;
+ RegCloseKey(hKey);
+ }
+}
+
+void NSISCALL myitoa(char *s, int d)
+{
+ static const char c[] = "%d";
+ wsprintf(s,c,d);
+}
+
+int NSISCALL myatoi(char *s)
+{
+ unsigned int v=0;
+ int sign=1; // sign of positive
+ char m=10; // base of 10
+ char t='9'; // cap top of numbers at 9
+
+ if (*s == '-')
+ {
+ s++; //skip over -
+ sign=-1; // sign flip
+ }
+
+ if (*s == '0')
+ {
+ s++; // skip over 0
+ if (s[0] >= '0' && s[0] <= '7')
+ {
+ m=8; // base of 8
+ t='7'; // cap top at 7
+ }
+ if ((s[0] & ~0x20) == 'X')
+ {
+ m=16; // base of 16
+ s++; // advance over 'x'
+ }
+ }
+
+ for (;;)
+ {
+ int c=*s++;
+ if (c >= '0' && c <= t) c-='0';
+ else if (m==16 && (c & ~0x20) >= 'A' && (c & ~0x20) <= 'F') c = (c & 7) + 9;
+ else break;
+ v*=m;
+ v+=c;
+ }
+ return ((int)v)*sign;
+}
+
+// Straight copies of selected shell functions. Calling local functions
+// requires less code than DLL functions. For the savings to outweigh the cost
+// of a new function there should be about a couple of dozen or so calls.
+char * NSISCALL mystrcpy(char *out, const char *in)
+{
+ return lstrcpyn(out, in, NSIS_MAX_STRLEN);
+}
+
+int NSISCALL mystrlen(const char *in)
+{
+ return lstrlen(in);
+}
+
+char * NSISCALL mystrcat(char *out, const char *concat)
+{
+ return lstrcat(out, concat);
+}
+
+char ps_tmpbuf[NSIS_MAX_STRLEN*2];
+
+const char SYSREGKEY[] = "Software\\Microsoft\\Windows\\CurrentVersion";
+const char QUICKLAUNCH[] = "\\Microsoft\\Internet Explorer\\Quick Launch";
+
+typedef HRESULT (__stdcall * PFNSHGETFOLDERPATHA)(HWND, int, HANDLE, DWORD, LPSTR);
+extern void *g_SHGetFolderPath;
+
+// Based on Dave Laundon's simplified process_string
+char * NSISCALL GetNSISString(char *outbuf, int strtab)
+{
+ char *in = (char*)GetNSISStringNP(GetNSISTab(strtab));
+ char *out = ps_tmpbuf;
+ if ((unsigned int) (outbuf - ps_tmpbuf) < sizeof(ps_tmpbuf))
+ {
+ out = outbuf;
+ outbuf = 0;
+ }
+ while (*in && out - ps_tmpbuf < NSIS_MAX_STRLEN)
+ {
+ unsigned char nVarIdx = (unsigned char)*in++;
+ int nData;
+ int fldrs[4];
+ if (nVarIdx > NS_CODES_START)
+ {
+ nData = ((in[1] & 0x7F) << 7) | (in[0] & 0x7F);
+ fldrs[0] = in[0]; // current user
+ fldrs[1] = in[0] | CSIDL_FLAG_CREATE;
+ fldrs[2] = in[1]; // all users
+ fldrs[3] = in[1] | CSIDL_FLAG_CREATE;
+ in += 2;
+
+ if (nVarIdx == NS_SHELL_CODE)
+ {
+ LPITEMIDLIST idl;
+
+ int x = 2;
+ DWORD ver = GetVersion();
+
+ /*
+
+ SHGetFolderPath as provided by shfolder.dll is used to get special folders
+ unless the installer is running on Windows 95/98. For 95/98 shfolder.dll is
+ only used for the Application Data and Documents folder (if the DLL exists).
+ Oherwise, the old SHGetSpecialFolderLocation API is called.
+
+ There reason for not using shfolder.dll for all folders on 95/98 is that
+ some unsupported folders (such as the Start Menu folder for all users) are
+ simulated instead of returning an error so whe can fall back on the folder
+ for the current user.
+
+ SHGetFolderPath in shell32.dll could be called directly for Windows versions
+ later than 95/98 but there is no need to do so, because shfolder.dll is still
+ provided and calls shell32.dll.
+
+ */
+
+ BOOL use_shfolder =
+ // Use shfolder if not on 95/98
+ !((ver & 0x80000000) && (LOWORD(ver) != 0x5A04)) ||
+
+ // Unless the Application Data or Documents folder is requested
+ (
+ (fldrs[2] == CSIDL_COMMON_APPDATA) ||
+ (fldrs[2] == CSIDL_COMMON_DOCUMENTS)
+ );
+
+ /* Carry on... shfolder stuff is over. */
+
+ if (g_exec_flags.all_user_var)
+ {
+ x = 4;
+ }
+
+ if (fldrs[0] & 0x80)
+ {
+ myRegGetStr(HKEY_LOCAL_MACHINE, SYSREGKEY, GetNSISStringNP(fldrs[0] & 0x3F), out, fldrs[0] & 0x40);
+ if (!*out)
+ GetNSISString(out, fldrs[2]);
+ x = 0;
+ }
+ else if (fldrs[0] == CSIDL_SYSTEM)
+ {
+ GetSystemDirectory(out, NSIS_MAX_STRLEN);
+ x = 0;
+ }
+ else if (fldrs[0] == CSIDL_WINDOWS)
+ {
+ GetWindowsDirectory(out, NSIS_MAX_STRLEN);
+ x = 0;
+ }
+
+ while (x--)
+ {
+ if (g_SHGetFolderPath && use_shfolder)
+ {
+ PFNSHGETFOLDERPATHA SHGetFolderPathFunc = (PFNSHGETFOLDERPATHA) g_SHGetFolderPath;
+ if (!SHGetFolderPathFunc(g_hwnd, fldrs[x], NULL, SHGFP_TYPE_CURRENT, out))
+ {
+ break;
+ }
+ }
+
+ if (!SHGetSpecialFolderLocation(g_hwnd, fldrs[x], &idl))
+ {
+ BOOL res = SHGetPathFromIDList(idl, out);
+ CoTaskMemFree(idl);
+ if (res) break;
+ }
+
+ *out=0;
+ }
+
+ if (*out)
+ {
+ // all users' version is CSIDL_APPDATA only for $QUICKLAUNCH
+ // for normal $APPDATA, it'd be CSIDL_APPDATA_COMMON
+ if (fldrs[2] == CSIDL_APPDATA)
+ {
+ mystrcat(out, QUICKLAUNCH);
+ }
+ }
+ validate_filename(out);
+ }
+ else if (nVarIdx == NS_VAR_CODE)
+ {
+ if (nData == 29) // $HWNDPARENT
+ myitoa(out, (unsigned int) g_hwnd);
+ else
+ mystrcpy(out, g_usrvars[nData]);
+ // validate the directory name
+ if ((unsigned int)(nData - 21) < 7) {
+ // validate paths for $INSTDIR, $OUTDIR, $EXEDIR, $LANGUAGE, $TEMP, $PLUGINSDIR and $EXEPATH
+ // $LANGUAGE is just a number anyway...
+ validate_filename(out);
+ }
+ } // == VAR_CODES_START
+ else if (nVarIdx == NS_LANG_CODE)
+ {
+ GetNSISString(out, -nData-1);
+ }
+ out += mystrlen(out);
+ }
+ else if (nVarIdx == NS_SKIP_CODE)
+ {
+ *out++ = *in++;
+ }
+ else // Normal char
+ {
+ *out++ = nVarIdx;
+ }
+ } // while
+ *out = 0;
+ if (outbuf)
+ return mystrcpy(outbuf, ps_tmpbuf);
+ return ps_tmpbuf;
+}
+
+void NSISCALL validate_filename(char *in) {
+ char *nono = "*?|<>/\":";
+ char *out;
+ char *out_save;
+
+ // ignoring spaces is wrong, " C:\blah" is invalid
+ //while (*in == ' ') in = CharNext(in);
+
+ if (in[0] == '\\' && in[1] == '\\' && in[2] == '?' && in[3] == '\\')
+ {
+ // at least four bytes
+ in += 4;
+ }
+ if (*in)
+ {
+ // at least two bytes
+ if (validpathspec(in)) in += 2;
+ }
+ out = out_save = in;
+ while (*in)
+ {
+ if ((unsigned char)*in > 31 && !*findchar(nono, *in))
+ {
+ mini_memcpy(out, in, CharNext(in) - in);
+ out = CharNext(out);
+ }
+ in = CharNext(in);
+ }
+ *out = 0;
+ do
+ {
+ out = CharPrev(out_save, out);
+ if (*out == ' ' || *out == '\\')
+ *out = 0;
+ else
+ break;
+ } while (out_save < out);
+}
+
+#ifdef NSIS_CONFIG_LOG
+int log_dolog;
+char log_text[2048]; // 1024 for each wsprintf
+
+#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
+void NSISCALL log_write(int close)
+{
+ static HANDLE fp=INVALID_HANDLE_VALUE;
+ if (close)
+ {
+ if (fp!=INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(fp);
+ }
+ fp=INVALID_HANDLE_VALUE;
+ return;
+ }
+ if (log_dolog)
+ {
+ if (g_log_file[0] && fp==INVALID_HANDLE_VALUE)
+ {
+ fp = myOpenFile(g_log_file,GENERIC_WRITE,OPEN_ALWAYS);
+ if (fp!=INVALID_HANDLE_VALUE)
+ SetFilePointer(fp,0,NULL,FILE_END);
+ }
+ if (fp!=INVALID_HANDLE_VALUE)
+ {
+ DWORD d;
+ mystrcat(log_text,"\r\n");
+ WriteFile(fp,log_text,mystrlen(log_text),&d,NULL);
+ }
+ }
+}
+#endif//!NSIS_CONFIG_LOG_ODS && !NSIS_CONFIG_LOG_STDOUT
+
+const char * _RegKeyHandleToName(HKEY hKey)
+{
+ if (hKey == HKEY_CLASSES_ROOT)
+ return "HKEY_CLASSES_ROOT";
+ else if (hKey == HKEY_CURRENT_USER)
+ return "HKEY_CURRENT_USER";
+ else if (hKey == HKEY_LOCAL_MACHINE)
+ return "HKEY_LOCAL_MACHINE";
+ else if (hKey == HKEY_USERS)
+ return "HKEY_USERS";
+ else if (hKey == HKEY_PERFORMANCE_DATA)
+ return "HKEY_PERFORMANCE_DATA";
+ else if (hKey == HKEY_CURRENT_CONFIG)
+ return "HKEY_CURRENT_CONFIG";
+ else if (hKey == HKEY_DYN_DATA)
+ return "HKEY_DYN_DATA";
+ else
+ return "invalid registry key";
+}
+
+void _LogData2Hex(char *buf, size_t buflen, unsigned char *data, size_t datalen)
+{
+ char *p = buf;
+
+ size_t i;
+
+ int dots = 0;
+ size_t bufbytes = buflen / 3; // 2 hex digits, one space/null
+
+ if (datalen > bufbytes)
+ {
+ bufbytes--;
+ dots = 1;
+ }
+ else
+ bufbytes = datalen;
+
+ for (i = 0; i < bufbytes; i++)
+ {
+ wsprintf(p, "%02x%c", data[i], (i == bufbytes - 1) ? '\0' : ' ');
+ p += 3;
+ }
+
+ if (dots)
+ mystrcat(buf, "...");
+}
+
+#ifdef NSIS_CONFIG_LOG_TIMESTAMP
+void log_timestamp(char *buf)
+{
+ SYSTEMTIME st;
+ GetLocalTime(&st);
+ wsprintf(buf,"[%04hu/%02hu/%02hu %02hu:%02hu:%02hu] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
+}
+#else
+# define log_timestamp(x)
+#endif//NSIS_CONFIG_LOG_TIMESTAMP
+
+void log_printf(char *format, ...)
+{
+ va_list val;
+ va_start(val,format);
+
+ log_text[0] = '\0';
+ log_timestamp(log_text);
+ wvsprintf(log_text+mystrlen(log_text),format,val);
+
+ va_end(val);
+#ifdef NSIS_CONFIG_LOG_ODS
+ if (log_dolog)
+ OutputDebugString(log_text);
+#endif
+#ifdef NSIS_CONFIG_LOG_STDOUT
+ if (log_dolog && GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE)
+ {
+ DWORD dwBytes;
+ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), log_text, lstrlen(log_text), &dwBytes, NULL);
+ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "\n", 1, &dwBytes, NULL);
+ }
+#endif
+#if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
+ log_write(0);
+#endif
+}
+#endif//NSIS_CONFIG_LOG
+
+WIN32_FIND_DATA * NSISCALL file_exists(char *buf)
+{
+ HANDLE h;
+ static WIN32_FIND_DATA fd;
+ h = FindFirstFile(buf,&fd);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ FindClose(h);
+ return &fd;
+ }
+ return NULL;
+}
+
+struct MGA_FUNC
+{
+ const char *dll;
+ const char *func;
+};
+
+struct MGA_FUNC MGA_FUNCS[] = {
+ {"KERNEL32", "GetDiskFreeSpaceExA"},
+ {"KERNEL32", "MoveFileExA"},
+ {"ADVAPI32", "RegDeleteKeyExA"},
+ {"ADVAPI32", "OpenProcessToken"},
+ {"ADVAPI32", "LookupPrivilegeValueA"},
+ {"ADVAPI32", "AdjustTokenPrivileges"},
+ {"KERNEL32", "GetUserDefaultUILanguage"},
+ {"SHLWAPI", "SHAutoComplete"},
+ {"SHFOLDER", "SHGetFolderPathA"}
+};
+
+void * NSISCALL myGetProcAddress(const enum myGetProcAddressFunctions func)
+{
+ const char *dll = MGA_FUNCS[func].dll;
+ HMODULE hModule = GetModuleHandle(dll);
+ if (!hModule)
+ hModule = LoadLibrary(dll);
+ if (!hModule)
+ return NULL;
+
+ return GetProcAddress(hModule, MGA_FUNCS[func].func);
+}
+
+void NSISCALL MessageLoop(UINT uCheckedMsg)
+{
+ MSG msg;
+ while (PeekMessage(&msg, NULL, uCheckedMsg, uCheckedMsg, PM_REMOVE))
+ DispatchMessage(&msg);
+}
diff --git a/Source/exehead/util.h b/Source/exehead/util.h
index 2667431..35a1846 100755
--- a/Source/exehead/util.h
+++ b/Source/exehead/util.h
@@ -1,122 +1,122 @@
-/*
- * util.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef ___NSIS_UTIL_H___
-#define ___NSIS_UTIL_H___
-
-#include "../Platform.h"
-#include "config.h"
-#include <shlobj.h>
-
-extern char ps_tmpbuf[NSIS_MAX_STRLEN*2];
-char * NSISCALL GetNSISString(char *outbuf, int strtab);
-#define GetNSISStringTT(strtab) GetNSISString(0, (strtab))
-#define GetNSISStringNP(strtab) ((const char *)g_blocks[NB_STRINGS].offset+(strtab))
-#define GetNSISTab(strtab) (strtab < 0 ? LANG_STR_TAB(strtab) : strtab)
-void NSISCALL myRegGetStr(HKEY root, const char *sub, const char *name, char *out, int x64);
-int NSISCALL myatoi(char *s);
-void NSISCALL myitoa(char *s, int d);
-char * NSISCALL mystrcpy(char *out, const char *in);
-int NSISCALL mystrlen(const char *in);
-char * NSISCALL mystrcat(char *out, const char *concat);
-char * NSISCALL mystrstr(char *a, char *b);
-WIN32_FIND_DATA * NSISCALL file_exists(char *buf);
-char * NSISCALL my_GetTempFileName(char *buf, const char *dir);
-
-//BOOL NSISCALL my_SetWindowText(HWND hWnd, const char *val);
-#define my_SetWindowText SetWindowText
-BOOL NSISCALL my_SetDialogItemText(HWND dlg, UINT idx, const char *val);
-//#define my_SetDialogItemText SetDlgItemText
-//int NSISCALL my_GetWindowText(HWND hWnd, char *val, int size);
-#define my_GetWindowText GetWindowText
-int NSISCALL my_GetDialogItemText(UINT idx, char *val);
-//#define my_GetDialogItemText GetDlgItemText
-
-#ifdef NSIS_CONFIG_LOG
-extern char log_text[2048];
-void NSISCALL log_write(int close);
-const char * _RegKeyHandleToName(HKEY hKey);
-void _LogData2Hex(char *buf, size_t buflen, unsigned char *data, size_t datalen);
-void log_printf(char *format, ...);
-#define log_printf2(x1,x2) log_printf(x1,x2);
-#define log_printf3(x1,x2,x3) log_printf(x1,x2,x3);
-#define log_printf4(x1,x2,x3,x4) log_printf(x1,x2,x3,x4);
-#define log_printf5(x1,x2,x3,x4,x5) log_printf(x1,x2,x3,x4,x5);
-#define log_printf6(x1,x2,x3,x4,x5,x6) log_printf(x1,x2,x3,x4,x5,x6);
-#define log_printf7(x1,x2,x3,x4,x5,x6,x7) log_printf(x1,x2,x3,x4,x5,x6,x7);
-#define log_printf8(x1,x2,x3,x4,x5,x6,x7,x8) log_printf(x1,x2,x3,x4,x5,x6,x7,x8);
-#define RegKeyHandleToName(x1) _RegKeyHandleToName(x1);
-#define LogData2Hex(x1,x2,x3,x4) _LogData2Hex(x1,x2,x3,x4);
-extern int log_dolog;
-extern char g_log_file[1024];
-#else
-#define log_printf(x1)
-#define log_printf2(x1,x2)
-#define log_printf3(x1,x2,x3)
-#define log_printf4(x1,x2,x3,x4)
-#define log_printf5(x1,x2,x3,x4,x5)
-#define log_printf6(x1,x2,x3,x4,x5,x6)
-#define log_printf7(x1,x2,x3,x4,x5,x6,x7)
-#define log_printf8(x1,x2,x3,x4,x5,x6,x7,x8)
-#define RegKeyHandleToName(x1) NULL
-#define LogData2Hex(x1,x2,x3,x4)
-#endif
-
-HANDLE NSISCALL myCreateProcess(char *cmd);
-int NSISCALL my_MessageBox(const char *text, UINT type);
-
-void NSISCALL myDelete(char *buf, int flags);
-
-HANDLE NSISCALL myOpenFile(const char *fn, DWORD da, DWORD cd);
-int NSISCALL validpathspec(char *ubuf);
-char * NSISCALL addtrailingslash(char *str);
-//char NSISCALL lastchar(const char *str);
-#define lastchar(str) *CharPrev(str,str+mystrlen(str))
-char * NSISCALL findchar(char *str, char c);
-char * NSISCALL trimslashtoend(char *buf);
-char * NSISCALL skip_root(char *path);
-int NSISCALL is_valid_instpath(char *s);
-void NSISCALL validate_filename(char *fn);
-void NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew);
-void NSISCALL mini_memcpy(void *out, const void *in, int len);
-void NSISCALL remove_ro_attr(char *file);
-
-enum myGetProcAddressFunctions {
- MGA_GetDiskFreeSpaceExA,
- MGA_MoveFileExA,
- MGA_RegDeleteKeyExA,
- MGA_OpenProcessToken,
- MGA_LookupPrivilegeValueA,
- MGA_AdjustTokenPrivileges,
- MGA_GetUserDefaultUILanguage,
- MGA_SHAutoComplete,
- MGA_SHGetFolderPathA
-};
-
-void * NSISCALL myGetProcAddress(const enum myGetProcAddressFunctions func);
-void NSISCALL MessageLoop(UINT uCheckedMsg);
-
-// Turn a pair of chars into a word
-// Turn four chars into a dword
-#ifdef __BIG_ENDIAN__ // Not very likely, but, still...
-#define CHAR2_TO_WORD(a,b) (((WORD)(b))|((a)<<8))
-#define CHAR4_TO_DWORD(a,b,c,d) (((DWORD)CHAR2_TO_WORD(c,d))|(CHAR2_TO_WORD(a,b)<<16))
-#else
-#define CHAR2_TO_WORD(a,b) (((WORD)(a))|((b)<<8))
-#define CHAR4_TO_DWORD(a,b,c,d) (((DWORD)CHAR2_TO_WORD(a,b))|(CHAR2_TO_WORD(c,d)<<16))
-#endif
-
-#endif//!___NSIS_UTIL_H___
+/*
+ * util.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef ___NSIS_UTIL_H___
+#define ___NSIS_UTIL_H___
+
+#include "../Platform.h"
+#include "config.h"
+#include <shlobj.h>
+
+extern char ps_tmpbuf[NSIS_MAX_STRLEN*2];
+char * NSISCALL GetNSISString(char *outbuf, int strtab);
+#define GetNSISStringTT(strtab) GetNSISString(0, (strtab))
+#define GetNSISStringNP(strtab) ((const char *)g_blocks[NB_STRINGS].offset+(strtab))
+#define GetNSISTab(strtab) (strtab < 0 ? LANG_STR_TAB(strtab) : strtab)
+void NSISCALL myRegGetStr(HKEY root, const char *sub, const char *name, char *out, int x64);
+int NSISCALL myatoi(char *s);
+void NSISCALL myitoa(char *s, int d);
+char * NSISCALL mystrcpy(char *out, const char *in);
+int NSISCALL mystrlen(const char *in);
+char * NSISCALL mystrcat(char *out, const char *concat);
+char * NSISCALL mystrstr(char *a, char *b);
+WIN32_FIND_DATA * NSISCALL file_exists(char *buf);
+char * NSISCALL my_GetTempFileName(char *buf, const char *dir);
+
+//BOOL NSISCALL my_SetWindowText(HWND hWnd, const char *val);
+#define my_SetWindowText SetWindowText
+BOOL NSISCALL my_SetDialogItemText(HWND dlg, UINT idx, const char *val);
+//#define my_SetDialogItemText SetDlgItemText
+//int NSISCALL my_GetWindowText(HWND hWnd, char *val, int size);
+#define my_GetWindowText GetWindowText
+int NSISCALL my_GetDialogItemText(UINT idx, char *val);
+//#define my_GetDialogItemText GetDlgItemText
+
+#ifdef NSIS_CONFIG_LOG
+extern char log_text[2048];
+void NSISCALL log_write(int close);
+const char * _RegKeyHandleToName(HKEY hKey);
+void _LogData2Hex(char *buf, size_t buflen, unsigned char *data, size_t datalen);
+void log_printf(char *format, ...);
+#define log_printf2(x1,x2) log_printf(x1,x2);
+#define log_printf3(x1,x2,x3) log_printf(x1,x2,x3);
+#define log_printf4(x1,x2,x3,x4) log_printf(x1,x2,x3,x4);
+#define log_printf5(x1,x2,x3,x4,x5) log_printf(x1,x2,x3,x4,x5);
+#define log_printf6(x1,x2,x3,x4,x5,x6) log_printf(x1,x2,x3,x4,x5,x6);
+#define log_printf7(x1,x2,x3,x4,x5,x6,x7) log_printf(x1,x2,x3,x4,x5,x6,x7);
+#define log_printf8(x1,x2,x3,x4,x5,x6,x7,x8) log_printf(x1,x2,x3,x4,x5,x6,x7,x8);
+#define RegKeyHandleToName(x1) _RegKeyHandleToName(x1);
+#define LogData2Hex(x1,x2,x3,x4) _LogData2Hex(x1,x2,x3,x4);
+extern int log_dolog;
+extern char g_log_file[1024];
+#else
+#define log_printf(x1)
+#define log_printf2(x1,x2)
+#define log_printf3(x1,x2,x3)
+#define log_printf4(x1,x2,x3,x4)
+#define log_printf5(x1,x2,x3,x4,x5)
+#define log_printf6(x1,x2,x3,x4,x5,x6)
+#define log_printf7(x1,x2,x3,x4,x5,x6,x7)
+#define log_printf8(x1,x2,x3,x4,x5,x6,x7,x8)
+#define RegKeyHandleToName(x1) NULL
+#define LogData2Hex(x1,x2,x3,x4)
+#endif
+
+HANDLE NSISCALL myCreateProcess(char *cmd);
+int NSISCALL my_MessageBox(const char *text, UINT type);
+
+void NSISCALL myDelete(char *buf, int flags);
+
+HANDLE NSISCALL myOpenFile(const char *fn, DWORD da, DWORD cd);
+int NSISCALL validpathspec(char *ubuf);
+char * NSISCALL addtrailingslash(char *str);
+//char NSISCALL lastchar(const char *str);
+#define lastchar(str) *CharPrev(str,str+mystrlen(str))
+char * NSISCALL findchar(char *str, char c);
+char * NSISCALL trimslashtoend(char *buf);
+char * NSISCALL skip_root(char *path);
+int NSISCALL is_valid_instpath(char *s);
+void NSISCALL validate_filename(char *fn);
+void NSISCALL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew);
+void NSISCALL mini_memcpy(void *out, const void *in, int len);
+void NSISCALL remove_ro_attr(char *file);
+
+enum myGetProcAddressFunctions {
+ MGA_GetDiskFreeSpaceExA,
+ MGA_MoveFileExA,
+ MGA_RegDeleteKeyExA,
+ MGA_OpenProcessToken,
+ MGA_LookupPrivilegeValueA,
+ MGA_AdjustTokenPrivileges,
+ MGA_GetUserDefaultUILanguage,
+ MGA_SHAutoComplete,
+ MGA_SHGetFolderPathA
+};
+
+void * NSISCALL myGetProcAddress(const enum myGetProcAddressFunctions func);
+void NSISCALL MessageLoop(UINT uCheckedMsg);
+
+// Turn a pair of chars into a word
+// Turn four chars into a dword
+#ifdef __BIG_ENDIAN__ // Not very likely, but, still...
+#define CHAR2_TO_WORD(a,b) (((WORD)(b))|((a)<<8))
+#define CHAR4_TO_DWORD(a,b,c,d) (((DWORD)CHAR2_TO_WORD(c,d))|(CHAR2_TO_WORD(a,b)<<16))
+#else
+#define CHAR2_TO_WORD(a,b) (((WORD)(a))|((b)<<8))
+#define CHAR4_TO_DWORD(a,b,c,d) (((DWORD)CHAR2_TO_WORD(a,b))|(CHAR2_TO_WORD(c,d)<<16))
+#endif
+
+#endif//!___NSIS_UTIL_H___
diff --git a/Source/fileform.cpp b/Source/fileform.cpp
index c2bdb67..fddf866 100755
--- a/Source/fileform.cpp
+++ b/Source/fileform.cpp
@@ -1,194 +1,194 @@
-/*
- * fileform.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "fileform.h"
-#include "exehead/config.h"
-#include "Platform.h"
-
-#include <cassert>
-
-// these functions MUST be synchronized with the structures in Source/exehead/fileform.h !
-// data must be written in the same order it's defined in Source/exehead/fileform.h
-// in the future, i hope to get one of the two automtaically generated from the other
-
-void firstheader_writer::write(const firstheader *data)
-{
- m_sink->write_int(data->flags);
- m_sink->write_int(data->siginfo);
- m_sink->write_int_array(data->nsinst, 3);
- m_sink->write_int(data->length_of_header);
- m_sink->write_int(data->length_of_all_following_data);
-}
-
-void block_header_writer::write(const block_header *data)
-{
- m_sink->write_int(data->offset);
- m_sink->write_int(data->num);
-}
-
-void header_writer::write(const header *data)
-{
- m_sink->write_int(data->flags);
-
- block_header_writer bw(writer::m_sink);
- for (int i = 0; i < BLOCKS_NUM; i++)
- {
- bw.write(&data->blocks[i]);
- }
-
- m_sink->write_int(data->install_reg_rootkey);
- m_sink->write_int(data->install_reg_key_ptr);
- m_sink->write_int(data->install_reg_value_ptr);
-
-#ifdef NSIS_SUPPORT_BGBG
- m_sink->write_int(data->bg_color1);
- m_sink->write_int(data->bg_color2);
- m_sink->write_int(data->bg_textcolor);
-#endif
-
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- m_sink->write_int(data->lb_bg);
- m_sink->write_int(data->lb_fg);
-#endif
-
- m_sink->write_int(data->langtable_size);
-
-#ifdef NSIS_CONFIG_LICENSEPAGE
- m_sink->write_int(data->license_bg);
-#endif//NSIS_CONFIG_LICENSEPAGE
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- m_sink->write_int(data->code_onInit);
- m_sink->write_int(data->code_onInstSuccess);
- m_sink->write_int(data->code_onInstFailed);
- m_sink->write_int(data->code_onUserAbort);
-#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
- m_sink->write_int(data->code_onGUIInit);
- m_sink->write_int(data->code_onGUIEnd);
- m_sink->write_int(data->code_onMouseOverSection);
-#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
- m_sink->write_int(data->code_onVerifyInstDir);
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- m_sink->write_int(data->code_onSelChange);
-#endif//NSIS_CONFIG_COMPONENTPAGE
-#ifdef NSIS_SUPPORT_REBOOT
- m_sink->write_int(data->code_onRebootFailed);
-#endif//NSIS_SUPPORT_REBOOT
-#endif//NSIS_SUPPORT_CODECALLBACKS
-
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- m_sink->write_int_array(data->install_types, NSIS_MAX_INST_TYPES + 1);
-#endif
-
- m_sink->write_int(data->install_directory_ptr);
- m_sink->write_int(data->install_directory_auto_append);
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- m_sink->write_int(data->str_uninstchild);
- m_sink->write_int(data->str_uninstcmd);
-#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
- m_sink->write_int(data->str_wininit);
-#endif//NSIS_SUPPORT_MOVEONREBOOT
-}
-
-void section_writer::write(const section *data)
-{
- m_sink->write_int(data->name_ptr);
- m_sink->write_int(data->install_types);
- m_sink->write_int(data->flags);
- m_sink->write_int(data->code);
- m_sink->write_int(data->code_size);
- m_sink->write_int(data->size_kb);
- m_sink->write_string(data->name, NSIS_MAX_STRLEN);
-}
-
-void entry_writer::write(const entry *data)
-{
- m_sink->write_int(data->which);
- m_sink->write_int_array(data->offsets, MAX_ENTRY_OFFSETS);
-}
-
-void page_writer::write(const page *data)
-{
- m_sink->write_int(data->dlg_id);
- m_sink->write_int(data->wndproc_id);
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- m_sink->write_int(data->prefunc);
- m_sink->write_int(data->showfunc);
- m_sink->write_int(data->leavefunc);
-#endif //NSIS_SUPPORT_CODECALLBACKS
-
- m_sink->write_int(data->flags);
-
- m_sink->write_int(data->caption);
- m_sink->write_int(data->back);
- m_sink->write_int(data->next);
- m_sink->write_int(data->clicknext);
- m_sink->write_int(data->cancel);
-
- m_sink->write_int_array(data->parms, 5);
-}
-
-void ctlcolors_writer::write(const ctlcolors *data)
-{
- m_sink->write_int(data->text);
- m_sink->write_int(data->bkc);
- m_sink->write_int(data->lbStyle);
- m_sink->write_int((int) data->bkb);
- m_sink->write_int(data->bkmode);
- m_sink->write_int(data->flags);
-}
-
-void LOGFONT_writer::write(const LOGFONT *data)
-{
- m_sink->write_int(data->lfHeight);
- m_sink->write_int(data->lfWidth);
- m_sink->write_int(data->lfEscapement);
- m_sink->write_int(data->lfOrientation);
- m_sink->write_int(data->lfWeight);
- m_sink->write_byte(data->lfItalic);
- m_sink->write_byte(data->lfUnderline);
- m_sink->write_byte(data->lfStrikeOut);
- m_sink->write_byte(data->lfCharSet);
- m_sink->write_byte(data->lfOutPrecision);
- m_sink->write_byte(data->lfClipPrecision);
- m_sink->write_byte(data->lfQuality);
- m_sink->write_byte(data->lfPitchAndFamily);
- m_sink->write_string(data->lfFaceName, LF_FACESIZE);
-}
-
-void lang_table_writer::write(const unsigned char *data)
-{
- assert(sizeof(LANGID) == sizeof(short));
-
- m_sink->write_short(* (short *) data);
- data += sizeof(short);
- m_sink->write_int_array((int *) data, m_lang_strings + 2);
-}
-
-void lang_table_writer::write_block(IGrowBuf *buf, writer_sink *sink, const size_t table_size)
-{
- unsigned char *tables = (unsigned char *) buf->get();
- size_t lang_strings = ( table_size - 2 * sizeof(int) - sizeof(LANGID) ) / sizeof(int);
- size_t l = buf->getlen() / table_size;
- lang_table_writer writer(sink, lang_strings);
- for (size_t i = 0; i < l; i++)
- {
- writer.write(tables + i * table_size);
- }
-}
+/*
+ * fileform.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "fileform.h"
+#include "exehead/config.h"
+#include "Platform.h"
+
+#include <cassert>
+
+// these functions MUST be synchronized with the structures in Source/exehead/fileform.h !
+// data must be written in the same order it's defined in Source/exehead/fileform.h
+// in the future, i hope to get one of the two automtaically generated from the other
+
+void firstheader_writer::write(const firstheader *data)
+{
+ m_sink->write_int(data->flags);
+ m_sink->write_int(data->siginfo);
+ m_sink->write_int_array(data->nsinst, 3);
+ m_sink->write_int(data->length_of_header);
+ m_sink->write_int(data->length_of_all_following_data);
+}
+
+void block_header_writer::write(const block_header *data)
+{
+ m_sink->write_int(data->offset);
+ m_sink->write_int(data->num);
+}
+
+void header_writer::write(const header *data)
+{
+ m_sink->write_int(data->flags);
+
+ block_header_writer bw(writer::m_sink);
+ for (int i = 0; i < BLOCKS_NUM; i++)
+ {
+ bw.write(&data->blocks[i]);
+ }
+
+ m_sink->write_int(data->install_reg_rootkey);
+ m_sink->write_int(data->install_reg_key_ptr);
+ m_sink->write_int(data->install_reg_value_ptr);
+
+#ifdef NSIS_SUPPORT_BGBG
+ m_sink->write_int(data->bg_color1);
+ m_sink->write_int(data->bg_color2);
+ m_sink->write_int(data->bg_textcolor);
+#endif
+
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ m_sink->write_int(data->lb_bg);
+ m_sink->write_int(data->lb_fg);
+#endif
+
+ m_sink->write_int(data->langtable_size);
+
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ m_sink->write_int(data->license_bg);
+#endif//NSIS_CONFIG_LICENSEPAGE
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ m_sink->write_int(data->code_onInit);
+ m_sink->write_int(data->code_onInstSuccess);
+ m_sink->write_int(data->code_onInstFailed);
+ m_sink->write_int(data->code_onUserAbort);
+#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ m_sink->write_int(data->code_onGUIInit);
+ m_sink->write_int(data->code_onGUIEnd);
+ m_sink->write_int(data->code_onMouseOverSection);
+#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ m_sink->write_int(data->code_onVerifyInstDir);
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ m_sink->write_int(data->code_onSelChange);
+#endif//NSIS_CONFIG_COMPONENTPAGE
+#ifdef NSIS_SUPPORT_REBOOT
+ m_sink->write_int(data->code_onRebootFailed);
+#endif//NSIS_SUPPORT_REBOOT
+#endif//NSIS_SUPPORT_CODECALLBACKS
+
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ m_sink->write_int_array(data->install_types, NSIS_MAX_INST_TYPES + 1);
+#endif
+
+ m_sink->write_int(data->install_directory_ptr);
+ m_sink->write_int(data->install_directory_auto_append);
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ m_sink->write_int(data->str_uninstchild);
+ m_sink->write_int(data->str_uninstcmd);
+#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+ m_sink->write_int(data->str_wininit);
+#endif//NSIS_SUPPORT_MOVEONREBOOT
+}
+
+void section_writer::write(const section *data)
+{
+ m_sink->write_int(data->name_ptr);
+ m_sink->write_int(data->install_types);
+ m_sink->write_int(data->flags);
+ m_sink->write_int(data->code);
+ m_sink->write_int(data->code_size);
+ m_sink->write_int(data->size_kb);
+ m_sink->write_string(data->name, NSIS_MAX_STRLEN);
+}
+
+void entry_writer::write(const entry *data)
+{
+ m_sink->write_int(data->which);
+ m_sink->write_int_array(data->offsets, MAX_ENTRY_OFFSETS);
+}
+
+void page_writer::write(const page *data)
+{
+ m_sink->write_int(data->dlg_id);
+ m_sink->write_int(data->wndproc_id);
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ m_sink->write_int(data->prefunc);
+ m_sink->write_int(data->showfunc);
+ m_sink->write_int(data->leavefunc);
+#endif //NSIS_SUPPORT_CODECALLBACKS
+
+ m_sink->write_int(data->flags);
+
+ m_sink->write_int(data->caption);
+ m_sink->write_int(data->back);
+ m_sink->write_int(data->next);
+ m_sink->write_int(data->clicknext);
+ m_sink->write_int(data->cancel);
+
+ m_sink->write_int_array(data->parms, 5);
+}
+
+void ctlcolors_writer::write(const ctlcolors *data)
+{
+ m_sink->write_int(data->text);
+ m_sink->write_int(data->bkc);
+ m_sink->write_int(data->lbStyle);
+ m_sink->write_int((int) data->bkb);
+ m_sink->write_int(data->bkmode);
+ m_sink->write_int(data->flags);
+}
+
+void LOGFONT_writer::write(const LOGFONT *data)
+{
+ m_sink->write_int(data->lfHeight);
+ m_sink->write_int(data->lfWidth);
+ m_sink->write_int(data->lfEscapement);
+ m_sink->write_int(data->lfOrientation);
+ m_sink->write_int(data->lfWeight);
+ m_sink->write_byte(data->lfItalic);
+ m_sink->write_byte(data->lfUnderline);
+ m_sink->write_byte(data->lfStrikeOut);
+ m_sink->write_byte(data->lfCharSet);
+ m_sink->write_byte(data->lfOutPrecision);
+ m_sink->write_byte(data->lfClipPrecision);
+ m_sink->write_byte(data->lfQuality);
+ m_sink->write_byte(data->lfPitchAndFamily);
+ m_sink->write_string(data->lfFaceName, LF_FACESIZE);
+}
+
+void lang_table_writer::write(const unsigned char *data)
+{
+ assert(sizeof(LANGID) == sizeof(short));
+
+ m_sink->write_short(* (short *) data);
+ data += sizeof(short);
+ m_sink->write_int_array((int *) data, m_lang_strings + 2);
+}
+
+void lang_table_writer::write_block(IGrowBuf *buf, writer_sink *sink, const size_t table_size)
+{
+ unsigned char *tables = (unsigned char *) buf->get();
+ size_t lang_strings = ( table_size - 2 * sizeof(int) - sizeof(LANGID) ) / sizeof(int);
+ size_t l = buf->getlen() / table_size;
+ lang_table_writer writer(sink, lang_strings);
+ for (size_t i = 0; i < l; i++)
+ {
+ writer.write(tables + i * table_size);
+ }
+}
diff --git a/Source/fileform.h b/Source/fileform.h
index 1244d18..71afdaf 100755
--- a/Source/fileform.h
+++ b/Source/fileform.h
@@ -1,63 +1,63 @@
-/*
- * fileform.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef ___MAKENSIS_FILEFORM_H___
-#define ___MAKENSIS_FILEFORM_H___
-
-#include "exehead/fileform.h"
-#include "writer.h"
-
-#define DECLARE_WRITER(x) \
- class x##_writer : public writer \
- { \
- public: \
- x##_writer(writer_sink *sink) : writer(sink) {} \
- void write(const x *data); \
- static void write_block(IGrowBuf *buf, writer_sink *sink) \
- { \
- x *arr = (x *) buf->get(); \
- size_t l = buf->getlen() / sizeof(x); \
- x##_writer writer(sink); \
- for (size_t i = 0; i < l; i++) \
- { \
- writer.write(&arr[i]); \
- } \
- } \
- }
-
-DECLARE_WRITER(firstheader);
-DECLARE_WRITER(block_header);
-DECLARE_WRITER(header);
-DECLARE_WRITER(section);
-DECLARE_WRITER(entry);
-DECLARE_WRITER(page);
-DECLARE_WRITER(ctlcolors);
-DECLARE_WRITER(LOGFONT);
-
-class lang_table_writer : public writer
-{
-public:
- lang_table_writer(writer_sink *sink, const size_t lang_strings) :
- writer(sink), m_lang_strings(lang_strings) {}
- void write(const unsigned char *data);
- static void write_block(IGrowBuf *buf, writer_sink *sink, const size_t table_size);
-
-private:
- size_t m_lang_strings;
-
-};
-
-#endif//!___MAKENSIS_FILEFORM_H___
+/*
+ * fileform.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef ___MAKENSIS_FILEFORM_H___
+#define ___MAKENSIS_FILEFORM_H___
+
+#include "exehead/fileform.h"
+#include "writer.h"
+
+#define DECLARE_WRITER(x) \
+ class x##_writer : public writer \
+ { \
+ public: \
+ x##_writer(writer_sink *sink) : writer(sink) {} \
+ void write(const x *data); \
+ static void write_block(IGrowBuf *buf, writer_sink *sink) \
+ { \
+ x *arr = (x *) buf->get(); \
+ size_t l = buf->getlen() / sizeof(x); \
+ x##_writer writer(sink); \
+ for (size_t i = 0; i < l; i++) \
+ { \
+ writer.write(&arr[i]); \
+ } \
+ } \
+ }
+
+DECLARE_WRITER(firstheader);
+DECLARE_WRITER(block_header);
+DECLARE_WRITER(header);
+DECLARE_WRITER(section);
+DECLARE_WRITER(entry);
+DECLARE_WRITER(page);
+DECLARE_WRITER(ctlcolors);
+DECLARE_WRITER(LOGFONT);
+
+class lang_table_writer : public writer
+{
+public:
+ lang_table_writer(writer_sink *sink, const size_t lang_strings) :
+ writer(sink), m_lang_strings(lang_strings) {}
+ void write(const unsigned char *data);
+ static void write_block(IGrowBuf *buf, writer_sink *sink, const size_t table_size);
+
+private:
+ size_t m_lang_strings;
+
+};
+
+#endif//!___MAKENSIS_FILEFORM_H___
diff --git a/Source/growbuf.cpp b/Source/growbuf.cpp
index 8a13b63..28d8842 100755
--- a/Source/growbuf.cpp
+++ b/Source/growbuf.cpp
@@ -1,88 +1,88 @@
-/*
- * growbuf.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "growbuf.h"
-
-#include <cstdlib> // for malloc/free
-#include <cstring> // for memcpy
-#include <cstdio> // for f*
-#include <algorithm> // for std::min
-
-#include "Platform.h"
-
-using namespace std;
-
-GrowBuf::GrowBuf() { m_alloc=m_used=m_zero=0; m_s=NULL; m_bs=32768; }
-GrowBuf::~GrowBuf() { free(m_s); }
-
-void GrowBuf::set_zeroing(int zero) { m_zero=zero; }
-
-int GrowBuf::add(const void *data, int len)
-{
- if (len<=0) return 0;
- resize(m_used+len);
- memcpy((char*)m_s+m_used-len,data,len);
- return m_used-len;
-}
-
-void GrowBuf::resize(int newlen)
-{
- int os=m_alloc;
- int ou=m_used;
- m_used=newlen;
- if (newlen > m_alloc)
- {
- void *n;
- m_alloc = newlen*2 + m_bs;
- n = realloc(m_s, m_alloc);
- if (!n)
- {
- extern FILE *g_output;
- extern int g_display_errors;
- if (g_display_errors)
- {
- fprintf(g_output,"\nack! realloc(%d) failed, trying malloc(%d)!\n",m_alloc,newlen);
- fflush(g_output);
- }
- m_alloc=newlen; // try to malloc the minimum needed
- n=malloc(m_alloc);
- if (!n)
- {
- extern void quit();
- if (g_display_errors)
- {
- fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n",m_alloc);
- fflush(g_output);
- }
- quit();
- }
- memcpy(n,m_s,min(newlen,os));
- free(m_s);
- }
- m_s=n;
- }
- if (m_zero && m_used > ou)
- memset((char*)m_s + ou, 0, m_used - ou);
- if (!m_used && m_alloc > 2*m_bs) // only free if you resize to 0 and we're > 64k
- {
- m_alloc=0;
- free(m_s);
- m_s=NULL;
- }
-}
-
-int GrowBuf::getlen() const { return m_used; }
-void *GrowBuf::get() const { return m_s; }
+/*
+ * growbuf.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "growbuf.h"
+
+#include <cstdlib> // for malloc/free
+#include <cstring> // for memcpy
+#include <cstdio> // for f*
+#include <algorithm> // for std::min
+
+#include "Platform.h"
+
+using namespace std;
+
+GrowBuf::GrowBuf() { m_alloc=m_used=m_zero=0; m_s=NULL; m_bs=32768; }
+GrowBuf::~GrowBuf() { free(m_s); }
+
+void GrowBuf::set_zeroing(int zero) { m_zero=zero; }
+
+int GrowBuf::add(const void *data, int len)
+{
+ if (len<=0) return 0;
+ resize(m_used+len);
+ memcpy((char*)m_s+m_used-len,data,len);
+ return m_used-len;
+}
+
+void GrowBuf::resize(int newlen)
+{
+ int os=m_alloc;
+ int ou=m_used;
+ m_used=newlen;
+ if (newlen > m_alloc)
+ {
+ void *n;
+ m_alloc = newlen*2 + m_bs;
+ n = realloc(m_s, m_alloc);
+ if (!n)
+ {
+ extern FILE *g_output;
+ extern int g_display_errors;
+ if (g_display_errors)
+ {
+ fprintf(g_output,"\nack! realloc(%d) failed, trying malloc(%d)!\n",m_alloc,newlen);
+ fflush(g_output);
+ }
+ m_alloc=newlen; // try to malloc the minimum needed
+ n=malloc(m_alloc);
+ if (!n)
+ {
+ extern void quit();
+ if (g_display_errors)
+ {
+ fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n",m_alloc);
+ fflush(g_output);
+ }
+ quit();
+ }
+ memcpy(n,m_s,min(newlen,os));
+ free(m_s);
+ }
+ m_s=n;
+ }
+ if (m_zero && m_used > ou)
+ memset((char*)m_s + ou, 0, m_used - ou);
+ if (!m_used && m_alloc > 2*m_bs) // only free if you resize to 0 and we're > 64k
+ {
+ m_alloc=0;
+ free(m_s);
+ m_s=NULL;
+ }
+}
+
+int GrowBuf::getlen() const { return m_used; }
+void *GrowBuf::get() const { return m_s; }
diff --git a/Source/growbuf.h b/Source/growbuf.h
index 42edef1..b3c3fb1 100755
--- a/Source/growbuf.h
+++ b/Source/growbuf.h
@@ -1,62 +1,62 @@
-/*
- * growbuf.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __GROWBUF_H_
-#define __GROWBUF_H_
-
-class IGrowBuf
-{
- public:
- virtual ~IGrowBuf() {}
- virtual int add(const void *data, int len)=0;
- virtual void resize(int newlen)=0;
- virtual int getlen() const=0;
- virtual void *get() const=0;
-};
-
-class GrowBuf : public IGrowBuf
-{
- private: // don't copy instances
- GrowBuf(const GrowBuf&);
- void operator=(const GrowBuf&);
-
- public:
- GrowBuf();
- virtual ~GrowBuf();
-
- void set_zeroing(int zero);
- int add(const void *data, int len);
- void resize(int newlen);
- int getlen() const;
- void *get() const;
-
- private:
- void *m_s;
- int m_alloc;
- int m_used;
- int m_zero;
-
- protected:
- int m_bs;
-};
-
-class TinyGrowBuf : public GrowBuf {
- public:
- TinyGrowBuf() : GrowBuf() { m_bs=1024; }
-};
-
-#endif
-
+/*
+ * growbuf.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __GROWBUF_H_
+#define __GROWBUF_H_
+
+class IGrowBuf
+{
+ public:
+ virtual ~IGrowBuf() {}
+ virtual int add(const void *data, int len)=0;
+ virtual void resize(int newlen)=0;
+ virtual int getlen() const=0;
+ virtual void *get() const=0;
+};
+
+class GrowBuf : public IGrowBuf
+{
+ private: // don't copy instances
+ GrowBuf(const GrowBuf&);
+ void operator=(const GrowBuf&);
+
+ public:
+ GrowBuf();
+ virtual ~GrowBuf();
+
+ void set_zeroing(int zero);
+ int add(const void *data, int len);
+ void resize(int newlen);
+ int getlen() const;
+ void *get() const;
+
+ private:
+ void *m_s;
+ int m_alloc;
+ int m_used;
+ int m_zero;
+
+ protected:
+ int m_bs;
+};
+
+class TinyGrowBuf : public GrowBuf {
+ public:
+ TinyGrowBuf() : GrowBuf() { m_bs=1024; }
+};
+
+#endif
+
diff --git a/Source/icon.cpp b/Source/icon.cpp
new file mode 100755
index 0000000..e169fcd
--- /dev/null
+++ b/Source/icon.cpp
@@ -0,0 +1,379 @@
+#include "Platform.h"
+#include "icon.h"
+#include "util.h"
+#include "lang.h"
+
+#include <stdio.h>
+#include <stdexcept>
+#include <vector>
+#include <algorithm>
+
+using namespace std;
+
+extern int g_display_errors;
+extern FILE *g_output;
+
+#define SIZEOF_RSRC_ICON_GROUP_ENTRY 14
+
+static FILE * open_icon(const char* filename, IconGroupHeader& igh)
+{
+ FILE* f = FOPEN(filename, "rb");
+ if (!f)
+ throw runtime_error("can't open file");
+
+ if (!fread(&igh, sizeof(IconGroupHeader), 1, f))
+ throw runtime_error("unable to read header from file");
+
+ FIX_ENDIAN_INT16_INPLACE(igh.wIsIcon);
+ FIX_ENDIAN_INT16_INPLACE(igh.wReserved);
+ FIX_ENDIAN_INT16_INPLACE(igh.wCount);
+
+ if (igh.wIsIcon != 1 || igh.wReserved != 0)
+ throw runtime_error("invalid icon file");
+
+ return f;
+}
+
+void free_loaded_icon(IconGroup icon)
+{
+ for (IconGroup::size_type i = 0; i < icon.size(); i++)
+ {
+ delete [] icon[i].data;
+ }
+}
+
+IconGroup load_icon_res(CResourceEditor* re, WORD id)
+{
+ IconGroupHeader* header;
+ IconGroup result;
+
+ LPBYTE group = re->GetResourceA(
+ RT_GROUP_ICON, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG);
+
+ if (!group)
+ throw runtime_error("can't find icon group");
+
+ header = (IconGroupHeader*) group;
+
+ for (WORD i = 0; i < FIX_ENDIAN_INT16(header->wCount); i++)
+ {
+ Icon icon;
+ icon.index = i;
+
+ RsrcIconGroupEntry* entry = (RsrcIconGroupEntry*) (group
+ + sizeof(IconGroupHeader) + SIZEOF_RSRC_ICON_GROUP_ENTRY * i);
+
+ memcpy(&icon.meta, &entry->header, sizeof(IconGroupEntry));
+
+ WORD rsrc_id = FIX_ENDIAN_INT16(entry->wRsrcId);
+
+ icon.data = re->GetResourceA(RT_ICON, MAKEINTRESOURCE(rsrc_id), NSIS_DEFAULT_LANG);
+
+ if (!icon.data)
+ {
+ free_loaded_icon(result);
+ throw runtime_error("can't find icon");
+ }
+
+ result.push_back(icon);
+ }
+
+ return result;
+}
+
+IconGroup load_icon_file(const char* filename)
+{
+ IconGroupHeader iconHeader;
+ IconGroup result;
+
+ FILE *file = open_icon(filename, iconHeader);
+
+ for (WORD i = 0; i < iconHeader.wCount; i++)
+ {
+ Icon icon;
+ icon.index = i;
+ icon.data = NULL;
+
+ if (!fread(&icon.meta, sizeof(IconGroupEntry), 1, file))
+ {
+ free_loaded_icon(result);
+ throw runtime_error("unable to read entry from file");
+ }
+
+ DWORD size = FIX_ENDIAN_INT32(icon.meta.dwRawSize);
+ if (size > 1048576) // magic numbers are great
+ {
+ free_loaded_icon(result);
+ throw runtime_error("invalid icon file size");
+ }
+
+ DWORD iconOffset;
+
+ if (!fread(&iconOffset, sizeof(DWORD), 1, file))
+ {
+ free_loaded_icon(result);
+ throw runtime_error("unable to read offset from file");
+ }
+
+ fpos_t pos;
+ fgetpos(file, &pos);
+
+ if (fseek(file, iconOffset, SEEK_SET))
+ {
+ free_loaded_icon(result);
+ throw runtime_error("corrupted icon file, too small");
+ }
+
+ icon.data = new BYTE[size];
+
+ if (!fread(icon.data, size, 1, file))
+ {
+ free_loaded_icon(result);
+ throw runtime_error("unable to read icon from file");
+ }
+
+ fsetpos(file, &pos);
+
+ result.push_back(icon);
+ }
+
+ return result;
+}
+
+typedef struct
+{
+ unsigned index1;
+ unsigned index2;
+ DWORD size;
+} IconPair;
+
+bool compare_icon(Icon a, Icon b)
+{
+ return FIX_ENDIAN_INT32(a.meta.dwRawSize) > FIX_ENDIAN_INT32(b.meta.dwRawSize);
+}
+
+static IconGroup sort_icon(IconGroup icon)
+{
+ IconGroup sorted = icon;
+ sort(sorted.begin(), sorted.end(), compare_icon);
+ return sorted;
+}
+
+static vector<IconPair> get_icon_order(IconGroup icon1, IconGroup icon2)
+{
+ IconGroup sorted_icons1 = sort_icon(icon1);
+ IconGroup sorted_icons2 = sort_icon(icon2);
+
+ IconGroup::size_type shared_count = min(sorted_icons1.size(), sorted_icons2.size());
+ IconGroup::size_type total_count = max(sorted_icons1.size(), sorted_icons2.size());
+
+ vector<IconPair> result;
+ IconGroup::size_type i;
+
+ for (i = 0; i < shared_count; i++)
+ {
+ IconPair pair;
+
+ pair.index1 = sorted_icons1[i].index;
+ pair.index2 = sorted_icons2[i].index;
+ pair.size = max(
+ FIX_ENDIAN_INT32(sorted_icons1[i].meta.dwRawSize),
+ FIX_ENDIAN_INT32(sorted_icons2[i].meta.dwRawSize)
+ );
+
+ result.push_back(pair);
+ }
+
+ for (; i < total_count; i++)
+ {
+ IconPair pair;
+
+ if (i < sorted_icons1.size())
+ {
+ pair.index1 = sorted_icons1[i].index;
+ pair.index2 = 0xffff;
+ pair.size = FIX_ENDIAN_INT32(sorted_icons1[i].meta.dwRawSize);
+ }
+
+ if (i < sorted_icons2.size())
+ {
+ pair.index2 = sorted_icons2[i].index;
+ pair.index1 = 0xffff;
+ pair.size = FIX_ENDIAN_INT32(sorted_icons2[i].meta.dwRawSize);
+ }
+
+ result.push_back(pair);
+ }
+
+ return result;
+}
+
+static LPBYTE generate_icon_group(IconGroup icon, vector<IconPair> order, bool first)
+{
+ LPBYTE group = new BYTE[
+ sizeof(IconGroupHeader) // header
+ + order.size() * SIZEOF_RSRC_ICON_GROUP_ENTRY // entries
+ ];
+
+ IconGroupHeader* header = (IconGroupHeader*) group;
+
+ header->wReserved = 0;
+ header->wIsIcon = FIX_ENDIAN_INT16(1);
+ header->wCount = FIX_ENDIAN_INT16(icon.size());
+
+ for (IconGroup::size_type i = 0; i < icon.size(); i++)
+ {
+ RsrcIconGroupEntry* entry = (RsrcIconGroupEntry*)
+ &group[sizeof(IconGroupHeader) + SIZEOF_RSRC_ICON_GROUP_ENTRY * i];
+ unsigned index = first ? order[i].index1 : order[i].index2;
+
+ memcpy(&entry->header, &icon[index].meta, sizeof(IconGroupEntry));
+ entry->wRsrcId = FIX_ENDIAN_INT16(i + 1);
+ }
+
+ return group;
+}
+
+// set_icon, must get an initialized resource editor
+void set_icon(CResourceEditor* re, WORD wIconId, IconGroup icon1, IconGroup icon2)
+{
+ vector<IconPair> order = get_icon_order(icon1, icon2);
+
+ // genreate group
+ LPBYTE group1 = generate_icon_group(icon1, order, true);
+
+ // set group
+ size_t group_size = sizeof(IconGroupHeader) // header
+ + order.size() * SIZEOF_RSRC_ICON_GROUP_ENTRY; // entries
+
+ re->UpdateResourceA(RT_GROUP_ICON, MAKEINTRESOURCE(wIconId), NSIS_DEFAULT_LANG, group1, group_size);
+
+ // delete old icons
+ unsigned i = 1;
+ while (re->UpdateResourceA(RT_ICON, MAKEINTRESOURCE(i++), NSIS_DEFAULT_LANG, 0, 0));
+
+ // set new icons
+ IconGroup::size_type order_index;
+ for (order_index = 0; order_index < order.size(); order_index++)
+ {
+ LPBYTE data = new BYTE[order[order_index].size];
+
+ if (order_index < icon1.size())
+ {
+ Icon* icon = &icon1[order[order_index].index1];
+ memcpy(data, icon->data, FIX_ENDIAN_INT32(icon->meta.dwRawSize));
+ }
+
+ re->UpdateResourceA(RT_ICON, MAKEINTRESOURCE(order_index + 1), NSIS_DEFAULT_LANG, data, order[order_index].size);
+
+ delete [] data;
+ }
+}
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+// returns the data of the uninstaller icon that should replace the installer icon data
+unsigned char* generate_uninstall_icon_data(IconGroup icon1, IconGroup icon2, size_t &data_size)
+{
+ IconGroup::size_type i;
+ vector<IconPair> order = get_icon_order(icon1, icon2);
+
+ // genreate group
+ LPBYTE group = generate_icon_group(icon2, order, false);
+
+ // calculate size
+ size_t group_size = sizeof(IconGroupHeader) // header
+ + order.size() * SIZEOF_RSRC_ICON_GROUP_ENTRY; // entries
+
+ data_size = group_size // group header
+ + sizeof(DWORD) * 2 // offset and size of group header
+ + (sizeof(DWORD) * 2) * icon2.size() // offset and size per entry
+ + sizeof(DWORD); // terminator
+
+ for (i = 0; i < icon2.size(); i++)
+ {
+ // add icon sizes
+ data_size += FIX_ENDIAN_INT32(icon2[i].meta.dwRawSize);
+ }
+
+ // allocate memory
+ LPBYTE uninst_data = new BYTE[data_size];
+ LPBYTE seeker = uninst_data;
+
+ // fill group header
+ *(LPDWORD) seeker = FIX_ENDIAN_INT32(group_size);
+ seeker += sizeof(DWORD);
+ *(LPDWORD) seeker = 0;
+ seeker += sizeof(DWORD);
+
+ memcpy(seeker, group, group_size);
+ seeker += group_size;
+
+ // fill entries
+ for (i = 0; i < icon2.size(); i++)
+ {
+ Icon* icon = &icon2[order[i].index2];
+ DWORD size = FIX_ENDIAN_INT32(icon->meta.dwRawSize);
+
+ *(LPDWORD) seeker = FIX_ENDIAN_INT32(size);
+ seeker += sizeof(DWORD);
+ *(LPDWORD) seeker = 0;
+ seeker += sizeof(DWORD);
+
+ memcpy(seeker, icon->data, size);
+ seeker += size;
+ }
+
+ // add terminator
+ *(LPDWORD) seeker = 0;
+
+ // done
+ return uninst_data;
+}
+
+// Fill the array of icons for uninstall with their offsets
+// Returns zero on failure
+int generate_unicons_offsets(LPBYTE exeHeader, size_t exeHeaderSize, LPBYTE uninstIconData, WORD wIconId) {
+ try
+ {
+ DWORD offset;
+ DWORD size;
+
+ CResourceEditor re(exeHeader, exeHeaderSize);
+
+ LPBYTE seeker = uninstIconData;
+
+ offset = re.GetResourceOffsetA(RT_GROUP_ICON, MAKEINTRESOURCE(wIconId), NSIS_DEFAULT_LANG);
+
+ size = *(LPDWORD)seeker;
+ seeker += sizeof(DWORD);
+ *(LPDWORD) seeker = FIX_ENDIAN_INT32(offset);
+ seeker += sizeof(DWORD);
+
+ seeker += FIX_ENDIAN_INT32(size);
+
+ WORD icon_index = 1;
+
+ while (*(LPDWORD)seeker)
+ {
+ offset = re.GetResourceOffsetA(RT_ICON, MAKEINTRESOURCE(icon_index), NSIS_DEFAULT_LANG);
+
+ size = *(LPDWORD)seeker;
+ seeker += sizeof(DWORD);
+ *(LPDWORD) seeker = FIX_ENDIAN_INT32(offset);
+ seeker += sizeof(DWORD);
+
+ seeker += FIX_ENDIAN_INT32(size);
+
+ icon_index++;
+ }
+ }
+ catch (const exception& e)
+ {
+ if (g_display_errors)
+ fprintf(g_output, "\nError generating uninstaller icon: %s -- failing!\n", e.what());
+ return 0;
+ }
+
+ return 1;
+}
+#endif // NSIS_CONFIG_UNINSTALL_SUPPORT
diff --git a/Source/icon.h b/Source/icon.h
new file mode 100755
index 0000000..e71f28b
--- /dev/null
+++ b/Source/icon.h
@@ -0,0 +1,76 @@
+/*
+ * icon.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef _ICON_H_
+#define _ICON_H_
+
+#include "ResourceEditor.h"
+
+#include <vector>
+
+typedef struct
+{
+ WORD wReserved;
+ WORD wIsIcon;
+ WORD wCount;
+} IconGroupHeader;
+
+typedef struct
+{
+ BYTE bWidth;
+ BYTE bHeight;
+ BYTE bPaletteEntries;
+ BYTE bReserved;
+ WORD wPlanes;
+ WORD wBitsPerPixel;
+ DWORD dwRawSize;
+} IconGroupEntry;
+
+typedef struct
+{
+ IconGroupEntry header;
+ DWORD dwImageOffset;
+} FileIconGroupEntry;
+
+typedef struct
+{
+ IconGroupEntry header;
+ WORD wRsrcId;
+} RsrcIconGroupEntry;
+
+typedef struct
+{
+ unsigned index;
+ IconGroupEntry meta;
+ LPBYTE data;
+} Icon;
+
+typedef std::vector<Icon> IconGroup;
+
+IconGroup load_icon_file(const char* filename);
+IconGroup load_icon_res(CResourceEditor* re, WORD id);
+void free_loaded_icon(IconGroup icon);
+
+void set_icon(CResourceEditor* re, WORD wIconId, IconGroup icon1, IconGroup icon2);
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+// returns the data of the uninstaller icon (inside filename) that should replace the installer icon data
+LPBYTE generate_uninstall_icon_data(IconGroup icon1, IconGroup icon2, size_t &size);
+// Fill the array of icons for uninstall with their offsets
+int generate_unicons_offsets(LPBYTE exeHeader, size_t exeHeaderSize, LPBYTE uninstIconData, WORD wIconId);
+#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
+
+#endif//_ICON_H_
diff --git a/Source/lang.cpp b/Source/lang.cpp
index 586c81a..1bf316f 100755
--- a/Source/lang.cpp
+++ b/Source/lang.cpp
@@ -1,1108 +1,1108 @@
-/*
- * lang.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include "build.h"
-#include "util.h"
-#include "DialogTemplate.h"
-#include "exehead/resource.h"
-#include "version.h"
-
-using namespace std;
-
-// Default English strings. Should match NSIS_DEFAULT_LANG
-// Do not change the first string in every item, it's the LangString
-// name for usage in scripts.
-
-typedef enum {
- NONE_STATIC = 0,
- INSTALL_STATIC = 1,
- UNINSTALL_STATIC = 2,
- BOTH_STATIC = 3
-} STATICID;
-
-struct NLFString {
- char *szLangStringName;
- char *szDefault;
- STATICID eStaticID;
-};
-
-NLFString NLFStrings[NLF_STRINGS] = {
- {"^Branding", "Nullsoft Install System %s", BOTH_STATIC},
- {"^SetupCaption", "$(^Name) Setup", INSTALL_STATIC},
- {"^UninstallCaption", "$(^Name) Uninstall", UNINSTALL_STATIC},
- {"^LicenseSubCaption", ": License Agreement", NONE_STATIC},
- {"^ComponentsSubCaption", ": Installation Options", NONE_STATIC},
- {"^DirSubCaption", ": Installation Folder", NONE_STATIC},
- {"^InstallingSubCaption", ": Installing", NONE_STATIC},
- {"^CompletedSubCaption", ": Completed", NONE_STATIC},
- {"^UnComponentsSubCaption", ": Uninstallation Options", NONE_STATIC},
- {"^UnDirSubCaption", ": Uninstallation Folder", NONE_STATIC},
- {"^ConfirmSubCaption", ": Confirmation", NONE_STATIC},
- {"^UninstallingSubCaption", ": Uninstalling", NONE_STATIC},
- {"^UnCompletedSubCaption", ": Completed", NONE_STATIC},
- {"^BackBtn", "< &Back", NONE_STATIC},
- {"^NextBtn", "&Next >", NONE_STATIC},
- {"^AgreeBtn", "I &Agree", NONE_STATIC},
- {"^AcceptBtn", "I &accept the terms in the License Agreement", NONE_STATIC},
- {"^DontAcceptBtn", "I &do not accept the terms in the License Agreement", NONE_STATIC},
- {"^InstallBtn", "&Install", NONE_STATIC},
- {"^UninstallBtn", "&Uninstall", NONE_STATIC},
- {"^CancelBtn", "Cancel", NONE_STATIC},
- {"^CloseBtn", "&Close", NONE_STATIC},
- {"^BrowseBtn", "B&rowse...", NONE_STATIC},
- {"^ShowDetailsBtn", "Show &details", NONE_STATIC},
- {"^ClickNext", "Click Next to continue.", NONE_STATIC},
- {"^ClickInstall", "Click Install to start the installation.", NONE_STATIC},
- {"^ClickUninstall", "Click Uninstall to start the uninstallation.", NONE_STATIC},
- {"^Name", "Name", BOTH_STATIC},
- {"^NameDA", 0, NONE_STATIC}, // virtual
- {"^Completed", "Completed", NONE_STATIC},
- {"^LicenseText", "Please review the license agreement before installing $(^NameDA). If you accept all terms of the agreement, click I Agree.", NONE_STATIC},
- {"^LicenseTextCB", "Please review the license agreement before installing $(^NameDA). If you accept all terms of the agreement, click the check box below. $_CLICK", NONE_STATIC},
- {"^LicenseTextRB", "Please review the license agreement before installing $(^NameDA). If you accept all terms of the agreement, select the first option below. $_CLICK", NONE_STATIC},
- {"^UnLicenseText", "Please review the license agreement before uninstalling $(^NameDA). If you accept all terms of the agreement, click I Agree.", NONE_STATIC},
- {"^UnLicenseTextCB", "Please review the license agreement before uninstalling $(^NameDA). If you accept all terms of the agreement, click the check box below. $_CLICK", NONE_STATIC},
- {"^UnLicenseTextRB", "Please review the license agreement before uninstalling $(^NameDA). If you accept all terms of the agreement, select the first option below. $_CLICK", NONE_STATIC},
- {"^LicenseData", 0, NONE_STATIC}, // virtual - not processed
- {"^Custom", "Custom", NONE_STATIC},
- {"^ComponentsText", "Check the components you want to install and uncheck the components you don't want to install. $_CLICK", NONE_STATIC},
- {"^ComponentsSubText1", "Select the type of install:", NONE_STATIC},
- {"^ComponentsSubText2_NoInstTypes", "Select components to install:", NONE_STATIC},
- {"^ComponentsSubText2", "Or, select the optional components you wish to install:", NONE_STATIC},
- {"^UnComponentsText", "Check the components you want to uninstall and uncheck the components you don't want to uninstall. $_CLICK", NONE_STATIC},
- {"^UnComponentsSubText1", "Select the type of uninstall:", NONE_STATIC},
- {"^UnComponentsSubText2_NoInstTypes", "Select components to uninstall:", NONE_STATIC},
- {"^UnComponentsSubText2", "Or, select the optional components you wish to uninstall:", NONE_STATIC},
- {"^DirText", "Setup will install $(^NameDA) in the following folder. To install in a different folder, click Browse and select another folder. $_CLICK", NONE_STATIC},
- {"^DirSubText", "Destination Folder", NONE_STATIC},
- {"^DirBrowseText", "Select the folder to install $(^NameDA) in:", NONE_STATIC},
- {"^UnDirText", "Setup will uninstall $(^NameDA) from the following folder. To uninstall from a different folder, click Browse and select another folder. $_CLICK", NONE_STATIC},
- {"^UnDirSubText", "", NONE_STATIC},
- {"^UnDirBrowseText", "Select the folder to uninstall $(^NameDA) from:", NONE_STATIC},
- {"^SpaceAvailable", "Space available: ", BOTH_STATIC},
- {"^SpaceRequired", "Space required: ", BOTH_STATIC},
- {"^UninstallingText", "This wizard will uninstall $(^NameDA) from your computer. $_CLICK", NONE_STATIC},
- {"^UninstallingSubText", "Uninstalling from:", NONE_STATIC},
- {"^FileError", "Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Abort to stop the installation,\r\nRetry to try again, or\r\nIgnore to skip this file.", NONE_STATIC},
- {"^FileError_NoIgnore", "Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Retry to try again, or\r\nCancel to stop the installation.", NONE_STATIC},
- {"^CantWrite", "Can't write: ", BOTH_STATIC},
- {"^CopyFailed", "Copy failed", BOTH_STATIC},
- {"^CopyTo", "Copy to ", BOTH_STATIC},
- {"^Registering", "Registering: ", NONE_STATIC},
- {"^Unregistering", "Unregistering: ", NONE_STATIC},
- {"^SymbolNotFound", "Could not find symbol: ", BOTH_STATIC},
- {"^CouldNotLoad", "Could not load: ", BOTH_STATIC},
- {"^CreateFolder", "Create folder: ", BOTH_STATIC},
- {"^CreateShortcut", "Create shortcut: ", BOTH_STATIC},
- {"^CreatedUninstaller", "Created uninstaller: ", BOTH_STATIC},
- {"^Delete", "Delete file: ", BOTH_STATIC},
- {"^DeleteOnReboot", "Delete on reboot: ", BOTH_STATIC},
- {"^ErrorCreatingShortcut", "Error creating shortcut: ", BOTH_STATIC},
- {"^ErrorCreating", "Error creating: ", BOTH_STATIC},
- {"^ErrorDecompressing", "Error decompressing data! Corrupted installer?", BOTH_STATIC},
- {"^ErrorRegistering", "Error registering DLL", BOTH_STATIC},
- {"^ExecShell", "ExecShell: ", BOTH_STATIC},
- {"^Exec", "Execute: ", BOTH_STATIC},
- {"^Extract", "Extract: ", BOTH_STATIC},
- {"^ErrorWriting", "Extract: error writing to file ", BOTH_STATIC},
- {"^InvalidOpcode", "Installer corrupted: invalid opcode", BOTH_STATIC},
- {"^NoOLE", "No OLE for: ", BOTH_STATIC},
- {"^OutputFolder", "Output folder: ", BOTH_STATIC},
- {"^RemoveFolder", "Remove folder: ", BOTH_STATIC},
- {"^RenameOnReboot", "Rename on reboot: ", BOTH_STATIC},
- {"^Rename", "Rename: ", BOTH_STATIC},
- {"^Skipped", "Skipped: ", BOTH_STATIC},
- {"^CopyDetails", "Copy Details To Clipboard", BOTH_STATIC},
- {"^LogInstall", "Log install process", BOTH_STATIC},
- {"^Byte", "B", BOTH_STATIC},
- {"^Kilo", "K", BOTH_STATIC},
- {"^Mega", "M", BOTH_STATIC},
- {"^Giga", "G", BOTH_STATIC},
- {"^Font", "MS Shell Dlg", NONE_STATIC},
- {"^FontSize", "8", NONE_STATIC},
- {"^RTL", "0", NONE_STATIC},
- {"^Language", "English", NONE_STATIC}
-};
-
-// ==============
-// LangStringList
-// ==============
-
-LangStringList::LangStringList() {
- count = 0;
-}
-
-int LangStringList::add(const char *name, int *sn/*=0*/)
-{
- int pos = SortedStringListND<struct langstring>::add(name);
- if (pos == -1) return -1;
-
- ((struct langstring*)gr.get())[pos].sn = count;
- if (sn) *sn = count;
- count++;
- ((struct langstring*)gr.get())[pos].index = -1;
- ((struct langstring*)gr.get())[pos].uindex = -1;
- ((struct langstring*)gr.get())[pos].process = 1;
-
- return pos;
-}
-
-int LangStringList::get(char *name, int *sn/*=0*/, int *index/*=0*/, int *uindex/*=0*/, int *process/*=0*/)
-{
- if (index) *index = -1;
- if (uindex) *uindex = -1;
- if (sn) *sn = -1;
- int v=find(name);
- if (v==-1) return -1;
- if (index) *index = ((struct langstring*)gr.get())[v].index;
- if (uindex) *uindex = ((struct langstring*)gr.get())[v].uindex;
- if (sn) *sn = ((struct langstring*)gr.get())[v].sn;
- if (process) *process = ((struct langstring*)gr.get())[v].process;
- return v;
-}
-
-void LangStringList::set(int pos, int index/*=-1*/, int uindex/*=-1*/, int process/*=-1*/)
-{
- if ((unsigned int)pos > (gr.getlen() / sizeof(struct langstring)))
- return;
-
- struct langstring *data=(struct langstring *)gr.get();
-
- if (index >= 0)
- data[pos].index = index;
- if (uindex >= 0)
- data[pos].uindex = uindex;
- if (process >= 0)
- data[pos].process = process;
-}
-
-void LangStringList::set(char *name, int index, int uindex/*=-1*/, int process/*=-1*/)
-{
- set(get(name), index, uindex, process);
-}
-
-const char* LangStringList::pos2name(int pos)
-{
- struct langstring *data=(struct langstring *)gr.get();
-
- if ((unsigned int)pos > (gr.getlen() / sizeof(struct langstring)))
- return 0;
-
- return ((const char*)strings.get() + data[pos].name);
-}
-
-const char* LangStringList::offset2name(int name)
-{
- if ((unsigned int)name > (unsigned int)strings.getlen())
- return 0;
-
- return (const char*)strings.get() + name;
-}
-
-int LangStringList::getnum()
-{
- return gr.getlen() / sizeof(struct langstring);
-}
-
-int LangStringList::compare_index(const void *item1, const void *item2)
-{
- struct langstring *ls1 = (struct langstring *)item1;
- struct langstring *ls2 = (struct langstring *)item2;
-
- return ls1->index - ls2->index;
-}
-
-langstring* LangStringList::sort_index(int *num)
-{
- if (!num) return 0;
- sortbuf.resize(0);
- sortbuf.add(gr.get(), gr.getlen());
- *num = sortbuf.getlen() / sizeof(struct langstring);
- qsort(sortbuf.get(), *num, sizeof(struct langstring), compare_index);
- return (struct langstring*) sortbuf.get();
-}
-
-int LangStringList::compare_uindex(const void *item1, const void *item2)
-{
- struct langstring *ls1 = (struct langstring *)item1;
- struct langstring *ls2 = (struct langstring *)item2;
-
- return ls1->uindex - ls2->uindex;
-}
-
-langstring* LangStringList::sort_uindex(int *num)
-{
- if (!num) return 0;
- sortbuf.resize(0);
- sortbuf.add(gr.get(), gr.getlen());
- *num = sortbuf.getlen() / sizeof(struct langstring);
- qsort(sortbuf.get(), *num, sizeof(struct langstring), compare_uindex);
- return (struct langstring*) sortbuf.get();
-}
-
-// ============
-// StringsArray
-// ============
-
-StringsArray::StringsArray()
-{
- offsets.set_zeroing(1);
-
- strings.add("", sizeof(""));
-}
-
-void StringsArray::resize(int num)
-{
- offsets.resize(num * sizeof(int));
-}
-
-int StringsArray::set(int idx, char *str)
-{
- if (idx < 0)
- return 0;
-
- if (idx >= (int)(offsets.getlen() / sizeof(int)))
- resize(idx+1);
-
- int old = ((int*)offsets.get())[idx];
-
- ((int*)offsets.get())[idx] = strings.add(str, strlen(str) + 1);
-
- return old;
-}
-
-const char* StringsArray::get(int idx)
-{
- if ((unsigned int)idx >= (offsets.getlen() / sizeof(int)))
- return 0;
-
- return (const char *)strings.get() + ((int*)offsets.get())[idx];
-}
-
-// =========
-// CEXEBuild
-// =========
-
-void CEXEBuild::InitLangTables() {
- keep_ref = false;
-
- for (int i = 0; i < NLF_STRINGS; i++) {
- NLFRefs[i].iRef = 0;
- NLFRefs[i].iUnRef = 0;
-
-#ifdef NSIS_CONFIG_LOG
- if (i == NLF_NAME) {
- NLFRefs[i].iRef++;
- NLFRefs[i].iUnRef++;
- }
-#endif
-
- if (NLFStrings[i].eStaticID & INSTALL_STATIC) {
- set_uninstall_mode(0);
- DefineLangString(NLFStrings[i].szLangStringName);
- }
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (NLFStrings[i].eStaticID & UNINSTALL_STATIC) {
- set_uninstall_mode(1);
- DefineLangString(NLFStrings[i].szLangStringName);
- }
-#endif
- }
-
- set_uninstall_mode(0);
-
- keep_ref = true;
-}
-
-LanguageTable* CEXEBuild::GetLangTable(LANGID &lang, bool create/*=true*/) {
- int nlt = lang_tables.getlen() / sizeof(LanguageTable);
- LanguageTable *nla = (LanguageTable*)lang_tables.get();
-
- lang = lang ? lang : last_used_lang;
- LanguageTable *table = NULL;
-
- for (int i = 0; i < nlt; i++) {
- if (lang == nla[i].lang_id) {
- table = &nla[i];
- break;
- }
- }
- if (!table && create) {
- LanguageTable newtable;
-
- newtable.lang_id = lang;
- newtable.dlg_offset = 0;
- memset(&newtable.nlf, 0, sizeof(NLF));
-
- newtable.lang_strings = new StringsArray;
-
- lang_tables.add(&newtable, sizeof(LanguageTable));
- table = (LanguageTable*)lang_tables.get() + nlt;
- }
-
- if (table) // update last used language if a table was loaded
- last_used_lang = lang;
-
- return table;
-}
-
-char *CEXEBuild::GetLangNameAndCP(LANGID lang, unsigned int *codepage/*=NULL*/) {
- LanguageTable *table = GetLangTable(lang, false);
-
- if (table && table->nlf.m_bLoaded) {
- if (codepage)
- *codepage = table->nlf.m_uCodePage;
-
- return table->nlf.m_szName;
- }
- else {
- if (codepage)
- *codepage = 1252; // English US
-
- if (lang == 1033)
- return "English";
- else
- return "???";
- }
-}
-
-int CEXEBuild::DefineLangString(char *name, int process/*=-1*/) {
- int index, uindex, pos, ret, sn;
- pos = build_langstrings.get(name, &sn, &index, &uindex);
- if (pos < 0) {
- pos = build_langstrings.add(name);
- }
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (!uninstall_mode) {
-#endif
- if (index < 0) {
- index = build_langstring_num++;
- }
- ret = -index - 1;
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- }
- else {
- if (uindex < 0) {
- uindex = ubuild_langstring_num++;
- }
- ret = -uindex - 1;
- }
-#endif
-
- build_langstrings.set(pos, index, uindex, process);
-
- // set reference count for NLF strings
- if (keep_ref && name[0] == '^') {
- for (int i = 0; i < NLF_STRINGS; i++) {
- if (!strcmp(name, NLFStrings[i].szLangStringName)) {
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (uninstall_mode)
- NLFRefs[i].iUnRef++;
- else
-#endif
- NLFRefs[i].iRef++;
-
- break;
- }
- }
- }
-
- return ret;
-}
-
-int CEXEBuild::DefineInnerLangString(int id, int process/*=-1*/) {
- bool old_keep_ref = keep_ref;
-
- // set reference count for NLF strings
- if (keep_ref) {
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (uninstall_mode)
- NLFRefs[id].iUnRef++;
- else
-#endif
- NLFRefs[id].iRef++;
-
- keep_ref = false;
- }
-
- int ret = DefineLangString(NLFStrings[id].szLangStringName, process);
-
- keep_ref = old_keep_ref;
-
- return ret;
-}
-
-int CEXEBuild::SetLangString(char *name, LANGID lang, char *string) {
- if (!string || !name) return PS_ERROR;
-
- LanguageTable *table = GetLangTable(lang);
- if (!table) return PS_ERROR;
-
- int sn;
-
- int pos = build_langstrings.get(name, &sn);
- if (pos < 0)
- pos = build_langstrings.add(name, &sn);
-
- if (table->lang_strings->set(sn, string))
- return PS_WARNING;
-
- return PS_OK;
-}
-
-int CEXEBuild::SetInnerString(int id, char *string) {
- if ((unsigned int)id >= NLF_STRINGS || !string) return PS_ERROR;
-
- int ret = PS_OK;
-
- const char *ps = UserInnerStrings.get(id);
- if (ps && *ps)
- ret = PS_WARNING;
-
- UserInnerStrings.set(id, string);
-
- return ret;
-}
-
-int CEXEBuild::GenerateLangTable(LanguageTable *lt, int num_lang_tables) {
- // Add all installer language strings
- int i, j, l, tabsset;
- struct langstring* lang_strings = NULL;
- TinyGrowBuf *string_ptrs = new TinyGrowBuf[num_lang_tables];
-
- tabsset = 1;
- while (tabsset)
- {
- tabsset = 0;
- for (i = num_lang_tables; i--; )
- {
- // Fill in default values for all used language strings that we can
- FillLanguageTable(&lt[i]);
- // Make sure the string lists are large enough
- string_ptrs[i].set_zeroing(1);
- if (!uninstall_mode)
- string_ptrs[i].resize(build_langstring_num * sizeof(int));
- else
- string_ptrs[i].resize(ubuild_langstring_num * sizeof(int));
- }
-
- // For all current language strings
- if (!uninstall_mode)
- lang_strings = build_langstrings.sort_index(&l);
- else
- lang_strings = build_langstrings.sort_uindex(&l);
-
- for (j = 0; j < l; j++)
- {
- int lang_string_index;
-
- if (!uninstall_mode)
- lang_string_index = lang_strings[j].index;
- else
- lang_string_index = lang_strings[j].uindex;
-
- // Is this language string used (in the installer)?
- if (lang_string_index >= 0)
- {
- // For each language
- for (i = num_lang_tables; i--; )
- {
- // Get the current string pointer
- int *ptr = (int *)string_ptrs[i].get() + lang_string_index;
- // Not already set?
- if (!*ptr)
- {
- // Get the language string and its name
- const char *str = lt[i].lang_strings->get(lang_strings[j].sn);
- const char *lsn = build_langstrings.offset2name(lang_strings[j].name);
- if (!str || !*str)
- {
- // No string is defined; give a warning (for user strings only)
- if (lsn[0] != '^')
- {
- if (lt[i].nlf.m_bLoaded)
- warning("LangString \"%s\" is not set in language table of language %s", lsn, lt[i].nlf.m_szName);
- else
- warning("LangString \"%s\" is not set in language table of language %d", lsn, lt[i].lang_id);
- }
- }
- else
- {
- // Add the language string to the string data block
- char fn[1024];
- sprintf(fn, "LangString %s", lsn);
- curfilename = fn;
- linecnt = lt[i].lang_id;
- *ptr = add_string(str, lang_strings[j].process, (WORD) lt[i].nlf.m_uCodePage);
- curfilename = 0;
- // Indicate that we should check again for any newly referenced language strings
- tabsset++;
- }
- }
- }
- }
- }
- }
-
- // Optimize langstrings and check for recursion
- for (i = num_lang_tables; i--; )
- {
- TinyGrowBuf rec;
- int *lst = (int *)string_ptrs[i].get();
-
- int langstring_num;
-
- if (!uninstall_mode)
- langstring_num = build_langstring_num;
- else
- langstring_num = ubuild_langstring_num;
-
- for (j = 0; j < langstring_num; j++)
- {
- // Does this string reference another language string directly?
- while (lst[j] < 0)
- {
- // Search through list of language string references
- for (l = 0; (unsigned int)l < rec.getlen() / sizeof(int); l++)
- {
- if (((int*)rec.get())[l] == lst[j])
- {
- // We have the index of a recursive language string; now find the name
- const char *name = "(unnamed)";
- for (l = 0; l < langstring_num; l++)
- {
- int index;
-
- if (!uninstall_mode)
- index = lang_strings[l].index;
- else
- index = lang_strings[l].uindex;
-
- if (lang_strings[l].index == j)
- {
- name = build_langstrings.offset2name(lang_strings[l].name);
- }
- }
- ERROR_MSG("Error: LangString %s is recursive!\n", name);
- delete [] string_ptrs;
- return PS_ERROR;
- }
- }
- // Add this reference to the list
- rec.add(&lst[j], sizeof(int));
- // and dereference it
- lst[j] = lst[-lst[j] - 1];
- }
- rec.resize(0);
- }
- }
-
- // Add language tables into their datablock
- for (i = num_lang_tables; i--; )
- {
- cur_langtables->add(&lt[i].lang_id, sizeof(LANGID));
- cur_langtables->add(&lt[i].dlg_offset, sizeof(int));
- int rtl = lt[i].nlf.m_bRTL ? 1 : 0;
- cur_langtables->add(&rtl, sizeof(int));
- cur_langtables->add(string_ptrs[i].get(), string_ptrs[i].getlen());
- string_ptrs[i].resize(0);
- }
-
- cur_header->blocks[NB_LANGTABLES].num = num_lang_tables;
- cur_header->langtable_size = cur_langtables->getlen() / num_lang_tables;
-
- delete [] string_ptrs;
-
- return PS_OK;
-}
-
-int CEXEBuild::GenerateLangTables() {
- int i;
- LanguageTable *lt = (LanguageTable*)lang_tables.get();
-
- SCRIPT_MSG("Generating language tables... ");
-
- if (
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- ubuild_langstring_num > MAX_CODED ||
-#endif
- build_langstring_num > MAX_CODED
- )
- {
- ERROR_MSG("\nError: too many LangStrings. Maximum allowed is %u.\n", MAX_CODED);
- return PS_ERROR;
- }
-
- // If we have no tables (user didn't set any string and didn't load any NLF) create the default one
- if (!lang_tables.getlen()) {
- LANGID lang = NSIS_DEFAULT_LANG;
- LanguageTable *table = GetLangTable(lang);
- if (!table) return PS_ERROR;
-
- lt = (LanguageTable*)lang_tables.get();
- }
-
- // Apply default font
- if (*build_font)
- {
- try {
- init_res_editor();
-
-#define ADD_FONT(id) { \
- BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG); \
- if (dlg) { \
- CDialogTemplate td(dlg); \
- res_editor->FreeResource(dlg); \
- td.SetFont(build_font, (WORD) build_font_size); \
- DWORD dwSize; \
- dlg = td.Save(dwSize); \
- res_editor->UpdateResourceA(RT_DIALOG, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG, dlg, dwSize); \
- delete [] dlg; \
- } \
- }
-
-#ifdef NSIS_CONFIG_LICENSEPAGE
- ADD_FONT(IDD_LICENSE);
- ADD_FONT(IDD_LICENSE_FSRB);
- ADD_FONT(IDD_LICENSE_FSCB);
-#endif
- ADD_FONT(IDD_DIR);
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- ADD_FONT(IDD_SELCOM);
-#endif
- ADD_FONT(IDD_INST);
- ADD_FONT(IDD_INSTFILES);
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- ADD_FONT(IDD_UNINST);
-#endif
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- ADD_FONT(IDD_VERIFY);
-#endif
-#undef ADD_FONT
- }
- catch (exception& err) {
- ERROR_MSG("\nError while applying font: %s\n", err.what());
- return PS_ERROR;
- }
- }
-
- // Fill tables with defaults (if needed) and with instruction strings
- // Create language specific resources (currently only dialogs with different fonts)
- int num_lang_tables = lang_tables.getlen() / sizeof(LanguageTable);
- // if there is one string table then there is no need for two sets of dialogs
- int cur_offset = num_lang_tables == 1 ? 0 : 100;
- for (i = 0; i < num_lang_tables; i++)
- {
- if ((lt[i].nlf.m_szFont && !*build_font) || lt[i].nlf.m_bRTL)
- {
- lt[i].dlg_offset = cur_offset;
-
- char *font = lt[i].nlf.m_szFont;
- if (*build_font) font = 0;
-
- try {
- init_res_editor();
-
-#define ADD_FONT(id) { \
- BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG); \
- if (dlg) { \
- CDialogTemplate td(dlg,lt[i].nlf.m_uCodePage); \
- res_editor->FreeResource(dlg); \
- if (font) td.SetFont(font, (WORD) lt[i].nlf.m_iFontSize); \
- if (lt[i].nlf.m_bRTL) { \
- td.ConvertToRTL(); \
- DialogItemTemplate* dir = td.GetItem(IDC_DIR); \
- if (id == IDD_DIR && dir) { \
- if ((dir->dwStyle & ES_CENTER) == 0) dir->dwStyle ^= ES_RIGHT; \
- dir->dwExtStyle &= ~(WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR); \
- } \
- } \
- DWORD dwSize; \
- dlg = td.Save(dwSize); \
- res_editor->UpdateResourceA(RT_DIALOG, MAKEINTRESOURCE(id+cur_offset), NSIS_DEFAULT_LANG, dlg, dwSize); \
- delete [] dlg; \
- } \
- }
-
-#ifdef NSIS_CONFIG_LICENSEPAGE
- ADD_FONT(IDD_LICENSE);
- ADD_FONT(IDD_LICENSE_FSRB);
- ADD_FONT(IDD_LICENSE_FSCB);
-#endif
- ADD_FONT(IDD_DIR);
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- ADD_FONT(IDD_SELCOM);
-#endif
- ADD_FONT(IDD_INST);
- ADD_FONT(IDD_INSTFILES);
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- ADD_FONT(IDD_UNINST);
-#endif
-#ifdef NSIS_CONFIG_CRC_SUPPORT
- ADD_FONT(IDD_VERIFY);
-#endif
-#undef ADD_FONT
- }
- catch (exception& err) {
- ERROR_MSG("\nError while applying NLF font/RTL: %s\n", err.what());
- return PS_ERROR;
- }
-
- cur_offset += 100;
- }
- }
-
- int orig_uninstall_mode = uninstall_mode;
-
- set_uninstall_mode(0);
- if (GenerateLangTable(lt, num_lang_tables) != PS_OK)
- return PS_ERROR;
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- set_uninstall_mode(1);
- if (GenerateLangTable(lt, num_lang_tables) != PS_OK)
- return PS_ERROR;
-#endif
-
- set_uninstall_mode(orig_uninstall_mode);
-
- SCRIPT_MSG("Done!\n");
-
- return PS_OK;
-}
-
-void CEXEBuild::FillLanguageTable(LanguageTable *table) {
- for (int i = 0; i < NLF_STRINGS; i++) {
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (!NLFRefs[i].iUnRef && !NLFRefs[i].iRef)
- continue;
-#else
- if (!NLFRefs[i].iRef)
- continue;
-#endif
-
- else if (i == NLF_SPACE_REQ || i == NLF_SPACE_AVAIL)
- {
- if (no_space_texts)
- {
- continue;
- }
- }
-
- int sn, index;
- int pos = build_langstrings.get(NLFStrings[i].szLangStringName, &sn, &index);
- if (pos >= 0) {
- const char *str = table->lang_strings->get(sn);
- if (!str || !*str) {
- const char *us = UserInnerStrings.get(i);
- if (i == NLF_NAME_DA && (!us || !*us))
- {
- // if the user didn't set NLF_NAME_DA we set it to $(^Name)
- table->lang_strings->set(sn, "$(^Name)");
- }
- if (us && *us) {
- table->lang_strings->set(sn, (char *) us);
- }
- else {
- char *dstr = table->nlf.m_szStrings[i] ? table->nlf.m_szStrings[i] : NLFStrings[i].szDefault;
- if (!dstr)
- continue;
- if (i == NLF_BRANDING) {
- char temp[NSIS_MAX_STRLEN + sizeof(NSIS_VERSION)];
- sprintf(temp, dstr, NSIS_VERSION);
- table->lang_strings->set(sn, temp);
- continue;
- }
- else if (i == NLF_FONT)
- {
- char *font = *build_font ? build_font : table->nlf.m_szFont;
- if (font)
- table->lang_strings->set(sn, font);
- else
- table->lang_strings->set(sn, dstr);
- continue;
- }
- else if (i == NLF_FONTSIZE)
- {
- WORD font_size = *build_font ? (WORD) build_font_size : (WORD) table->nlf.m_iFontSize;
- if (font_size)
- {
- char temp[64];
- sprintf(temp, "%d", font_size);
- table->lang_strings->set(sn, temp);
- }
- else
- table->lang_strings->set(sn, dstr);
- continue;
- }
- table->lang_strings->set(sn, dstr);
- }
- }
- }
- }
-}
-
-char SkipComments(FILE *f) {
- int c;
- while ((c = fgetc(f))) {
- while (c == '\n' || c == '\r') {
- c = fgetc(f); // Skip empty lines
- }
- if (c == '#' || c == ';') {
- while ((c = fgetc(f))) {
- if (c == '\n') break;
- }
- }
- else break;
- }
- return (char) c;
-}
-
-// NSIS Language File parser
-LanguageTable * CEXEBuild::LoadLangFile(char *filename) {
- FILE *f = FOPEN(filename, "r");
- if (!f) {
- ERROR_MSG("Error: Can't open language file - \"%s\"!\n",filename);
- return 0;
- }
-
- // Check header
- char buf[NSIS_MAX_STRLEN];
- buf[0] = SkipComments(f);
- fgets(buf+1, NSIS_MAX_STRLEN, f);
-
- if (strncmp(buf, "NLF v", 5)) {
- ERROR_MSG("Error: Invalid language file.\n");
- return 0;
- }
- int nlf_version = atoi(buf+5);
- if (nlf_version != NLF_VERSION) {
- if (nlf_version != 2 && nlf_version != 3 && nlf_version != 4 && nlf_version != 5) {
- ERROR_MSG("Error: Language file version doesn't match NSIS version.\n");
- return 0;
- }
- }
-
- // Get language ID
- buf[0] = SkipComments(f);
- fgets(buf+1, NSIS_MAX_STRLEN, f);
- LANGID lang_id = atoi(buf);
-
- // Get appropriate table
- LanguageTable *table = GetLangTable(lang_id);
- if (!table)
- return 0;
-
- NLF *nlf = &table->nlf;
-
- if (nlf->m_bLoaded) {
- ERROR_MSG("Error: can't load same language file twice.\n");
- return 0;
- }
-
- // Generate language name
- char *p, *p2, t = 0;
-
- p = strrchr(filename, '.');
- if (p) {
- t = *p;
- *p = 0;
- }
- p2 = strrchr(filename, '\\');
- if (p2) {
- p2++;
- nlf->m_szName = (char*)malloc(strlen(p2)+1);
- strcpy(nlf->m_szName, p2);
- }
- else {
- nlf->m_szName = (char*)malloc(strlen(filename)+1);
- strcpy(nlf->m_szName, filename);
- }
- if (p) *p = t;
-
- if (nlf_version != NLF_VERSION) {
- warning_fl("%s language file version doesn't match. Using default English texts for missing strings.", nlf->m_szName);
- }
-
- // set ^Language
- nlf->m_szStrings[NLF_LANGUAGE] = strdup(nlf->m_szName);
-
- int temp;
-
- // Get font
- buf[0] = SkipComments(f);
- fgets(buf+1, NSIS_MAX_STRLEN, f);
- if (!nlf->m_szFont) {
- temp=strlen(buf);
- while (buf[temp-1] == '\n' || buf[temp-1] == '\r') {
- buf[temp-1] = 0;
- temp--;
- }
- if (buf[0] != '-' || buf[1] != 0) {
- nlf->m_szFont = (char*)malloc(strlen(buf)+1);
- strcpy(nlf->m_szFont, buf);
- }
- }
-
- buf[0] = SkipComments(f);
- fgets(buf+1, NSIS_MAX_STRLEN, f);
- if (!nlf->m_iFontSize) {
- if (buf[0] != '-' || buf[1] != 0) {
- nlf->m_iFontSize = atoi(buf);
- }
- }
-
- // Get code page
- nlf->m_uCodePage = CP_ACP;
- buf[0] = SkipComments(f);
- fgets(buf+1, NSIS_MAX_STRLEN, f);
- if (buf[0] != '-' || buf[1] != 0) {
- nlf->m_uCodePage = atoi(buf);
- if (!IsValidCodePage(nlf->m_uCodePage))
- nlf->m_uCodePage = CP_ACP;
- }
-
- // Get RTL setting
- nlf->m_szStrings[NLF_RTL] = (char *)malloc(2);
- nlf->m_bRTL = false;
- buf[0] = SkipComments(f);
- fgets(buf+1, NSIS_MAX_STRLEN, f);
- if (buf[0] == 'R' && buf[1] == 'T' && buf[2] == 'L' && (!buf[3] || buf[3] == '\r' || buf[3] == '\n')) {
- nlf->m_bRTL = true;
- strcpy(nlf->m_szStrings[NLF_RTL], "1");
- }
- else {
- strcpy(nlf->m_szStrings[NLF_RTL], "0");
- }
-
- // Read strings
- for (int i = 0; i < NLF_STRINGS_NO_SPECIAL; i++) {
-
- // skip virtual strings
- if (!NLFStrings[i].szDefault)
- continue;
-
- // Fill in for missing strings
- // 0 will mean default will be used from NLFStrings
- switch (i) {
- case NLF_BTN_LICENSE_AGREE:
- case NLF_BTN_LICENSE_DISAGREE:
- if (nlf_version >= 3) break;
- case NLF_LOG_INSTALL_PROCESS:
- case NLF_BYTE:
- case NLF_KILO:
- case NLF_MEGA:
- case NLF_GIGA:
- case NLF_REGISTERING:
- case NLF_UNREGISTERING:
- if (nlf_version >= 4) break;
- case NLF_FILE_ERROR_NOIGNORE:
- if (nlf_version >= 5) break;
- case NLF_USUBCAPTION_OPTIONS:
- case NLF_USUBCAPTION_DIR:
- case NLF_CLICK_NEXT:
- case NLF_CLICK_INSTALL:
- case NLF_CLICK_UNINSTALL:
- case NLF_LICENSE_TEXT:
- case NLF_LICENSE_TEXT_FSCB:
- case NLF_LICENSE_TEXT_FSRB:
- case NLF_ULICENSE_TEXT:
- case NLF_ULICENSE_TEXT_FSCB:
- case NLF_ULICENSE_TEXT_FSRB:
- case NLF_COMP_TEXT:
- case NLF_UCOMP_TEXT:
- case NLF_UCOMP_SUBTEXT1:
- case NLF_UCOMP_SUBTEXT1_NO_INST_TYPES:
- case NLF_UCOMP_SUBTEXT2:
- case NLF_DIR_TEXT:
- case NLF_DIR_BROWSETEXT:
- case NLF_UDIR_TEXT:
- case NLF_UDIR_SUBTEXT:
- case NLF_UDIR_BROWSETEXT:
- case NLF_UNINST_TEXT:
- if (nlf_version >= 6) break;
- nlf->m_szStrings[i] = 0;
- continue;
- }
-
- buf[0] = SkipComments(f);
-
- fgets(buf+1, NSIS_MAX_STRLEN, f);
- if (strlen(buf) == NSIS_MAX_STRLEN-1) {
- ERROR_MSG("Error: String too long (string #%d - \"%s\")", i, NLFStrings[i].szLangStringName);
- return 0;
- }
- temp=strlen(buf);
-
- while (buf[temp-1] == '\n' || buf[temp-1] == '\r') {
- buf[--temp] = 0;
- }
-
- char *in = buf;
-
- // trim quotes
- if (buf[0] == '"' && buf[temp-1] == '"') {
- in++;
- buf[--temp] = 0;
- }
-
- nlf->m_szStrings[i] = (char*)malloc(temp+1);
- char *out;
- for (out = nlf->m_szStrings[i]; *in; in++, out++) {
- if (*in == '\\') {
- in++;
- switch (*in) {
- case 'n':
- *out = '\n';
- break;
- case 'r':
- *out = '\r';
- break;
- case 't':
- *out = '\t';
- break;
- default:
- *out++ = '\\';
- *out = *in;
- }
- }
- else *out = *in;
- }
- *out = 0;
- }
- fclose(f);
-
- nlf->m_bLoaded = true;
-
- return table;
-}
-
-void CEXEBuild::DeleteLangTable(LanguageTable *table) {
- if (table->nlf.m_szName)
- free(table->nlf.m_szName);
- if (table->nlf.m_szFont)
- free(table->nlf.m_szFont);
- delete table->lang_strings;
- for (int i = 0; i < NLF_STRINGS; i++) {
- if (table->nlf.m_szStrings[i])
- free(table->nlf.m_szStrings[i]);
- }
-}
+/*
+ * lang.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "build.h"
+#include "util.h"
+#include "DialogTemplate.h"
+#include "exehead/resource.h"
+#include "version.h"
+
+using namespace std;
+
+// Default English strings. Should match NSIS_DEFAULT_LANG
+// Do not change the first string in every item, it's the LangString
+// name for usage in scripts.
+
+typedef enum {
+ NONE_STATIC = 0,
+ INSTALL_STATIC = 1,
+ UNINSTALL_STATIC = 2,
+ BOTH_STATIC = 3
+} STATICID;
+
+struct NLFString {
+ char *szLangStringName;
+ char *szDefault;
+ STATICID eStaticID;
+};
+
+NLFString NLFStrings[NLF_STRINGS] = {
+ {"^Branding", "Nullsoft Install System %s", BOTH_STATIC},
+ {"^SetupCaption", "$(^Name) Setup", INSTALL_STATIC},
+ {"^UninstallCaption", "$(^Name) Uninstall", UNINSTALL_STATIC},
+ {"^LicenseSubCaption", ": License Agreement", NONE_STATIC},
+ {"^ComponentsSubCaption", ": Installation Options", NONE_STATIC},
+ {"^DirSubCaption", ": Installation Folder", NONE_STATIC},
+ {"^InstallingSubCaption", ": Installing", NONE_STATIC},
+ {"^CompletedSubCaption", ": Completed", NONE_STATIC},
+ {"^UnComponentsSubCaption", ": Uninstallation Options", NONE_STATIC},
+ {"^UnDirSubCaption", ": Uninstallation Folder", NONE_STATIC},
+ {"^ConfirmSubCaption", ": Confirmation", NONE_STATIC},
+ {"^UninstallingSubCaption", ": Uninstalling", NONE_STATIC},
+ {"^UnCompletedSubCaption", ": Completed", NONE_STATIC},
+ {"^BackBtn", "< &Back", NONE_STATIC},
+ {"^NextBtn", "&Next >", NONE_STATIC},
+ {"^AgreeBtn", "I &Agree", NONE_STATIC},
+ {"^AcceptBtn", "I &accept the terms in the License Agreement", NONE_STATIC},
+ {"^DontAcceptBtn", "I &do not accept the terms in the License Agreement", NONE_STATIC},
+ {"^InstallBtn", "&Install", NONE_STATIC},
+ {"^UninstallBtn", "&Uninstall", NONE_STATIC},
+ {"^CancelBtn", "Cancel", NONE_STATIC},
+ {"^CloseBtn", "&Close", NONE_STATIC},
+ {"^BrowseBtn", "B&rowse...", NONE_STATIC},
+ {"^ShowDetailsBtn", "Show &details", NONE_STATIC},
+ {"^ClickNext", "Click Next to continue.", NONE_STATIC},
+ {"^ClickInstall", "Click Install to start the installation.", NONE_STATIC},
+ {"^ClickUninstall", "Click Uninstall to start the uninstallation.", NONE_STATIC},
+ {"^Name", "Name", BOTH_STATIC},
+ {"^NameDA", 0, NONE_STATIC}, // virtual
+ {"^Completed", "Completed", NONE_STATIC},
+ {"^LicenseText", "Please review the license agreement before installing $(^NameDA). If you accept all terms of the agreement, click I Agree.", NONE_STATIC},
+ {"^LicenseTextCB", "Please review the license agreement before installing $(^NameDA). If you accept all terms of the agreement, click the check box below. $_CLICK", NONE_STATIC},
+ {"^LicenseTextRB", "Please review the license agreement before installing $(^NameDA). If you accept all terms of the agreement, select the first option below. $_CLICK", NONE_STATIC},
+ {"^UnLicenseText", "Please review the license agreement before uninstalling $(^NameDA). If you accept all terms of the agreement, click I Agree.", NONE_STATIC},
+ {"^UnLicenseTextCB", "Please review the license agreement before uninstalling $(^NameDA). If you accept all terms of the agreement, click the check box below. $_CLICK", NONE_STATIC},
+ {"^UnLicenseTextRB", "Please review the license agreement before uninstalling $(^NameDA). If you accept all terms of the agreement, select the first option below. $_CLICK", NONE_STATIC},
+ {"^LicenseData", 0, NONE_STATIC}, // virtual - not processed
+ {"^Custom", "Custom", NONE_STATIC},
+ {"^ComponentsText", "Check the components you want to install and uncheck the components you don't want to install. $_CLICK", NONE_STATIC},
+ {"^ComponentsSubText1", "Select the type of install:", NONE_STATIC},
+ {"^ComponentsSubText2_NoInstTypes", "Select components to install:", NONE_STATIC},
+ {"^ComponentsSubText2", "Or, select the optional components you wish to install:", NONE_STATIC},
+ {"^UnComponentsText", "Check the components you want to uninstall and uncheck the components you don't want to uninstall. $_CLICK", NONE_STATIC},
+ {"^UnComponentsSubText1", "Select the type of uninstall:", NONE_STATIC},
+ {"^UnComponentsSubText2_NoInstTypes", "Select components to uninstall:", NONE_STATIC},
+ {"^UnComponentsSubText2", "Or, select the optional components you wish to uninstall:", NONE_STATIC},
+ {"^DirText", "Setup will install $(^NameDA) in the following folder. To install in a different folder, click Browse and select another folder. $_CLICK", NONE_STATIC},
+ {"^DirSubText", "Destination Folder", NONE_STATIC},
+ {"^DirBrowseText", "Select the folder to install $(^NameDA) in:", NONE_STATIC},
+ {"^UnDirText", "Setup will uninstall $(^NameDA) from the following folder. To uninstall from a different folder, click Browse and select another folder. $_CLICK", NONE_STATIC},
+ {"^UnDirSubText", "", NONE_STATIC},
+ {"^UnDirBrowseText", "Select the folder to uninstall $(^NameDA) from:", NONE_STATIC},
+ {"^SpaceAvailable", "Space available: ", BOTH_STATIC},
+ {"^SpaceRequired", "Space required: ", BOTH_STATIC},
+ {"^UninstallingText", "This wizard will uninstall $(^NameDA) from your computer. $_CLICK", NONE_STATIC},
+ {"^UninstallingSubText", "Uninstalling from:", NONE_STATIC},
+ {"^FileError", "Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Abort to stop the installation,\r\nRetry to try again, or\r\nIgnore to skip this file.", NONE_STATIC},
+ {"^FileError_NoIgnore", "Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Retry to try again, or\r\nCancel to stop the installation.", NONE_STATIC},
+ {"^CantWrite", "Can't write: ", BOTH_STATIC},
+ {"^CopyFailed", "Copy failed", BOTH_STATIC},
+ {"^CopyTo", "Copy to ", BOTH_STATIC},
+ {"^Registering", "Registering: ", NONE_STATIC},
+ {"^Unregistering", "Unregistering: ", NONE_STATIC},
+ {"^SymbolNotFound", "Could not find symbol: ", BOTH_STATIC},
+ {"^CouldNotLoad", "Could not load: ", BOTH_STATIC},
+ {"^CreateFolder", "Create folder: ", BOTH_STATIC},
+ {"^CreateShortcut", "Create shortcut: ", BOTH_STATIC},
+ {"^CreatedUninstaller", "Created uninstaller: ", BOTH_STATIC},
+ {"^Delete", "Delete file: ", BOTH_STATIC},
+ {"^DeleteOnReboot", "Delete on reboot: ", BOTH_STATIC},
+ {"^ErrorCreatingShortcut", "Error creating shortcut: ", BOTH_STATIC},
+ {"^ErrorCreating", "Error creating: ", BOTH_STATIC},
+ {"^ErrorDecompressing", "Error decompressing data! Corrupted installer?", BOTH_STATIC},
+ {"^ErrorRegistering", "Error registering DLL", BOTH_STATIC},
+ {"^ExecShell", "ExecShell: ", BOTH_STATIC},
+ {"^Exec", "Execute: ", BOTH_STATIC},
+ {"^Extract", "Extract: ", BOTH_STATIC},
+ {"^ErrorWriting", "Extract: error writing to file ", BOTH_STATIC},
+ {"^InvalidOpcode", "Installer corrupted: invalid opcode", BOTH_STATIC},
+ {"^NoOLE", "No OLE for: ", BOTH_STATIC},
+ {"^OutputFolder", "Output folder: ", BOTH_STATIC},
+ {"^RemoveFolder", "Remove folder: ", BOTH_STATIC},
+ {"^RenameOnReboot", "Rename on reboot: ", BOTH_STATIC},
+ {"^Rename", "Rename: ", BOTH_STATIC},
+ {"^Skipped", "Skipped: ", BOTH_STATIC},
+ {"^CopyDetails", "Copy Details To Clipboard", BOTH_STATIC},
+ {"^LogInstall", "Log install process", BOTH_STATIC},
+ {"^Byte", "B", BOTH_STATIC},
+ {"^Kilo", "K", BOTH_STATIC},
+ {"^Mega", "M", BOTH_STATIC},
+ {"^Giga", "G", BOTH_STATIC},
+ {"^Font", "MS Shell Dlg", NONE_STATIC},
+ {"^FontSize", "8", NONE_STATIC},
+ {"^RTL", "0", NONE_STATIC},
+ {"^Language", "English", NONE_STATIC}
+};
+
+// ==============
+// LangStringList
+// ==============
+
+LangStringList::LangStringList() {
+ count = 0;
+}
+
+int LangStringList::add(const char *name, int *sn/*=0*/)
+{
+ int pos = SortedStringListND<struct langstring>::add(name);
+ if (pos == -1) return -1;
+
+ ((struct langstring*)gr.get())[pos].sn = count;
+ if (sn) *sn = count;
+ count++;
+ ((struct langstring*)gr.get())[pos].index = -1;
+ ((struct langstring*)gr.get())[pos].uindex = -1;
+ ((struct langstring*)gr.get())[pos].process = 1;
+
+ return pos;
+}
+
+int LangStringList::get(char *name, int *sn/*=0*/, int *index/*=0*/, int *uindex/*=0*/, int *process/*=0*/)
+{
+ if (index) *index = -1;
+ if (uindex) *uindex = -1;
+ if (sn) *sn = -1;
+ int v=find(name);
+ if (v==-1) return -1;
+ if (index) *index = ((struct langstring*)gr.get())[v].index;
+ if (uindex) *uindex = ((struct langstring*)gr.get())[v].uindex;
+ if (sn) *sn = ((struct langstring*)gr.get())[v].sn;
+ if (process) *process = ((struct langstring*)gr.get())[v].process;
+ return v;
+}
+
+void LangStringList::set(int pos, int index/*=-1*/, int uindex/*=-1*/, int process/*=-1*/)
+{
+ if ((unsigned int)pos > (gr.getlen() / sizeof(struct langstring)))
+ return;
+
+ struct langstring *data=(struct langstring *)gr.get();
+
+ if (index >= 0)
+ data[pos].index = index;
+ if (uindex >= 0)
+ data[pos].uindex = uindex;
+ if (process >= 0)
+ data[pos].process = process;
+}
+
+void LangStringList::set(char *name, int index, int uindex/*=-1*/, int process/*=-1*/)
+{
+ set(get(name), index, uindex, process);
+}
+
+const char* LangStringList::pos2name(int pos)
+{
+ struct langstring *data=(struct langstring *)gr.get();
+
+ if ((unsigned int)pos > (gr.getlen() / sizeof(struct langstring)))
+ return 0;
+
+ return ((const char*)strings.get() + data[pos].name);
+}
+
+const char* LangStringList::offset2name(int name)
+{
+ if ((unsigned int)name > (unsigned int)strings.getlen())
+ return 0;
+
+ return (const char*)strings.get() + name;
+}
+
+int LangStringList::getnum()
+{
+ return gr.getlen() / sizeof(struct langstring);
+}
+
+int LangStringList::compare_index(const void *item1, const void *item2)
+{
+ struct langstring *ls1 = (struct langstring *)item1;
+ struct langstring *ls2 = (struct langstring *)item2;
+
+ return ls1->index - ls2->index;
+}
+
+langstring* LangStringList::sort_index(int *num)
+{
+ if (!num) return 0;
+ sortbuf.resize(0);
+ sortbuf.add(gr.get(), gr.getlen());
+ *num = sortbuf.getlen() / sizeof(struct langstring);
+ qsort(sortbuf.get(), *num, sizeof(struct langstring), compare_index);
+ return (struct langstring*) sortbuf.get();
+}
+
+int LangStringList::compare_uindex(const void *item1, const void *item2)
+{
+ struct langstring *ls1 = (struct langstring *)item1;
+ struct langstring *ls2 = (struct langstring *)item2;
+
+ return ls1->uindex - ls2->uindex;
+}
+
+langstring* LangStringList::sort_uindex(int *num)
+{
+ if (!num) return 0;
+ sortbuf.resize(0);
+ sortbuf.add(gr.get(), gr.getlen());
+ *num = sortbuf.getlen() / sizeof(struct langstring);
+ qsort(sortbuf.get(), *num, sizeof(struct langstring), compare_uindex);
+ return (struct langstring*) sortbuf.get();
+}
+
+// ============
+// StringsArray
+// ============
+
+StringsArray::StringsArray()
+{
+ offsets.set_zeroing(1);
+
+ strings.add("", sizeof(""));
+}
+
+void StringsArray::resize(int num)
+{
+ offsets.resize(num * sizeof(int));
+}
+
+int StringsArray::set(int idx, char *str)
+{
+ if (idx < 0)
+ return 0;
+
+ if (idx >= (int)(offsets.getlen() / sizeof(int)))
+ resize(idx+1);
+
+ int old = ((int*)offsets.get())[idx];
+
+ ((int*)offsets.get())[idx] = strings.add(str, strlen(str) + 1);
+
+ return old;
+}
+
+const char* StringsArray::get(int idx)
+{
+ if ((unsigned int)idx >= (offsets.getlen() / sizeof(int)))
+ return 0;
+
+ return (const char *)strings.get() + ((int*)offsets.get())[idx];
+}
+
+// =========
+// CEXEBuild
+// =========
+
+void CEXEBuild::InitLangTables() {
+ keep_ref = false;
+
+ for (int i = 0; i < NLF_STRINGS; i++) {
+ NLFRefs[i].iRef = 0;
+ NLFRefs[i].iUnRef = 0;
+
+#ifdef NSIS_CONFIG_LOG
+ if (i == NLF_NAME) {
+ NLFRefs[i].iRef++;
+ NLFRefs[i].iUnRef++;
+ }
+#endif
+
+ if (NLFStrings[i].eStaticID & INSTALL_STATIC) {
+ set_uninstall_mode(0);
+ DefineLangString(NLFStrings[i].szLangStringName);
+ }
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (NLFStrings[i].eStaticID & UNINSTALL_STATIC) {
+ set_uninstall_mode(1);
+ DefineLangString(NLFStrings[i].szLangStringName);
+ }
+#endif
+ }
+
+ set_uninstall_mode(0);
+
+ keep_ref = true;
+}
+
+LanguageTable* CEXEBuild::GetLangTable(LANGID &lang, bool create/*=true*/) {
+ int nlt = lang_tables.getlen() / sizeof(LanguageTable);
+ LanguageTable *nla = (LanguageTable*)lang_tables.get();
+
+ lang = lang ? lang : last_used_lang;
+ LanguageTable *table = NULL;
+
+ for (int i = 0; i < nlt; i++) {
+ if (lang == nla[i].lang_id) {
+ table = &nla[i];
+ break;
+ }
+ }
+ if (!table && create) {
+ LanguageTable newtable;
+
+ newtable.lang_id = lang;
+ newtable.dlg_offset = 0;
+ memset(&newtable.nlf, 0, sizeof(NLF));
+
+ newtable.lang_strings = new StringsArray;
+
+ lang_tables.add(&newtable, sizeof(LanguageTable));
+ table = (LanguageTable*)lang_tables.get() + nlt;
+ }
+
+ if (table) // update last used language if a table was loaded
+ last_used_lang = lang;
+
+ return table;
+}
+
+char *CEXEBuild::GetLangNameAndCP(LANGID lang, unsigned int *codepage/*=NULL*/) {
+ LanguageTable *table = GetLangTable(lang, false);
+
+ if (table && table->nlf.m_bLoaded) {
+ if (codepage)
+ *codepage = table->nlf.m_uCodePage;
+
+ return table->nlf.m_szName;
+ }
+ else {
+ if (codepage)
+ *codepage = 1252; // English US
+
+ if (lang == 1033)
+ return "English";
+ else
+ return "???";
+ }
+}
+
+int CEXEBuild::DefineLangString(char *name, int process/*=-1*/) {
+ int index, uindex, pos, ret, sn;
+ pos = build_langstrings.get(name, &sn, &index, &uindex);
+ if (pos < 0) {
+ pos = build_langstrings.add(name);
+ }
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (!uninstall_mode) {
+#endif
+ if (index < 0) {
+ index = build_langstring_num++;
+ }
+ ret = -index - 1;
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ }
+ else {
+ if (uindex < 0) {
+ uindex = ubuild_langstring_num++;
+ }
+ ret = -uindex - 1;
+ }
+#endif
+
+ build_langstrings.set(pos, index, uindex, process);
+
+ // set reference count for NLF strings
+ if (keep_ref && name[0] == '^') {
+ for (int i = 0; i < NLF_STRINGS; i++) {
+ if (!strcmp(name, NLFStrings[i].szLangStringName)) {
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (uninstall_mode)
+ NLFRefs[i].iUnRef++;
+ else
+#endif
+ NLFRefs[i].iRef++;
+
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+int CEXEBuild::DefineInnerLangString(int id, int process/*=-1*/) {
+ bool old_keep_ref = keep_ref;
+
+ // set reference count for NLF strings
+ if (keep_ref) {
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (uninstall_mode)
+ NLFRefs[id].iUnRef++;
+ else
+#endif
+ NLFRefs[id].iRef++;
+
+ keep_ref = false;
+ }
+
+ int ret = DefineLangString(NLFStrings[id].szLangStringName, process);
+
+ keep_ref = old_keep_ref;
+
+ return ret;
+}
+
+int CEXEBuild::SetLangString(char *name, LANGID lang, char *string) {
+ if (!string || !name) return PS_ERROR;
+
+ LanguageTable *table = GetLangTable(lang);
+ if (!table) return PS_ERROR;
+
+ int sn;
+
+ int pos = build_langstrings.get(name, &sn);
+ if (pos < 0)
+ pos = build_langstrings.add(name, &sn);
+
+ if (table->lang_strings->set(sn, string))
+ return PS_WARNING;
+
+ return PS_OK;
+}
+
+int CEXEBuild::SetInnerString(int id, char *string) {
+ if ((unsigned int)id >= NLF_STRINGS || !string) return PS_ERROR;
+
+ int ret = PS_OK;
+
+ const char *ps = UserInnerStrings.get(id);
+ if (ps && *ps)
+ ret = PS_WARNING;
+
+ UserInnerStrings.set(id, string);
+
+ return ret;
+}
+
+int CEXEBuild::GenerateLangTable(LanguageTable *lt, int num_lang_tables) {
+ // Add all installer language strings
+ int i, j, l, tabsset;
+ struct langstring* lang_strings = NULL;
+ TinyGrowBuf *string_ptrs = new TinyGrowBuf[num_lang_tables];
+
+ tabsset = 1;
+ while (tabsset)
+ {
+ tabsset = 0;
+ for (i = num_lang_tables; i--; )
+ {
+ // Fill in default values for all used language strings that we can
+ FillLanguageTable(&lt[i]);
+ // Make sure the string lists are large enough
+ string_ptrs[i].set_zeroing(1);
+ if (!uninstall_mode)
+ string_ptrs[i].resize(build_langstring_num * sizeof(int));
+ else
+ string_ptrs[i].resize(ubuild_langstring_num * sizeof(int));
+ }
+
+ // For all current language strings
+ if (!uninstall_mode)
+ lang_strings = build_langstrings.sort_index(&l);
+ else
+ lang_strings = build_langstrings.sort_uindex(&l);
+
+ for (j = 0; j < l; j++)
+ {
+ int lang_string_index;
+
+ if (!uninstall_mode)
+ lang_string_index = lang_strings[j].index;
+ else
+ lang_string_index = lang_strings[j].uindex;
+
+ // Is this language string used (in the installer)?
+ if (lang_string_index >= 0)
+ {
+ // For each language
+ for (i = num_lang_tables; i--; )
+ {
+ // Get the current string pointer
+ int *ptr = (int *)string_ptrs[i].get() + lang_string_index;
+ // Not already set?
+ if (!*ptr)
+ {
+ // Get the language string and its name
+ const char *str = lt[i].lang_strings->get(lang_strings[j].sn);
+ const char *lsn = build_langstrings.offset2name(lang_strings[j].name);
+ if (!str || !*str)
+ {
+ // No string is defined; give a warning (for user strings only)
+ if (lsn[0] != '^')
+ {
+ if (lt[i].nlf.m_bLoaded)
+ warning("LangString \"%s\" is not set in language table of language %s", lsn, lt[i].nlf.m_szName);
+ else
+ warning("LangString \"%s\" is not set in language table of language %d", lsn, lt[i].lang_id);
+ }
+ }
+ else
+ {
+ // Add the language string to the string data block
+ char fn[1024];
+ sprintf(fn, "LangString %s", lsn);
+ curfilename = fn;
+ linecnt = lt[i].lang_id;
+ *ptr = add_string(str, lang_strings[j].process, (WORD) lt[i].nlf.m_uCodePage);
+ curfilename = 0;
+ // Indicate that we should check again for any newly referenced language strings
+ tabsset++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Optimize langstrings and check for recursion
+ for (i = num_lang_tables; i--; )
+ {
+ TinyGrowBuf rec;
+ int *lst = (int *)string_ptrs[i].get();
+
+ int langstring_num;
+
+ if (!uninstall_mode)
+ langstring_num = build_langstring_num;
+ else
+ langstring_num = ubuild_langstring_num;
+
+ for (j = 0; j < langstring_num; j++)
+ {
+ // Does this string reference another language string directly?
+ while (lst[j] < 0)
+ {
+ // Search through list of language string references
+ for (l = 0; (unsigned int)l < rec.getlen() / sizeof(int); l++)
+ {
+ if (((int*)rec.get())[l] == lst[j])
+ {
+ // We have the index of a recursive language string; now find the name
+ const char *name = "(unnamed)";
+ for (l = 0; l < langstring_num; l++)
+ {
+ int index;
+
+ if (!uninstall_mode)
+ index = lang_strings[l].index;
+ else
+ index = lang_strings[l].uindex;
+
+ if (lang_strings[l].index == j)
+ {
+ name = build_langstrings.offset2name(lang_strings[l].name);
+ }
+ }
+ ERROR_MSG("Error: LangString %s is recursive!\n", name);
+ delete [] string_ptrs;
+ return PS_ERROR;
+ }
+ }
+ // Add this reference to the list
+ rec.add(&lst[j], sizeof(int));
+ // and dereference it
+ lst[j] = lst[-lst[j] - 1];
+ }
+ rec.resize(0);
+ }
+ }
+
+ // Add language tables into their datablock
+ for (i = num_lang_tables; i--; )
+ {
+ cur_langtables->add(&lt[i].lang_id, sizeof(LANGID));
+ cur_langtables->add(&lt[i].dlg_offset, sizeof(int));
+ int rtl = lt[i].nlf.m_bRTL ? 1 : 0;
+ cur_langtables->add(&rtl, sizeof(int));
+ cur_langtables->add(string_ptrs[i].get(), string_ptrs[i].getlen());
+ string_ptrs[i].resize(0);
+ }
+
+ cur_header->blocks[NB_LANGTABLES].num = num_lang_tables;
+ cur_header->langtable_size = cur_langtables->getlen() / num_lang_tables;
+
+ delete [] string_ptrs;
+
+ return PS_OK;
+}
+
+int CEXEBuild::GenerateLangTables() {
+ int i;
+ LanguageTable *lt = (LanguageTable*)lang_tables.get();
+
+ SCRIPT_MSG("Generating language tables... ");
+
+ if (
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ ubuild_langstring_num > MAX_CODED ||
+#endif
+ build_langstring_num > MAX_CODED
+ )
+ {
+ ERROR_MSG("\nError: too many LangStrings. Maximum allowed is %u.\n", MAX_CODED);
+ return PS_ERROR;
+ }
+
+ // If we have no tables (user didn't set any string and didn't load any NLF) create the default one
+ if (!lang_tables.getlen()) {
+ LANGID lang = NSIS_DEFAULT_LANG;
+ LanguageTable *table = GetLangTable(lang);
+ if (!table) return PS_ERROR;
+
+ lt = (LanguageTable*)lang_tables.get();
+ }
+
+ // Apply default font
+ if (*build_font)
+ {
+ try {
+ init_res_editor();
+
+#define ADD_FONT(id) { \
+ BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG); \
+ if (dlg) { \
+ CDialogTemplate td(dlg); \
+ res_editor->FreeResource(dlg); \
+ td.SetFont(build_font, (WORD) build_font_size); \
+ DWORD dwSize; \
+ dlg = td.Save(dwSize); \
+ res_editor->UpdateResourceA(RT_DIALOG, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG, dlg, dwSize); \
+ delete [] dlg; \
+ } \
+ }
+
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ ADD_FONT(IDD_LICENSE);
+ ADD_FONT(IDD_LICENSE_FSRB);
+ ADD_FONT(IDD_LICENSE_FSCB);
+#endif
+ ADD_FONT(IDD_DIR);
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ ADD_FONT(IDD_SELCOM);
+#endif
+ ADD_FONT(IDD_INST);
+ ADD_FONT(IDD_INSTFILES);
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ ADD_FONT(IDD_UNINST);
+#endif
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ ADD_FONT(IDD_VERIFY);
+#endif
+#undef ADD_FONT
+ }
+ catch (exception& err) {
+ ERROR_MSG("\nError while applying font: %s\n", err.what());
+ return PS_ERROR;
+ }
+ }
+
+ // Fill tables with defaults (if needed) and with instruction strings
+ // Create language specific resources (currently only dialogs with different fonts)
+ int num_lang_tables = lang_tables.getlen() / sizeof(LanguageTable);
+ // if there is one string table then there is no need for two sets of dialogs
+ int cur_offset = num_lang_tables == 1 ? 0 : 100;
+ for (i = 0; i < num_lang_tables; i++)
+ {
+ if ((lt[i].nlf.m_szFont && !*build_font) || lt[i].nlf.m_bRTL)
+ {
+ lt[i].dlg_offset = cur_offset;
+
+ char *font = lt[i].nlf.m_szFont;
+ if (*build_font) font = 0;
+
+ try {
+ init_res_editor();
+
+#define ADD_FONT(id) { \
+ BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG); \
+ if (dlg) { \
+ CDialogTemplate td(dlg,lt[i].nlf.m_uCodePage); \
+ res_editor->FreeResource(dlg); \
+ if (font) td.SetFont(font, (WORD) lt[i].nlf.m_iFontSize); \
+ if (lt[i].nlf.m_bRTL) { \
+ td.ConvertToRTL(); \
+ DialogItemTemplate* dir = td.GetItem(IDC_DIR); \
+ if (id == IDD_DIR && dir) { \
+ if ((dir->dwStyle & ES_CENTER) == 0) dir->dwStyle ^= ES_RIGHT; \
+ dir->dwExtStyle &= ~(WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR); \
+ } \
+ } \
+ DWORD dwSize; \
+ dlg = td.Save(dwSize); \
+ res_editor->UpdateResourceA(RT_DIALOG, MAKEINTRESOURCE(id+cur_offset), NSIS_DEFAULT_LANG, dlg, dwSize); \
+ delete [] dlg; \
+ } \
+ }
+
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ ADD_FONT(IDD_LICENSE);
+ ADD_FONT(IDD_LICENSE_FSRB);
+ ADD_FONT(IDD_LICENSE_FSCB);
+#endif
+ ADD_FONT(IDD_DIR);
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ ADD_FONT(IDD_SELCOM);
+#endif
+ ADD_FONT(IDD_INST);
+ ADD_FONT(IDD_INSTFILES);
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ ADD_FONT(IDD_UNINST);
+#endif
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+ ADD_FONT(IDD_VERIFY);
+#endif
+#undef ADD_FONT
+ }
+ catch (exception& err) {
+ ERROR_MSG("\nError while applying NLF font/RTL: %s\n", err.what());
+ return PS_ERROR;
+ }
+
+ cur_offset += 100;
+ }
+ }
+
+ int orig_uninstall_mode = uninstall_mode;
+
+ set_uninstall_mode(0);
+ if (GenerateLangTable(lt, num_lang_tables) != PS_OK)
+ return PS_ERROR;
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ set_uninstall_mode(1);
+ if (GenerateLangTable(lt, num_lang_tables) != PS_OK)
+ return PS_ERROR;
+#endif
+
+ set_uninstall_mode(orig_uninstall_mode);
+
+ SCRIPT_MSG("Done!\n");
+
+ return PS_OK;
+}
+
+void CEXEBuild::FillLanguageTable(LanguageTable *table) {
+ for (int i = 0; i < NLF_STRINGS; i++) {
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (!NLFRefs[i].iUnRef && !NLFRefs[i].iRef)
+ continue;
+#else
+ if (!NLFRefs[i].iRef)
+ continue;
+#endif
+
+ else if (i == NLF_SPACE_REQ || i == NLF_SPACE_AVAIL)
+ {
+ if (no_space_texts)
+ {
+ continue;
+ }
+ }
+
+ int sn, index;
+ int pos = build_langstrings.get(NLFStrings[i].szLangStringName, &sn, &index);
+ if (pos >= 0) {
+ const char *str = table->lang_strings->get(sn);
+ if (!str || !*str) {
+ const char *us = UserInnerStrings.get(i);
+ if (i == NLF_NAME_DA && (!us || !*us))
+ {
+ // if the user didn't set NLF_NAME_DA we set it to $(^Name)
+ table->lang_strings->set(sn, "$(^Name)");
+ }
+ if (us && *us) {
+ table->lang_strings->set(sn, (char *) us);
+ }
+ else {
+ char *dstr = table->nlf.m_szStrings[i] ? table->nlf.m_szStrings[i] : NLFStrings[i].szDefault;
+ if (!dstr)
+ continue;
+ if (i == NLF_BRANDING) {
+ char temp[NSIS_MAX_STRLEN + sizeof(NSIS_VERSION)];
+ sprintf(temp, dstr, NSIS_VERSION);
+ table->lang_strings->set(sn, temp);
+ continue;
+ }
+ else if (i == NLF_FONT)
+ {
+ char *font = *build_font ? build_font : table->nlf.m_szFont;
+ if (font)
+ table->lang_strings->set(sn, font);
+ else
+ table->lang_strings->set(sn, dstr);
+ continue;
+ }
+ else if (i == NLF_FONTSIZE)
+ {
+ WORD font_size = *build_font ? (WORD) build_font_size : (WORD) table->nlf.m_iFontSize;
+ if (font_size)
+ {
+ char temp[64];
+ sprintf(temp, "%d", font_size);
+ table->lang_strings->set(sn, temp);
+ }
+ else
+ table->lang_strings->set(sn, dstr);
+ continue;
+ }
+ table->lang_strings->set(sn, dstr);
+ }
+ }
+ }
+ }
+}
+
+char SkipComments(FILE *f) {
+ int c;
+ while ((c = fgetc(f))) {
+ while (c == '\n' || c == '\r') {
+ c = fgetc(f); // Skip empty lines
+ }
+ if (c == '#' || c == ';') {
+ while ((c = fgetc(f))) {
+ if (c == '\n') break;
+ }
+ }
+ else break;
+ }
+ return (char) c;
+}
+
+// NSIS Language File parser
+LanguageTable * CEXEBuild::LoadLangFile(char *filename) {
+ FILE *f = FOPEN(filename, "r");
+ if (!f) {
+ ERROR_MSG("Error: Can't open language file - \"%s\"!\n",filename);
+ return 0;
+ }
+
+ // Check header
+ char buf[NSIS_MAX_STRLEN];
+ buf[0] = SkipComments(f);
+ fgets(buf+1, NSIS_MAX_STRLEN, f);
+
+ if (strncmp(buf, "NLF v", 5)) {
+ ERROR_MSG("Error: Invalid language file.\n");
+ return 0;
+ }
+ int nlf_version = atoi(buf+5);
+ if (nlf_version != NLF_VERSION) {
+ if (nlf_version != 2 && nlf_version != 3 && nlf_version != 4 && nlf_version != 5) {
+ ERROR_MSG("Error: Language file version doesn't match NSIS version.\n");
+ return 0;
+ }
+ }
+
+ // Get language ID
+ buf[0] = SkipComments(f);
+ fgets(buf+1, NSIS_MAX_STRLEN, f);
+ LANGID lang_id = atoi(buf);
+
+ // Get appropriate table
+ LanguageTable *table = GetLangTable(lang_id);
+ if (!table)
+ return 0;
+
+ NLF *nlf = &table->nlf;
+
+ if (nlf->m_bLoaded) {
+ ERROR_MSG("Error: can't load same language file twice.\n");
+ return 0;
+ }
+
+ // Generate language name
+ char *p, *p2, t = 0;
+
+ p = strrchr(filename, '.');
+ if (p) {
+ t = *p;
+ *p = 0;
+ }
+ p2 = strrchr(filename, '\\');
+ if (p2) {
+ p2++;
+ nlf->m_szName = (char*)malloc(strlen(p2)+1);
+ strcpy(nlf->m_szName, p2);
+ }
+ else {
+ nlf->m_szName = (char*)malloc(strlen(filename)+1);
+ strcpy(nlf->m_szName, filename);
+ }
+ if (p) *p = t;
+
+ if (nlf_version != NLF_VERSION) {
+ warning_fl("%s language file version doesn't match. Using default English texts for missing strings.", nlf->m_szName);
+ }
+
+ // set ^Language
+ nlf->m_szStrings[NLF_LANGUAGE] = strdup(nlf->m_szName);
+
+ int temp;
+
+ // Get font
+ buf[0] = SkipComments(f);
+ fgets(buf+1, NSIS_MAX_STRLEN, f);
+ if (!nlf->m_szFont) {
+ temp=strlen(buf);
+ while (buf[temp-1] == '\n' || buf[temp-1] == '\r') {
+ buf[temp-1] = 0;
+ temp--;
+ }
+ if (buf[0] != '-' || buf[1] != 0) {
+ nlf->m_szFont = (char*)malloc(strlen(buf)+1);
+ strcpy(nlf->m_szFont, buf);
+ }
+ }
+
+ buf[0] = SkipComments(f);
+ fgets(buf+1, NSIS_MAX_STRLEN, f);
+ if (!nlf->m_iFontSize) {
+ if (buf[0] != '-' || buf[1] != 0) {
+ nlf->m_iFontSize = atoi(buf);
+ }
+ }
+
+ // Get code page
+ nlf->m_uCodePage = CP_ACP;
+ buf[0] = SkipComments(f);
+ fgets(buf+1, NSIS_MAX_STRLEN, f);
+ if (buf[0] != '-' || buf[1] != 0) {
+ nlf->m_uCodePage = atoi(buf);
+ if (!IsValidCodePage(nlf->m_uCodePage))
+ nlf->m_uCodePage = CP_ACP;
+ }
+
+ // Get RTL setting
+ nlf->m_szStrings[NLF_RTL] = (char *)malloc(2);
+ nlf->m_bRTL = false;
+ buf[0] = SkipComments(f);
+ fgets(buf+1, NSIS_MAX_STRLEN, f);
+ if (buf[0] == 'R' && buf[1] == 'T' && buf[2] == 'L' && (!buf[3] || buf[3] == '\r' || buf[3] == '\n')) {
+ nlf->m_bRTL = true;
+ strcpy(nlf->m_szStrings[NLF_RTL], "1");
+ }
+ else {
+ strcpy(nlf->m_szStrings[NLF_RTL], "0");
+ }
+
+ // Read strings
+ for (int i = 0; i < NLF_STRINGS_NO_SPECIAL; i++) {
+
+ // skip virtual strings
+ if (!NLFStrings[i].szDefault)
+ continue;
+
+ // Fill in for missing strings
+ // 0 will mean default will be used from NLFStrings
+ switch (i) {
+ case NLF_BTN_LICENSE_AGREE:
+ case NLF_BTN_LICENSE_DISAGREE:
+ if (nlf_version >= 3) break;
+ case NLF_LOG_INSTALL_PROCESS:
+ case NLF_BYTE:
+ case NLF_KILO:
+ case NLF_MEGA:
+ case NLF_GIGA:
+ case NLF_REGISTERING:
+ case NLF_UNREGISTERING:
+ if (nlf_version >= 4) break;
+ case NLF_FILE_ERROR_NOIGNORE:
+ if (nlf_version >= 5) break;
+ case NLF_USUBCAPTION_OPTIONS:
+ case NLF_USUBCAPTION_DIR:
+ case NLF_CLICK_NEXT:
+ case NLF_CLICK_INSTALL:
+ case NLF_CLICK_UNINSTALL:
+ case NLF_LICENSE_TEXT:
+ case NLF_LICENSE_TEXT_FSCB:
+ case NLF_LICENSE_TEXT_FSRB:
+ case NLF_ULICENSE_TEXT:
+ case NLF_ULICENSE_TEXT_FSCB:
+ case NLF_ULICENSE_TEXT_FSRB:
+ case NLF_COMP_TEXT:
+ case NLF_UCOMP_TEXT:
+ case NLF_UCOMP_SUBTEXT1:
+ case NLF_UCOMP_SUBTEXT1_NO_INST_TYPES:
+ case NLF_UCOMP_SUBTEXT2:
+ case NLF_DIR_TEXT:
+ case NLF_DIR_BROWSETEXT:
+ case NLF_UDIR_TEXT:
+ case NLF_UDIR_SUBTEXT:
+ case NLF_UDIR_BROWSETEXT:
+ case NLF_UNINST_TEXT:
+ if (nlf_version >= 6) break;
+ nlf->m_szStrings[i] = 0;
+ continue;
+ }
+
+ buf[0] = SkipComments(f);
+
+ fgets(buf+1, NSIS_MAX_STRLEN, f);
+ if (strlen(buf) == NSIS_MAX_STRLEN-1) {
+ ERROR_MSG("Error: String too long (string #%d - \"%s\")", i, NLFStrings[i].szLangStringName);
+ return 0;
+ }
+ temp=strlen(buf);
+
+ while (buf[temp-1] == '\n' || buf[temp-1] == '\r') {
+ buf[--temp] = 0;
+ }
+
+ char *in = buf;
+
+ // trim quotes
+ if (buf[0] == '"' && buf[temp-1] == '"') {
+ in++;
+ buf[--temp] = 0;
+ }
+
+ nlf->m_szStrings[i] = (char*)malloc(temp+1);
+ char *out;
+ for (out = nlf->m_szStrings[i]; *in; in++, out++) {
+ if (*in == '\\') {
+ in++;
+ switch (*in) {
+ case 'n':
+ *out = '\n';
+ break;
+ case 'r':
+ *out = '\r';
+ break;
+ case 't':
+ *out = '\t';
+ break;
+ default:
+ *out++ = '\\';
+ *out = *in;
+ }
+ }
+ else *out = *in;
+ }
+ *out = 0;
+ }
+ fclose(f);
+
+ nlf->m_bLoaded = true;
+
+ return table;
+}
+
+void CEXEBuild::DeleteLangTable(LanguageTable *table) {
+ if (table->nlf.m_szName)
+ free(table->nlf.m_szName);
+ if (table->nlf.m_szFont)
+ free(table->nlf.m_szFont);
+ delete table->lang_strings;
+ for (int i = 0; i < NLF_STRINGS; i++) {
+ if (table->nlf.m_szStrings[i])
+ free(table->nlf.m_szStrings[i]);
+ }
+}
diff --git a/Source/lang.h b/Source/lang.h
index 18dc243..6bf2a41 100755
--- a/Source/lang.h
+++ b/Source/lang.h
@@ -1,199 +1,199 @@
-/*
- * lang.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef ___NLF___H_____
-#define ___NLF___H_____
-
-#include "strlist.h"
-#include "growbuf.h"
-#include "exehead/fileform.h"
-
-struct NLFRef {
- int iRef;
- int iUnRef;
-};
-
-struct langstring {
- int name;
- int sn;
- int index;
- int uindex;
- int process;
-};
-
-class LangStringList : public SortedStringListND<struct langstring>
-{
- public:
- LangStringList();
-
- int add(const char *name, int *sn=0);
- int get(char *name, int *sn=0, int *index=0, int *uindex=0, int *process=0);
- void set(int pos, int index=-1, int uindex=-1, int process=-1);
- void set(char *name, int index, int uindex=-1, int process=-1);
- const char *pos2name(int pos);
- const char *offset2name(int name);
- int getnum();
- static int compare_index(const void *item1, const void *item2);
- langstring *sort_index(int *num);
- static int compare_uindex(const void *item1, const void *item2);
- langstring *sort_uindex(int *num);
-
- private:
- int count;
- TinyGrowBuf sortbuf;
-};
-
-class StringsArray
-{
- public:
- StringsArray();
-
- void resize(int num);
- int set(int idx, char *str);
- const char *get(int idx);
-
- private:
- TinyGrowBuf offsets;
- GrowBuf strings;
-};
-
-#define NLF_VERSION 6
-
-enum {
- NLF_BRANDING,
- NLF_CAPTION,
- NLF_UCAPTION,
- NLF_SUBCAPTION_LICENSE,
- NLF_SUBCAPTION_OPTIONS,
- NLF_SUBCAPTION_DIR,
- NLF_SUBCAPTION_INSTFILES,
- NLF_SUBCAPTION_COMPLETED,
- NLF_USUBCAPTION_OPTIONS,
- NLF_USUBCAPTION_DIR,
- NLF_USUBCAPTION_CONFIRM,
- NLF_USUBCAPTION_INSTFILES,
- NLF_USUBCAPTION_COMPLETED,
- NLF_BTN_BACK,
- NLF_BTN_NEXT,
- NLF_BTN_LICENSE,
- NLF_BTN_LICENSE_AGREE,
- NLF_BTN_LICENSE_DISAGREE,
- NLF_BTN_INSTALL,
- NLF_BTN_UNINSTALL,
- NLF_BTN_CANCEL,
- NLF_BTN_CLOSE,
- NLF_BTN_BROWSE,
- NLF_BTN_DETAILS,
- NLF_CLICK_NEXT,
- NLF_CLICK_INSTALL,
- NLF_CLICK_UNINSTALL,
- NLF_NAME,
- NLF_NAME_DA, // name with doubled ampersands - virtual
- NLF_COMPLETED,
- NLF_LICENSE_TEXT,
- NLF_LICENSE_TEXT_FSCB,
- NLF_LICENSE_TEXT_FSRB,
- NLF_ULICENSE_TEXT,
- NLF_ULICENSE_TEXT_FSCB,
- NLF_ULICENSE_TEXT_FSRB,
- NLF_LICENSE_DATA, // virtual
- NLF_COMP_CUSTOM,
- NLF_COMP_TEXT,
- NLF_COMP_SUBTEXT1,
- NLF_COMP_SUBTEXT1_NO_INST_TYPES,
- NLF_COMP_SUBTEXT2,
- NLF_UCOMP_TEXT,
- NLF_UCOMP_SUBTEXT1,
- NLF_UCOMP_SUBTEXT1_NO_INST_TYPES,
- NLF_UCOMP_SUBTEXT2,
- NLF_DIR_TEXT,
- NLF_DIR_SUBTEXT,
- NLF_DIR_BROWSETEXT,
- NLF_UDIR_TEXT,
- NLF_UDIR_SUBTEXT,
- NLF_UDIR_BROWSETEXT,
- NLF_SPACE_AVAIL,
- NLF_SPACE_REQ,
- NLF_UNINST_TEXT,
- NLF_UNINST_SUBTEXT,
- NLF_FILE_ERROR,
- NLF_FILE_ERROR_NOIGNORE,
- NLF_CANT_WRITE,
- NLF_COPY_FAILED,
- NLF_COPY_TO,
- NLF_REGISTERING,
- NLF_UNREGISTERING,
- NLF_SYMBOL_NOT_FOUND,
- NLF_COULD_NOT_LOAD,
- NLF_CREATE_DIR,
- NLF_CREATE_SHORTCUT,
- NLF_CREATED_UNINST,
- NLF_DEL_FILE,
- NLF_DEL_ON_REBOOT,
- NLF_ERR_CREATING_SHORTCUT,
- NLF_ERR_CREATING,
- NLF_ERR_DECOMPRESSING,
- NLF_ERR_REG_DLL,
- NLF_EXEC_SHELL,
- NLF_EXEC,
- NLF_EXTRACT,
- NLF_ERR_WRITING,
- NLF_INST_CORRUPTED,
- NLF_NO_OLE,
- NLF_OUTPUT_DIR,
- NLF_REMOVE_DIR,
- NLF_RENAME_ON_REBOOT,
- NLF_RENAME,
- NLF_SKIPPED,
- NLF_COPY_DETAILS,
- NLF_LOG_INSTALL_PROCESS,
- NLF_BYTE,
- NLF_KILO,
- NLF_MEGA,
- NLF_GIGA,
-
- NLF_STRINGS_NO_SPECIAL,
-
- NLF_FONT = NLF_STRINGS_NO_SPECIAL,
- NLF_FONTSIZE,
- NLF_RTL,
- NLF_LANGUAGE,
-
- NLF_STRINGS
-};
-
-struct NLF {
- bool m_bLoaded;
- char *m_szName;
- char *m_szFont;
- int m_iFontSize;
- unsigned int m_uCodePage;
- bool m_bRTL;
-
- char *m_szStrings[NLF_STRINGS];
-};
-
-struct LanguageTable {
- LANGID lang_id;
-
- int dlg_offset;
-
- StringsArray *lang_strings;
-
- NLF nlf;
-};
-
-#endif
+/*
+ * lang.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef ___NLF___H_____
+#define ___NLF___H_____
+
+#include "strlist.h"
+#include "growbuf.h"
+#include "exehead/fileform.h"
+
+struct NLFRef {
+ int iRef;
+ int iUnRef;
+};
+
+struct langstring {
+ int name;
+ int sn;
+ int index;
+ int uindex;
+ int process;
+};
+
+class LangStringList : public SortedStringListND<struct langstring>
+{
+ public:
+ LangStringList();
+
+ int add(const char *name, int *sn=0);
+ int get(char *name, int *sn=0, int *index=0, int *uindex=0, int *process=0);
+ void set(int pos, int index=-1, int uindex=-1, int process=-1);
+ void set(char *name, int index, int uindex=-1, int process=-1);
+ const char *pos2name(int pos);
+ const char *offset2name(int name);
+ int getnum();
+ static int compare_index(const void *item1, const void *item2);
+ langstring *sort_index(int *num);
+ static int compare_uindex(const void *item1, const void *item2);
+ langstring *sort_uindex(int *num);
+
+ private:
+ int count;
+ TinyGrowBuf sortbuf;
+};
+
+class StringsArray
+{
+ public:
+ StringsArray();
+
+ void resize(int num);
+ int set(int idx, char *str);
+ const char *get(int idx);
+
+ private:
+ TinyGrowBuf offsets;
+ GrowBuf strings;
+};
+
+#define NLF_VERSION 6
+
+enum {
+ NLF_BRANDING,
+ NLF_CAPTION,
+ NLF_UCAPTION,
+ NLF_SUBCAPTION_LICENSE,
+ NLF_SUBCAPTION_OPTIONS,
+ NLF_SUBCAPTION_DIR,
+ NLF_SUBCAPTION_INSTFILES,
+ NLF_SUBCAPTION_COMPLETED,
+ NLF_USUBCAPTION_OPTIONS,
+ NLF_USUBCAPTION_DIR,
+ NLF_USUBCAPTION_CONFIRM,
+ NLF_USUBCAPTION_INSTFILES,
+ NLF_USUBCAPTION_COMPLETED,
+ NLF_BTN_BACK,
+ NLF_BTN_NEXT,
+ NLF_BTN_LICENSE,
+ NLF_BTN_LICENSE_AGREE,
+ NLF_BTN_LICENSE_DISAGREE,
+ NLF_BTN_INSTALL,
+ NLF_BTN_UNINSTALL,
+ NLF_BTN_CANCEL,
+ NLF_BTN_CLOSE,
+ NLF_BTN_BROWSE,
+ NLF_BTN_DETAILS,
+ NLF_CLICK_NEXT,
+ NLF_CLICK_INSTALL,
+ NLF_CLICK_UNINSTALL,
+ NLF_NAME,
+ NLF_NAME_DA, // name with doubled ampersands - virtual
+ NLF_COMPLETED,
+ NLF_LICENSE_TEXT,
+ NLF_LICENSE_TEXT_FSCB,
+ NLF_LICENSE_TEXT_FSRB,
+ NLF_ULICENSE_TEXT,
+ NLF_ULICENSE_TEXT_FSCB,
+ NLF_ULICENSE_TEXT_FSRB,
+ NLF_LICENSE_DATA, // virtual
+ NLF_COMP_CUSTOM,
+ NLF_COMP_TEXT,
+ NLF_COMP_SUBTEXT1,
+ NLF_COMP_SUBTEXT1_NO_INST_TYPES,
+ NLF_COMP_SUBTEXT2,
+ NLF_UCOMP_TEXT,
+ NLF_UCOMP_SUBTEXT1,
+ NLF_UCOMP_SUBTEXT1_NO_INST_TYPES,
+ NLF_UCOMP_SUBTEXT2,
+ NLF_DIR_TEXT,
+ NLF_DIR_SUBTEXT,
+ NLF_DIR_BROWSETEXT,
+ NLF_UDIR_TEXT,
+ NLF_UDIR_SUBTEXT,
+ NLF_UDIR_BROWSETEXT,
+ NLF_SPACE_AVAIL,
+ NLF_SPACE_REQ,
+ NLF_UNINST_TEXT,
+ NLF_UNINST_SUBTEXT,
+ NLF_FILE_ERROR,
+ NLF_FILE_ERROR_NOIGNORE,
+ NLF_CANT_WRITE,
+ NLF_COPY_FAILED,
+ NLF_COPY_TO,
+ NLF_REGISTERING,
+ NLF_UNREGISTERING,
+ NLF_SYMBOL_NOT_FOUND,
+ NLF_COULD_NOT_LOAD,
+ NLF_CREATE_DIR,
+ NLF_CREATE_SHORTCUT,
+ NLF_CREATED_UNINST,
+ NLF_DEL_FILE,
+ NLF_DEL_ON_REBOOT,
+ NLF_ERR_CREATING_SHORTCUT,
+ NLF_ERR_CREATING,
+ NLF_ERR_DECOMPRESSING,
+ NLF_ERR_REG_DLL,
+ NLF_EXEC_SHELL,
+ NLF_EXEC,
+ NLF_EXTRACT,
+ NLF_ERR_WRITING,
+ NLF_INST_CORRUPTED,
+ NLF_NO_OLE,
+ NLF_OUTPUT_DIR,
+ NLF_REMOVE_DIR,
+ NLF_RENAME_ON_REBOOT,
+ NLF_RENAME,
+ NLF_SKIPPED,
+ NLF_COPY_DETAILS,
+ NLF_LOG_INSTALL_PROCESS,
+ NLF_BYTE,
+ NLF_KILO,
+ NLF_MEGA,
+ NLF_GIGA,
+
+ NLF_STRINGS_NO_SPECIAL,
+
+ NLF_FONT = NLF_STRINGS_NO_SPECIAL,
+ NLF_FONTSIZE,
+ NLF_RTL,
+ NLF_LANGUAGE,
+
+ NLF_STRINGS
+};
+
+struct NLF {
+ bool m_bLoaded;
+ char *m_szName;
+ char *m_szFont;
+ int m_iFontSize;
+ unsigned int m_uCodePage;
+ bool m_bRTL;
+
+ char *m_szStrings[NLF_STRINGS];
+};
+
+struct LanguageTable {
+ LANGID lang_id;
+
+ int dlg_offset;
+
+ StringsArray *lang_strings;
+
+ NLF nlf;
+};
+
+#endif
diff --git a/Source/lineparse.cpp b/Source/lineparse.cpp
index 2d42ae6..d933aa1 100755
--- a/Source/lineparse.cpp
+++ b/Source/lineparse.cpp
@@ -1,236 +1,236 @@
-/*
- * lineparse.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "lineparse.h"
-#include "Platform.h"
-
-#include <cstdlib>
-#include <cstring>
-
-LineParser::LineParser(bool bCommentBlock)
-{
- m_incommentblock=bCommentBlock;
- m_incomment=false;
- m_nt=m_eat=0;
- m_tokens=0;
-}
-
-LineParser::~LineParser()
-{
- freetokens();
-}
-
-bool LineParser::inComment()
-{
- return m_incomment;
-}
-
-bool LineParser::inCommentBlock()
-{
- return m_incommentblock;
-}
-
-int LineParser::parse(char *line, int ignore_escaping/*=0*/) // returns -1 on error
-{
- freetokens();
- bool bPrevCB=m_incommentblock;
- int n=doline(line, ignore_escaping);
- if (n) return n;
- if (m_nt)
- {
- m_incommentblock=bPrevCB;
- m_tokens=(char**)malloc(sizeof(char*)*m_nt);
- n=doline(line, ignore_escaping);
- if (n)
- {
- freetokens();
- return -1;
- }
- }
- return 0;
-}
-
-int LineParser::getnumtokens()
-{
- return m_nt-m_eat;
-}
-
-void LineParser::eattoken()
-{
- m_eat++;
-}
-
-double LineParser::gettoken_float(int token, int *success/*=0*/)
-{
- token+=m_eat;
- if (token < 0 || token >= m_nt)
- {
- if (success) *success=0;
- return 0.0;
- }
- if (success)
- {
- char *t=m_tokens[token];
- *success=*t?1:0;
- while (*t)
- {
- if ((*t < '0' || *t > '9')&&*t != '.') *success=0;
- t++;
- }
- }
- return atof(m_tokens[token]);
-}
-
-int LineParser::gettoken_int(int token, int *success/*=0*/)
-{
- token+=m_eat;
- if (token < 0 || token >= m_nt || !m_tokens[token][0])
- {
- if (success) *success=0;
- return 0;
- }
- char *tmp;
- int l;
- if (m_tokens[token][0] == '-') l=strtol(m_tokens[token],&tmp,0);
- else l=(int)strtoul(m_tokens[token],&tmp,0);
- if (success) *success=! (int)(*tmp);
- return l;
-}
-
-char* LineParser::gettoken_str(int token)
-{
- token+=m_eat;
- if (token < 0 || token >= m_nt) return "";
- return m_tokens[token];
-}
-
-int LineParser::gettoken_enum(int token, const char *strlist) // null seperated list
-{
- int x=0;
- char *tt=gettoken_str(token);
- if (tt && *tt) while (*strlist)
- {
- if (!stricmp(tt,strlist)) return x;
- strlist+=strlen(strlist)+1;
- x++;
- }
- return -1;
-}
-
-void LineParser::freetokens()
-{
- if (m_tokens)
- {
- int x;
- for (x = 0; x < m_nt; x ++)
- free(m_tokens[x]);
- free(m_tokens);
- }
- m_tokens=0;
- m_nt=0;
-}
-
-int LineParser::doline(char *line, int ignore_escaping/*=0*/)
-{
- m_nt=0;
- m_incomment = false;
- while (*line == ' ' || *line == '\t') line++;
- while (*line)
- {
- if ( m_incommentblock )
- {
- while ( *line )
- {
- if ( *line == '*' && *(line+1) == '/' )
- {
- m_incommentblock=false; // Found end of comment block
- line+=2;
- while (*line == ' ' || *line == '\t') line++;
- break;
- }
- else line++;
- }
- }
- else {
- int lstate=0; // 1=", 2=`, 4='
- if (*line == ';' || *line == '#')
- {
- m_incomment = true;
- break;
- }
- if (*line == '/' && *(line+1) == '*')
- {
- m_incommentblock = true;
- line+=2;
- }
- else {
- if (*line == '\"') lstate=1;
- else if (*line == '\'') lstate=2;
- else if (*line == '`') lstate=4;
- if (lstate) line++;
- int nc=0;
- char *p = line;
- while (*line)
- {
- if (line[0] == '$' && line[1] == '\\') {
- switch (line[2]) {
- case '"':
- case '\'':
- case '`':
- nc += ignore_escaping ? 3 : 1;
- line += 3;
- continue;
- }
- }
- if (lstate==1 && *line =='\"') break;
- if (lstate==2 && *line =='\'') break;
- if (lstate==4 && *line =='`') break;
- if (!lstate && (*line == ' ' || *line == '\t')) break;
-#ifdef NSIS_FIX_COMMENT_HANDLING
- if (!lstate && (*line == ';' || *line == '#' || (*line == '/' && *(line+1) == '*'))) break;
-#endif
- line++;
- nc++;
- }
- if (m_tokens)
- {
- int i;
- m_tokens[m_nt]=(char*)malloc(nc+1);
- for (i = 0; p < line; i++, p++) {
- if (!ignore_escaping && p[0] == '$' && p[1] == '\\') {
- switch (p[2]) {
- case '"':
- case '\'':
- case '`':
- p += 2;
- }
- }
- m_tokens[m_nt][i] = *p;
- }
- m_tokens[m_nt][nc]=0;
- }
- m_nt++;
- if (lstate)
- {
- if (*line) line++;
- else return -2;
- }
- while (*line == ' ' || *line == '\t') line++;
- }
- }
- }
- return 0;
-}
+/*
+ * lineparse.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "lineparse.h"
+#include "Platform.h"
+
+#include <cstdlib>
+#include <cstring>
+
+LineParser::LineParser(bool bCommentBlock)
+{
+ m_incommentblock=bCommentBlock;
+ m_incomment=false;
+ m_nt=m_eat=0;
+ m_tokens=0;
+}
+
+LineParser::~LineParser()
+{
+ freetokens();
+}
+
+bool LineParser::inComment()
+{
+ return m_incomment;
+}
+
+bool LineParser::inCommentBlock()
+{
+ return m_incommentblock;
+}
+
+int LineParser::parse(char *line, int ignore_escaping/*=0*/) // returns -1 on error
+{
+ freetokens();
+ bool bPrevCB=m_incommentblock;
+ int n=doline(line, ignore_escaping);
+ if (n) return n;
+ if (m_nt)
+ {
+ m_incommentblock=bPrevCB;
+ m_tokens=(char**)malloc(sizeof(char*)*m_nt);
+ n=doline(line, ignore_escaping);
+ if (n)
+ {
+ freetokens();
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int LineParser::getnumtokens()
+{
+ return m_nt-m_eat;
+}
+
+void LineParser::eattoken()
+{
+ m_eat++;
+}
+
+double LineParser::gettoken_float(int token, int *success/*=0*/)
+{
+ token+=m_eat;
+ if (token < 0 || token >= m_nt)
+ {
+ if (success) *success=0;
+ return 0.0;
+ }
+ if (success)
+ {
+ char *t=m_tokens[token];
+ *success=*t?1:0;
+ while (*t)
+ {
+ if ((*t < '0' || *t > '9')&&*t != '.') *success=0;
+ t++;
+ }
+ }
+ return atof(m_tokens[token]);
+}
+
+int LineParser::gettoken_int(int token, int *success/*=0*/)
+{
+ token+=m_eat;
+ if (token < 0 || token >= m_nt || !m_tokens[token][0])
+ {
+ if (success) *success=0;
+ return 0;
+ }
+ char *tmp;
+ int l;
+ if (m_tokens[token][0] == '-') l=strtol(m_tokens[token],&tmp,0);
+ else l=(int)strtoul(m_tokens[token],&tmp,0);
+ if (success) *success=! (int)(*tmp);
+ return l;
+}
+
+char* LineParser::gettoken_str(int token)
+{
+ token+=m_eat;
+ if (token < 0 || token >= m_nt) return "";
+ return m_tokens[token];
+}
+
+int LineParser::gettoken_enum(int token, const char *strlist) // null seperated list
+{
+ int x=0;
+ char *tt=gettoken_str(token);
+ if (tt && *tt) while (*strlist)
+ {
+ if (!stricmp(tt,strlist)) return x;
+ strlist+=strlen(strlist)+1;
+ x++;
+ }
+ return -1;
+}
+
+void LineParser::freetokens()
+{
+ if (m_tokens)
+ {
+ int x;
+ for (x = 0; x < m_nt; x ++)
+ free(m_tokens[x]);
+ free(m_tokens);
+ }
+ m_tokens=0;
+ m_nt=0;
+}
+
+int LineParser::doline(char *line, int ignore_escaping/*=0*/)
+{
+ m_nt=0;
+ m_incomment = false;
+ while (*line == ' ' || *line == '\t') line++;
+ while (*line)
+ {
+ if ( m_incommentblock )
+ {
+ while ( *line )
+ {
+ if ( *line == '*' && *(line+1) == '/' )
+ {
+ m_incommentblock=false; // Found end of comment block
+ line+=2;
+ while (*line == ' ' || *line == '\t') line++;
+ break;
+ }
+ else line++;
+ }
+ }
+ else {
+ int lstate=0; // 1=", 2=`, 4='
+ if (*line == ';' || *line == '#')
+ {
+ m_incomment = true;
+ break;
+ }
+ if (*line == '/' && *(line+1) == '*')
+ {
+ m_incommentblock = true;
+ line+=2;
+ }
+ else {
+ if (*line == '\"') lstate=1;
+ else if (*line == '\'') lstate=2;
+ else if (*line == '`') lstate=4;
+ if (lstate) line++;
+ int nc=0;
+ char *p = line;
+ while (*line)
+ {
+ if (line[0] == '$' && line[1] == '\\') {
+ switch (line[2]) {
+ case '"':
+ case '\'':
+ case '`':
+ nc += ignore_escaping ? 3 : 1;
+ line += 3;
+ continue;
+ }
+ }
+ if (lstate==1 && *line =='\"') break;
+ if (lstate==2 && *line =='\'') break;
+ if (lstate==4 && *line =='`') break;
+ if (!lstate && (*line == ' ' || *line == '\t')) break;
+#ifdef NSIS_FIX_COMMENT_HANDLING
+ if (!lstate && (*line == ';' || *line == '#' || (*line == '/' && *(line+1) == '*'))) break;
+#endif
+ line++;
+ nc++;
+ }
+ if (m_tokens)
+ {
+ int i;
+ m_tokens[m_nt]=(char*)malloc(nc+1);
+ for (i = 0; p < line; i++, p++) {
+ if (!ignore_escaping && p[0] == '$' && p[1] == '\\') {
+ switch (p[2]) {
+ case '"':
+ case '\'':
+ case '`':
+ p += 2;
+ }
+ }
+ m_tokens[m_nt][i] = *p;
+ }
+ m_tokens[m_nt][nc]=0;
+ }
+ m_nt++;
+ if (lstate)
+ {
+ if (*line) line++;
+ else return -2;
+ }
+ while (*line == ' ' || *line == '\t') line++;
+ }
+ }
+ }
+ return 0;
+}
diff --git a/Source/lineparse.h b/Source/lineparse.h
index 2ab67f1..326fbdb 100755
--- a/Source/lineparse.h
+++ b/Source/lineparse.h
@@ -1,47 +1,47 @@
-/*
- * lineparse.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef _LINEPARSE_H_
-#define _LINEPARSE_H_
-
-class LineParser {
- public:
-
- LineParser(bool bCommentBlock);
- virtual ~LineParser();
-
- bool inComment();
- bool inCommentBlock();
- int parse(char *line, int ignore_escaping=0); // returns -1 on error
- int getnumtokens();
- void eattoken();
- double gettoken_float(int token, int *success=0);
- int gettoken_int(int token, int *success=0);
- char *gettoken_str(int token);
- int gettoken_enum(int token, const char *strlist); // null seperated list
-
- private:
-
- void freetokens();
- int doline(char *line, int ignore_escaping=0);
-
- int m_eat;
- int m_nt;
- bool m_incommentblock;
- bool m_incomment;
- char **m_tokens;
-};
-#endif//_LINEPARSE_H_
+/*
+ * lineparse.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef _LINEPARSE_H_
+#define _LINEPARSE_H_
+
+class LineParser {
+ public:
+
+ LineParser(bool bCommentBlock);
+ virtual ~LineParser();
+
+ bool inComment();
+ bool inCommentBlock();
+ int parse(char *line, int ignore_escaping=0); // returns -1 on error
+ int getnumtokens();
+ void eattoken();
+ double gettoken_float(int token, int *success=0);
+ int gettoken_int(int token, int *success=0);
+ char *gettoken_str(int token);
+ int gettoken_enum(int token, const char *strlist); // null seperated list
+
+ private:
+
+ void freetokens();
+ int doline(char *line, int ignore_escaping=0);
+
+ int m_eat;
+ int m_nt;
+ bool m_incommentblock;
+ bool m_incomment;
+ char **m_tokens;
+};
+#endif//_LINEPARSE_H_
diff --git a/Source/makenssi.cpp b/Source/makenssi.cpp
index 46551d5..ef58fba 100755
--- a/Source/makenssi.cpp
+++ b/Source/makenssi.cpp
@@ -1,554 +1,554 @@
-/*
- * makenssi.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-#include <stdio.h>
-#include <signal.h>
-#ifdef _WIN32
-# include <direct.h>
-#else
-# include <unistd.h>
-#endif
-#include <string>
-
-#include "build.h"
-#include "util.h"
-
-#include "version.h"
-
-using namespace std;
-
-int g_noconfig=0;
-int g_display_errors=1;
-FILE *g_output=stdout;
-
-void quit()
-{
- if (g_display_errors)
- {
- fprintf(g_output,"\nNote: you may have one or two (large) stale temporary file(s)\n"
- "left in your temporary directory (Generally this only happens on Windows 9x).\n");
- fflush(g_output);
- }
- exit(1);
-}
-
-static void myatexit()
-{
- dopause();
- if (g_output != stdout && g_output) fclose(g_output);
-}
-
-static void sigint(int sig)
-{
- if (g_display_errors)
- {
- fprintf(g_output,"\n\nAborting on Ctrl+C...\n");
- fflush(g_output);
- }
- quit();
-}
-
-#ifdef _WIN32
-static DWORD WINAPI sigint_event_msg_handler(LPVOID)
-{
- HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, "makensis win32 signint event");
-
- if (hEvent)
- {
- if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0)
- raise(SIGINT);
- CloseHandle(hEvent);
- }
-
- return 0;
-}
-#endif
-
-static void init_signals()
-{
- atexit(myatexit);
- signal(SIGINT,sigint);
-
-#ifdef _WIN32
- DWORD id;
- HANDLE hThread = CreateThread(NULL, 0, sigint_event_msg_handler, NULL, 0, &id);
- if (hThread) CloseHandle(hThread);
-#endif
-}
-
-static void print_logo()
-{
- fprintf(g_output,"MakeNSIS %s - Copyright 1995-2007 Contributors\n"
- "See the file COPYING for license details.\n"
- "Credits can be found in the Users Manual.\n\n", NSIS_VERSION);
- fflush(g_output);
-}
-
-static void print_license()
-{
- fprintf(g_output,"Copyright (C) 1999-2007 Nullsoft and Contributors\n\n"
- "This license applies to everything in the NSIS package, except where otherwise\n"
- "noted.\n\n"
- "This software is provided 'as-is', without any express or implied warranty.\n"
- "In no event will the authors be held liable for any damages arising from the\n"
- "use of this software.\n\n"
- "Permission is granted to anyone to use this software for any purpose, including\n"
- "commercial applications, and to alter it and redistribute it freely, subject to\n"
- "the following restrictions:\n"
- " 1. The origin of this software must not be misrepresented; you must not claim\n"
- " that you wrote the original software. If you use this software in a\n"
- " product, an acknowledgment in the product documentation would be\n"
- " appreciated but is not required.\n"
- " 2. Altered source versions must be plainly marked as such, and must not be\n"
- " misrepresented as being the original software.\n"
- " 3. This notice may not be removed or altered from any source distribution.\n\n"
- "In addition to this license, different licenses apply to the included\n"
- "compression modules. See the file COPYING for details.\n");
- fflush(g_output);
-}
-
-static void print_usage()
-{
- fprintf(g_output,"Usage:\n"
- " makensis [option | script.nsi | - [...]]\n"
- " options are:\n"
- " " OPT_STR "CMDHELP item prints out help for 'item', or lists all commands\n"
- " " OPT_STR "HDRINFO prints information about what options makensis was compiled with\n"
- " " OPT_STR "LICENSE prints the makensis software license\n"
- " " OPT_STR "VERSION prints the makensis version and exits\n"
- " " OPT_STR "Px sets the compiler process priority, where x is 5=realtime,4=high,\n"
- " " " 3=above normal,2=normal,1=below normal,0=idle\n"
- " " OPT_STR "Vx verbosity where x is 4=all,3=no script,2=no info,1=no warnings,0=none\n"
- " " OPT_STR "Ofile specifies a text file to log compiler output (default is stdout)\n"
- " " OPT_STR "PAUSE pauses after execution\n"
- " " OPT_STR "NOCONFIG disables inclusion of <path to makensis.exe>" PLATFORM_PATH_SEPARATOR_STR "nsisconf.nsh\n"
- " " OPT_STR "NOCD disabled the current directory change to that of the .nsi file\n"
- " " OPT_STR "Ddefine[=value] defines the symbol \"define\" for the script [to value]\n"
- " " OPT_STR "Xscriptcmd executes scriptcmd in script (i.e. \"" OPT_STR "XOutFile poop.exe\")\n"
- " parameters are processed by order (" OPT_STR "Ddef ins.nsi != ins.nsi " OPT_STR "Ddef)\n"
- " for script file name, you can use - to read from the standard input\n"
-#ifdef _WIN32
- " you can also use - as an option character: -PAUSE as well as /PAUSE\n"
-#endif
- " you can use a double-dash to end options processing: makensis -- -ins.nsi\n");
- fflush(g_output);
-}
-
-static void print_stub_info(CEXEBuild& build)
-{
- if (build.display_info)
- {
- fprintf(g_output,"Size of first header is %lu bytes.\n",(unsigned long)sizeof(firstheader));
- fprintf(g_output,"Size of main header is %lu bytes.\n",(unsigned long)sizeof(header));
- fprintf(g_output,"Size of each section is %lu bytes.\n",(unsigned long)sizeof(section));
- fprintf(g_output,"Size of each page is %lu bytes.\n",(unsigned long)sizeof(page));
- fprintf(g_output,"Size of each instruction is %lu bytes.\n",(unsigned long)sizeof(entry));
- int x=build.definedlist.getnum();
- fprintf(g_output,"\nDefined symbols: ");
- for (int i=0; i<x; i++)
- {
- fprintf(g_output,"%s",build.definedlist.getname(i));
- char *p=build.definedlist.getvalue(i);
- if (*p) fprintf(g_output,"=%s",p);
- if (i<x-1) fprintf(g_output,",");
- }
- if (!x) fprintf(g_output,"none");
- fprintf(g_output,"\n");
- fflush(g_output);
- }
-}
-
-static string get_home()
-{
- char *home = getenv(
-#ifdef _WIN32
- "APPDATA"
-#else
- "HOME"
-#endif
- );
-
- return home ? home : "";
-}
-
-static int process_config(CEXEBuild& build, string& conf)
-{
- FILE *cfg=fopen(conf.c_str(),"rt");
- if (cfg)
- {
- if (build.display_script)
- {
- fprintf(g_output,"Processing config: \n");
- fflush(g_output);
- }
- int ret=build.process_script(cfg,(char*)conf.c_str());
- fclose(cfg);
- if (ret != PS_OK && ret != PS_EOF)
- {
- if (build.display_errors)
- {
- fprintf(g_output,"Error in config on line %d -- aborting creation process\n",build.linecnt);
- fflush(g_output);
- }
- return 1;
- }
- if (build.display_script)
- {
- fprintf(g_output,"\n");
- fflush(g_output);
- }
- }
- return 0;
-}
-
-static int change_to_script_dir(CEXEBuild& build, string& script)
-{
- string dir = get_dir_name(get_full_path(script));
- if (!dir.empty())
- {
- if (build.display_script)
- {
- fprintf(g_output,"Changing directory to: \"%s\"\n",dir.c_str());
- fflush(g_output);
- }
- if (chdir(dir.c_str()))
- {
- if (build.display_errors)
- {
- fprintf(g_output,"Error changing directory to \"%s\"\n",dir.c_str());
- fflush(g_output);
- }
- return 1;
- }
- if (build.display_script)
- {
- fprintf(g_output,"\n");
- fflush(g_output);
- }
- }
- return 0;
-}
-
-#ifdef NSIS_HPUX_ALLOW_UNALIGNED_DATA_ACCESS
-extern "C" void allow_unaligned_data_access();
-#endif
-
-int main(int argc, char **argv)
-{
-#ifdef NSIS_HPUX_ALLOW_UNALIGNED_DATA_ACCESS
- allow_unaligned_data_access();
-#endif
-
- CEXEBuild build;
- int do_cd=1;
- int outputtried=0;
- int argpos=1;
- int nousage=0;
- int files_processed=0;
- int cmds_processed=0;
- FILE *fp;
- int tmpargpos=1;
- int no_logo=0;
- int in_files=0;
-
- try
- {
- build.initialize(argv[0]);
- }
- catch (exception& err)
- {
- fprintf(g_output, "Error initalizing CEXEBuild: %s\n", err.what());
- fflush(g_output);
- return 1;
- }
-
- if (argc > 1 && IS_OPT(argv[1]) && !stricmp(&argv[1][1],"VERSION"))
- {
- fprintf(g_output,NSIS_VERSION);
- fflush(g_output);
- return 0;
- }
- if (argc > 1 && IS_OPT(argv[1]) && (argv[1][1]=='v' || argv[1][1]=='V'))
- {
- tmpargpos++;
- if (argv[1][2] <= '2' && argv[1][2] >= '0')
- {
- no_logo=1;
- }
- }
-
- if (!no_logo)
- {
- if (argc > tmpargpos && IS_OPT(argv[tmpargpos]) && (argv[tmpargpos][1]=='o' || argv[tmpargpos][1]=='O') && argv[tmpargpos][2])
- {
- g_output=fopen(argv[tmpargpos]+2,"w");
- if (!g_output)
- {
- printf("Error opening output log for writing. Using stdout.\n");
- g_output=stdout;
- }
- outputtried=1;
- }
- print_logo();
- }
-
- init_signals();
-
- if (!g_output) g_output=stdout;
- while (argpos < argc)
- {
- if (!strcmp(argv[argpos], "--"))
- in_files=1;
- else if (IS_OPT(argv[argpos]) && strcmp(argv[argpos], "-") && !in_files)
- {
- if ((argv[argpos][1]=='D' || argv[argpos][1]=='d') && argv[argpos][2])
- {
- char *p=argv[argpos]+2;
- char *s=strdup(p),*v;
- if (build.display_script)
- {
- fprintf(g_output,"Command line defined: \"%s\"\n",p);
- fflush(g_output);
- }
- v=strstr(s,"=");
- if (v) *v++=0;
- build.define(s,v?v:"");
- free(s);
- }
- else if ((argv[argpos][1]=='X' || argv[argpos][1]=='x') && argv[argpos][2])
- {
- if (build.process_oneline(argv[argpos]+2,"command line",argpos+1) != PS_OK)
- {
- return 1;
- }
- cmds_processed++;
- }
- else if ((argv[argpos][1]=='O' || argv[argpos][1]=='o') && argv[argpos][2])
- {
- if (!outputtried)
- {
- g_output=fopen(argv[argpos]+2,"w");
- if (!g_output)
- {
- if (build.display_errors) printf("Error opening output log for writing. Using stdout.\n");
- g_output=stdout;
- }
- outputtried=1;
- }
- }
- else if (!stricmp(&argv[argpos][1],"NOCD")) do_cd=0;
- else if ((argv[argpos][1] == 'V' || argv[argpos][1] == 'v') &&
- argv[argpos][2] >= '0' && argv[argpos][2] <= '4' && !argv[argpos][3])
- {
- int v=argv[argpos][2]-'0';
- build.display_script=v>3;
- build.display_info=v>2;
- build.display_warnings=v>1;
- build.display_errors=v>0;
- g_display_errors=build.display_errors;
- }
- else if (!stricmp(&argv[argpos][1],"NOCONFIG")) g_noconfig=1;
- else if (!stricmp(&argv[argpos][1],"PAUSE")) g_dopause=1;
- else if (!stricmp(&argv[argpos][1],"LICENSE"))
- {
- if (build.display_info)
- {
- print_license();
- }
- nousage++;
- }
- else if (!stricmp(&argv[argpos][1],"CMDHELP"))
- {
- if (argpos < argc-1)
- build.print_help(argv[++argpos]);
- else
- build.print_help(NULL);
- nousage++;
- }
- else if (!stricmp(&argv[argpos][1],"NOTIFYHWND"))
- {
-#ifdef _WIN32
- build.notify_hwnd=(HWND)atol(argv[++argpos]);
- if (!IsWindow(build.notify_hwnd))
- build.notify_hwnd=0;
-#else
- argpos++;
- build.warning(OPT_STR "NOTIFYHWND is disabled for non Win32 platforms.");
-#endif
- }
- else if (!stricmp(&argv[argpos][1],"HDRINFO"))
- {
- print_stub_info(build);
- nousage++;
- }
- else if ((argv[argpos][1]=='P' || argv[argpos][1]=='p') &&
- argv[argpos][2] >= '0' && argv[argpos][2] <= '5' && !argv[argpos][3])
- {
-#ifdef _WIN32
- // priority setting added 01-2007 by Comm@nder21
- int p=argv[argpos][2]-'0';
- HANDLE hProc = GetCurrentProcess();
-
- struct
- {
- DWORD priority;
- DWORD fallback;
- } classes[] = {
- {IDLE_PRIORITY_CLASS, IDLE_PRIORITY_CLASS},
- {BELOW_NORMAL_PRIORITY_CLASS, IDLE_PRIORITY_CLASS},
- {NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS},
- {ABOVE_NORMAL_PRIORITY_CLASS, HIGH_PRIORITY_CLASS},
- {HIGH_PRIORITY_CLASS, HIGH_PRIORITY_CLASS},
- {REALTIME_PRIORITY_CLASS, REALTIME_PRIORITY_CLASS}
- };
-
- if (SetPriorityClass(hProc, classes[p].priority) == FALSE)
- {
- SetPriorityClass(hProc, classes[p].fallback);
- }
-
- if (p == 5)
- build.warning("makensis is running in REALTIME priority mode!");
-
-#else
- build.warning(OPT_STR "Px is disabled for non Win32 platforms.");
-#endif
- }
- else break;
- }
- else
- {
- files_processed++;
- if (!strcmp(argv[argpos],"-") && !in_files)
- g_dopause=0;
- if (!g_noconfig)
- {
- g_noconfig=1;
- string main_conf;
- char* env_var = getenv("NSISCONFDIR");
- if(env_var == NULL)
-#ifndef NSIS_CONFIG_CONST_DATA_PATH
- main_conf = get_executable_dir(argv[0]);
-#else
- main_conf = PREFIX_CONF;
-#endif
- else main_conf = env_var;
- main_conf += PLATFORM_PATH_SEPARATOR_STR;
- main_conf += "nsisconf.nsh";
- if (process_config(build, main_conf))
- return 1;
-
- string home_conf = get_home();
- if (home_conf != "")
- {
- home_conf += PLATFORM_PATH_SEPARATOR_STR;
-#ifdef _WIN32
- home_conf += "nsisconf.nsh";
-#else
- home_conf += ".nsisconf.nsh";
-#endif
- if (process_config(build, home_conf))
- return 1;
- }
- }
-
- {
- char sfile[1024];
- if (!strcmp(argv[argpos],"-") && !in_files)
- {
- fp=stdin;
- strcpy(sfile,"stdin");
- }
- else
- {
- strcpy(sfile,argv[argpos]);
- fp=fopen(sfile,"rt");
- if (!fp)
- {
- sprintf(sfile,"%s.nsi",argv[argpos]);
- fp=fopen(sfile,"rt");
- if (!fp)
- {
- if (build.display_errors)
- {
- sfile[strlen(sfile)-4]=0;
- fprintf(g_output,"Can't open script \"%s\"\n",sfile);
- fflush(g_output);
- }
- return 1;
- }
- }
- if (do_cd)
- {
- string script_file = string(sfile);
- if (change_to_script_dir(build, script_file))
- return 1;
- }
- }
-
- if (build.display_script)
- {
- build.notify(MAKENSIS_NOTIFY_SCRIPT,sfile);
- fprintf(g_output,"Processing script file: \"%s\"\n",sfile);
- fflush(g_output);
- }
- int ret=build.process_script(fp,sfile);
- if (fp != stdin) fclose(fp);
-
- if (ret != PS_EOF && ret != PS_OK)
- {
- if (build.display_errors)
- {
- fprintf(g_output,"Error in script \"%s\" on line %d -- aborting creation process\n",sfile,build.linecnt);
- fflush(g_output);
- }
- return 1;
- }
- }
- }
- argpos++;
- }
-
- if (argpos<argc || (!files_processed && !cmds_processed))
- {
- if (build.display_errors && !nousage)
- {
- print_usage();
- }
- return 1;
- }
-
- if (build.display_info)
- {
- fprintf(g_output,"\nProcessed ");
- if (files_processed) fprintf(g_output,"%d file%s, ",files_processed,files_processed==1?"":"s");
- if (cmds_processed) fprintf(g_output,"%d command line command%s, ",cmds_processed,cmds_processed==1?"":"s");
- fprintf(g_output,"writing output:\n");
- fflush(g_output);
- }
-
- if (build.write_output())
- {
- if (build.display_errors)
- {
- fprintf(g_output,"Error - aborting creation process\n");
- fflush(g_output);
- }
- return 1;
- }
- return 0;
-}
+/*
+ * makenssi.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+#include <stdio.h>
+#include <signal.h>
+#ifdef _WIN32
+# include <direct.h>
+#else
+# include <unistd.h>
+#endif
+#include <string>
+
+#include "build.h"
+#include "util.h"
+
+#include "version.h"
+
+using namespace std;
+
+int g_noconfig=0;
+int g_display_errors=1;
+FILE *g_output=stdout;
+
+void quit()
+{
+ if (g_display_errors)
+ {
+ fprintf(g_output,"\nNote: you may have one or two (large) stale temporary file(s)\n"
+ "left in your temporary directory (Generally this only happens on Windows 9x).\n");
+ fflush(g_output);
+ }
+ exit(1);
+}
+
+static void myatexit()
+{
+ dopause();
+ if (g_output != stdout && g_output) fclose(g_output);
+}
+
+static void sigint(int sig)
+{
+ if (g_display_errors)
+ {
+ fprintf(g_output,"\n\nAborting on Ctrl+C...\n");
+ fflush(g_output);
+ }
+ quit();
+}
+
+#ifdef _WIN32
+static DWORD WINAPI sigint_event_msg_handler(LPVOID)
+{
+ HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, "makensis win32 signint event");
+
+ if (hEvent)
+ {
+ if (WaitForSingleObject(hEvent, INFINITE) == WAIT_OBJECT_0)
+ raise(SIGINT);
+ CloseHandle(hEvent);
+ }
+
+ return 0;
+}
+#endif
+
+static void init_signals()
+{
+ atexit(myatexit);
+ signal(SIGINT,sigint);
+
+#ifdef _WIN32
+ DWORD id;
+ HANDLE hThread = CreateThread(NULL, 0, sigint_event_msg_handler, NULL, 0, &id);
+ if (hThread) CloseHandle(hThread);
+#endif
+}
+
+static void print_logo()
+{
+ fprintf(g_output,"MakeNSIS %s - Copyright 1995-2007 Contributors\n"
+ "See the file COPYING for license details.\n"
+ "Credits can be found in the Users Manual.\n\n", NSIS_VERSION);
+ fflush(g_output);
+}
+
+static void print_license()
+{
+ fprintf(g_output,"Copyright (C) 1999-2007 Nullsoft and Contributors\n\n"
+ "This license applies to everything in the NSIS package, except where otherwise\n"
+ "noted.\n\n"
+ "This software is provided 'as-is', without any express or implied warranty.\n"
+ "In no event will the authors be held liable for any damages arising from the\n"
+ "use of this software.\n\n"
+ "Permission is granted to anyone to use this software for any purpose, including\n"
+ "commercial applications, and to alter it and redistribute it freely, subject to\n"
+ "the following restrictions:\n"
+ " 1. The origin of this software must not be misrepresented; you must not claim\n"
+ " that you wrote the original software. If you use this software in a\n"
+ " product, an acknowledgment in the product documentation would be\n"
+ " appreciated but is not required.\n"
+ " 2. Altered source versions must be plainly marked as such, and must not be\n"
+ " misrepresented as being the original software.\n"
+ " 3. This notice may not be removed or altered from any source distribution.\n\n"
+ "In addition to this license, different licenses apply to the included\n"
+ "compression modules. See the file COPYING for details.\n");
+ fflush(g_output);
+}
+
+static void print_usage()
+{
+ fprintf(g_output,"Usage:\n"
+ " makensis [option | script.nsi | - [...]]\n"
+ " options are:\n"
+ " " OPT_STR "CMDHELP item prints out help for 'item', or lists all commands\n"
+ " " OPT_STR "HDRINFO prints information about what options makensis was compiled with\n"
+ " " OPT_STR "LICENSE prints the makensis software license\n"
+ " " OPT_STR "VERSION prints the makensis version and exits\n"
+ " " OPT_STR "Px sets the compiler process priority, where x is 5=realtime,4=high,\n"
+ " " " 3=above normal,2=normal,1=below normal,0=idle\n"
+ " " OPT_STR "Vx verbosity where x is 4=all,3=no script,2=no info,1=no warnings,0=none\n"
+ " " OPT_STR "Ofile specifies a text file to log compiler output (default is stdout)\n"
+ " " OPT_STR "PAUSE pauses after execution\n"
+ " " OPT_STR "NOCONFIG disables inclusion of <path to makensis.exe>" PLATFORM_PATH_SEPARATOR_STR "nsisconf.nsh\n"
+ " " OPT_STR "NOCD disabled the current directory change to that of the .nsi file\n"
+ " " OPT_STR "Ddefine[=value] defines the symbol \"define\" for the script [to value]\n"
+ " " OPT_STR "Xscriptcmd executes scriptcmd in script (i.e. \"" OPT_STR "XOutFile poop.exe\")\n"
+ " parameters are processed by order (" OPT_STR "Ddef ins.nsi != ins.nsi " OPT_STR "Ddef)\n"
+ " for script file name, you can use - to read from the standard input\n"
+#ifdef _WIN32
+ " you can also use - as an option character: -PAUSE as well as /PAUSE\n"
+#endif
+ " you can use a double-dash to end options processing: makensis -- -ins.nsi\n");
+ fflush(g_output);
+}
+
+static void print_stub_info(CEXEBuild& build)
+{
+ if (build.display_info)
+ {
+ fprintf(g_output,"Size of first header is %lu bytes.\n",(unsigned long)sizeof(firstheader));
+ fprintf(g_output,"Size of main header is %lu bytes.\n",(unsigned long)sizeof(header));
+ fprintf(g_output,"Size of each section is %lu bytes.\n",(unsigned long)sizeof(section));
+ fprintf(g_output,"Size of each page is %lu bytes.\n",(unsigned long)sizeof(page));
+ fprintf(g_output,"Size of each instruction is %lu bytes.\n",(unsigned long)sizeof(entry));
+ int x=build.definedlist.getnum();
+ fprintf(g_output,"\nDefined symbols: ");
+ for (int i=0; i<x; i++)
+ {
+ fprintf(g_output,"%s",build.definedlist.getname(i));
+ char *p=build.definedlist.getvalue(i);
+ if (*p) fprintf(g_output,"=%s",p);
+ if (i<x-1) fprintf(g_output,",");
+ }
+ if (!x) fprintf(g_output,"none");
+ fprintf(g_output,"\n");
+ fflush(g_output);
+ }
+}
+
+static string get_home()
+{
+ char *home = getenv(
+#ifdef _WIN32
+ "APPDATA"
+#else
+ "HOME"
+#endif
+ );
+
+ return home ? home : "";
+}
+
+static int process_config(CEXEBuild& build, string& conf)
+{
+ FILE *cfg=fopen(conf.c_str(),"rt");
+ if (cfg)
+ {
+ if (build.display_script)
+ {
+ fprintf(g_output,"Processing config: \n");
+ fflush(g_output);
+ }
+ int ret=build.process_script(cfg,(char*)conf.c_str());
+ fclose(cfg);
+ if (ret != PS_OK && ret != PS_EOF)
+ {
+ if (build.display_errors)
+ {
+ fprintf(g_output,"Error in config on line %d -- aborting creation process\n",build.linecnt);
+ fflush(g_output);
+ }
+ return 1;
+ }
+ if (build.display_script)
+ {
+ fprintf(g_output,"\n");
+ fflush(g_output);
+ }
+ }
+ return 0;
+}
+
+static int change_to_script_dir(CEXEBuild& build, string& script)
+{
+ string dir = get_dir_name(get_full_path(script));
+ if (!dir.empty())
+ {
+ if (build.display_script)
+ {
+ fprintf(g_output,"Changing directory to: \"%s\"\n",dir.c_str());
+ fflush(g_output);
+ }
+ if (chdir(dir.c_str()))
+ {
+ if (build.display_errors)
+ {
+ fprintf(g_output,"Error changing directory to \"%s\"\n",dir.c_str());
+ fflush(g_output);
+ }
+ return 1;
+ }
+ if (build.display_script)
+ {
+ fprintf(g_output,"\n");
+ fflush(g_output);
+ }
+ }
+ return 0;
+}
+
+#ifdef NSIS_HPUX_ALLOW_UNALIGNED_DATA_ACCESS
+extern "C" void allow_unaligned_data_access();
+#endif
+
+int main(int argc, char **argv)
+{
+#ifdef NSIS_HPUX_ALLOW_UNALIGNED_DATA_ACCESS
+ allow_unaligned_data_access();
+#endif
+
+ CEXEBuild build;
+ int do_cd=1;
+ int outputtried=0;
+ int argpos=1;
+ int nousage=0;
+ int files_processed=0;
+ int cmds_processed=0;
+ FILE *fp;
+ int tmpargpos=1;
+ int no_logo=0;
+ int in_files=0;
+
+ try
+ {
+ build.initialize(argv[0]);
+ }
+ catch (exception& err)
+ {
+ fprintf(g_output, "Error initalizing CEXEBuild: %s\n", err.what());
+ fflush(g_output);
+ return 1;
+ }
+
+ if (argc > 1 && IS_OPT(argv[1]) && !stricmp(&argv[1][1],"VERSION"))
+ {
+ fprintf(g_output,NSIS_VERSION);
+ fflush(g_output);
+ return 0;
+ }
+ if (argc > 1 && IS_OPT(argv[1]) && (argv[1][1]=='v' || argv[1][1]=='V'))
+ {
+ tmpargpos++;
+ if (argv[1][2] <= '2' && argv[1][2] >= '0')
+ {
+ no_logo=1;
+ }
+ }
+
+ if (!no_logo)
+ {
+ if (argc > tmpargpos && IS_OPT(argv[tmpargpos]) && (argv[tmpargpos][1]=='o' || argv[tmpargpos][1]=='O') && argv[tmpargpos][2])
+ {
+ g_output=fopen(argv[tmpargpos]+2,"w");
+ if (!g_output)
+ {
+ printf("Error opening output log for writing. Using stdout.\n");
+ g_output=stdout;
+ }
+ outputtried=1;
+ }
+ print_logo();
+ }
+
+ init_signals();
+
+ if (!g_output) g_output=stdout;
+ while (argpos < argc)
+ {
+ if (!strcmp(argv[argpos], "--"))
+ in_files=1;
+ else if (IS_OPT(argv[argpos]) && strcmp(argv[argpos], "-") && !in_files)
+ {
+ if ((argv[argpos][1]=='D' || argv[argpos][1]=='d') && argv[argpos][2])
+ {
+ char *p=argv[argpos]+2;
+ char *s=strdup(p),*v;
+ if (build.display_script)
+ {
+ fprintf(g_output,"Command line defined: \"%s\"\n",p);
+ fflush(g_output);
+ }
+ v=strstr(s,"=");
+ if (v) *v++=0;
+ build.define(s,v?v:"");
+ free(s);
+ }
+ else if ((argv[argpos][1]=='X' || argv[argpos][1]=='x') && argv[argpos][2])
+ {
+ if (build.process_oneline(argv[argpos]+2,"command line",argpos+1) != PS_OK)
+ {
+ return 1;
+ }
+ cmds_processed++;
+ }
+ else if ((argv[argpos][1]=='O' || argv[argpos][1]=='o') && argv[argpos][2])
+ {
+ if (!outputtried)
+ {
+ g_output=fopen(argv[argpos]+2,"w");
+ if (!g_output)
+ {
+ if (build.display_errors) printf("Error opening output log for writing. Using stdout.\n");
+ g_output=stdout;
+ }
+ outputtried=1;
+ }
+ }
+ else if (!stricmp(&argv[argpos][1],"NOCD")) do_cd=0;
+ else if ((argv[argpos][1] == 'V' || argv[argpos][1] == 'v') &&
+ argv[argpos][2] >= '0' && argv[argpos][2] <= '4' && !argv[argpos][3])
+ {
+ int v=argv[argpos][2]-'0';
+ build.display_script=v>3;
+ build.display_info=v>2;
+ build.display_warnings=v>1;
+ build.display_errors=v>0;
+ g_display_errors=build.display_errors;
+ }
+ else if (!stricmp(&argv[argpos][1],"NOCONFIG")) g_noconfig=1;
+ else if (!stricmp(&argv[argpos][1],"PAUSE")) g_dopause=1;
+ else if (!stricmp(&argv[argpos][1],"LICENSE"))
+ {
+ if (build.display_info)
+ {
+ print_license();
+ }
+ nousage++;
+ }
+ else if (!stricmp(&argv[argpos][1],"CMDHELP"))
+ {
+ if (argpos < argc-1)
+ build.print_help(argv[++argpos]);
+ else
+ build.print_help(NULL);
+ nousage++;
+ }
+ else if (!stricmp(&argv[argpos][1],"NOTIFYHWND"))
+ {
+#ifdef _WIN32
+ build.notify_hwnd=(HWND)atol(argv[++argpos]);
+ if (!IsWindow(build.notify_hwnd))
+ build.notify_hwnd=0;
+#else
+ argpos++;
+ build.warning(OPT_STR "NOTIFYHWND is disabled for non Win32 platforms.");
+#endif
+ }
+ else if (!stricmp(&argv[argpos][1],"HDRINFO"))
+ {
+ print_stub_info(build);
+ nousage++;
+ }
+ else if ((argv[argpos][1]=='P' || argv[argpos][1]=='p') &&
+ argv[argpos][2] >= '0' && argv[argpos][2] <= '5' && !argv[argpos][3])
+ {
+#ifdef _WIN32
+ // priority setting added 01-2007 by Comm@nder21
+ int p=argv[argpos][2]-'0';
+ HANDLE hProc = GetCurrentProcess();
+
+ struct
+ {
+ DWORD priority;
+ DWORD fallback;
+ } classes[] = {
+ {IDLE_PRIORITY_CLASS, IDLE_PRIORITY_CLASS},
+ {BELOW_NORMAL_PRIORITY_CLASS, IDLE_PRIORITY_CLASS},
+ {NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS},
+ {ABOVE_NORMAL_PRIORITY_CLASS, HIGH_PRIORITY_CLASS},
+ {HIGH_PRIORITY_CLASS, HIGH_PRIORITY_CLASS},
+ {REALTIME_PRIORITY_CLASS, REALTIME_PRIORITY_CLASS}
+ };
+
+ if (SetPriorityClass(hProc, classes[p].priority) == FALSE)
+ {
+ SetPriorityClass(hProc, classes[p].fallback);
+ }
+
+ if (p == 5)
+ build.warning("makensis is running in REALTIME priority mode!");
+
+#else
+ build.warning(OPT_STR "Px is disabled for non Win32 platforms.");
+#endif
+ }
+ else break;
+ }
+ else
+ {
+ files_processed++;
+ if (!strcmp(argv[argpos],"-") && !in_files)
+ g_dopause=0;
+ if (!g_noconfig)
+ {
+ g_noconfig=1;
+ string main_conf;
+ char* env_var = getenv("NSISCONFDIR");
+ if(env_var == NULL)
+#ifndef NSIS_CONFIG_CONST_DATA_PATH
+ main_conf = get_executable_dir(argv[0]);
+#else
+ main_conf = PREFIX_CONF;
+#endif
+ else main_conf = env_var;
+ main_conf += PLATFORM_PATH_SEPARATOR_STR;
+ main_conf += "nsisconf.nsh";
+ if (process_config(build, main_conf))
+ return 1;
+
+ string home_conf = get_home();
+ if (home_conf != "")
+ {
+ home_conf += PLATFORM_PATH_SEPARATOR_STR;
+#ifdef _WIN32
+ home_conf += "nsisconf.nsh";
+#else
+ home_conf += ".nsisconf.nsh";
+#endif
+ if (process_config(build, home_conf))
+ return 1;
+ }
+ }
+
+ {
+ char sfile[1024];
+ if (!strcmp(argv[argpos],"-") && !in_files)
+ {
+ fp=stdin;
+ strcpy(sfile,"stdin");
+ }
+ else
+ {
+ strcpy(sfile,argv[argpos]);
+ fp=fopen(sfile,"rt");
+ if (!fp)
+ {
+ sprintf(sfile,"%s.nsi",argv[argpos]);
+ fp=fopen(sfile,"rt");
+ if (!fp)
+ {
+ if (build.display_errors)
+ {
+ sfile[strlen(sfile)-4]=0;
+ fprintf(g_output,"Can't open script \"%s\"\n",sfile);
+ fflush(g_output);
+ }
+ return 1;
+ }
+ }
+ if (do_cd)
+ {
+ string script_file = string(sfile);
+ if (change_to_script_dir(build, script_file))
+ return 1;
+ }
+ }
+
+ if (build.display_script)
+ {
+ build.notify(MAKENSIS_NOTIFY_SCRIPT,sfile);
+ fprintf(g_output,"Processing script file: \"%s\"\n",sfile);
+ fflush(g_output);
+ }
+ int ret=build.process_script(fp,sfile);
+ if (fp != stdin) fclose(fp);
+
+ if (ret != PS_EOF && ret != PS_OK)
+ {
+ if (build.display_errors)
+ {
+ fprintf(g_output,"Error in script \"%s\" on line %d -- aborting creation process\n",sfile,build.linecnt);
+ fflush(g_output);
+ }
+ return 1;
+ }
+ }
+ }
+ argpos++;
+ }
+
+ if (argpos<argc || (!files_processed && !cmds_processed))
+ {
+ if (build.display_errors && !nousage)
+ {
+ print_usage();
+ }
+ return 1;
+ }
+
+ if (build.display_info)
+ {
+ fprintf(g_output,"\nProcessed ");
+ if (files_processed) fprintf(g_output,"%d file%s, ",files_processed,files_processed==1?"":"s");
+ if (cmds_processed) fprintf(g_output,"%d command line command%s, ",cmds_processed,cmds_processed==1?"":"s");
+ fprintf(g_output,"writing output:\n");
+ fflush(g_output);
+ }
+
+ if (build.write_output())
+ {
+ if (build.display_errors)
+ {
+ fprintf(g_output,"Error - aborting creation process\n");
+ fflush(g_output);
+ }
+ return 1;
+ }
+ return 0;
+}
diff --git a/Source/manifest.cpp b/Source/manifest.cpp
index 3d6d005..abd55a6 100755
--- a/Source/manifest.cpp
+++ b/Source/manifest.cpp
@@ -1,67 +1,67 @@
-/*
- * manifest.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-#include "manifest.h"
-#include "version.h"
-
-namespace manifest
-{
-
-using namespace std;
-
-string generate(comctl comctl_selection, exec_level exec_level_selection)
-{
- if (comctl_selection == comctl_old && exec_level_selection == exec_level_none)
- return "";
-
- string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\"><assemblyIdentity version=\"1.0.0.0\" processorArchitecture=\"X86\" name=\"Nullsoft.NSIS.exehead\" type=\"win32\"/><description>Nullsoft Install System " NSIS_VERSION "</description>";
-
- if (comctl_selection == comctl_xp)
- {
- xml += "<dependency><dependentAssembly><assemblyIdentity type=\"win32\" name=\"Microsoft.Windows.Common-Controls\" version=\"6.0.0.0\" processorArchitecture=\"X86\" publicKeyToken=\"6595b64144ccf1df\" language=\"*\" /></dependentAssembly></dependency>";
- }
-
- if (exec_level_selection != exec_level_none)
- {
- string level = "";
-
- switch (exec_level_selection)
- {
- case exec_level_none:
- break;
- case exec_level_user:
- level = "asInvoker";
- break;
- case exec_level_highest:
- level = "highestAvailable";
- break;
- case exec_level_admin:
- level = "requireAdministrator";
- break;
- }
-
- xml += "<trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\"><security><requestedPrivileges><requestedExecutionLevel level=\"";
- xml += level;
- xml += "\" uiAccess=\"false\"/></requestedPrivileges></security></trustInfo>";
- }
-
- xml += "</assembly>";
-
- return xml;
-}
-
-};
+/*
+ * manifest.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+#include "manifest.h"
+#include "version.h"
+
+namespace manifest
+{
+
+using namespace std;
+
+string generate(comctl comctl_selection, exec_level exec_level_selection)
+{
+ if (comctl_selection == comctl_old && exec_level_selection == exec_level_none)
+ return "";
+
+ string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\"><assemblyIdentity version=\"1.0.0.0\" processorArchitecture=\"X86\" name=\"Nullsoft.NSIS.exehead\" type=\"win32\"/><description>Nullsoft Install System " NSIS_VERSION "</description>";
+
+ if (comctl_selection == comctl_xp)
+ {
+ xml += "<dependency><dependentAssembly><assemblyIdentity type=\"win32\" name=\"Microsoft.Windows.Common-Controls\" version=\"6.0.0.0\" processorArchitecture=\"X86\" publicKeyToken=\"6595b64144ccf1df\" language=\"*\" /></dependentAssembly></dependency>";
+ }
+
+ if (exec_level_selection != exec_level_none)
+ {
+ string level = "";
+
+ switch (exec_level_selection)
+ {
+ case exec_level_none:
+ break;
+ case exec_level_user:
+ level = "asInvoker";
+ break;
+ case exec_level_highest:
+ level = "highestAvailable";
+ break;
+ case exec_level_admin:
+ level = "requireAdministrator";
+ break;
+ }
+
+ xml += "<trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\"><security><requestedPrivileges><requestedExecutionLevel level=\"";
+ xml += level;
+ xml += "\" uiAccess=\"false\"/></requestedPrivileges></security></trustInfo>";
+ }
+
+ xml += "</assembly>";
+
+ return xml;
+}
+
+};
diff --git a/Source/manifest.h b/Source/manifest.h
index 7533ee8..c336af6 100755
--- a/Source/manifest.h
+++ b/Source/manifest.h
@@ -1,41 +1,41 @@
-/*
- * manifest.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef ___MANIFEST_H___
-#define ___MANIFEST_H___
-
-#include <string>
-
-namespace manifest
-{
- enum comctl
- {
- comctl_old,
- comctl_xp
- };
-
- enum exec_level
- {
- exec_level_none,
- exec_level_user,
- exec_level_highest,
- exec_level_admin
- };
-
- std::string generate(comctl, exec_level);
-};
-
-#endif//!___MANIFEST_H___
+/*
+ * manifest.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef ___MANIFEST_H___
+#define ___MANIFEST_H___
+
+#include <string>
+
+namespace manifest
+{
+ enum comctl
+ {
+ comctl_old,
+ comctl_xp
+ };
+
+ enum exec_level
+ {
+ exec_level_none,
+ exec_level_user,
+ exec_level_highest,
+ exec_level_admin
+ };
+
+ std::string generate(comctl, exec_level);
+};
+
+#endif//!___MANIFEST_H___
diff --git a/Source/mmap.cpp b/Source/mmap.cpp
index aecdba2..25668c9 100755
--- a/Source/mmap.cpp
+++ b/Source/mmap.cpp
@@ -1,512 +1,512 @@
-/*
- * mmap.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "mmap.h"
-
-#include <cstdio> // for f*
-#include <cassert> // for assert
-#ifndef _WIN32
-# include <sys/types.h> // for freebsd
-# include <sys/mman.h>
-# include <sys/stat.h>
-# include <fcntl.h>
-# include <unistd.h>
-#endif
-
-// ========
-// MMapFile
-// ========
-
-int MMapFile::m_iAllocationGranularity = 0;
-
-MMapFile::MMapFile()
-{
-#ifdef _WIN32
- m_hFile = INVALID_HANDLE_VALUE;
- m_hFileMap = NULL;
-#else
- m_hFile = NULL;
- m_hFileDesc = -1;
-#endif
-
- m_pView = NULL;
- m_iSize = 0;
- m_bReadOnly = FALSE;
- m_bTempHandle = FALSE;
-
- if (!m_iAllocationGranularity)
- {
-#ifdef _WIN32
- SYSTEM_INFO si;
- GetSystemInfo(&si);
- m_iAllocationGranularity = (int) si.dwAllocationGranularity;
-#else
- m_iAllocationGranularity = getpagesize();
-#endif
- }
-}
-
-MMapFile::~MMapFile()
-{
- clear();
-}
-
-void MMapFile::clear()
-{
- release();
-
-#ifdef _WIN32
- if (m_hFileMap)
- CloseHandle(m_hFileMap);
- if (m_bTempHandle && m_hFile != INVALID_HANDLE_VALUE)
- CloseHandle(m_hFile);
-
- m_hFile = INVALID_HANDLE_VALUE;
- m_hFileMap = 0;
-#else
- if (m_bTempHandle && m_hFile)
- fclose(m_hFile);
-
- m_hFile = NULL;
-#endif
-}
-
-void MMapFile::setro(BOOL bRO)
-{
- m_bReadOnly = bRO;
-}
-
-#ifdef _WIN32
-int MMapFile::setfile(HANDLE hFile, DWORD dwSize)
-#else
-int MMapFile::setfile(int hFile, DWORD dwSize)
-#endif
-{
- clear();
-
-#ifdef _WIN32
- m_hFile = hFile;
-#else
- m_hFileDesc = hFile;
-#endif
- m_bTempHandle = FALSE;
-
-#ifdef _WIN32
- if (m_hFile == INVALID_HANDLE_VALUE)
-#else
- if (m_hFileDesc == -1)
-#endif
- return 0;
-
- m_iSize = (int) dwSize;
-
- if (m_iSize <= 0)
- return 0;
-
-#ifdef _WIN32
- m_hFileMap = CreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, m_iSize, NULL);
-
- if (!m_hFileMap)
- return 0;
-#endif
-
- m_bReadOnly = TRUE;
-
- return 1;
-}
-
-void MMapFile::resize(int newsize)
-{
- release();
-
- if (newsize > m_iSize)
- {
-#ifdef _WIN32
- if (m_hFileMap)
- CloseHandle(m_hFileMap);
-
- m_hFileMap = 0;
-#endif
-
- m_iSize = newsize;
-
-#ifdef _WIN32
- if (m_hFile == INVALID_HANDLE_VALUE)
- {
- char buf[MAX_PATH], buf2[MAX_PATH];
-
- GetTempPath(MAX_PATH, buf);
- GetTempFileName(buf, "nsd", 0, buf2);
-
- m_hFile = CreateFile(
- buf2,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL
- );
-
- m_bTempHandle = TRUE;
- }
-
- if (m_hFile != INVALID_HANDLE_VALUE)
- {
- m_hFileMap = CreateFileMapping(
- m_hFile,
- NULL,
- m_bReadOnly ? PAGE_READONLY : PAGE_READWRITE,
- 0,
- m_iSize,
- NULL
- );
- }
-#else
- if (m_hFile == NULL)
- {
- m_hFile = tmpfile();
- if (m_hFile != NULL)
- {
- m_hFileDesc = fileno(m_hFile);
- m_bTempHandle = TRUE;
- }
- }
-
- // resize
- if (m_hFileDesc != -1)
- {
- unsigned char c = 0;
-
- if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1)
- {
- if (read(m_hFileDesc, &c, 1) != -1)
- {
- if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1)
- {
- if (write(m_hFileDesc, &c, 1) != -1)
- {
- return; // no errors
- }
- }
- }
- }
- }
-
- m_hFileDesc = -1; // some error occurred, bail
-#endif
-
-#ifdef _WIN32
- if (!m_hFileMap)
-#else
- if (m_hFileDesc == -1)
-#endif
- {
- extern FILE *g_output;
- extern void quit(); extern int g_display_errors;
- if (g_display_errors)
- {
- fprintf(g_output,"\nInternal compiler error #12345: error creating mmap the size of %d.\n", m_iSize);
- fflush(g_output);
- }
- quit();
- }
- }
-}
-
-int MMapFile::getsize() const
-{
- return m_iSize;
-}
-
-void *MMapFile::get(int offset, int size) const
-{
- return get(offset, &size);
-}
-
-void *MMapFile::get(int offset, int *sizep) const
-{
- if (!sizep)
- return NULL;
-
- assert(!m_pView);
-
- int size = *sizep;
-
- if (!m_iSize || offset + size > m_iSize)
- {
- extern FILE *g_output;
- extern void quit(); extern int g_display_errors;
- if (g_display_errors)
- {
- fprintf(g_output,"\nInternal compiler error #12345: error mmapping file (%d, %d) is out of range.\n", offset, size);
- fflush(g_output);
- }
- quit();
- }
-
- // fix offset
- int alignedoffset = offset - (offset % m_iAllocationGranularity);
- size += offset - alignedoffset;
-
-#ifdef _WIN32
- const_cast<MMapFile*>(this)->m_pView =
- MapViewOfFile(m_hFileMap, m_bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, alignedoffset, size);
-#else
- const_cast<MMapFile*>(this)->m_pView =
- mmap(0, size, m_bReadOnly ? PROT_READ : PROT_READ | PROT_WRITE, MAP_SHARED, m_hFileDesc, alignedoffset);
- const_cast<MMapFile*>(this)->m_iMappedSize = *sizep = size;
-#endif
-
-#ifdef _WIN32
- if (!m_pView)
-#else
- if (m_pView == MAP_FAILED)
-#endif
- {
- extern FILE *g_output;
- extern void quit(); extern int g_display_errors;
- if (g_display_errors)
- {
- fprintf(g_output,"\nInternal compiler error #12345: error mmapping datablock to %d.\n", size);
- fflush(g_output);
- }
- quit();
- }
-
- return (void *)((char *)m_pView + offset - alignedoffset);
-}
-
-void *MMapFile::getmore(int offset, int size) const
-{
- void *pView;
- void *pViewBackup = m_pView;
-#ifndef _WIN32
- int iMappedSizeBackup = m_iMappedSize;
-#endif
- const_cast<MMapFile*>(this)->m_pView = 0;
- pView = get(offset, size);
- const_cast<MMapFile*>(this)->m_pView = pViewBackup;
-#ifndef _WIN32
- const_cast<MMapFile*>(this)->m_iMappedSize = iMappedSizeBackup;
-#endif
- return pView;
-}
-
-void MMapFile::release()
-{
- if (!m_pView)
- return;
-
-#ifdef _WIN32
- UnmapViewOfFile(m_pView);
-#else
- munmap(m_pView, m_iMappedSize);
-#endif
- m_pView = NULL;
-}
-
-void MMapFile::release(void *pView, int size)
-{
- if (!pView)
- return;
-
- unsigned int alignment = ((unsigned int)pView) % m_iAllocationGranularity;
- pView = (char *)pView - alignment;
- size += alignment;
-#ifdef _WIN32
- UnmapViewOfFile(pView);
-#else
- munmap(pView, size);
-#endif
-}
-
-void MMapFile::flush(int num)
-{
- if (m_pView)
-#ifdef _WIN32
- FlushViewOfFile(m_pView, num);
-#else
- msync(m_pView, num, MS_SYNC);
-#endif
-}
-
-// ========
-// MMapFake
-// ========
-
-MMapFake::MMapFake()
-{
- m_pMem = NULL;
- m_iSize = 0;
-}
-
-void MMapFake::set(const char *pMem, int iSize)
-{
- m_pMem = pMem;
- m_iSize = iSize;
-}
-
-int MMapFake::getsize() const
-{
- return m_iSize;
-}
-
-void *MMapFake::get(int offset, int size) const
-{
- return get(offset, &size);
-}
-
-void *MMapFake::get(int offset, int *size) const
-{
- if (!size || (offset + *size > m_iSize))
- return NULL;
- return (void *)(m_pMem + offset);
-}
-
-void *MMapFake::getmore(int offset, int size) const
-{
- return get(offset, size);
-}
-
-void MMapFake::resize(int n) {}
-void MMapFake::release() {}
-void MMapFake::release(void *p, int size) {}
-void MMapFake::clear() {}
-void MMapFake::setro(BOOL b) {}
-void MMapFake::flush(BOOL b) {}
-
-// =======
-// MMapBuf
-// =======
-
-MMapBuf::MMapBuf()
-{
- m_gb_u=0;
- m_alloc=m_used=0;
-}
-
-MMapBuf::~MMapBuf()
-{
- m_fm.release();
-}
-
-int MMapBuf::add(const void *data, int len)
-{
- if (len <= 0) return 0;
- resize(getlen() + len);
- memcpy((char*)get(getlen() - len, len), data, len);
- release();
- return getlen() - len;
-}
-
-void MMapBuf::setro(BOOL bRO)
-{
- m_fm.setro(bRO);
-}
-
-void MMapBuf::resize(int newlen)
-{
- if (!m_gb_u && newlen < (16 << 20)) // still in db mode
- {
- m_gb.resize(newlen);
- return;
- }
-
- // not in db mode
- m_gb_u = 1;
- m_used = newlen;
-
- if (newlen > m_alloc)
- {
- m_alloc = newlen + (16 << 20); // add 16mb to top of mapping
-
- m_fm.resize(m_alloc);
-
- if (m_gb.getlen())
- {
- memcpy(m_fm.get(0, m_gb.getlen()), m_gb.get(), m_gb.getlen());
- m_fm.flush(m_gb.getlen());
- m_fm.release();
- m_gb.resize(0);
- }
- }
-}
-
-int MMapBuf::getsize() const
-{
- if (m_gb_u)
- return m_fm.getsize();
- return m_gb.getlen();
-}
-
-int MMapBuf::getlen() const
-{
- if (m_gb_u)
- return m_used;
- return m_gb.getlen();
-}
-
-void *MMapBuf::get() const
-{
- return get(0, m_alloc);
-}
-
-void *MMapBuf::get(int offset, int *sizep) const
-{
- if (!sizep)
- return NULL;
- int size = *sizep;
- return get(offset, size);
-}
-
-void *MMapBuf::get(int offset, int size) const
-{
- if (m_gb_u)
- return m_fm.get(offset, size);
- return (void *) ((char *) m_gb.get() + offset);
-}
-
-void *MMapBuf::getmore(int offset, int size) const
-{
- if (m_gb_u)
- return m_fm.getmore(offset, size);
- return (void *) ((char *) m_gb.get() + offset);
-}
-
-void MMapBuf::release()
-{
- if (m_gb_u)
- m_fm.release();
-}
-
-void MMapBuf::release(void *pView, int size)
-{
- if (m_gb_u)
- m_fm.release(pView, size);
-}
-
-void MMapBuf::clear()
-{
- if (m_gb_u)
- m_fm.clear();
-}
-
-void MMapBuf::flush(int num)
-{
- if (m_gb_u)
- m_fm.flush(num);
-}
+/*
+ * mmap.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "mmap.h"
+
+#include <cstdio> // for f*
+#include <cassert> // for assert
+#ifndef _WIN32
+# include <sys/types.h> // for freebsd
+# include <sys/mman.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <unistd.h>
+#endif
+
+// ========
+// MMapFile
+// ========
+
+int MMapFile::m_iAllocationGranularity = 0;
+
+MMapFile::MMapFile()
+{
+#ifdef _WIN32
+ m_hFile = INVALID_HANDLE_VALUE;
+ m_hFileMap = NULL;
+#else
+ m_hFile = NULL;
+ m_hFileDesc = -1;
+#endif
+
+ m_pView = NULL;
+ m_iSize = 0;
+ m_bReadOnly = FALSE;
+ m_bTempHandle = FALSE;
+
+ if (!m_iAllocationGranularity)
+ {
+#ifdef _WIN32
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ m_iAllocationGranularity = (int) si.dwAllocationGranularity;
+#else
+ m_iAllocationGranularity = getpagesize();
+#endif
+ }
+}
+
+MMapFile::~MMapFile()
+{
+ clear();
+}
+
+void MMapFile::clear()
+{
+ release();
+
+#ifdef _WIN32
+ if (m_hFileMap)
+ CloseHandle(m_hFileMap);
+ if (m_bTempHandle && m_hFile != INVALID_HANDLE_VALUE)
+ CloseHandle(m_hFile);
+
+ m_hFile = INVALID_HANDLE_VALUE;
+ m_hFileMap = 0;
+#else
+ if (m_bTempHandle && m_hFile)
+ fclose(m_hFile);
+
+ m_hFile = NULL;
+#endif
+}
+
+void MMapFile::setro(BOOL bRO)
+{
+ m_bReadOnly = bRO;
+}
+
+#ifdef _WIN32
+int MMapFile::setfile(HANDLE hFile, DWORD dwSize)
+#else
+int MMapFile::setfile(int hFile, DWORD dwSize)
+#endif
+{
+ clear();
+
+#ifdef _WIN32
+ m_hFile = hFile;
+#else
+ m_hFileDesc = hFile;
+#endif
+ m_bTempHandle = FALSE;
+
+#ifdef _WIN32
+ if (m_hFile == INVALID_HANDLE_VALUE)
+#else
+ if (m_hFileDesc == -1)
+#endif
+ return 0;
+
+ m_iSize = (int) dwSize;
+
+ if (m_iSize <= 0)
+ return 0;
+
+#ifdef _WIN32
+ m_hFileMap = CreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, m_iSize, NULL);
+
+ if (!m_hFileMap)
+ return 0;
+#endif
+
+ m_bReadOnly = TRUE;
+
+ return 1;
+}
+
+void MMapFile::resize(int newsize)
+{
+ release();
+
+ if (newsize > m_iSize)
+ {
+#ifdef _WIN32
+ if (m_hFileMap)
+ CloseHandle(m_hFileMap);
+
+ m_hFileMap = 0;
+#endif
+
+ m_iSize = newsize;
+
+#ifdef _WIN32
+ if (m_hFile == INVALID_HANDLE_VALUE)
+ {
+ char buf[MAX_PATH], buf2[MAX_PATH];
+
+ GetTempPath(MAX_PATH, buf);
+ GetTempFileName(buf, "nsd", 0, buf2);
+
+ m_hFile = CreateFile(
+ buf2,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_SEQUENTIAL_SCAN,
+ NULL
+ );
+
+ m_bTempHandle = TRUE;
+ }
+
+ if (m_hFile != INVALID_HANDLE_VALUE)
+ {
+ m_hFileMap = CreateFileMapping(
+ m_hFile,
+ NULL,
+ m_bReadOnly ? PAGE_READONLY : PAGE_READWRITE,
+ 0,
+ m_iSize,
+ NULL
+ );
+ }
+#else
+ if (m_hFile == NULL)
+ {
+ m_hFile = tmpfile();
+ if (m_hFile != NULL)
+ {
+ m_hFileDesc = fileno(m_hFile);
+ m_bTempHandle = TRUE;
+ }
+ }
+
+ // resize
+ if (m_hFileDesc != -1)
+ {
+ unsigned char c = 0;
+
+ if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1)
+ {
+ if (read(m_hFileDesc, &c, 1) != -1)
+ {
+ if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1)
+ {
+ if (write(m_hFileDesc, &c, 1) != -1)
+ {
+ return; // no errors
+ }
+ }
+ }
+ }
+ }
+
+ m_hFileDesc = -1; // some error occurred, bail
+#endif
+
+#ifdef _WIN32
+ if (!m_hFileMap)
+#else
+ if (m_hFileDesc == -1)
+#endif
+ {
+ extern FILE *g_output;
+ extern void quit(); extern int g_display_errors;
+ if (g_display_errors)
+ {
+ fprintf(g_output,"\nInternal compiler error #12345: error creating mmap the size of %d.\n", m_iSize);
+ fflush(g_output);
+ }
+ quit();
+ }
+ }
+}
+
+int MMapFile::getsize() const
+{
+ return m_iSize;
+}
+
+void *MMapFile::get(int offset, int size) const
+{
+ return get(offset, &size);
+}
+
+void *MMapFile::get(int offset, int *sizep) const
+{
+ if (!sizep)
+ return NULL;
+
+ assert(!m_pView);
+
+ int size = *sizep;
+
+ if (!m_iSize || offset + size > m_iSize)
+ {
+ extern FILE *g_output;
+ extern void quit(); extern int g_display_errors;
+ if (g_display_errors)
+ {
+ fprintf(g_output,"\nInternal compiler error #12345: error mmapping file (%d, %d) is out of range.\n", offset, size);
+ fflush(g_output);
+ }
+ quit();
+ }
+
+ // fix offset
+ int alignedoffset = offset - (offset % m_iAllocationGranularity);
+ size += offset - alignedoffset;
+
+#ifdef _WIN32
+ const_cast<MMapFile*>(this)->m_pView =
+ MapViewOfFile(m_hFileMap, m_bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, alignedoffset, size);
+#else
+ const_cast<MMapFile*>(this)->m_pView =
+ mmap(0, size, m_bReadOnly ? PROT_READ : PROT_READ | PROT_WRITE, MAP_SHARED, m_hFileDesc, alignedoffset);
+ const_cast<MMapFile*>(this)->m_iMappedSize = *sizep = size;
+#endif
+
+#ifdef _WIN32
+ if (!m_pView)
+#else
+ if (m_pView == MAP_FAILED)
+#endif
+ {
+ extern FILE *g_output;
+ extern void quit(); extern int g_display_errors;
+ if (g_display_errors)
+ {
+ fprintf(g_output,"\nInternal compiler error #12345: error mmapping datablock to %d.\n", size);
+ fflush(g_output);
+ }
+ quit();
+ }
+
+ return (void *)((char *)m_pView + offset - alignedoffset);
+}
+
+void *MMapFile::getmore(int offset, int size) const
+{
+ void *pView;
+ void *pViewBackup = m_pView;
+#ifndef _WIN32
+ int iMappedSizeBackup = m_iMappedSize;
+#endif
+ const_cast<MMapFile*>(this)->m_pView = 0;
+ pView = get(offset, size);
+ const_cast<MMapFile*>(this)->m_pView = pViewBackup;
+#ifndef _WIN32
+ const_cast<MMapFile*>(this)->m_iMappedSize = iMappedSizeBackup;
+#endif
+ return pView;
+}
+
+void MMapFile::release()
+{
+ if (!m_pView)
+ return;
+
+#ifdef _WIN32
+ UnmapViewOfFile(m_pView);
+#else
+ munmap(m_pView, m_iMappedSize);
+#endif
+ m_pView = NULL;
+}
+
+void MMapFile::release(void *pView, int size)
+{
+ if (!pView)
+ return;
+
+ unsigned int alignment = ((unsigned int)pView) % m_iAllocationGranularity;
+ pView = (char *)pView - alignment;
+ size += alignment;
+#ifdef _WIN32
+ UnmapViewOfFile(pView);
+#else
+ munmap(pView, size);
+#endif
+}
+
+void MMapFile::flush(int num)
+{
+ if (m_pView)
+#ifdef _WIN32
+ FlushViewOfFile(m_pView, num);
+#else
+ msync(m_pView, num, MS_SYNC);
+#endif
+}
+
+// ========
+// MMapFake
+// ========
+
+MMapFake::MMapFake()
+{
+ m_pMem = NULL;
+ m_iSize = 0;
+}
+
+void MMapFake::set(const char *pMem, int iSize)
+{
+ m_pMem = pMem;
+ m_iSize = iSize;
+}
+
+int MMapFake::getsize() const
+{
+ return m_iSize;
+}
+
+void *MMapFake::get(int offset, int size) const
+{
+ return get(offset, &size);
+}
+
+void *MMapFake::get(int offset, int *size) const
+{
+ if (!size || (offset + *size > m_iSize))
+ return NULL;
+ return (void *)(m_pMem + offset);
+}
+
+void *MMapFake::getmore(int offset, int size) const
+{
+ return get(offset, size);
+}
+
+void MMapFake::resize(int n) {}
+void MMapFake::release() {}
+void MMapFake::release(void *p, int size) {}
+void MMapFake::clear() {}
+void MMapFake::setro(BOOL b) {}
+void MMapFake::flush(BOOL b) {}
+
+// =======
+// MMapBuf
+// =======
+
+MMapBuf::MMapBuf()
+{
+ m_gb_u=0;
+ m_alloc=m_used=0;
+}
+
+MMapBuf::~MMapBuf()
+{
+ m_fm.release();
+}
+
+int MMapBuf::add(const void *data, int len)
+{
+ if (len <= 0) return 0;
+ resize(getlen() + len);
+ memcpy((char*)get(getlen() - len, len), data, len);
+ release();
+ return getlen() - len;
+}
+
+void MMapBuf::setro(BOOL bRO)
+{
+ m_fm.setro(bRO);
+}
+
+void MMapBuf::resize(int newlen)
+{
+ if (!m_gb_u && newlen < (16 << 20)) // still in db mode
+ {
+ m_gb.resize(newlen);
+ return;
+ }
+
+ // not in db mode
+ m_gb_u = 1;
+ m_used = newlen;
+
+ if (newlen > m_alloc)
+ {
+ m_alloc = newlen + (16 << 20); // add 16mb to top of mapping
+
+ m_fm.resize(m_alloc);
+
+ if (m_gb.getlen())
+ {
+ memcpy(m_fm.get(0, m_gb.getlen()), m_gb.get(), m_gb.getlen());
+ m_fm.flush(m_gb.getlen());
+ m_fm.release();
+ m_gb.resize(0);
+ }
+ }
+}
+
+int MMapBuf::getsize() const
+{
+ if (m_gb_u)
+ return m_fm.getsize();
+ return m_gb.getlen();
+}
+
+int MMapBuf::getlen() const
+{
+ if (m_gb_u)
+ return m_used;
+ return m_gb.getlen();
+}
+
+void *MMapBuf::get() const
+{
+ return get(0, m_alloc);
+}
+
+void *MMapBuf::get(int offset, int *sizep) const
+{
+ if (!sizep)
+ return NULL;
+ int size = *sizep;
+ return get(offset, size);
+}
+
+void *MMapBuf::get(int offset, int size) const
+{
+ if (m_gb_u)
+ return m_fm.get(offset, size);
+ return (void *) ((char *) m_gb.get() + offset);
+}
+
+void *MMapBuf::getmore(int offset, int size) const
+{
+ if (m_gb_u)
+ return m_fm.getmore(offset, size);
+ return (void *) ((char *) m_gb.get() + offset);
+}
+
+void MMapBuf::release()
+{
+ if (m_gb_u)
+ m_fm.release();
+}
+
+void MMapBuf::release(void *pView, int size)
+{
+ if (m_gb_u)
+ m_fm.release(pView, size);
+}
+
+void MMapBuf::clear()
+{
+ if (m_gb_u)
+ m_fm.clear();
+}
+
+void MMapBuf::flush(int num)
+{
+ if (m_gb_u)
+ m_fm.flush(num);
+}
diff --git a/Source/mmap.h b/Source/mmap.h
index 80e6124..77d810b 100755
--- a/Source/mmap.h
+++ b/Source/mmap.h
@@ -1,144 +1,144 @@
-/*
- * mmap.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef __MMAP_H_
-#define __MMAP_H_
-
-#include "Platform.h"
-#include "growbuf.h"
-
-#ifndef _WIN32
-#include <cstdio> // for FILE*
-#endif
-
-class IMMap
-{
- public:
- virtual void resize(int newlen)=0;
- virtual int getsize() const=0;
- virtual void *get(int offset, int size) const=0;
- virtual void *get(int offset, int *size) const=0;
- virtual void *getmore(int offset, int size) const=0;
- virtual void release()=0;
- virtual void release(void *view, int size)=0;
- virtual void clear()=0;
- virtual void setro(BOOL bRO)=0;
- virtual void flush(int num)=0;
- virtual ~IMMap() {}
-};
-
-class MMapFile : public IMMap
-{
- private: // don't copy instances
- MMapFile(const MMapFile&);
- void operator=(const MMapFile&);
-
- public:
- MMapFile();
- virtual ~MMapFile();
-
- void clear();
- void setro(BOOL bRO);
-#ifdef _WIN32
- int setfile(HANDLE hFile, DWORD dwSize);
-#else
- int setfile(int hFile, DWORD dwSize);
-#endif
- void resize(int newsize);
- int getsize() const;
- void *get(int offset, int size) const;
- void *get(int offset, int *sizep) const;
- void *getmore(int offset, int size) const;
- void release();
- void release(void *pView, int size);
- void flush(int num);
-
- private:
-#ifdef _WIN32
- HANDLE m_hFile, m_hFileMap;
-#else
- FILE *m_hFile;
- int m_hFileDesc;
- int m_iMappedSize;
-#endif
- void *m_pView;
- int m_iSize;
- BOOL m_bReadOnly;
- BOOL m_bTempHandle;
-
- static int m_iAllocationGranularity;
-};
-
-class MMapFake : public IMMap
-{
- private: // don't copy instances
- MMapFake(const MMapFake&);
- void operator=(const MMapFake&);
- public:
- MMapFake();
-
- void set(const char *pMem, int iSize);
- int getsize() const;
- void *get(int offset, int size) const;
- void *get(int offset, int *size) const;
- void *getmore(int offset, int size) const;
-
- void resize(int n);
- void release();
- void release(void *p, int size);
- void clear();
- void setro(BOOL b);
- void flush(BOOL b);
-
- private:
- const char *m_pMem;
- int m_iSize;
-};
-
-class MMapBuf : public IGrowBuf, public IMMap
-{
- private: // don't copy instances
- MMapBuf(const MMapBuf&);
- void operator=(const MMapBuf&);
-
- public:
- MMapBuf();
- virtual ~MMapBuf();
-
- int add(const void *data, int len);
- void setro(BOOL bRO);
- void resize(int newlen);
- int getsize() const;
- int getlen() const;
- void *get() const;
- void *get(int offset, int *sizep) const;
- void *get(int offset, int size) const;
- void *getmore(int offset, int size) const;
- void release();
- void release(void *pView, int size);
- void clear();
- void flush(int num);
-
- private:
- GrowBuf m_gb;
- MMapFile m_fm;
-
- int m_gb_u;
- int m_alloc, m_used;
-};
-
-#endif//__MMAP_H_
-
+/*
+ * mmap.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef __MMAP_H_
+#define __MMAP_H_
+
+#include "Platform.h"
+#include "growbuf.h"
+
+#ifndef _WIN32
+#include <cstdio> // for FILE*
+#endif
+
+class IMMap
+{
+ public:
+ virtual void resize(int newlen)=0;
+ virtual int getsize() const=0;
+ virtual void *get(int offset, int size) const=0;
+ virtual void *get(int offset, int *size) const=0;
+ virtual void *getmore(int offset, int size) const=0;
+ virtual void release()=0;
+ virtual void release(void *view, int size)=0;
+ virtual void clear()=0;
+ virtual void setro(BOOL bRO)=0;
+ virtual void flush(int num)=0;
+ virtual ~IMMap() {}
+};
+
+class MMapFile : public IMMap
+{
+ private: // don't copy instances
+ MMapFile(const MMapFile&);
+ void operator=(const MMapFile&);
+
+ public:
+ MMapFile();
+ virtual ~MMapFile();
+
+ void clear();
+ void setro(BOOL bRO);
+#ifdef _WIN32
+ int setfile(HANDLE hFile, DWORD dwSize);
+#else
+ int setfile(int hFile, DWORD dwSize);
+#endif
+ void resize(int newsize);
+ int getsize() const;
+ void *get(int offset, int size) const;
+ void *get(int offset, int *sizep) const;
+ void *getmore(int offset, int size) const;
+ void release();
+ void release(void *pView, int size);
+ void flush(int num);
+
+ private:
+#ifdef _WIN32
+ HANDLE m_hFile, m_hFileMap;
+#else
+ FILE *m_hFile;
+ int m_hFileDesc;
+ int m_iMappedSize;
+#endif
+ void *m_pView;
+ int m_iSize;
+ BOOL m_bReadOnly;
+ BOOL m_bTempHandle;
+
+ static int m_iAllocationGranularity;
+};
+
+class MMapFake : public IMMap
+{
+ private: // don't copy instances
+ MMapFake(const MMapFake&);
+ void operator=(const MMapFake&);
+ public:
+ MMapFake();
+
+ void set(const char *pMem, int iSize);
+ int getsize() const;
+ void *get(int offset, int size) const;
+ void *get(int offset, int *size) const;
+ void *getmore(int offset, int size) const;
+
+ void resize(int n);
+ void release();
+ void release(void *p, int size);
+ void clear();
+ void setro(BOOL b);
+ void flush(BOOL b);
+
+ private:
+ const char *m_pMem;
+ int m_iSize;
+};
+
+class MMapBuf : public IGrowBuf, public IMMap
+{
+ private: // don't copy instances
+ MMapBuf(const MMapBuf&);
+ void operator=(const MMapBuf&);
+
+ public:
+ MMapBuf();
+ virtual ~MMapBuf();
+
+ int add(const void *data, int len);
+ void setro(BOOL bRO);
+ void resize(int newlen);
+ int getsize() const;
+ int getlen() const;
+ void *get() const;
+ void *get(int offset, int *sizep) const;
+ void *get(int offset, int size) const;
+ void *getmore(int offset, int size) const;
+ void release();
+ void release(void *pView, int size);
+ void clear();
+ void flush(int num);
+
+ private:
+ GrowBuf m_gb;
+ MMapFile m_fm;
+
+ int m_gb_u;
+ int m_alloc, m_used;
+};
+
+#endif//__MMAP_H_
+
diff --git a/Source/script.cpp b/Source/script.cpp
index 69144c3..e291e1f 100755
--- a/Source/script.cpp
+++ b/Source/script.cpp
@@ -1,6171 +1,6176 @@
-/*
- * script.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-#include <stdio.h>
-#include <ctype.h>
-#include "tokens.h"
-#include "build.h"
-#include "util.h"
-#include "winchar.h"
-#include "ResourceEditor.h"
-#include "DialogTemplate.h"
-#include "lang.h"
-#include "dirreader.h"
-#include "version.h"
-#include "exehead/resource.h"
-#include <cassert> // for assert(3)
-#include <time.h>
-#include <string>
-#include <algorithm>
-#include "boost/scoped_ptr.hpp"
-
-using namespace std;
-
-#ifdef _WIN32
-# include <direct.h> // for chdir
-#else
-# include <sys/stat.h> // for stat and umask
-# include <sys/types.h> // for mode_t
-# include <fcntl.h> // for O_RDONLY
-# include <unistd.h>
-# include <stdlib.h> // for mkstemp
-#endif
-
-#define MAX_INCLUDEDEPTH 10
-#define MAX_LINELENGTH 16384
-
-#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
-// Added by Sunil Kamath 11 June 2003
-char *CEXEBuild::set_file_predefine(char *filename)
-{
- char *oldfilename = definedlist.find("__FILE__");
- if(oldfilename)
- {
- oldfilename = strdup(oldfilename);
- definedlist.del("__FILE__");
- }
- char *p = strrchr(filename,'\\');
- if(p) {
- p++;
- }
- else {
- p = curfilename;
- }
- definedlist.add("__FILE__",p);
-
- return oldfilename;
-}
-
-void CEXEBuild::restore_file_predefine(char *oldfilename)
-{
- definedlist.del("__FILE__");
- if(oldfilename) {
- definedlist.add("__FILE__",oldfilename);
- free(oldfilename);
- }
-}
-
-char *CEXEBuild::set_timestamp_predefine(char *filename)
-{
- char *oldtimestamp = definedlist.find("__TIMESTAMP__");
- if(oldtimestamp) {
- oldtimestamp = strdup(oldtimestamp);
- definedlist.del("__TIMESTAMP__");
- }
-
-#ifdef _WIN32
- char timestampbuf[256] = "";
- char datebuf[128] = "";
- char timebuf[128] = "";
- WIN32_FIND_DATA fd;
- FILETIME floctime;
- SYSTEMTIME stime;
-
- HANDLE hSearch = FindFirstFile(filename, &fd);
- if (hSearch != INVALID_HANDLE_VALUE)
- {
- FindClose(hSearch);
-
- FileTimeToLocalFileTime(&fd.ftLastWriteTime, &floctime);
- FileTimeToSystemTime(&floctime, &stime);
-
- GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &stime, NULL, datebuf, sizeof(datebuf));
- GetTimeFormat(LOCALE_USER_DEFAULT, 0, &stime, NULL, timebuf, sizeof(timebuf));
- wsprintf(timestampbuf,"%s %s",datebuf,timebuf);
-
- definedlist.add("__TIMESTAMP__",timestampbuf);
- }
-#else
- struct stat st;
- if (!stat(filename, &st))
- definedlist.add("__TIMESTAMP__",ctime(&st.st_mtime));
-#endif
-
- return oldtimestamp;
-}
-
-void CEXEBuild::restore_timestamp_predefine(char *oldtimestamp)
-{
- definedlist.del("__TIMESTAMP__");
- if(oldtimestamp) {
- definedlist.add("__TIMESTAMP__",oldtimestamp);
- free(oldtimestamp);
- }
-}
-
-char *CEXEBuild::set_line_predefine(int linecnt, BOOL is_macro)
-{
- char* linebuf = NULL;
- MANAGE_WITH(linebuf, free);
-
- char temp[128] = "";
- sprintf(temp,"%d",linecnt);
-
- char *oldline = definedlist.find("__LINE__");
- if(oldline) {
- oldline = strdup(oldline);
- definedlist.del("__LINE__");
- }
- if(is_macro && oldline) {
- linebuf = (char *)malloc(strlen(oldline)+strlen(temp)+2);
- sprintf(linebuf,"%s.%s",oldline,temp);
- }
- else {
- linebuf = strdup(temp);
- }
- definedlist.add("__LINE__",linebuf);
-
- return oldline;
-}
-
-void CEXEBuild::restore_line_predefine(char *oldline)
-{
- definedlist.del("__LINE__");
- if(oldline) {
- definedlist.add("__LINE__",oldline);
- free(oldline);
- }
-}
-
-void CEXEBuild::set_date_time_predefines()
-{
- time_t etime;
- struct tm * ltime;
- char datebuf[128];
- char timebuf[128];
-
- time(&etime);
- ltime = localtime(&etime);
-#ifdef _WIN32
- SYSTEMTIME stime;
- stime.wYear = ltime->tm_year+1900;
- stime.wMonth = ltime->tm_mon + 1;
- stime.wDay = ltime->tm_mday;
- stime.wHour= ltime->tm_hour;
- stime.wMinute= ltime->tm_min;
- stime.wSecond= ltime->tm_sec;
- stime.wMilliseconds= 0;
- GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stime, NULL, datebuf, sizeof(datebuf));
- definedlist.add("__DATE__",(char *)datebuf);
- GetTimeFormat(LOCALE_USER_DEFAULT, 0, &stime, NULL, timebuf, sizeof(timebuf));
- definedlist.add("__TIME__",(char *)timebuf);
-#else
- my_strftime(datebuf, sizeof(datebuf), "%x", ltime);
- definedlist.add("__DATE__",(char *)datebuf);
- my_strftime(timebuf, sizeof(timebuf), "%X", ltime);
- definedlist.add("__TIME__",(char *)timebuf);
-#endif
-}
-
-void CEXEBuild::del_date_time_predefines()
-{
- definedlist.del("__DATE__");
- definedlist.del("__TIME__");
-}
-#endif
-
-int CEXEBuild::process_script(FILE *filepointer, char *filename)
-{
- linecnt = 0;
- fp = filepointer;
- curfilename = filename;
-
- if (has_called_write_output)
- {
- ERROR_MSG("Error (process_script): write_output already called, can't continue\n");
- return PS_ERROR;
- }
-
-#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
- // Added by Sunil Kamath 11 June 2003
- set_date_time_predefines();
- char *oldfilename = set_file_predefine(curfilename);
- char *oldtimestamp = set_timestamp_predefine(curfilename);
-#endif
-
- int ret=parseScript();
-
-#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
- // Added by Sunil Kamath 11 June 2003
- restore_file_predefine(oldfilename);
- restore_timestamp_predefine(oldtimestamp);
- del_date_time_predefines();
-#endif
-
- fp = 0;
- curfilename = 0;
-
- if (m_linebuild.getlen())
- {
- ERROR_MSG("Error: invalid script: last line ended with \\\n");
- return PS_ERROR;
- }
-
- if (ret == PS_EOF && num_ifblock())
- {
- ERROR_MSG("!if[macro][n]def: open at EOF - need !endif\n");
- return PS_ERROR;
- }
-
- return ret;
-}
-
-#define PRINTHELP() { print_help(line.gettoken_str(0)); return PS_ERROR; }
-
-void CEXEBuild::start_ifblock()
-{
- ifblock ib = {0, };
- if (cur_ifblock)
- ib.inherited_ignore = cur_ifblock->ignore || cur_ifblock->inherited_ignore;
- int num = build_preprocessor_data.getlen() / sizeof(ifblock);
- build_preprocessor_data.add(&ib, sizeof(ifblock));
- cur_ifblock = (ifblock *) build_preprocessor_data.get() + num;
-}
-
-void CEXEBuild::end_ifblock()
-{
- if (build_preprocessor_data.getlen())
- {
- cur_ifblock--;
- build_preprocessor_data.resize(build_preprocessor_data.getlen() - sizeof(ifblock));
- if (!build_preprocessor_data.getlen())
- cur_ifblock = 0;
- }
-}
-
-int CEXEBuild::num_ifblock()
-{
- return build_preprocessor_data.getlen() / sizeof(ifblock);
-}
-
-// Func size: just under 200 lines (orip)
-int CEXEBuild::doParse(const char *str)
-{
- LineParser line(inside_comment);
- int res;
-
- while (*str == ' ' || *str == '\t') str++;
-
- // remove trailing slash and null, if there's a previous line
- if (m_linebuild.getlen()>1)
- m_linebuild.resize(m_linebuild.getlen()-2);
-
- m_linebuild.add(str,strlen(str)+1);
-
- // keep waiting for more lines, if this line ends with a backslash
- if (str[0] && CharPrev(str,str+strlen(str))[0] == '\\')
- {
- line.parse((char*)m_linebuild.get());
- if (line.inComment())
- {
- warning_fl("comment contains line-continuation character, following line will be ignored");
- }
- return PS_OK;
- }
-
- // parse before checking if the line should be ignored, so block comments won't be missed
-
- // escaped quotes should be ignored for compile time commands that set defines
- // because defines can be inserted in commands at a later stage
- bool ignore_escaping = (!strnicmp((char*)m_linebuild.get(),"!define",7) || !strnicmp((char*)m_linebuild.get(),"!insertmacro",12));
- res=line.parse((char*)m_linebuild.get(), ignore_escaping);
-
- inside_comment = line.inCommentBlock();
-
- // if ignoring, ignore all lines that don't begin with an exclamation mark
- {
- bool ignore_line = cur_ifblock && (cur_ifblock->ignore || cur_ifblock->inherited_ignore);
- char first_char = *(char *) m_linebuild.get();
- if (ignore_line && (first_char!='!' || !is_valid_token(line.gettoken_str(0))))
- {
- m_linebuild.resize(0);
- return PS_OK;
- }
- }
-
- m_linebuild.resize(0);
-
- if (res)
- {
- if (res==-2) ERROR_MSG("Error: unterminated string parsing line at %s:%d\n",curfilename,linecnt);
- else ERROR_MSG("Error: error parsing line (%s:%d)\n",curfilename,linecnt);
- return PS_ERROR;
- }
-
-parse_again:
- if (line.getnumtokens() < 1) return PS_OK;
-
- int np,op,pos;
- int tkid=get_commandtoken(line.gettoken_str(0),&np,&op,&pos);
- if (tkid == -1)
- {
- char *p=line.gettoken_str(0);
- if (p[0] && p[strlen(p)-1]==':')
- {
- if (p[0] == '!' || (p[0] >= '0' && p[0] <= '9') || p[0] == '$' || p[0] == '-' || p[0] == '+')
- {
- ERROR_MSG("Invalid label: %s (labels cannot begin with !, $, -, +, or 0-9)\n",line.gettoken_str(0));
- return PS_ERROR;
- }
- if (add_label(line.gettoken_str(0))) return PS_ERROR;
- line.eattoken();
- goto parse_again;
- }
-
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
- // Added by Ximon Eighteen 5th August 2002
- // We didn't recognise this command, could it be the name of a
- // function exported from a dll?
- if (m_plugins.IsPluginCommand(line.gettoken_str(0)))
- {
- np = 0; // parameters are optional
- op = -1; // unlimited number of optional parameters
- pos = -1; // placement will tested later
- tkid = TOK__PLUGINCOMMAND;
- }
- else
-#endif
- {
- ERROR_MSG("Invalid command: %s\n",line.gettoken_str(0));
- return PS_ERROR;
- }
- }
-
- if (IsTokenPlacedRight(pos, line.gettoken_str(0)) != PS_OK)
- return PS_ERROR;
-
- int v=line.getnumtokens()-(np+1);
- if (v < 0 || (op >= 0 && v > op)) // opt_parms is -1 for unlimited
- {
- ERROR_MSG("%s expects %d",line.gettoken_str(0),np);
- if (op < 0) ERROR_MSG("+");
- if (op > 0) ERROR_MSG("-%d",op+np);
- ERROR_MSG(" parameters, got %d.\n",line.getnumtokens()-1);
- PRINTHELP()
- }
-
- int if_from_else = 0;
-
- if (tkid == TOK_P_ELSE)
- {
- if (cur_ifblock && cur_ifblock->inherited_ignore)
- return PS_OK;
-
- if (!num_ifblock())
- {
- ERROR_MSG("!else: no if block open (!if[macro][n][def])\n");
- return PS_ERROR;
- }
-
- if (cur_ifblock->elseused)
- {
- ERROR_MSG("!else: else already used in current if block\n");
- return PS_ERROR;
- }
-
- if (cur_ifblock->hasexeced)
- {
- cur_ifblock->ignore++;
- return PS_OK;
- }
-
- if (line.getnumtokens() == 1)
- {
- cur_ifblock->ignore = !cur_ifblock->ignore;
- // if not executed up until now, it will now
- cur_ifblock->hasexeced++;
- cur_ifblock->elseused++;
- return PS_OK;
- }
-
- line.eattoken();
-
- int v=line.gettoken_enum(0,"if\0ifdef\0ifndef\0ifmacrodef\0ifmacrondef\0");
- if (v < 0) PRINTHELP()
- if (line.getnumtokens() == 1) PRINTHELP()
- int cmds[] = {TOK_P_IF, TOK_P_IFDEF, TOK_P_IFNDEF, TOK_P_IFMACRODEF, TOK_P_IFMACRONDEF};
- tkid = cmds[v];
- if_from_else++;
- }
-
- if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFDEF ||
- tkid == TOK_P_IFMACRODEF || tkid == TOK_P_IFMACRONDEF ||
- tkid == TOK_P_IF)
- {
- if (!if_from_else)
- start_ifblock();
-
- if (cur_ifblock && cur_ifblock->inherited_ignore)
- {
- return PS_OK;
- }
-
- int istrue=0;
-
- int mod=0;
-
- int p=0;
-
- if (tkid == TOK_P_IF) {
- if(!strcmp(line.gettoken_str(1),"!")) {
- p = 1;
- line.eattoken();
- }
-
- if(line.getnumtokens() == 2)
- istrue = line.gettoken_int(1);
-
- else if (line.getnumtokens() == 4) {
- mod = line.gettoken_enum(2,"=\0==\0!=\0<=\0<\0>\0>=\0&\0&&\0|\0||\0");
-
- switch(mod) {
- case 0:
- case 1:
- istrue = stricmp(line.gettoken_str(1),line.gettoken_str(3)) == 0; break;
- case 2:
- istrue = stricmp(line.gettoken_str(1),line.gettoken_str(3)) != 0; break;
- case 3:
- istrue = line.gettoken_float(1) <= line.gettoken_float(3); break;
- case 4:
- istrue = line.gettoken_float(1) < line.gettoken_float(3); break;
- case 5:
- istrue = line.gettoken_float(1) > line.gettoken_float(3); break;
- case 6:
- istrue = line.gettoken_float(1) >= line.gettoken_float(3); break;
- case 7:
- case 8:
- istrue = line.gettoken_int(1) && line.gettoken_int(3); break;
- case 9:
- case 10:
- istrue = line.gettoken_int(1) || line.gettoken_int(3); break;
- default:
- PRINTHELP()
- }
- }
- else PRINTHELP()
-
- if(p) istrue = !istrue;
- }
-
- else {
-
- // pure left to right precedence. Not too powerful, but useful.
- for (p = 1; p < line.getnumtokens(); p ++)
- {
- if (p & 1)
- {
- int new_s;
- if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFDEF)
- new_s=!!definedlist.find(line.gettoken_str(p));
- else
- new_s=MacroExists(line.gettoken_str(p));
- if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFMACRONDEF)
- new_s=!new_s;
-
- if (mod == 0) istrue = istrue || new_s;
- else istrue = istrue && new_s;
- }
- else
- {
- mod=line.gettoken_enum(p,"|\0&\0||\0&&\0");
- if (mod == -1) PRINTHELP()
- mod &= 1;
- }
- }
- }
-
- if (istrue)
- {
- cur_ifblock->hasexeced++;
- cur_ifblock->ignore = 0;
- }
- else
- cur_ifblock->ignore++;
-
- return PS_OK;
- }
- if (tkid == TOK_P_ENDIF) {
- if (!num_ifblock())
- {
- ERROR_MSG("!endif: no if block open (!if[macro][n][def])\n");
- return PS_ERROR;
- }
- end_ifblock();
- return PS_OK;
- }
- if (!cur_ifblock || (!cur_ifblock->ignore && !cur_ifblock->inherited_ignore))
- {
- return doCommand(tkid,line);
- }
-
- return PS_OK;
-}
-
-// Func size: about 140 lines (orip)
-#ifdef NSIS_FIX_DEFINES_IN_STRINGS
-void CEXEBuild::ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist, bool bIgnoreDefines /*= false*/)
-#else
-void CEXEBuild::ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist)
-#endif
-{
- // convert $\r, $\n to their literals
- // preprocessor replace ${VAR} and $%VAR% with whatever value
- // note that if VAR does not exist, ${VAR} or $%VAR% will go through unmodified
- const char *in=str;
- while (*in)
- {
- int add=1;
- char *t;
- char c=*in;
- t=CharNext(in);
-
- if (t-in > 1) // handle multibyte chars (no escape)
- {
- linedata.add((void*)in,t-in);
- in=t;
- continue;
- }
- in=t;
-
- if (c == '$')
- {
- if (in[0] == '\\')
- {
- if (in[1] == 'r')
- {
- in+=2;
- c='\r';
- }
- else if (in[1] == 'n')
- {
- in+=2;
- c='\n';
- }
- else if (in[1] == 't')
- {
- in+=2;
- c='\t';
- }
- }
- else if (in[0] == '{')
- {
- char *s=strdup(in+1);
- MANAGE_WITH(s, free);
- char *t=s;
- unsigned int bn = 0;
- while (*t)
- {
- if (*t == '{') bn++;
- if (*t == '}' && bn-- == 0) break;
- t=CharNext(t);
- }
- if (*t && t!=s
-#ifdef NSIS_FIX_DEFINES_IN_STRINGS
- && !bIgnoreDefines
-#endif
- )
- {
- *t=0;
- // check for defines inside the define name - ${bla${blo}}
- GrowBuf defname;
- ps_addtoline(s,defname,hist);
- defname.add("",1);
- t=definedlist.find((char*)defname.get());
- if (t && hist.find((char*)defname.get(),0)<0)
- {
- in+=strlen(s)+2;
- add=0;
- hist.add((char*)defname.get(),0);
-#ifdef NSIS_FIX_DEFINES_IN_STRINGS
- ps_addtoline(t,linedata,hist,true);
-#else
- ps_addtoline(t,linedata,hist);
-#endif
- hist.delbypos(hist.find((char*)defname.get(),0));
- }
- }
- }
- else if (in[0] == '%')
- {
- char *s=strdup(in+1);
- MANAGE_WITH(s, free);
- char *t=s;
- while (*t)
- {
- if (*t == '%') break;
- t=CharNext(t);
- }
- if (*t && t!=s)
- {
- *t=0;
- // check for defines inside the define name - ${bla${blo}}
- GrowBuf defname;
- ps_addtoline(s,defname,hist);
- defname.add("",1);
- t=getenv((char*)defname.get());
- if (t && hist.find((char*)defname.get(),0)<0)
- {
- in+=strlen(s)+2;
- add=0;
- hist.add((char*)defname.get(),0);
-#ifdef NSIS_FIX_DEFINES_IN_STRINGS
- ps_addtoline(t,linedata,hist,true);
-#else
- ps_addtoline(t,linedata,hist);
-#endif
- hist.delbypos(hist.find((char*)defname.get(),0));
- }
- }
- }
-#ifdef NSIS_FIX_DEFINES_IN_STRINGS
- else if (in[0] == '$')
- {
- if (in[1] == '{') // Found $$ before - Don't replace this define
- {
- char *s=strdup(in+2);
- MANAGE_WITH(s, free);
- char *t=s;
- unsigned int bn = 0;
- while (*t)
- {
- if (*t == '{') bn++;
- if (*t == '}' && bn-- == 0) break;
- t=CharNext(t);
- }
- if (*t && t!=s)
- {
- *t=0;
- // add text unchanged
- GrowBuf defname;
- ps_addtoline(s,defname,hist);
- in++;
- }
- }
- else
- {
- linedata.add((void*)&c,1);
- in++;
- }
- }
-#endif
- }
- if (add) linedata.add((void*)&c,1);
- }
-}
-
-int CEXEBuild::parseScript()
-{
- char str[MAX_LINELENGTH];
-
- for (;;)
- {
- char *p=str;
- *p=0;
- fgets(str,MAX_LINELENGTH,fp);
- linecnt++;
- if (feof(fp)&&!str[0]) break;
-
- // remove trailing whitespace
- while (*p) p++;
- if (p > str) p--;
- while (p >= str && (*p == '\r' || *p == '\n' || *p == ' ' || *p == '\t')) p--;
- *++p=0;
-
- StringList hist;
- GrowBuf linedata;
-
-#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
- // Added by Sunil Kamath 11 June 2003
- char *oldline = set_line_predefine(linecnt, FALSE);
-#endif
-
- ps_addtoline(str,linedata,hist);
- linedata.add((void*)"",1);
- int ret=doParse((char*)linedata.get());
-
-#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
- // Added by Sunil Kamath 11 June 2003
- restore_line_predefine(oldline);
-#endif
-
- if (ret != PS_OK) return ret;
- }
-
- return PS_EOF;
-}
-
-int CEXEBuild::includeScript(char *f)
-{
- SCRIPT_MSG("!include: \"%s\"\n",f);
- FILE *incfp=FOPEN(f,"rt");
- if (!incfp)
- {
- ERROR_MSG("!include: could not open file: \"%s\"\n",f);
- return PS_ERROR;
- }
-
- // auto-fclose(3) incfp
- MANAGE_WITH(incfp, fclose);
-
- if (build_include_depth >= MAX_INCLUDEDEPTH)
- {
- ERROR_MSG("parseScript: too many levels of includes (%d max).\n",MAX_INCLUDEDEPTH);
- return PS_ERROR;
- }
- build_include_depth++;
-
- int last_linecnt=linecnt;
- linecnt=0;
- char *last_filename=curfilename;
- curfilename=f;
- FILE *last_fp=fp;
- fp=incfp;
-
-#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
- // Added by Sunil Kamath 11 June 2003
- char *oldfilename = set_file_predefine(curfilename);
- char *oldtimestamp = set_timestamp_predefine(curfilename);
-#endif
-
- int r=parseScript();
-
-#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
- // Added by Sunil Kamath 11 June 2003
- restore_file_predefine(oldfilename);
- restore_timestamp_predefine(oldtimestamp);
-#endif
-
- int errlinecnt=linecnt;
-
- linecnt=last_linecnt;
- curfilename=last_filename;
- fp=last_fp;
-
- build_include_depth--;
- if (r != PS_EOF && r != PS_OK)
- {
- ERROR_MSG("!include: error in script: \"%s\" on line %d\n",f,errlinecnt);
- return PS_ERROR;
- }
- SCRIPT_MSG("!include: closed: \"%s\"\n",f);
- return PS_OK;
-}
-
-// !ifmacro[n]def based on Anders Kjersem's code
-int CEXEBuild::MacroExists(const char *macroname)
-{
- char *m = (char *) m_macros.get();
-
- while (m && *m)
- {
- // check if macroname matches
- if (!stricmp(m, macroname))
- return 1;
-
- // skip macro name
- m += strlen(m) + 1;
-
- // skip params
- while (*m) m += strlen(m) + 1;
- m++;
-
- // skip data
- while (*m) m += strlen(m) + 1;
- if (m - (char *) m_macros.get() >= m_macros.getlen() - 1) break;
- m++;
- }
- return 0;
-}
-
-int CEXEBuild::process_oneline(char *line, char *filename, int linenum)
-{
- char *last_filename=curfilename;
- curfilename=filename;
- int last_linecnt=linecnt;
- linecnt=linenum;
-
- StringList hist;
- GrowBuf linedata;
-
-#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
- // Added by Sunil Kamath 11 June 2003
- char *oldfilename = NULL;
- char *oldtimestamp = NULL;
- char *oldline = NULL;
- BOOL is_commandline = !strcmp(filename,"command line");
- BOOL is_macro = !strncmp(filename,"macro:",strlen("macro:"));
-
- if(!is_commandline) { // Don't set the predefines for command line /X option
- if(!is_macro) {
- oldfilename = set_file_predefine(curfilename);
- oldtimestamp = set_timestamp_predefine(curfilename);
- }
- oldline = set_line_predefine(linecnt, is_macro);
- }
-#endif
-
- ps_addtoline(line,linedata,hist);
- linedata.add((void*)"",1);
- int ret=doParse((char*)linedata.get());
-
-#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
- // Added by Sunil Kamath 11 June 2003
- if(!is_commandline) { // Don't set the predefines for command line /X option
- if(!is_macro) {
- restore_file_predefine(oldfilename);
- restore_timestamp_predefine(oldtimestamp);
- }
- restore_line_predefine(oldline);
- }
-#endif
-
- linecnt=last_linecnt;
- curfilename=last_filename;
-
- return ret;
-}
-
-int CEXEBuild::process_jump(LineParser &line, int wt, int *offs)
-{
- const char *s=line.gettoken_str(wt);
- int v;
-
- if (!stricmp(s,"0") || !stricmp(s,"")) *offs=0;
- else if ((v=GetUserVarIndex(line, wt))>=0)
- {
- *offs=-v-1; // to jump to a user variable target, -variable_index-1 is stored.
- }
- else
- {
- if ((s[0] == '-' || s[0] == '+') && !atoi(s+1))
- {
- ERROR_MSG("Error: Goto targets beginning with '+' or '-' must be followed by nonzero integer (relative jump)\n");
- return 1;
- }
- if ((s[0] >= '0' && s[0] <= '9') || s[0] == '$' || s[0] == '!')
- {
- ERROR_MSG("Error: Goto targets cannot begin with 0-9, $, !\n");
- return 1;
- }
- *offs=ns_label.add(s,0);
- }
- return 0;
-}
-
-#define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags, flag)/sizeof(int))
-#define SECTION_FIELD_GET(field) (FIELD_OFFSET(section, field)/sizeof(int))
-#define SECTION_FIELD_SET(field) (-1 - (int)(FIELD_OFFSET(section, field)/sizeof(int)))
-
-// Func size: about 5000 lines (orip)
-int CEXEBuild::doCommand(int which_token, LineParser &line)
-{
- static const char *rootkeys[2] = {
- "HKCR\0HKLM\0HKCU\0HKU\0HKCC\0HKDD\0HKPD\0SHCTX\0",
- "HKEY_CLASSES_ROOT\0HKEY_LOCAL_MACHINE\0HKEY_CURRENT_USER\0HKEY_USERS\0HKEY_CURRENT_CONFIG\0HKEY_DYN_DATA\0HKEY_PERFORMANCE_DATA\0SHELL_CONTEXT\0"
- };
- static HKEY rootkey_tab[] = {
- HKEY_CLASSES_ROOT,HKEY_LOCAL_MACHINE,HKEY_CURRENT_USER,HKEY_USERS,HKEY_CURRENT_CONFIG,HKEY_DYN_DATA,HKEY_PERFORMANCE_DATA,0
- };
-
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
- build_plugin_table();
-#endif
-
- multiple_entries_instruction=0;
-
- entry ent={0,};
- switch (which_token)
- {
- // macro shit
- ///////////////////////////////////////////////////////////////////////////////
- case TOK_P_MACRO:
- {
- if (!line.gettoken_str(1)[0]) PRINTHELP()
- char *t=(char *)m_macros.get();
- while (t && *t)
- {
- if (!stricmp(t,line.gettoken_str(1))) break;
- t+=strlen(t)+1;
-
- // advance over parameters
- while (*t) t+=strlen(t)+1;
- t++;
-
- // advance over data
- while (*t) t+=strlen(t)+1;
- if (t-(char *)m_macros.get() >= m_macros.getlen()-1)
- break;
- t++;
- }
- if (t && *t)
- {
- ERROR_MSG("!macro: macro named \"%s\" already found!\n",line.gettoken_str(1));
- return PS_ERROR;
- }
- m_macros.add(line.gettoken_str(1),strlen(line.gettoken_str(1))+1);
-
- int pc;
- for (pc=2; pc < line.getnumtokens(); pc ++)
- {
- if (!line.gettoken_str(pc)[0])
- {
- ERROR_MSG("!macro: macro parameter %d is empty, not valid!\n",pc-1);
- return PS_ERROR;
- }
- int a;
- for (a=2; a < pc; a ++)
- {
- if (!stricmp(line.gettoken_str(pc),line.gettoken_str(a)))
- {
- ERROR_MSG("!macro: macro parameter named %s is used multiple times!\n",
- line.gettoken_str(pc));
- return PS_ERROR;
- }
- }
- m_macros.add(line.gettoken_str(pc),strlen(line.gettoken_str(pc))+1);
- }
- m_macros.add("",1);
-
- for (;;)
- {
- char str[MAX_LINELENGTH];
- char *p=str;
- str[0]=0;
- fgets(str,MAX_LINELENGTH,fp);
- //SCRIPT_MSG("%s%s", str, str[strlen(str)-1]=='\n'?"":"\n");
- if (feof(fp) && !str[0])
- {
- ERROR_MSG("!macro \"%s\": unterminated (no !macroend found in file)!\n",line.gettoken_str(1));
- return PS_ERROR;
- }
- // remove trailing whitespace
- while (*p) p++;
- if (p > str) p--;
- while (p >= str && (*p == '\r' || *p == '\n' || *p == ' ' || *p == '\t')) p--;
- *++p=0;
- LineParser l2(false);
- if (!l2.parse(str))
- {
- if (!stricmp(l2.gettoken_str(0),"!macroend"))
- {
- linecnt++;
- break;
- }
- if (!stricmp(l2.gettoken_str(0),"!macro"))
- {
- ERROR_MSG("Error: can't define a macro inside a macro!\n");
- return PS_ERROR;
- }
- }
- if (str[0]) m_macros.add(str,strlen(str)+1);
- else m_macros.add(" ",2);
- linecnt++;
- }
- m_macros.add("",1);
- }
- return PS_OK;
- case TOK_P_MACROEND:
- ERROR_MSG("!macroend: no macro currently open.\n");
- return PS_ERROR;
- case TOK_P_INSERTMACRO:
- {
- if (!line.gettoken_str(1)[0]) PRINTHELP()
- char *t=(char *)m_macros.get();
- char *m=t;
- while (t && *t)
- {
- if (!stricmp(t,line.gettoken_str(1))) break;
- t+=strlen(t)+1;
-
- // advance over parms
- while (*t) t+=strlen(t)+1;
- t++;
-
- // advance over data
- while (*t) t+=strlen(t)+1;
- if (t-(char *)m_macros.get() >= m_macros.getlen()-1)
- break;
- t++;
- }
- SCRIPT_MSG("!insertmacro: %s\n",line.gettoken_str(1));
- if (!t || !*t)
- {
- ERROR_MSG("!insertmacro: macro named \"%s\" not found!\n",line.gettoken_str(1));
- return PS_ERROR;
- }
- t+=strlen(t)+1;
-
-
- GrowBuf l_define_names;
- DefineList l_define_saves;
- int npr=0;
- // advance over parms
- while (*t)
- {
- char *v=definedlist.find(t);
- if (v)
- {
- l_define_saves.add(t,v);
- definedlist.del(t);
- }
- l_define_names.add(t,strlen(t)+1);
- definedlist.add(t,line.gettoken_str(npr+2));
-
- npr++;
- t+=strlen(t)+1;
- }
- l_define_names.add("",1);
- t++;
- if (npr != line.getnumtokens()-2)
- {
- ERROR_MSG("!insertmacro: macro \"%s\" requires %d parameter(s), passed %d!\n",
- line.gettoken_str(1),npr,line.getnumtokens()-2);
- return PS_ERROR;
- }
-
- int lp=0;
- char str[1024];
- if (m_macro_entry.find(line.gettoken_str(1),0)>=0)
- {
- ERROR_MSG("!insertmacro: macro \"%s\" already being inserted!\n",line.gettoken_str(1));
- return PS_ERROR;
- }
- int npos=m_macro_entry.add(line.gettoken_str(1),0);
-
- wsprintf(str,"macro:%s",line.gettoken_str(1));
- while (*t)
- {
- lp++;
- if (strcmp(t," "))
- {
- int ret=process_oneline(t,str,lp);
- if (ret != PS_OK)
- {
- ERROR_MSG("Error in macro %s on macroline %d\n",line.gettoken_str(1),lp);
- return ret;
- }
- }
- {
- // fix t if process_oneline changed m_macros
- char *nm=(char *)m_macros.get();
- if (nm != m)
- {
- t += nm - m;
- m = nm;
- }
- }
- t+=strlen(t)+1;
- }
- m_macro_entry.delbypos(npos);
- {
- char *p=(char*)l_define_names.get();
- while (*p)
- {
- definedlist.del(p);
- char *v;
- if ((v=l_define_saves.find(p))) definedlist.add(p,v);
- p+=strlen(p)+1;
- }
- }
- SCRIPT_MSG("!insertmacro: end of %s\n",line.gettoken_str(1));
- }
- return PS_OK;
-
- // preprocessor files fun
- ///////////////////////////////////////////////////////////////////////////////
-
- case TOK_P_TEMPFILE:
- {
- char *symbol = line.gettoken_str(1);
- char *fpath;
-
-#ifdef _WIN32
- char buf[MAX_PATH], buf2[MAX_PATH];
-
- GetTempPath(MAX_PATH, buf);
- if (!GetTempFileName(buf, "nst", 0, buf2))
- {
- ERROR_MSG("!tempfile: unable to create temporary file.\n");
- return PS_ERROR;
- }
-
- fpath = buf2;
-#else
- char t[] = "/tmp/makensisXXXXXX";
-
- mode_t old_umask = umask(0077);
-
- int fd = mkstemp(t);
- if (fd == -1) {
- ERROR_MSG("!tempfile: unable to create temporary file.\n");
- return PS_ERROR;
- }
- close(fd);
-
- umask(old_umask);
-
- fpath = t;
-#endif
-
- if (definedlist.add(symbol, fpath))
- {
- ERROR_MSG("!tempfile: \"%s\" already defined!\n", symbol);
- return PS_ERROR;
- }
-
- SCRIPT_MSG("!tempfile: \"%s\"=\"%s\"\n", symbol, fpath);
- }
- return PS_OK;
-
- case TOK_P_DELFILE:
- {
- char *file = line.gettoken_str(1);
-#ifndef _WIN32
- file = my_convert(file);
-#endif
- int result = unlink(file);
-#ifndef _WIN32
- my_convert_free(file);
-#endif
- if (result == -1) {
- ERROR_MSG("!delfile: \"%s\" couldn't be deleted.\n", line.gettoken_str(1));
- return PS_ERROR;
- }
-
- SCRIPT_MSG("!delfile: \"%s\"\n", line.gettoken_str(1));
- }
- return PS_OK;
-
- case TOK_P_APPENDFILE:
- {
- char *file = line.gettoken_str(1);
- char *text = line.gettoken_str(2);
-
- FILE *fp = FOPEN(file, "a");
- if (!fp)
- {
- ERROR_MSG("!appendfile: \"%s\" couldn't be opened.\n", file);
- return PS_ERROR;
- }
-
- if (fputs(text, fp) < 0)
- {
- ERROR_MSG("!appendfile: error writing to \"%s\".\n", file);
- return PS_ERROR;
- }
-
- fclose(fp);
-
- SCRIPT_MSG("!appendfile: \"%s\" \"%s\"\n", file, text);
- }
- return PS_OK;
-
- // page ordering shit
- ///////////////////////////////////////////////////////////////////////////////
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- case TOK_UNINSTPAGE:
- set_uninstall_mode(1);
- case TOK_PAGE:
- {
- if (!uninstall_mode) {
- enable_last_page_cancel = 0;
- if (!stricmp(line.gettoken_str(line.getnumtokens()-1),"/ENABLECANCEL"))
- enable_last_page_cancel = 1;
- }
- else {
- uenable_last_page_cancel = 0;
- if (!stricmp(line.gettoken_str(line.getnumtokens()-1),"/ENABLECANCEL"))
- uenable_last_page_cancel = 1;
- }
-
- int k = line.gettoken_enum(1,"custom\0license\0components\0directory\0instfiles\0uninstConfirm\0");
-
- if (k < 0) PRINTHELP();
-
- if (add_page(k) != PS_OK)
- return PS_ERROR;
-
-#ifndef NSIS_SUPPORT_CODECALLBACKS
- if (!k) {
- ERROR_MSG("Error: custom page specified, NSIS_SUPPORT_CODECALLBACKS not defined.\n");
- return PS_ERROR;
- }
-#endif//!NSIS_SUPPORT_CODECALLBACKS
-
- if (k) {
- // not custom
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- switch (line.getnumtokens() - enable_last_page_cancel) {
- case 6:
- PRINTHELP();
- case 5:
- if (*line.gettoken_str(4))
- cur_page->leavefunc = ns_func.add(line.gettoken_str(4),0);
- case 4:
- if (*line.gettoken_str(3))
- cur_page->showfunc = ns_func.add(line.gettoken_str(3),0);
- case 3:
- if (*line.gettoken_str(2))
- cur_page->prefunc = ns_func.add(line.gettoken_str(2),0);
- }
-#endif//NSIS_SUPPORT_CODECALLBACKS
- }
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- else {
- // a custom page
- switch (line.getnumtokens() - enable_last_page_cancel) {
- case 6:
- PRINTHELP();
- case 5:
- cur_page->caption = add_string(line.gettoken_str(4));
- case 4:
- if (*line.gettoken_str(3))
- cur_page->leavefunc = ns_func.add(line.gettoken_str(3),0);
- case 3:
- if (*line.gettoken_str(2))
- cur_page->prefunc = ns_func.add(line.gettoken_str(2),0);
- break;
- case 2:
- ERROR_MSG("Error: custom page must have a creator function!\n");
- PRINTHELP();
- }
- }
-#endif//NSIS_SUPPORT_CODECALLBACKS
-
- SCRIPT_MSG("%sPage: %s", uninstall_mode?"Uninst":"", line.gettoken_str(1));
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- if (cur_page->prefunc>=0)
- SCRIPT_MSG(" (%s:%s)", k?"pre":"creator", line.gettoken_str(2));
- if (cur_page->showfunc>=0 && k)
- SCRIPT_MSG(" (show:%s)", line.gettoken_str(3));
- if (cur_page->leavefunc>=0)
- SCRIPT_MSG(" (leave:%s)", line.gettoken_str(4-!k));
- else if (cur_page->caption && !k)
- SCRIPT_MSG(" (caption:%s)", line.gettoken_str(3));
-#endif
- SCRIPT_MSG("\n");
-
- page_end();
-
- if (k == PAGE_INSTFILES) {
- add_page(PAGE_COMPLETED);
- page_end();
- }
-
- set_uninstall_mode(0);
- }
- return PS_OK;
-
- // extended page setting
- case TOK_PAGEEX:
- {
- int k = line.gettoken_enum(1,"custom\0license\0components\0directory\0instfiles\0uninstConfirm\0");
- if (k < 0) {
- k = line.gettoken_enum(1,"un.custom\0un.license\0un.components\0un.directory\0un.instfiles\0un.uninstConfirm\0");
- if (k < 0) PRINTHELP();
- set_uninstall_mode(1);
- }
-
- SCRIPT_MSG("PageEx: %s\n", line.gettoken_str(1));
-
- if (add_page(k) != PS_OK)
- return PS_ERROR;
-
- cur_page->flags |= PF_PAGE_EX;
- }
- return PS_OK;
-
- case TOK_PAGEEXEND:
- {
- SCRIPT_MSG("PageExEnd\n");
-
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- if (cur_page_type == PAGE_CUSTOM && !cur_page->prefunc) {
- ERROR_MSG("Error: custom pages must have a creator function.\n");
- return PS_ERROR;
- }
-#endif
-
- page_end();
-
- if (cur_page_type == PAGE_INSTFILES) {
- add_page(PAGE_COMPLETED);
- page_end();
- }
-
- set_uninstall_mode(0);
- }
- return PS_OK;
- case TOK_PAGECALLBACKS:
-#ifdef NSIS_SUPPORT_CODECALLBACKS
- {
- SCRIPT_MSG("PageCallbacks:");
-
- if (cur_page_type == PAGE_CUSTOM)
- {
- switch (line.getnumtokens())
- {
- case 4:
- {
- PRINTHELP();
- }
- case 3:
- {
- if (*line.gettoken_str(2))
- {
- if (strnicmp(line.gettoken_str(2), "un.", 3))
- {
- if (uninstall_mode)
- {
- ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
- return PS_ERROR;
- }
- }
- else
- {
- if (!uninstall_mode)
- {
- ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
- return PS_ERROR;
- }
- }
- cur_page->leavefunc = ns_func.add(line.gettoken_str(2),0);
- }
- }
- case 2:
- {
- if (*line.gettoken_str(1))
- {
- if (strnicmp(line.gettoken_str(1), "un.", 3))
- {
- if (uninstall_mode)
- {
- ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
- return PS_ERROR;
- }
- }
- else
- {
- if (!uninstall_mode)
- {
- ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
- return PS_ERROR;
- }
- }
- cur_page->prefunc = ns_func.add(line.gettoken_str(1),0);
- }
- }
- }
- }
- else
- {
- switch (line.getnumtokens())
- {
- case 4:
- {
- if (*line.gettoken_str(3))
- {
- if (strnicmp(line.gettoken_str(3), "un.", 3))
- {
- if (uninstall_mode)
- {
- ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
- return PS_ERROR;
- }
- }
- else
- {
- if (!uninstall_mode)
- {
- ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
- return PS_ERROR;
- }
- }
- cur_page->leavefunc = ns_func.add(line.gettoken_str(3),0);
- }
- }
- case 3:
- {
- if (*line.gettoken_str(2))
- {
- if (strnicmp(line.gettoken_str(2), "un.", 3))
- {
- if (uninstall_mode)
- {
- ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
- return PS_ERROR;
- }
- }
- else
- {
- if (!uninstall_mode)
- {
- ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
- return PS_ERROR;
- }
- }
- cur_page->showfunc = ns_func.add(line.gettoken_str(2),0);
- }
- }
- case 2:
- {
- if (*line.gettoken_str(1))
- {
- if (strnicmp(line.gettoken_str(1), "un.", 3))
- {
- if (uninstall_mode)
- {
- ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
- return PS_ERROR;
- }
- }
- else
- {
- if (!uninstall_mode)
- {
- ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
- return PS_ERROR;
- }
- }
- cur_page->prefunc = ns_func.add(line.gettoken_str(1),0);
- }
- }
- }
- }
-
- int custom = cur_page_type == PAGE_CUSTOM ? 1 : 0;
-
- if (cur_page->prefunc>=0)
- SCRIPT_MSG(" %s:%s", !custom?"pre":"creator", line.gettoken_str(1));
- if (cur_page->showfunc>=0 && !custom)
- SCRIPT_MSG(" show:%s", line.gettoken_str(2));
- if (cur_page->leavefunc>=0)
- SCRIPT_MSG(" leave:%s", line.gettoken_str(3-custom));
-
- SCRIPT_MSG("\n");
- }
- return PS_OK;
-#else
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_CODECALLBACKS not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//NSIS_SUPPORT_CODECALLBACKS
-#else
- case TOK_PAGE:
- case TOK_UNINSTPAGE:
- case TOK_PAGEEX:
- case TOK_PAGEEXEND:
- case TOK_PAGECALLBACKS:
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//NSIS_CONFIG_VISIBLE_SUPPORT
- // header flags
- ///////////////////////////////////////////////////////////////////////////////
- case TOK_LANGSTRING:
- {
- char *name = line.gettoken_str(1);
- LANGID lang = line.gettoken_int(2);
- char *str = line.gettoken_str(3);
- int ret = SetLangString(name, lang, str);
- if (ret == PS_WARNING)
- warning_fl("LangString \"%s\" set multiple times for %d, wasting space", name, lang);
- else if (ret == PS_ERROR) {
- ERROR_MSG("Error: can't set LangString \"%s\"!\n", name);
- return PS_ERROR;
- }
- SCRIPT_MSG("LangString: \"%s\" %d \"%s\"\n", name, lang, str);
- }
- return PS_OK;
- case TOK_LANGSTRINGUP:
- SCRIPT_MSG("Error: LangStringUP is obsolete, there are no more unprocessed strings. Use LangString.\n");
- return PS_ERROR;
- case TOK_LICENSELANGSTRING:
- {
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- if (build_header.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG))
- {
- warning_fl("LicenseLangString: SilentInstall enabled, wasting space");
- }
-#endif
- char *name = line.gettoken_str(1);
- LANGID lang = line.gettoken_int(2);
- char *file = line.gettoken_str(3);
-
- FILE *fp;
- unsigned int datalen;
- fp=FOPEN(file,"rb");
- if (!fp)
- {
- ERROR_MSG("LicenseLangString: open failed \"%s\"\n",file);
- PRINTHELP()
- }
- MANAGE_WITH(fp, fclose);
- fseek(fp,0,SEEK_END);
- datalen=ftell(fp);
- if (!datalen)
- {
- ERROR_MSG("LicenseLangString: empty license file \"%s\"\n",file);
- return PS_ERROR;
- }
- rewind(fp);
- char *data=(char*)malloc(datalen+2);
- if (!data)
- {
- ERROR_MSG("Internal compiler error #12345: LicenseData malloc(%d) failed.\n", datalen+2);
- return PS_ERROR;
- }
- MANAGE_WITH(data, free);
- char *ldata=data+1;
- if (fread(ldata,1,datalen,fp) != datalen)
- {
- ERROR_MSG("LicenseLangString: can't read file.\n");
- return PS_ERROR;
- }
- ldata[datalen]=0;
- if (!strncmp(ldata,"{\\rtf",sizeof("{\\rtf")-1))
- *data = SF_RTF;
- else
- *data = SF_TEXT;
-
- int ret = SetLangString(name, lang, data);
- if (ret == PS_WARNING)
- warning_fl("LicenseLangString \"%s\" set multiple times for %d, wasting space", name, lang);
- else if (ret == PS_ERROR)
- {
- ERROR_MSG("Error: can't set LicenseLangString \"%s\"!\n", name);
- return PS_ERROR;
- }
-
- SCRIPT_MSG("LicenseLangString: \"%s\" %d \"%s\"\n", name, lang, file);
- }
- return PS_OK;
- case TOK_NAME:
- {
- if (SetInnerString(NLF_NAME,line.gettoken_str(1)) == PS_WARNING)
- warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
- SetInnerString(NLF_NAME_DA,line.gettoken_str(2));
- SCRIPT_MSG("Name: \"%s\"",line.gettoken_str(1));
- if (*line.gettoken_str(2))
- SCRIPT_MSG(" \"%s\"",line.gettoken_str(2));
- SCRIPT_MSG("\n");
- }
- return PS_OK;
- case TOK_CAPTION:
- {
- if (!cur_page)
- {
- if (SetInnerString(NLF_CAPTION,line.gettoken_str(1)) == PS_WARNING)
- warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
- }
- else
- {
- cur_page->caption = add_string(line.gettoken_str(1));
- }
- SCRIPT_MSG("Caption: \"%s\"\n",line.gettoken_str(1));
- }
- return PS_OK;
- case TOK_ICON:
- SCRIPT_MSG("Icon: \"%s\"\n",line.gettoken_str(1));
- try {
- init_res_editor();
- replace_icon(res_editor, IDI_ICON2, line.gettoken_str(1));
- }
- catch (exception& err) {
- ERROR_MSG("Error while setting icon to \"%s\": %s\n", line.gettoken_str(1), err.what());
- return PS_ERROR;
- }
- return PS_OK;
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- case TOK_CHECKBITMAP:
- SCRIPT_MSG("CheckBitmap: \"%s\"\n",line.gettoken_str(1));
- try {
- init_res_editor();
- int err = update_bitmap(res_editor, IDB_BITMAP1, line.gettoken_str(1), 96, 16, 8);
- if (err) {
- switch (err) {
- case -1:
- ERROR_MSG("Error: can't find bitmap\n");
- break;
- case -2:
- ERROR_MSG("Error: invalid bitmap file - corrupted or not a bitmap\n");
- break;
- case -3:
- ERROR_MSG("Error: bitmap isn't 96x16 in size\n");
- break;
- case -4:
- ERROR_MSG("Error: bitmap has more than 8bpp\n");
- break;
- }
- return PS_ERROR;
- }
- }
- catch (exception& err) {
- ERROR_MSG("Error while replacing bitmap: %s\n", err.what());
- return PS_ERROR;
- }
- return PS_OK;
-#else//NSIS_CONFIG_COMPONENTPAGE
- case TOK_CHECKBITMAP:
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_COMPONENTPAGE not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_CONFIG_COMPONENTPAGE
- case TOK_DIRTEXT:
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- {
- if (!cur_page) {
- if (SetInnerString(NLF_DIR_TEXT, line.gettoken_str(1)) == PS_WARNING)
- warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
- if (line.getnumtokens() > 2)
- SetInnerString(NLF_DIR_SUBTEXT, line.gettoken_str(2));
- if (line.getnumtokens() > 3)
- SetInnerString(NLF_BTN_BROWSE, line.gettoken_str(3));
- if (line.getnumtokens() > 4)
- SetInnerString(NLF_DIR_BROWSETEXT, line.gettoken_str(4));
- }
- else {
- if (cur_page_type != PAGE_DIRECTORY) {
- ERROR_MSG("Error: DirText can only be used inside PageEx directory.\n");
- return PS_ERROR;
- }
- cur_page->parms[0] = add_string(line.gettoken_str(1));
- if (line.getnumtokens() > 2)
- cur_page->parms[1] = add_string(line.gettoken_str(2));
- if (line.getnumtokens() > 3)
- cur_page->parms[2] = add_string(line.gettoken_str(3));
- if (line.getnumtokens() > 4)
- cur_page->parms[3] = add_string(line.gettoken_str(4));
- }
- SCRIPT_MSG("DirText: \"%s\" \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
- }
- return PS_OK;
-#else//NSIS_CONFIG_VISIBLE_SUPPORT
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_CONFIG_VISIBLE_SUPPORT
- case TOK_DIRVAR:
- {
- if (cur_page_type != PAGE_DIRECTORY && cur_page_type != PAGE_UNINSTCONFIRM) {
- ERROR_MSG("Error: can't use DirVar outside of PageEx directory|uninstConfirm.\n");
- return PS_ERROR;
- }
- cur_page->parms[4] = GetUserVarIndex(line, 1) + 1;
- if (cur_page->parms[4] <= 0) PRINTHELP();
- SCRIPT_MSG("DirVar: %s\n", line.gettoken_str(1));
- }
- return PS_OK;
- case TOK_DIRVERIFY:
- {
- if (cur_page_type != PAGE_DIRECTORY) {
- ERROR_MSG("Error: can't use DirVerify outside of PageEx directory.\n");
- return PS_ERROR;
- }
- cur_page->flags &= ~PF_DIR_NO_BTN_DISABLE;
- int k = line.gettoken_enum(1,"auto\0leave\0");
- if (k == -1)
- PRINTHELP();
- if (k)
- cur_page->flags |= PF_DIR_NO_BTN_DISABLE;
- SCRIPT_MSG("DirVerify: %s\n", line.gettoken_str(1));
- }
- return PS_OK;
- case TOK_GETINSTDIRERROR:
- ent.which = EW_GETFLAG;
- ent.offsets[0] = GetUserVarIndex(line, 1);
- ent.offsets[1] = FLAG_OFFSET(instdir_error);
- return add_entry(&ent);
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- case TOK_COMPTEXT:
- {
- if (!cur_page) {
- if (SetInnerString(NLF_COMP_TEXT, line.gettoken_str(1)) == PS_WARNING)
- warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
- if (line.getnumtokens() > 2)
- SetInnerString(NLF_COMP_SUBTEXT1, line.gettoken_str(2));
- if (line.getnumtokens() > 3)
- SetInnerString(NLF_COMP_SUBTEXT2, line.gettoken_str(3));
- }
- else {
- if (cur_page_type != PAGE_COMPONENTS) {
- ERROR_MSG("Error: ComponentText can only be used inside PageEx components.\n");
- return PS_ERROR;
- }
- cur_page->parms[0] = add_string(line.gettoken_str(1));
- cur_page->parms[1] = add_string(line.gettoken_str(2));
- cur_page->parms[2] = add_string(line.gettoken_str(3));
- cur_page->parms[3] = cur_page->parms[1];
- cur_page->parms[4] = cur_page->parms[2];
- }
- SCRIPT_MSG("ComponentText: \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
- }
- return PS_OK;
- case TOK_INSTTYPE:
- {
- int x;
-
- if (!stricmp(line.gettoken_str(1),"/NOCUSTOM"))
- {
- build_header.flags|=CH_FLAGS_NO_CUSTOM;
- SCRIPT_MSG("InstType: disabling custom install type\n");
- }
- else if (!stricmp(line.gettoken_str(1),"/COMPONENTSONLYONCUSTOM"))
- {
- build_header.flags|=CH_FLAGS_COMP_ONLY_ON_CUSTOM;
- SCRIPT_MSG("InstType: making components viewable only on custom install type\n");
- }
- else if (!strnicmp(line.gettoken_str(1),"/CUSTOMSTRING=",14))
- {
- SCRIPT_MSG("InstType: setting custom text to: \"%s\"\n",line.gettoken_str(1)+14);
- if (SetInnerString(NLF_COMP_CUSTOM,line.gettoken_str(1)+14) == PS_WARNING)
- warning_fl("%s: specified multiple times, wasting space","InstType /CUSTOMSTRING");
- }
- else if (line.gettoken_str(1)[0]=='/')
- {
- PRINTHELP()
- }
- else
- {
- char *itname = line.gettoken_str(1);
-
- if (!strnicmp(itname, "un.", 3)) {
- set_uninstall_mode(1);
- itname += 3;
- }
-
- for (x = 0; x < NSIS_MAX_INST_TYPES && cur_header->install_types[x]; x ++);
- if (x == NSIS_MAX_INST_TYPES)
- {
- ERROR_MSG("InstType: no more than %d install types allowed. %d specified\n", NSIS_MAX_INST_TYPES, NSIS_MAX_INST_TYPES + 1);
- return PS_ERROR;
- }
- else
- {
- cur_header->install_types[x] = add_string(itname);
- SCRIPT_MSG("InstType: %s%d=\"%s\"\n", uninstall_mode ? "(uninstall) " : "", x+1, itname);
- }
-
- set_uninstall_mode(0);
- }
- }
- return PS_OK;
-#else//NSIS_CONFIG_COMPONENTPAGE
- case TOK_COMPTEXT:
- case TOK_INSTTYPE:
- ERROR_MSG("Error: %s specified but NSIS_CONFIG_COMPONENTPAGE not defined\n",line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_CONFIG_COMPONENTPAGE
-#ifdef NSIS_CONFIG_LICENSEPAGE
- case TOK_LICENSETEXT:
- {
- if (!cur_page) {
- if (SetInnerString(NLF_LICENSE_TEXT, line.gettoken_str(1)) == PS_WARNING)
- warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
- SetInnerString(NLF_LICENSE_TEXT_FSRB, line.gettoken_str(1));
- SetInnerString(NLF_LICENSE_TEXT_FSCB, line.gettoken_str(1));
- if (line.getnumtokens() > 2)
- SetInnerString(NLF_BTN_LICENSE, line.gettoken_str(2));
- }
- else {
- if (cur_page_type != PAGE_LICENSE) {
- ERROR_MSG("Error: LicenseText can only be used inside PageEx license.\n");
- return PS_ERROR;
- }
- cur_page->parms[0] = add_string(line.gettoken_str(1));
- cur_page->next = add_string(line.gettoken_str(2));
- }
- SCRIPT_MSG("LicenseText: \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2));
- }
- return PS_OK;
- case TOK_LICENSEDATA:
- {
- int idx = 0;
- char *file = line.gettoken_str(1);
- char *data = NULL;
-
- if (file[0] == '$' && file[1] == '(')
- {
- char *cp = strdup(file+2);
- MANAGE_WITH(cp, free);
- char *p = strchr(cp, ')');
- if (p && p[1] == 0) { // if string is only a language str identifier
- *p = 0;
- idx = DefineLangString(cp, 0);
- }
- data = file;
- }
-
- if (!idx)
- {
- unsigned int datalen;
- FILE *fp=FOPEN(file,"rb");
- if (!fp)
- {
- ERROR_MSG("LicenseData: open failed \"%s\"\n",file);
- PRINTHELP()
- }
- MANAGE_WITH(fp, fclose);
- fseek(fp,0,SEEK_END);
- datalen=ftell(fp);
- if (!datalen)
- {
- ERROR_MSG("LicenseData: empty license file \"%s\"\n",file);
- return PS_ERROR;
- }
- rewind(fp);
- data=(char*)malloc(datalen+2);
- if (!data)
- {
- ERROR_MSG("Internal compiler error #12345: LicenseData malloc(%d) failed.\n", datalen+2);
- return PS_ERROR;
- }
- //MANAGE_WITH(data, free);
- char *ldata=data+1;
- if (fread(ldata,1,datalen,fp) != datalen) {
- ERROR_MSG("LicenseData: can't read file.\n");
- free(data); // TODO: fix later (orip)
- return PS_ERROR;
- }
- ldata[datalen]=0;
- if (!strncmp(ldata,"{\\rtf",sizeof("{\\rtf")-1))
- *data = SF_RTF;
- else
- *data = SF_TEXT;
- }
-
- if (!cur_page) {
- if (SetInnerString(NLF_LICENSE_DATA,data) == PS_WARNING)
- warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
- }
- else {
- if (cur_page_type != PAGE_LICENSE) {
- ERROR_MSG("Error: LicenseData can only be used inside PageEx license.\n");
- return PS_ERROR;
- }
-
- cur_page->parms[1] = add_string(data, 0);
- }
-
- if (!idx) free(data); // TODO: fix later (orip)
-
- SCRIPT_MSG("LicenseData: \"%s\"\n",file);
- }
- return PS_OK;
- case TOK_LICENSEFORCESELECTION:
- {
- int k=line.gettoken_enum(1,"off\0checkbox\0radiobuttons\0");
- if (k == -1) PRINTHELP()
- if (k < line.getnumtokens() - 2) PRINTHELP()
-
- if (!cur_page) {
- switch (line.getnumtokens()) {
- case 4:
- SetInnerString(NLF_BTN_LICENSE_DISAGREE, line.gettoken_str(3));
- case 3:
- SetInnerString(NLF_BTN_LICENSE_AGREE, line.gettoken_str(2));
- break;
- }
-
- switch (k) {
- case 0:
- license_res_id = IDD_LICENSE;
- break;
- case 1:
- license_res_id = IDD_LICENSE_FSCB;
- break;
- case 2:
- license_res_id = IDD_LICENSE_FSRB;
- break;
- }
- }
- else {
- if (cur_page_type != PAGE_LICENSE) {
- ERROR_MSG("Error: LicenseForceSelection can only be used inside PageEx license.\n");
- return PS_ERROR;
- }
- switch (line.getnumtokens()) {
- case 4:
- cur_page->parms[3] = add_string(line.gettoken_str(3));
- case 3:
- cur_page->parms[2] = add_string(line.gettoken_str(2));
- break;
- }
-
- cur_page->flags &= ~(PF_LICENSE_FORCE_SELECTION | PF_LICENSE_NO_FORCE_SELECTION);
-
- switch (k) {
- case 0:
- cur_page->dlg_id = IDD_LICENSE;
- cur_page->flags |= PF_LICENSE_NO_FORCE_SELECTION;
- break;
- case 1:
- cur_page->dlg_id = IDD_LICENSE_FSCB;
- cur_page->flags |= PF_LICENSE_FORCE_SELECTION;
- break;
- case 2:
- cur_page->dlg_id = IDD_LICENSE_FSRB;
- cur_page->flags |= PF_LICENSE_FORCE_SELECTION;
- break;
- }
- }
-
- SCRIPT_MSG("LicenseForceSelection: %s \"%s\" \"%s\"\n", line.gettoken_str(1), line.gettoken_str(2), line.gettoken_str(3));
- }
- return PS_OK;
- case TOK_LICENSEBKCOLOR:
- {
- char *p = line.gettoken_str(1);
- if (!strcmpi(p,"/windows"))
- {
- build_header.license_bg=-COLOR_WINDOW;
- SCRIPT_MSG("LicenseBkColor: /windows\n");
- }
- else if (!strcmpi(p,"/grey") || !strcmpi(p,"/gray"))
- {
- build_header.license_bg=-COLOR_BTNFACE;
- SCRIPT_MSG("LicenseBkColor: /grey\n");
- }
- else
- {
- int v=strtoul(p,&p,16);
- build_header.license_bg=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16);
- build_uninst.license_bg=build_header.license_bg;
- SCRIPT_MSG("LicenseBkColor: %06X\n",v);
- }
- }
- return PS_OK;
-#else//!NSIS_CONFIG_LICENSEPAGE
- case TOK_LICENSETEXT:
- case TOK_LICENSEDATA:
- case TOK_LICENSEBKCOLOR:
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_LICENSEPAGE not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_CONFIG_LICENSEPAGE
-#ifdef NSIS_CONFIG_SILENT_SUPPORT
- case TOK_SILENTINST:
- {
- int k=line.gettoken_enum(1,"normal\0silent\0silentlog\0");
- if (k<0) PRINTHELP()
-#ifndef NSIS_CONFIG_LOG
- if (k == 2)
- {
- ERROR_MSG("SilentInstall: silentlog specified, no log support compiled in (use NSIS_CONFIG_LOG)\n");
- return PS_ERROR;
- }
-#endif//NSIS_CONFIG_LOG
- SCRIPT_MSG("SilentInstall: %s\n",line.gettoken_str(1));
-#ifdef NSIS_CONFIG_LICENSEPAGE
- if (k && HasUserDefined(NLF_LICENSE_DATA))
- {
- warning_fl("SilentInstall: LicenseData already specified. wasting space");
- }
- if (k) {
- build_header.flags|=CH_FLAGS_SILENT;
- if (k == 2)
- build_header.flags|=CH_FLAGS_SILENT_LOG;
- }
- else {
- build_header.flags&=~CH_FLAGS_SILENT;
- build_header.flags&=~CH_FLAGS_SILENT_LOG;
- }
-#endif//NSIS_CONFIG_LICENSEPAGE
- }
- return PS_OK;
- case TOK_SILENTUNINST:
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- {
- int k=line.gettoken_enum(1,"normal\0silent\0");
- if (k<0) PRINTHELP()
- if (k)
- build_uninst.flags|=CH_FLAGS_SILENT;
- else
- build_uninst.flags&=~CH_FLAGS_SILENT;
- SCRIPT_MSG("SilentUnInstall: %s\n",line.gettoken_str(1));
- }
- return PS_OK;
-#else
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif
- case TOK_IFSILENT:
- ent.which=EW_IFFLAG;
- if (process_jump(line,1,&ent.offsets[0]) ||
- process_jump(line,2,&ent.offsets[1])) PRINTHELP()
- ent.offsets[2]=FLAG_OFFSET(silent);
- ent.offsets[3]=~0;//new value mask - keep flag
- SCRIPT_MSG("IfSilent ?%s:%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_SETSILENT:
- {
- ent.which=EW_SETFLAG;
- ent.offsets[0]=FLAG_OFFSET(silent);
- int k=line.gettoken_enum(1,"normal\0silent\0");
- if (k<0) PRINTHELP()
- ent.offsets[1]=add_intstring(k);
- SCRIPT_MSG("SetSilent: %s\n",line.gettoken_str(1));
- }
- return add_entry(&ent);
-#else//!NSIS_CONFIG_SILENT_SUPPORT
- case TOK_SILENTINST:
- case TOK_SILENTUNINST:
- case TOK_IFSILENT:
- case TOK_SETSILENT:
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_SILENT_SUPPORT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//NSIS_CONFIG_SILENT_SUPPORT
- case TOK_OUTFILE:
- strncpy(build_output_filename,line.gettoken_str(1),1024-1);
- SCRIPT_MSG("OutFile: \"%s\"\n",build_output_filename);
- return PS_OK;
- case TOK_INSTDIR:
- {
- char *p = line.gettoken_str(1);
- if (build_header.install_directory_ptr)
- {
- warning_fl("%s: specified multiple times. wasting space",line.gettoken_str(0));
- }
- build_header.install_directory_ptr = add_string(p);
- build_header.install_directory_auto_append = 0;
- char *p2 = p + strlen(p);
- if (*p && *CharPrev(p, p2) != '\\')
- {
- // we risk hitting $\r or something like $(bla\ad) or ${bla\ad} here, but it's better
- // than hitting backslashes in processed strings
- while (p2 > p && *p2 != '\\')
- p2 = CharPrev(p, p2);
- if (*p2 == '\\')
- {
- build_header.install_directory_auto_append = add_string(p2 + 1);
- }
- }
- SCRIPT_MSG("InstallDir: \"%s\"\n",line.gettoken_str(1));
- }
- return PS_OK;
- case TOK_INSTALLDIRREGKEY: // InstallDirRegKey
- {
- if (build_header.install_reg_key_ptr)
- {
- warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
- }
- int k=line.gettoken_enum(1,rootkeys[0]);
- if (k == -1) k=line.gettoken_enum(1,rootkeys[1]);
- if (k == -1) PRINTHELP()
- build_header.install_reg_rootkey=(int)rootkey_tab[k];
- if (!build_header.install_reg_rootkey) PRINTHELP() // SHCTX is invalid here
- build_header.install_reg_key_ptr = add_string(line.gettoken_str(2),0);
- if (line.gettoken_str(2)[0] == '\\')
- warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0));
- build_header.install_reg_value_ptr = add_string(line.gettoken_str(3),0);
- SCRIPT_MSG("InstallRegKey: \"%s\\%s\\%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
- }
- return PS_OK;
- case TOK_CRCCHECK:
- build_crcchk=line.gettoken_enum(1,"off\0on\0force\0");
- if (build_crcchk==-1) PRINTHELP()
- SCRIPT_MSG("CRCCheck: %s\n",line.gettoken_str(1));
- return PS_OK;
- case TOK_INSTPROGRESSFLAGS:
- {
- int x;
- int smooth=0;
- build_header.flags&=~CH_FLAGS_PROGRESS_COLORED;
- for (x = 1; x < line.getnumtokens(); x ++)
- {
- if (!stricmp(line.gettoken_str(x),"smooth")) smooth=1;
- else if (!stricmp(line.gettoken_str(x),"colored")) build_header.flags|=CH_FLAGS_PROGRESS_COLORED;
- else PRINTHELP()
- }
- try {
- init_res_editor();
-
- BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(IDD_INSTFILES), NSIS_DEFAULT_LANG);
- if (!dlg) throw runtime_error("IDD_INSTFILES doesn't exist!");
- CDialogTemplate dt(dlg,uDefCodePage);
- free(dlg);
- DialogItemTemplate* progress = dt.GetItem(IDC_PROGRESS);
- if (!progress) {
- throw runtime_error("IDC_PROGRESS doesn't exist!");
- }
-
- if (smooth)
- progress->dwStyle |= PBS_SMOOTH;
- else
- progress->dwStyle &= ~PBS_SMOOTH;
-
- DWORD dwSize;
- dlg = dt.Save(dwSize);
- res_editor->UpdateResourceA(RT_DIALOG, MAKEINTRESOURCE(IDD_INSTFILES), NSIS_DEFAULT_LANG, dlg, dwSize);
- delete [] dlg;
- }
- catch (exception& err) {
- ERROR_MSG("Error setting smooth progress bar: %s\n", err.what());
- return PS_ERROR;
- }
- SCRIPT_MSG("InstProgressFlags: smooth=%d, colored=%d\n",smooth,
- !!(build_header.flags&CH_FLAGS_PROGRESS_COLORED));
- }
- return PS_OK;
- case TOK_AUTOCLOSE:
- {
- int k=line.gettoken_enum(1,"false\0true\0");
- if (k == -1) PRINTHELP();
- if (k)
- build_header.flags|=CH_FLAGS_AUTO_CLOSE;
- else
- build_header.flags&=~CH_FLAGS_AUTO_CLOSE;
- SCRIPT_MSG("AutoCloseWindow: %s\n",k?"true":"false");
- }
- return PS_OK;
- case TOK_WINDOWICON:
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- disable_window_icon=line.gettoken_enum(1,"on\0off\0");
- if (disable_window_icon == -1) PRINTHELP();
- SCRIPT_MSG("WindowIcon: %s\n",line.gettoken_str(1));
- return PS_OK;
-#else
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n",line.gettoken_str(0));
- return PS_ERROR;
-#endif // NSIS_CONFIG_VISIBLE_SUPPORT
- case TOK_SHOWDETAILSUNINST:
-#ifndef NSIS_CONFIG_UNINSTALL_SUPPORT
- ERROR_MSG("Error: ShowUninstDetails specified but NSIS_CONFIG_UNINSTALL_SUPPORT not defined\n");
- return PS_ERROR;
-#endif
- case TOK_SHOWDETAILS:
- {
- int k=line.gettoken_enum(1,"hide\0show\0nevershow\0");
- if (k == -1) PRINTHELP()
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (which_token == TOK_SHOWDETAILSUNINST)
- {
- build_uninst.flags&=~(CH_FLAGS_DETAILS_NEVERSHOW|CH_FLAGS_DETAILS_SHOWDETAILS);
- if (k==1)
- build_uninst.flags|=CH_FLAGS_DETAILS_SHOWDETAILS;
- else if (k==2)
- build_uninst.flags|=CH_FLAGS_DETAILS_NEVERSHOW;
- }
- else
-#endif
- {
- build_header.flags&=~(CH_FLAGS_DETAILS_NEVERSHOW|CH_FLAGS_DETAILS_SHOWDETAILS);
- if (k==1)
- build_header.flags|=CH_FLAGS_DETAILS_SHOWDETAILS;
- else if (k==2)
- build_header.flags|=CH_FLAGS_DETAILS_NEVERSHOW;
- }
- SCRIPT_MSG("%s: %s\n",line.gettoken_str(0),line.gettoken_str(1));
- }
- return PS_OK;
- case TOK_DIRSHOW:
- /*{
- int k=line.gettoken_enum(1,"show\0hide\0");
- if (k == -1) PRINTHELP();
- if (k)
- build_header.flags|=CH_FLAGS_DIR_NO_SHOW;
- else
- build_header.flags&=~CH_FLAGS_DIR_NO_SHOW;
- SCRIPT_MSG("DirShow: %s\n",k?"hide":"show");
- }*/
- ERROR_MSG("Error: DirShow doesn't currently work\n");
- return PS_ERROR;
- case TOK_ROOTDIRINST:
- {
- int k=line.gettoken_enum(1,"true\0false\0");
- if (k == -1) PRINTHELP();
- if (k)
- build_header.flags|=CH_FLAGS_NO_ROOT_DIR;
- else
- build_header.flags&=~CH_FLAGS_NO_ROOT_DIR;
- SCRIPT_MSG("AllowRootDirInstall: %s\n",k?"false":"true");
- }
- return PS_OK;
- case TOK_BGFONT:
-#ifndef NSIS_SUPPORT_BGBG
- ERROR_MSG("Error: BGFont specified but NSIS_SUPPORT_BGBG not defined\n");
- return PS_ERROR;
-#else//NSIS_SUPPORT_BGBG
- if (line.getnumtokens()==1)
- {
- memcpy(&bg_font,&bg_default_font,sizeof(LOGFONT));
- SCRIPT_MSG("BGFont: default font\n");
- return PS_OK;
- }
-
- LOGFONT newfont;
- newfont.lfHeight=40;
- newfont.lfWidth=0;
- newfont.lfEscapement=0;
- newfont.lfOrientation=0;
- newfont.lfWeight=FW_NORMAL;
- newfont.lfItalic=FALSE;
- newfont.lfUnderline=FALSE;
- newfont.lfStrikeOut=FALSE;
- newfont.lfCharSet=DEFAULT_CHARSET;
- newfont.lfOutPrecision=OUT_DEFAULT_PRECIS;
- newfont.lfClipPrecision=CLIP_DEFAULT_PRECIS;
- newfont.lfQuality=DEFAULT_QUALITY;
- newfont.lfPitchAndFamily=DEFAULT_PITCH;
-
- strncpy(newfont.lfFaceName,line.gettoken_str(1),LF_FACESIZE);
-
- SCRIPT_MSG("BGFont: \"%s\"",line.gettoken_str(1));
- {
- bool height=false;
- bool weight=false;
- for (int i = 2; i < line.getnumtokens(); i++) {
- char *tok=line.gettoken_str(i);
- if (tok[0]=='/') {
- if (!strcmpi(tok,"/ITALIC")) {
- SCRIPT_MSG(" /ITALIC");
- newfont.lfItalic=TRUE;
- }
- else if (!strcmpi(tok,"/UNDERLINE")) {
- SCRIPT_MSG(" /UNDERLINE");
- newfont.lfUnderline=TRUE;
- }
- else if (!strcmpi(tok,"/STRIKE")) {
- SCRIPT_MSG(" /STRIKE");
- newfont.lfStrikeOut=TRUE;
- }
- else {
- SCRIPT_MSG("\n");
- PRINTHELP();
- }
- }
- else {
- if (!height) {
- SCRIPT_MSG(" height=%s",tok);
- newfont.lfHeight=line.gettoken_int(i);
- height=true;
- }
- else if (!weight) {
- SCRIPT_MSG(" weight=%s",tok);
- newfont.lfWeight=line.gettoken_int(i);
- weight=true;
- }
- else {
- SCRIPT_MSG("\n");
- PRINTHELP();
- }
- }
- }
- }
- SCRIPT_MSG("\n");
- memcpy(&bg_font, &newfont, sizeof(LOGFONT));
- return PS_OK;
-#endif//NSIS_SUPPORT_BGBG
- case TOK_BGGRADIENT:
-#ifndef NSIS_SUPPORT_BGBG
- ERROR_MSG("Error: BGGradient specified but NSIS_SUPPORT_BGBG not defined\n");
- return PS_ERROR;
-#else//NSIS_SUPPORT_BGBG
- if (line.getnumtokens()==1)
- {
- SCRIPT_MSG("BGGradient: default colors\n");
- build_header.bg_color1=0;
- build_header.bg_color2=RGB(0,0,255);
- }
- else if (!stricmp(line.gettoken_str(1),"off"))
- {
- build_header.bg_color1=build_header.bg_color2=build_header.bg_textcolor=-1;
- SCRIPT_MSG("BGGradient: off\n");
- if (line.getnumtokens()>2) PRINTHELP()
- }
- else
- {
- char *p = line.gettoken_str(1);
- int v1,v2,v3=-1;
- v1=strtoul(p,&p,16);
- build_header.bg_color1=((v1&0xff)<<16)|(v1&0xff00)|((v1&0xff0000)>>16);
- p=line.gettoken_str(2);
- v2=strtoul(p,&p,16);
- build_header.bg_color2=((v2&0xff)<<16)|(v2&0xff00)|((v2&0xff0000)>>16);
-
- p=line.gettoken_str(3);
- if (*p)
- {
- if (!stricmp(p,"notext")) build_header.bg_textcolor=-1;
- else
- {
- v3=strtoul(p,&p,16);
- build_header.bg_textcolor=((v3&0xff)<<16)|(v3&0xff00)|((v3&0xff0000)>>16);
- }
- }
-
- SCRIPT_MSG("BGGradient: 0x%06X->0x%06X (text=0x%06X)\n",v1,v2,v3);
- }
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- build_uninst.bg_color1=build_header.bg_color1;
- build_uninst.bg_color2=build_header.bg_color2;
- build_uninst.bg_textcolor=build_header.bg_textcolor;
-#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
-#endif//NSIS_SUPPORT_BGBG
- return PS_OK;
-#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
- case TOK_INSTCOLORS:
- {
- char *p = line.gettoken_str(1);
- if (p[0]=='/')
- {
- if (stricmp(p,"/windows") || line.getnumtokens()!=2) PRINTHELP()
- build_header.lb_fg=build_header.lb_bg=-1;
- SCRIPT_MSG("InstallColors: windows default colors\n");
- }
- else
- {
- int v1,v2;
- if (line.getnumtokens()!=3) PRINTHELP()
- v1=strtoul(p,&p,16);
- build_header.lb_fg=((v1&0xff)<<16)|(v1&0xff00)|((v1&0xff0000)>>16);
- p=line.gettoken_str(2);
- v2=strtoul(p,&p,16);
- build_header.lb_bg=((v2&0xff)<<16)|(v2&0xff00)|((v2&0xff0000)>>16);
- SCRIPT_MSG("InstallColors: fg=%06X bg=%06X\n",v1,v2);
- }
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- build_uninst.lb_fg=build_header.lb_fg;
- build_uninst.lb_bg=build_header.lb_bg;
-#endif
- }
- return PS_OK;
- case TOK_XPSTYLE:
- {
- int k=line.gettoken_enum(1,"on\0off\0");
- if (k == -1) PRINTHELP()
- SCRIPT_MSG("XPStyle: %s\n", line.gettoken_str(1));
- if (!k)
- manifest_comctl = manifest::comctl_xp;
- else
- manifest_comctl = manifest::comctl_old;
- }
- return PS_OK;
- case TOK_CHANGEUI:
- try {
- DWORD dwSize;
- int k=line.gettoken_enum(1, "all\0IDD_LICENSE\0IDD_DIR\0IDD_SELCOM\0IDD_INST\0IDD_INSTFILES\0IDD_UNINST\0IDD_VERIFY\0IDD_LICENSE_FSRB\0IDD_LICENSE_FSCB\0");
- if (k<0) PRINTHELP();
-
- FILE *fui = FOPEN(line.gettoken_str(2), "rb");
- if (!fui) {
- ERROR_MSG("Error: Can't open \"%s\"!\n", line.gettoken_str(2));
- return PS_ERROR;
- }
- MANAGE_WITH(fui, fclose);
-
- fseek(fui, 0, SEEK_END);
- unsigned int len = ftell(fui);
- fseek(fui, 0, SEEK_SET);
- LPBYTE ui = (LPBYTE) malloc(len);
- if (!ui) {
- ERROR_MSG("Internal compiler error #12345: malloc(%d) failed\n", len);
- extern void quit(); quit();
- }
- MANAGE_WITH(ui, free);
- if (fread(ui, 1, len, fui) != len) {
- ERROR_MSG("Error: Can't read \"%s\"!\n", line.gettoken_str(2));
- return PS_ERROR;
- }
-
- CResourceEditor *uire = new CResourceEditor(ui, len);
-
- init_res_editor();
-
- // Search for required items
- #define GET(x) dlg = uire->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(x), 0); if (!dlg) return PS_ERROR; CDialogTemplate UIDlg(dlg, uDefCodePage);
- #define SEARCH(x) if (!UIDlg.GetItem(x)) {ERROR_MSG("Error: Can't find %s (%u) in the custom UI!\n", #x, x);delete [] dlg;delete uire;return PS_ERROR;}
- #define SAVE(x) dwSize = UIDlg.GetSize(); res_editor->UpdateResourceA(RT_DIALOG, x, NSIS_DEFAULT_LANG, dlg, dwSize); delete [] dlg;
-
- LPBYTE dlg = NULL;
-
- if (k == 0 || k == 1) {
- GET(IDD_LICENSE);
- SEARCH(IDC_EDIT1);
- SAVE(IDD_LICENSE);
- }
-
- if (k == 0 || k == 2) {
- GET(IDD_DIR);
- SEARCH(IDC_DIR);
- SEARCH(IDC_BROWSE);
-#ifdef NSIS_CONFIG_LOG
- SEARCH(IDC_CHECK1);
-#endif
- SAVE(IDD_DIR);
- }
-
- if (k == 0 || k == 3) {
- GET(IDD_SELCOM);
- SEARCH(IDC_TREE1);
- SEARCH(IDC_COMBO1);
- SAVE(IDD_SELCOM);
- }
-
- if (k == 0 || k == 4) {
- GET(IDD_INST);
- SEARCH(IDC_BACK);
- SEARCH(IDC_CHILDRECT);
- SEARCH(IDC_VERSTR);
- SEARCH(IDOK);
- SEARCH(IDCANCEL);
-
- // Search for bitmap holder (default for SetBrandingImage)
- branding_image_found = false;
- DialogItemTemplate* dlgItem = 0;
- for (int i = 0; (dlgItem = UIDlg.GetItemByIdx(i)); i++) {
- bool check = false;
-
- if (IS_INTRESOURCE(dlgItem->szClass)) {
- if (dlgItem->szClass == MAKEINTRESOURCEW(0x0082)) {
- check = true;
- }
- } else {
- char *szClass = winchar_toansi(dlgItem->szClass);
- check = strcmp(szClass, "Static") == 0;
- delete [] szClass;
- }
-
- if (check) {
- if ((dlgItem->dwStyle & SS_BITMAP) == SS_BITMAP) {
- branding_image_found = true;
- branding_image_id = dlgItem->wId;
- break;
- }
- }
- }
-
- SAVE(IDD_INST);
- }
-
- if (k == 0 || k == 5) {
- GET(IDD_INSTFILES);
- SEARCH(IDC_LIST1);
- SEARCH(IDC_PROGRESS);
- SEARCH(IDC_SHOWDETAILS);
- SAVE(IDD_INSTFILES);
- }
-
- if (k == 0 || k == 6) {
- GET(IDD_UNINST);
- SEARCH(IDC_EDIT1);
- SAVE(IDD_UNINST);
- }
-
- if (k == 0 || k == 7) {
- GET(IDD_VERIFY);
- SEARCH(IDC_STR);
- SAVE(IDD_VERIFY);
- }
-
- if (k == 0 || k == 8) {
- GET(IDD_LICENSE_FSRB);
- SEARCH(IDC_EDIT1);
- SEARCH(IDC_LICENSEAGREE);
- SEARCH(IDC_LICENSEDISAGREE);
- SAVE(IDD_LICENSE_FSRB);
- }
-
- if (k == 0 || k == 9) {
- GET(IDD_LICENSE_FSCB);
- SEARCH(IDC_EDIT1);
- SEARCH(IDC_LICENSEAGREE);
- SAVE(IDD_LICENSE_FSCB);
- }
-
- delete uire;
-
- SCRIPT_MSG("ChangeUI: %s %s%s\n", line.gettoken_str(1), line.gettoken_str(2), branding_image_found?" (branding image holder found)":"");
- }
- catch (exception& err) {
- ERROR_MSG("Error while changing UI: %s\n", err.what());
- return PS_ERROR;
- }
- return PS_OK;
- case TOK_ADDBRANDINGIMAGE:
-#ifdef _WIN32
- try {
- int k=line.gettoken_enum(1,"top\0left\0bottom\0right\0");
- int wh=line.gettoken_int(2);
- if (k == -1) PRINTHELP();
- int padding = 2;
- if (line.getnumtokens() == 4)
- padding = line.gettoken_int(3);
-
- init_res_editor();
- BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), NSIS_DEFAULT_LANG);
-
- CDialogTemplate dt(dlg, uDefCodePage);
-
- res_editor->FreeResource(dlg);
-
- DialogItemTemplate brandingCtl = {0,};
-
- brandingCtl.dwStyle = SS_BITMAP | WS_CHILD | WS_VISIBLE;
- brandingCtl.sX = padding;
- brandingCtl.sY = padding;
- brandingCtl.szClass = MAKEINTRESOURCEW(0x0082);
- brandingCtl.szTitle = NULL;
- brandingCtl.wId = IDC_BRANDIMAGE;
-
- brandingCtl.sHeight = wh;
- brandingCtl.sWidth = wh;
- dt.PixelsToDlgUnits(brandingCtl.sWidth, brandingCtl.sHeight);
- if (k%2) {
- // left (1) / right (3)
-
- if (k & 2) // right
- brandingCtl.sX += dt.GetWidth();
- else // left
- dt.MoveAll(brandingCtl.sWidth + (padding * 2), 0);
-
- dt.Resize(brandingCtl.sWidth + (padding * 2), 0);
-
- brandingCtl.sHeight = dt.GetHeight() - (padding * 2);
- }
- else {
- // top (0) / bottom (2)
-
- if (k & 2) // bottom
- brandingCtl.sY += dt.GetHeight();
- else // top
- dt.MoveAll(0, brandingCtl.sHeight + (padding * 2));
-
- dt.Resize(0, brandingCtl.sHeight + (padding * 2));
-
- brandingCtl.sWidth = dt.GetWidth() - (padding * 2);
- }
-
- dt.AddItem(brandingCtl);
-
- DWORD dwDlgSize;
- dlg = dt.Save(dwDlgSize);
-
- res_editor->UpdateResourceA(RT_DIALOG, IDD_INST, NSIS_DEFAULT_LANG, dlg, dwDlgSize);
-
- delete [] dlg;
-
- dt.DlgUnitsToPixels(brandingCtl.sWidth, brandingCtl.sHeight);
- SCRIPT_MSG("AddBrandingImage: %s %ux%u\n", line.gettoken_str(1), brandingCtl.sWidth, brandingCtl.sHeight);
-
- branding_image_found = true;
- branding_image_id = IDC_BRANDIMAGE;
- }
- catch (exception& err) {
- ERROR_MSG("Error while adding image branding support: %s\n", err.what());
- return PS_ERROR;
- }
- return PS_OK;
-#else
- ERROR_MSG("Error: AddBrandingImage is disabled for non Win32 platforms.\n");
- return PS_ERROR;
-#endif
- case TOK_SETFONT:
- {
- if (!strnicmp(line.gettoken_str(1), "/LANG=", 6))
- {
- LANGID lang_id = atoi(line.gettoken_str(1) + 6);
- LanguageTable *table = GetLangTable(lang_id);
- table->nlf.m_szFont = (char*)malloc(strlen(line.gettoken_str(2))+1);
- strcpy(table->nlf.m_szFont, line.gettoken_str(2));
- table->nlf.m_iFontSize = line.gettoken_int(3);
-
- SCRIPT_MSG("SetFont: lang=%d \"%s\" %s\n", lang_id, line.gettoken_str(2), line.gettoken_str(3));
- }
- else
- {
- strncpy(build_font, line.gettoken_str(1), sizeof(build_font));
- build_font_size = line.gettoken_int(2);
-
- SCRIPT_MSG("SetFont: \"%s\" %s\n", line.gettoken_str(1), line.gettoken_str(2));
- }
- }
- return PS_OK;
-#else
- case TOK_INSTCOLORS:
- case TOK_XPSTYLE:
- case TOK_CHANGEUI:
- case TOK_ADDBRANDINGIMAGE:
- case TOK_SETFONT:
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n",line.gettoken_str(0));
- return PS_ERROR;
-#endif// NSIS_CONFIG_VISIBLE_SUPPORT
-
- case TOK_REQEXECLEVEL:
- {
- int k=line.gettoken_enum(1,"none\0user\0highest\0admin\0");
- switch (k)
- {
- case 0:
- manifest_exec_level = manifest::exec_level_none;
- break;
- case 1:
- manifest_exec_level = manifest::exec_level_user;
- break;
- case 2:
- manifest_exec_level = manifest::exec_level_highest;
- break;
- case 3:
- manifest_exec_level = manifest::exec_level_admin;
- break;
- default:
- PRINTHELP();
- }
- }
- return PS_OK;
-
- // Ability to change compression methods from within the script
- case TOK_SETCOMPRESSOR:
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- {
- if (build_compressor_set) {
- ERROR_MSG("Error: can't change compressor after data already got compressed or header already changed!\n");
- return PS_ERROR;
- }
-
- if (build_compressor_final)
- {
- warning_fl("SetCompressor ignored due to previous call with the /FINAL switch");
- return PS_OK;
- }
-
- int a = 1;
-
- build_compress_whole = false;
-
- while (line.gettoken_str(a)[0] == '/')
- {
- if (!strcmpi(line.gettoken_str(a),"/FINAL"))
- {
- build_compressor_final = true;
- a++;
- }
- else if (!strcmpi(line.gettoken_str(a),"/SOLID"))
- {
- build_compress_whole = true;
- a++;
- }
- else PRINTHELP();
- }
-
- if (a != line.getnumtokens() - 1)
- {
- ERROR_MSG("%s expects %d parameters, got %d.\n", line.gettoken_str(0), a + 1, line.getnumtokens());
- PRINTHELP();
- }
-
- int k=line.gettoken_enum(a, "zlib\0bzip2\0lzma\0");
- switch (k) {
- case 0:
- compressor = &zlib_compressor;
- break;
-
- case 1:
- compressor = &bzip2_compressor;
- break;
-
- case 2:
- compressor = &lzma_compressor;
- break;
-
- default:
- PRINTHELP();
- }
-
- string compressor_name = line.gettoken_str(a);
- compressor_name = lowercase(compressor_name);
-
- if (set_compressor(compressor_name, build_compress_whole) != PS_OK)
- {
- SCRIPT_MSG("SetCompressor: error loading stub for \"%s\" compressor.\n", compressor_name.c_str());
- return PS_ERROR;
- }
-
- SCRIPT_MSG("SetCompressor: %s%s%s\n", build_compressor_final ? "/FINAL " : "", build_compress_whole ? "/SOLID " : "", line.gettoken_str(a));
- }
- return PS_OK;
-#else//NSIS_CONFIG_COMPRESSION_SUPPORT
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_COMPRESSION_SUPPORT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
- case TOK_LOADNLF:
- {
- SCRIPT_MSG("LoadLanguageFile: %s\n", line.gettoken_str(1));
-
- LanguageTable *table = LoadLangFile(line.gettoken_str(1));
-
- if (!table)
- return PS_ERROR;
-
- if (!defcodepage_set)
- {
- uDefCodePage = table->nlf.m_uCodePage;
- defcodepage_set = true;
- }
-
- last_used_lang = table->lang_id;
- // define LANG_LangName as "####" (lang id)
- // for example ${LANG_ENGLISH} = 1033
- char lang_id[16];
- char lang_cp[16];
- char lang_name[1024];
- wsprintf(lang_name, "LANG_%s", table->nlf.m_szName);
- wsprintf(lang_id, "%u", table->lang_id);
- wsprintf(lang_cp, "%u", table->nlf.m_uCodePage);
- definedlist.add(lang_name, lang_id);
- wsprintf(lang_name, "LANG_%s_CP", table->nlf.m_szName);
- definedlist.add(lang_name, lang_cp);
- }
- return PS_OK;
-
- // preprocessor-ish (ifdef/ifndef/else/endif are handled one step out from here)
- ///////////////////////////////////////////////////////////////////////////////
- case TOK_P_DEFINE:
- {
- char *define=line.gettoken_str(1);
- char *value;
- char datebuf[256];
- char mathbuf[256];
-
- if (!stricmp(define,"/date") || !stricmp(define,"/utcdate")) {
- if (line.getnumtokens()!=4) PRINTHELP()
-
- char *date_type = define;
-
- define=line.gettoken_str(2);
- value=line.gettoken_str(3);
-
- time_t rawtime;
- time(&rawtime);
-
- if (!stricmp(date_type,"/utcdate"))
- rawtime = mktime(gmtime(&rawtime));
-
- datebuf[0]=0;
- size_t s=strftime(datebuf,sizeof(datebuf),value,localtime(&rawtime));
-
- if (s == 0)
- datebuf[0]=0;
- else
- datebuf[max(s,sizeof(datebuf)-1)]=0;
-
- value=datebuf;
-
- } else if (!stricmp(define,"/math")) {
-
- int value1;
- int value2;
- char *mathop;
-
- if (line.getnumtokens()!=6) PRINTHELP()
-
- define = line.gettoken_str(2);
- value1 = line.gettoken_int(3);
- mathop = line.gettoken_str(4);
- value2 = line.gettoken_int(5);
- value = mathbuf;
-
- if (!strcmp(mathop,"+")) {
- sprintf(value,"%d",value1+value2);
- } else if (!strcmp(mathop,"-")) {
- sprintf(value,"%d",value1-value2);
- } else if (!strcmp(mathop,"*")) {
- sprintf(value,"%d",value1*value2);
- } else if (!strcmp(mathop,"&")) {
- sprintf(value,"%d",value1&value2);
- } else if (!strcmp(mathop,"|")) {
- sprintf(value,"%d",value1|value2);
- } else if (!strcmp(mathop,"^")) {
- sprintf(value,"%d",value1^value2);
- } else if (!strcmp(mathop,"/")) {
- if (value2==0) {
- ERROR_MSG("!define /math: division by zero! (\"%i / %i\")\n",value1,value2);
- return PS_ERROR;
- }
- sprintf(value,"%d",value1/value2);
- } else if (!strcmp(mathop,"%")) {
- if (value2==0) {
- ERROR_MSG("!define /math: division by zero! (\"%i %% %i\")\n",value1,value2);
- return PS_ERROR;
- }
- sprintf(value,"%d",value1%value2);
- } else PRINTHELP()
-
- } else {
- if (line.getnumtokens()==4) PRINTHELP()
-
- value=line.gettoken_str(2);
- }
-
- if (definedlist.add(define,value))
- {
- ERROR_MSG("!define: \"%s\" already defined!\n",define);
- return PS_ERROR;
- }
- SCRIPT_MSG("!define: \"%s\"=\"%s\"\n",define,value);
- }
- return PS_OK;
- case TOK_P_UNDEF:
- if (definedlist.del(line.gettoken_str(1)))
- {
- ERROR_MSG("!undef: \"%s\" not defined!\n",line.gettoken_str(1));
- return PS_ERROR;
- }
- SCRIPT_MSG("!undef: \"%s\"\n",line.gettoken_str(1));
- return PS_OK;
- case TOK_P_PACKEXEHEADER:
- strncpy(build_packname,line.gettoken_str(1),sizeof(build_packname)-1);
- strncpy(build_packcmd,line.gettoken_str(2),sizeof(build_packcmd)-1);
- SCRIPT_MSG("!packhdr: filename=\"%s\", command=\"%s\"\n",
- build_packname, build_packcmd);
- return PS_OK;
- case TOK_P_SYSTEMEXEC:
- {
- char *exec=line.gettoken_str(1);
- int comp=line.gettoken_enum(2,"<\0>\0<>\0=\0ignore\0");
- if (line.getnumtokens() == 2) comp = 4;
- if (comp == -1 && line.getnumtokens() == 3) comp=4;
- if (comp == -1) PRINTHELP()
- int success=0;
- int cmpv=line.gettoken_int(3,&success);
- if (!success && comp != 4) PRINTHELP()
- SCRIPT_MSG("!system: \"%s\"\n",exec);
-#ifdef _WIN32
- int ret=sane_system(exec);
-#else
- char *execfixed = my_convert(exec);
- int ret=system(execfixed);
- my_convert_free(execfixed);
-#endif
- if (comp == 0 && ret < cmpv);
- else if (comp == 1 && ret > cmpv);
- else if (comp == 2 && ret != cmpv);
- else if (comp == 3 && ret == cmpv);
- else if (comp == 4);
- else
- {
- ERROR_MSG("!system: returned %d, aborting\n",ret);
- return PS_ERROR;
- }
- SCRIPT_MSG("!system: returned %d\n",ret);
- }
- return PS_OK;
- case TOK_P_EXECUTE:
- {
- char *exec=line.gettoken_str(1);
-#ifdef _WIN32
- PROCESS_INFORMATION pi;
- STARTUPINFO si={sizeof(STARTUPINFO),};
- if (CreateProcess(NULL,exec,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
- {
- WaitForSingleObject(pi.hProcess,INFINITE);
- CloseHandle(pi.hThread);
- CloseHandle(pi.hProcess);
- }
-#else
- char *execfixed = my_convert(exec);
- system(execfixed);
- my_convert_free(execfixed);
-#endif
- SCRIPT_MSG("!execute: \"%s\"\n",exec);
- }
- case TOK_P_ADDINCLUDEDIR:
-#ifdef _WIN32
- include_dirs.add(line.gettoken_str(1),0);
-#else
- {
- char *f = line.gettoken_str(1);
- char *fc = my_convert(f);
- include_dirs.add(fc,0);
- my_convert_free(fc);
- }
-#endif
- return PS_OK;
- case TOK_P_INCLUDE:
- {
- bool required = true;
-
- char *f = line.gettoken_str(1);
-
- if(!stricmp(f,"/nonfatal")) {
- if (line.getnumtokens()!=3)
- PRINTHELP();
-
- f = line.gettoken_str(2);
- required = false;
- } else if (line.getnumtokens()!=2) {
- PRINTHELP();
- }
-
-#ifdef _WIN32
- char *fc = f;
-#else
- char *fc = my_convert(f);
-#endif
- int included = 0;
-
- string dir = get_dir_name(fc);
- string spec = get_file_name(fc);
- string basedir = dir + PLATFORM_PATH_SEPARATOR_STR;
- if (dir == spec) {
- // no path, just file name
- dir = ".";
- basedir = "";
- }
-
-#ifndef _WIN32
- my_convert_free(fc);
-#endif
-
- // search working directory
- boost::scoped_ptr<dir_reader> dr( new_dir_reader() );
- dr->read(dir);
-
- for (dir_reader::iterator files_itr = dr->files().begin();
- files_itr != dr->files().end();
- files_itr++)
- {
- if (!dir_reader::matches(*files_itr, spec))
- continue;
-
- string incfile = basedir + *files_itr;
-
- if (includeScript((char *) incfile.c_str()) != PS_OK) {
- return PS_ERROR;
- }
-
- included++;
- }
-
- if (included)
- return PS_OK;
-
- // search include dirs
- char *incdir = include_dirs.get();
- int incdirs = include_dirs.getnum();
-
- for (int i = 0; i < incdirs; i++, incdir += strlen(incdir) + 1) {
- string curincdir = string(incdir) + PLATFORM_PATH_SEPARATOR_STR + dir;
-
- boost::scoped_ptr<dir_reader> dr( new_dir_reader() );
- dr->read(curincdir);
-
- for (dir_reader::iterator incdir_itr = dr->files().begin();
- incdir_itr != dr->files().end();
- incdir_itr++)
- {
- if (!dir_reader::matches(*incdir_itr, spec))
- continue;
-
- string incfile = string(incdir) + PLATFORM_PATH_SEPARATOR_STR + basedir + *incdir_itr;
-
- if (includeScript((char *) incfile.c_str()) != PS_OK) {
- return PS_ERROR;
- }
-
- included++;
- }
-
- if (included)
- return PS_OK;
-
- }
-
- // nothing found
- if (!included)
- {
- if(required) {
- ERROR_MSG("!include: could not find: \"%s\"\n",f);
- return PS_ERROR;
- } else {
- warning_fl("!include: could not find: \"%s\"",f);
- }
- }
- }
- return PS_OK;
- case TOK_P_CD:
- if (!line.gettoken_str(1)[0] || chdir(line.gettoken_str(1)))
- {
- ERROR_MSG("!cd: error changing to: \"%s\"\n",line.gettoken_str(1));
- return PS_ERROR;
- }
- return PS_OK;
- case TOK_P_ERROR:
- ERROR_MSG("!error: %s\n",line.gettoken_str(1));
- return PS_ERROR;
- case TOK_P_WARNING:
- warning_fl("!warning: %s",line.gettoken_str(1));
- return PS_OK;
- case TOK_P_ECHO:
- SCRIPT_MSG("%s (%s:%d)\n", line.gettoken_str(1),curfilename,linecnt);
- return PS_OK;
-
- case TOK_P_VERBOSE:
- {
- extern int g_display_errors;
- int k=line.gettoken_enum(1,"push\0pop\0");
- int v;
- if (k < 0)
- // just set
- v=line.gettoken_int(1);
- else
- {
- if (k)
- {
- // pop
- int l=verbose_stack.getlen();
- if (l)
- {
- v=((int*)verbose_stack.get())[(l/sizeof(int))-1];
- verbose_stack.resize(l-sizeof(int));
- }
- else
- return PS_OK;
- }
- else
- {
- // push
- v=0;
- if (display_errors)
- {
- v++;
- if (display_warnings)
- {
- v++;
- if (display_info)
- {
- v++;
- if (display_script)
- {
- v++;
- }
- }
- }
- }
- verbose_stack.add(&v,sizeof(int));
- return PS_OK;
- }
- }
- display_script=v>3;
- display_info=v>2;
- display_warnings=v>1;
- display_errors=v>0;
- g_display_errors=display_errors;
- }
- return PS_OK;
-
- case TOK_UNINSTALLEXENAME: PRINTHELP()
-
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- case TOK_UNINSTCAPTION:
- {
- if (SetInnerString(NLF_UCAPTION,line.gettoken_str(1)) == PS_WARNING)
- warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
- SCRIPT_MSG("UninstCaption: \"%s\"\n",line.gettoken_str(1));
- }
- return PS_OK;
- case TOK_UNINSTICON:
- SCRIPT_MSG("UninstallIcon: \"%s\"\n",line.gettoken_str(1));
- try {
- free(m_unicon_data);
- m_unicon_data = generate_uninstall_icon_data(line.gettoken_str(1), m_unicon_size);
- }
- catch (exception& err) {
- ERROR_MSG("Error while setting icon to \"%s\": %s\n", line.gettoken_str(1), err.what());
- return PS_ERROR;
- }
- return PS_OK;
- case TOK_UNINSTTEXT:
- {
- if (!cur_page) {
- if (SetInnerString(NLF_UNINST_TEXT, line.gettoken_str(1)) == PS_WARNING)
- warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
- SetInnerString(NLF_UNINST_SUBTEXT, line.gettoken_str(2));
- }
- else {
- if (cur_page_type != PAGE_UNINSTCONFIRM) {
- ERROR_MSG("Error: UninstallText can only be used inside PageEx uninstConfirm.\n");
- return PS_ERROR;
- }
- cur_page->parms[0] = add_string(line.gettoken_str(1));
- cur_page->parms[1] = add_string(line.gettoken_str(2));
- }
- SCRIPT_MSG("UninstallText: \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2));
- }
- return PS_OK;
- case TOK_UNINSTSUBCAPTION:
- {
- int s;
- int w=line.gettoken_int(1,&s);
- if (!s || w < 0 || w > 2) PRINTHELP()
- SetInnerString(NLF_USUBCAPTION_CONFIRM+w,line.gettoken_str(2));
- SCRIPT_MSG("UninstSubCaption: page:%d, text=%s\n",w,line.gettoken_str(2));
- }
- return PS_OK;
- case TOK_WRITEUNINSTALLER:
- {
- if (uninstall_mode)
- {
- ERROR_MSG("WriteUninstaller only valid from install, not from uninstall.\n");
- PRINTHELP()
- }
- uninstaller_writes_used++;
- ent.which=EW_WRITEUNINSTALLER;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- string full = string("$INSTDIR\\") + string(line.gettoken_str(1));
- ent.offsets[3]=add_string(full.c_str());
- // ent.offsets[1] and ent.offsets[2] are set in CEXEBuild::uninstall_generate()
- if (!ent.offsets[0]) PRINTHELP()
- SCRIPT_MSG("WriteUninstaller: \"%s\"\n",line.gettoken_str(1));
-
- DefineInnerLangString(NLF_ERR_CREATING);
- DefineInnerLangString(NLF_CREATED_UNINST);
- }
- return add_entry(&ent);
-#else//!NSIS_CONFIG_UNINSTALL_SUPPORT
- case TOK_WRITEUNINSTALLER:
- case TOK_UNINSTCAPTION:
- case TOK_UNINSTICON:
- case TOK_UNINSTTEXT:
- case TOK_UNINSTSUBCAPTION:
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif
-
-
-
- // section/function shit
- ///////////////////////////////////////////////////////////////////////////////
-
- case TOK_SECTION:
- {
- int a=1,unselected = 0;
- if (!strcmpi(line.gettoken_str(1),"/o"))
- {
- unselected = 1;
- a++;
- }
- else if (line.getnumtokens() > 3)
- PRINTHELP();
- SCRIPT_MSG("Section: \"%s\"",line.gettoken_str(a));
- if (line.gettoken_str(a+1)[0]) SCRIPT_MSG(" ->(%s)",line.gettoken_str(a+1));
- SCRIPT_MSG("\n");
-#ifndef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (!stricmp(line.gettoken_str(a),"uninstall"))
- {
- ERROR_MSG("Error: Uninstall section declared, no NSIS_CONFIG_UNINSTALL_SUPPORT\n");
- return PS_ERROR;
- }
-#endif
-
- int ret;
-
- if (line.gettoken_str(a)[0]=='-')
- {
- if (!strnicmp(line.gettoken_str(a)+1,"un.",3))
- ret=add_section("un.",line.gettoken_str(a+1));
- else
- ret=add_section("",line.gettoken_str(a+1));
- }
- else ret=add_section(line.gettoken_str(a),line.gettoken_str(a+1));
- if (ret != PS_OK) return ret;
-
- if (unselected)
- build_cursection->flags &= ~SF_SELECTED;
-
- return PS_OK;
- }
- case TOK_SECTIONEND:
- SCRIPT_MSG("SectionEnd\n");
- return section_end();
- case TOK_SECTIONIN:
- {
- SCRIPT_MSG("SectionIn: ");
- int wt;
- for (wt = 1; wt < line.getnumtokens(); wt ++)
- {
- char *p=line.gettoken_str(wt);
- if (!stricmp(p, "RO"))
- {
- if (section_add_flags(SF_RO) != PS_OK) return PS_ERROR;
- SCRIPT_MSG("[RO] ");
- }
- else
- {
- int x=atoi(p)-1;
- if (x >= 0 && x < NSIS_MAX_INST_TYPES)
- {
- if (section_add_install_type(1<<x) != PS_OK) return PS_ERROR;
- SCRIPT_MSG("[%d] ",x);
- }
- else if (x < 0)
- {
- PRINTHELP()
- }
- else
- {
- ERROR_MSG("Error: SectionIn section %d out of range 1-%d\n",x+1,NSIS_MAX_INST_TYPES);
- return PS_ERROR;
- }
- p++;
- }
- }
- SCRIPT_MSG("\n");
- }
- return PS_OK;
- case TOK_SECTIONGROUPEND:
- case TOK_SUBSECTIONEND:
- case TOK_SECTIONGROUP:
- case TOK_SUBSECTION:
- {
- char buf[1024];
- int a=1,ex = 0;
- if (!strcmpi(line.gettoken_str(1),"/e"))
- {
- ex = 1;
- a++;
- }
- wsprintf(buf,"-%s",line.gettoken_str(a));
- if (which_token == TOK_SECTIONGROUP || which_token == TOK_SUBSECTION)
- {
- char *s = line.gettoken_str(a);
- if (!s[0] || (!strcmpi(s, "un.") && !s[3]))
- PRINTHELP();
- }
-
- SCRIPT_MSG("%s %s",line.gettoken_str(0),line.gettoken_str(a));
- if (line.gettoken_str(a+1)[0]) SCRIPT_MSG(" ->(%s)",line.gettoken_str(a+1));
- SCRIPT_MSG("\n");
- return add_section(buf,line.gettoken_str(a+1),ex);
- }
- case TOK_FUNCTION:
- if (!line.gettoken_str(1)[0]) PRINTHELP()
- if (line.gettoken_str(1)[0]==':' || line.gettoken_str(1)[0]=='/')
- {
- ERROR_MSG("Function: function name cannot begin with : or /.\n");
- PRINTHELP()
- }
- SCRIPT_MSG("Function: \"%s\"\n",line.gettoken_str(1));
-#ifndef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (!strnicmp(line.gettoken_str(1),"un.",3))
- {
- ERROR_MSG("Error: Uninstall function declared, no NSIS_CONFIG_UNINSTALL_SUPPORT\n");
- return PS_ERROR;
- }
-#endif
- return add_function(line.gettoken_str(1));
- case TOK_FUNCTIONEND:
- SCRIPT_MSG("FunctionEnd\n");
- return function_end();
-
- // flag setters
- ///////////////////////////////////////////////////////////////////////////////
-
- // BEGIN - Added by ramon 23 May 2003
- case TOK_ALLOWSKIPFILES:
- build_allowskipfiles=line.gettoken_enum(1,"off\0on\0");
- if (build_allowskipfiles==-1) PRINTHELP()
- SCRIPT_MSG("AllowSkipFiles: %s\n",line.gettoken_str(1));
- return PS_OK;
- // END - Added by ramon 23 May 2003
- case TOK_SETDATESAVE:
- build_datesave=line.gettoken_enum(1,"off\0on\0");
- if (build_datesave==-1) PRINTHELP()
- SCRIPT_MSG("SetDateSave: %s\n",line.gettoken_str(1));
- return PS_OK;
- case TOK_SETOVERWRITE:
- {
- int k=line.gettoken_enum(1,"on\0off\0try\0ifnewer\0ifdiff\0lastused\0");
- if (k==-1) PRINTHELP()
- if (k==5)
- {
- k=build_overwrite;
- build_overwrite=build_last_overwrite;
- build_last_overwrite=k;
- }
- else
- {
- build_last_overwrite=build_overwrite;
- build_overwrite=k;
- }
- SCRIPT_MSG("SetOverwrite: %s\n",line.gettoken_str(1));
- }
- return PS_OK;
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
- case TOK_SETPLUGINUNLOAD:
- build_plugin_unload=line.gettoken_enum(1,"manual\0alwaysoff\0");
- if (build_plugin_unload==-1) PRINTHELP()
- SCRIPT_MSG("SetPluginUnload: %s\n",line.gettoken_str(1));
- return PS_OK;
-#endif //NSIS_CONFIG_PLUGIN_SUPPORT
- case TOK_SETCOMPRESS:
- build_compress=line.gettoken_enum(1,"off\0auto\0force\0");
- if (build_compress==-1) PRINTHELP()
- if (build_compress==0 && build_compress_whole)
- {
- warning_fl("'SetCompress off' encountered, and in whole compression mode. Effectively ignored.");
- }
- SCRIPT_MSG("SetCompress: %s\n",line.gettoken_str(1));
- return PS_OK;
- case TOK_DBOPTIMIZE:
- build_optimize_datablock=line.gettoken_enum(1,"off\0on\0");
- if (build_optimize_datablock==-1) PRINTHELP()
- SCRIPT_MSG("SetDatablockOptimize: %s\n",line.gettoken_str(1));
- return PS_OK;
- case TOK_FILEBUFSIZE:
- build_filebuflen=line.gettoken_int(1);
- build_filebuflen<<=20;
- if (build_filebuflen<=0)
- {
- ERROR_MSG("Error: FileBufSize: invalid buffer size -- %d\n",build_filebuflen);
- return PS_ERROR;
- }
- SCRIPT_MSG("FileBufSize: %smb (%d bytes)\n",line.gettoken_str(1),build_filebuflen);
- return PS_OK;
-#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
- case TOK_SETCOMPRESSIONLEVEL:
- {
- if (compressor == &lzma_compressor)
- warning_fl("SetCompressionLevel: compressor is set to LZMA. Effectively ignored.");
- if (build_compressor_set && build_compress_whole)
- warning_fl("SetCompressionLevel: data already compressed in compress whole mode. Effectively ignored.");
-
- int s;
- build_compress_level=line.gettoken_int(1,&s);
- if (!s || build_compress_level < 0 || build_compress_level > 9) PRINTHELP();
- SCRIPT_MSG("SetCompressionLevel: %u\n", build_compress_level);
- }
- return PS_OK;
- case TOK_SETCOMPRESSORDICTSIZE:
- {
- if (compressor != &lzma_compressor)
- warning_fl("SetCompressorDictSize: compressor is not set to LZMA. Effectively ignored.");
- if (build_compressor_set && build_compress_whole)
- warning_fl("SetCompressorDictSize: data already compressed in compress whole mode. Effectively ignored.");
-
- int s;
- build_compress_dict_size=line.gettoken_int(1,&s);
- if (!s) PRINTHELP();
- SCRIPT_MSG("SetCompressorDictSize: %u mb\n", build_compress_dict_size);
- build_compress_dict_size <<= 20;
- }
- return PS_OK;
-#else
- case TOK_SETCOMPRESSIONLEVEL:
- case TOK_SETCOMPRESSORDICTSIZE:
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_COMPRESSION_SUPPORT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
- case TOK_ADDSIZE:
- {
- int s;
- int size_kb=line.gettoken_int(1,&s);
- if (!s) PRINTHELP()
- SCRIPT_MSG("AddSize: %d kb\n",size_kb);
- section_add_size_kb(size_kb);
- }
- return PS_OK;
- case TOK_SUBCAPTION:
- {
- int s;
- int w=line.gettoken_int(1,&s);
- if (!s || w < 0 || w > 4) PRINTHELP()
- SetInnerString(NLF_SUBCAPTION_LICENSE+w,line.gettoken_str(2));
- SCRIPT_MSG("SubCaption: page:%d, text=%s\n",w,line.gettoken_str(2));
- }
- return PS_OK;
- case TOK_FILEERRORTEXT:
-#ifdef NSIS_SUPPORT_FILE
- {
- SetInnerString(NLF_FILE_ERROR,line.gettoken_str(1));
- SetInnerString(NLF_FILE_ERROR_NOIGNORE,line.gettoken_str(2));
- SCRIPT_MSG("FileErrorText: \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2));
- }
- return PS_OK;
-#else
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_FILE not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif
- case TOK_BRANDINGTEXT:
- {
- int a = 1;
- int trim = 0;
- while (line.gettoken_str(a)[0] == '/') {
- if (!strnicmp(line.gettoken_str(a),"/TRIM",5)) {
- if (!stricmp(line.gettoken_str(a)+5,"LEFT")) trim = 1;
- else if (!stricmp(line.gettoken_str(a)+5,"RIGHT")) trim = 2;
- else if (!stricmp(line.gettoken_str(a)+5,"CENTER")) trim = 3;
- else PRINTHELP();
- a++;
- }
- else break;
- }
- if (line.getnumtokens()!=a+1 && !trim) PRINTHELP();
- if (line.getnumtokens()==a+1)
- SetInnerString(NLF_BRANDING,line.gettoken_str(a));
-#ifdef _WIN32
- if (trim) try {
- init_res_editor();
-
- BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), NSIS_DEFAULT_LANG);
- CDialogTemplate td(dlg,uDefCodePage);
- free(dlg);
-
- if (trim) {
- char str[512];
- if (line.getnumtokens()==a+1 && line.gettoken_str(a)[0])
- strcpy(str, line.gettoken_str(a));
- else
- wsprintf(str, "Nullsoft Install System %s", NSIS_VERSION);
-
- short old_width = td.GetItem(IDC_VERSTR)->sWidth;
-
- switch (trim) {
- case 1: td.LTrimToString(IDC_VERSTR, str, 4); break;
- case 2: td.RTrimToString(IDC_VERSTR, str, 4); break;
- case 3: td.CTrimToString(IDC_VERSTR, str, 4); break;
- }
-
- if (td.GetItem(IDC_VERSTR)->sWidth > old_width)
- {
- warning_fl("BrandingText: \"%s\" is too long, trimming has expanded the label", str);
- }
- }
-
- DWORD dwSize;
- dlg = td.Save(dwSize);
- res_editor->UpdateResourceA(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), NSIS_DEFAULT_LANG, dlg, dwSize);
- res_editor->FreeResource(dlg);
- }
- catch (exception& err) {
- ERROR_MSG("Error while triming branding text control: %s\n", err.what());
- return PS_ERROR;
- }
-#else
- if (trim)
- {
- ERROR_MSG("Error: BrandingText /TRIM* is disabled for non Win32 platforms.\n");
- return PS_ERROR;
- }
-#endif
- SCRIPT_MSG("BrandingText: \"%s\"\n",line.gettoken_str(a));
- }
- return PS_OK;
- case TOK_MISCBUTTONTEXT:
- {
- SetInnerString(NLF_BTN_BACK,line.gettoken_str(1));
- SetInnerString(NLF_BTN_NEXT,line.gettoken_str(2));
- SetInnerString(NLF_BTN_CANCEL,line.gettoken_str(3));
- SetInnerString(NLF_BTN_CLOSE,line.gettoken_str(4));
- SCRIPT_MSG("MiscButtonText: back=\"%s\" next=\"%s\" cancel=\"%s\" close=\"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
- }
- return PS_OK;
- case TOK_SPACETEXTS:
- {
- if (!strcmpi(line.gettoken_str(1), "none")) {
- no_space_texts=true;
- SCRIPT_MSG("SpaceTexts: none\n");
- }
- else {
- no_space_texts=false;
- SetInnerString(NLF_SPACE_REQ,line.gettoken_str(1));
- SetInnerString(NLF_SPACE_AVAIL,line.gettoken_str(2));
- SCRIPT_MSG("SpaceTexts: required=\"%s\" available=\"%s\"\n",line.gettoken_str(1),line.gettoken_str(2));
- }
- }
- return PS_OK;
- case TOK_INSTBUTTONTEXT:
- {
- SetInnerString(NLF_BTN_INSTALL,line.gettoken_str(1));
- SCRIPT_MSG("InstallButtonText: \"%s\"\n",line.gettoken_str(1));
- }
- return PS_OK;
- case TOK_DETAILSBUTTONTEXT:
- {
- if (!cur_page) {
- if (SetInnerString(NLF_BTN_DETAILS,line.gettoken_str(1)) == PS_WARNING)
- warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
- }
- else {
- if (cur_page_type != PAGE_INSTFILES) {
- ERROR_MSG("Error: DetailsButtonText can only be used inside PageEx instfiles.\n");
- return PS_ERROR;
- }
- cur_page->parms[1] = add_string(line.gettoken_str(1));
- }
- SCRIPT_MSG("DetailsButtonText: \"%s\"\n",line.gettoken_str(1));
- }
- return PS_OK;
- case TOK_COMPLETEDTEXT:
- {
- if (!cur_page) {
- if (SetInnerString(NLF_COMPLETED,line.gettoken_str(1)) == PS_WARNING)
- warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
- }
- else {
- if (cur_page_type != PAGE_INSTFILES) {
- ERROR_MSG("Error: CompletedText can only be used inside PageEx instfiles.\n");
- return PS_ERROR;
- }
- cur_page->parms[2] = add_string(line.gettoken_str(1));
- }
- SCRIPT_MSG("CompletedText: \"%s\"\n",line.gettoken_str(1));
- }
- return PS_OK;
- case TOK_UNINSTBUTTONTEXT:
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- {
- SetInnerString(NLF_BTN_UNINSTALL,line.gettoken_str(1));
- SCRIPT_MSG("UninstButtonText: \"%s\"\n",line.gettoken_str(1));
- }
- return PS_OK;
-#else
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif
-
- // instructions
- ///////////////////////////////////////////////////////////////////////////////
- case TOK_NOP:
- SCRIPT_MSG("Nop\n");
- ent.which=EW_NOP;
- return add_entry(&ent);
- case TOK_GOTO:
- ent.which=EW_NOP;
- if (process_jump(line,1,&ent.offsets[0])) PRINTHELP()
- SCRIPT_MSG("Goto: %s\n",line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_SETREGVIEW:
- {
- ent.which=EW_SETFLAG;
- ent.offsets[0]=FLAG_OFFSET(alter_reg_view);
- // "64" results in setting the flag to 1 which alters the view
- int k=line.gettoken_enum(1,"32\0" "64\0lastused\0");
- if (k<0) PRINTHELP()
- if (k == 0) // 32
- ent.offsets[1]=add_intstring(0);
- else if (k == 1) // 64
- ent.offsets[1]=add_intstring(KEY_WOW64_64KEY);
- else if (k == 2) // last used
- ent.offsets[2]=1;
- SCRIPT_MSG("SetRegView: %s\n",line.gettoken_str(1));
- }
- return add_entry(&ent);
- case TOK_SETSHELLVARCONTEXT:
- {
- ent.which=EW_SETFLAG;
- ent.offsets[0]=FLAG_OFFSET(all_user_var);
- int k=line.gettoken_enum(1,"current\0all\0");
- if (k<0) PRINTHELP()
- ent.offsets[1]=add_intstring(k);
- SCRIPT_MSG("SetShellVarContext: %s\n",line.gettoken_str(1));
- }
- return add_entry(&ent);
- case TOK_RET:
- SCRIPT_MSG("Return\n");
- ent.which=EW_RET;
- return add_entry(&ent);
- case TOK_CALL:
- if (!line.gettoken_str(1)[0] || (line.gettoken_str(1)[0]==':' && !line.gettoken_str(1)[1] )) PRINTHELP()
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
- if (uninstall_mode && strnicmp(line.gettoken_str(1),"un.",3)
- && (GetUserVarIndex(line,1) < 0) && line.gettoken_str(1)[0]!=':')
- {
- ERROR_MSG("Call must be used with function names starting with \"un.\" in the uninstall section.\n");
- PRINTHELP()
- }
- if (!uninstall_mode && !strnicmp(line.gettoken_str(1),"un.",3))
- {
- ERROR_MSG("Call must not be used with functions starting with \"un.\" in the non-uninstall sections.\n");
- PRINTHELP()
- }
-#endif
- ent.which=EW_CALL;
- ent.offsets[1]=0;
- {
- int v;
- if ((v=GetUserVarIndex(line, 1))>=0)
- {
- ent.offsets[0]=-v-2;
- }
- else
- {
- if (line.gettoken_str(1)[0] == ':')
- {
- ent.offsets[1]=1;
- ent.offsets[0]=ns_label.add(line.gettoken_str(1)+1,0);
- }
- else ent.offsets[0]=ns_func.add(line.gettoken_str(1),0);
- }
- }
- SCRIPT_MSG("Call \"%s\"\n",line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_SETOUTPATH:
- {
- char *op=line.gettoken_str(1);
- if (!strcmp(op,"-"))
- {
- op="$INSTDIR";
- }
- SCRIPT_MSG("SetOutPath: \"%s\"\n",op);
- ent.which=EW_CREATEDIR;
- ent.offsets[0]=add_string(op);
- ent.offsets[1]=1;
-
- DefineInnerLangString(NLF_OUTPUT_DIR);
- }
- return add_entry(&ent);
- case TOK_CREATEDIR:
- {
- char out_path[1024];
- char *p=line.gettoken_str(1);
- if (*p == '-') out_path[0]=0;
- else
- {
- if (p[0] == '\\' && p[1] != '\\') p++;
- strncpy(out_path,p,1024-1);
- if (*CharPrev(out_path,out_path+strlen(out_path))=='\\')
- *CharPrev(out_path,out_path+strlen(out_path))=0; // remove trailing slash
- }
- if (!*out_path) PRINTHELP()
- SCRIPT_MSG("CreateDirectory: \"%s\"\n",out_path);
- ent.which=EW_CREATEDIR;
- ent.offsets[0]=add_string(out_path);
-
- DefineInnerLangString(NLF_CREATE_DIR);
- }
- return add_entry(&ent);
- case TOK_EXEC:
- case TOK_EXECWAIT:
-#ifdef NSIS_SUPPORT_EXECUTE
- ent.which=EW_EXECUTE;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[2]=0;
- if (which_token == TOK_EXECWAIT)
- {
- ent.offsets[2]=1;
- ent.offsets[1]=GetUserVarIndex(line, 2);
- if (line.gettoken_str(2)[0] && ent.offsets[1]<0) PRINTHELP()
- }
- SCRIPT_MSG("%s: \"%s\" (->%s)\n",ent.offsets[2]?"ExecWait":"Exec",line.gettoken_str(1),line.gettoken_str(2));
-
- DefineInnerLangString(NLF_EXEC);
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_EXECUTE
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_EXECUTE not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_EXECUTE
- case TOK_EXECSHELL: // this uses improvements of Andras Varga
-#ifdef NSIS_SUPPORT_SHELLEXECUTE
- {
- ent.which=EW_SHELLEXEC;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=add_string(line.gettoken_str(3));
- ent.offsets[3]=SW_SHOWNORMAL;
- if (line.getnumtokens() > 4)
- {
- int tab[4]={SW_SHOWNORMAL,SW_SHOWMAXIMIZED,SW_SHOWMINIMIZED,SW_HIDE};
- int a=line.gettoken_enum(4,"SW_SHOWNORMAL\0SW_SHOWMAXIMIZED\0SW_SHOWMINIMIZED\0SW_HIDE\0");
- if (a < 0) PRINTHELP()
- ent.offsets[3]=tab[a];
- }
- string detail=string(line.gettoken_str(1))+" "+string(line.gettoken_str(2));
- ent.offsets[5]=add_string(detail.c_str());
- SCRIPT_MSG("ExecShell: %s: \"%s\" \"%s\" %s\n",line.gettoken_str(1),line.gettoken_str(2),
- line.gettoken_str(3),line.gettoken_str(4));
-
- DefineInnerLangString(NLF_EXEC_SHELL);
- }
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_SHELLEXECUTE
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_SHELLEXECUTE not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_SHELLEXECUTE
- case TOK_CALLINSTDLL:
- case TOK_REGDLL:
- case TOK_UNREGDLL:
-#ifndef NSIS_SUPPORT_ACTIVEXREG
- ERROR_MSG("%s: support not compiled in (NSIS_SUPPORT_ACTIVEXREG)\n",line.gettoken_str(0));
- return PS_ERROR;
-#else//NSIS_SUPPORT_ACTIVEXREG
- ent.which=EW_REGISTERDLL;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- if (which_token == TOK_UNREGDLL)
- {
- ent.offsets[1]=add_string("DllUnregisterServer");
- ent.offsets[2]=DefineInnerLangString(NLF_UNREGISTERING);
- }
- else if (which_token == TOK_CALLINSTDLL)
- {
- int a = 2;
- if (!stricmp(line.gettoken_str(a), "/NOUNLOAD")) {
- ent.offsets[3]=1;
- a++;
- }
- if (a+1 != line.getnumtokens()) PRINTHELP();
- ent.offsets[1]=add_string(line.gettoken_str(a));
- if (!ent.offsets[1]) PRINTHELP()
- ent.offsets[2]=0;
- }
- else // register
- {
- ent.offsets[1] = add_string(line.gettoken_str(2));
- if (!ent.offsets[1]) ent.offsets[1]=add_string("DllRegisterServer");
- ent.offsets[2]=DefineInnerLangString(NLF_REGISTERING);
- }
-
- SCRIPT_MSG("%s: \"%s\" %s\n",line.gettoken_str(0),line.gettoken_str(1), line.gettoken_str(ent.offsets[3]?3:2));
-
- DefineInnerLangString(NLF_SYMBOL_NOT_FOUND);
- DefineInnerLangString(NLF_COULD_NOT_LOAD);
- DefineInnerLangString(NLF_NO_OLE);
- // not used anywhere - DefineInnerLangString(NLF_ERR_REG_DLL);
- return add_entry(&ent);
-#endif//NSIS_SUPPORT_ACTIVEXREG
- case TOK_RENAME:
-#ifdef NSIS_SUPPORT_RENAME
- {
- int a=1;
- ent.which=EW_RENAME;
- if (!stricmp(line.gettoken_str(1),"/REBOOTOK"))
- {
- ent.offsets[2]=1;
- a++;
-#ifndef NSIS_SUPPORT_MOVEONREBOOT
- ERROR_MSG("Error: /REBOOTOK specified, NSIS_SUPPORT_MOVEONREBOOT not defined\n");
- PRINTHELP()
-#endif
- }
- else if (line.gettoken_str(1)[0]=='/')
- {
- a=line.getnumtokens(); // cause usage to go here:
- }
- if (line.getnumtokens()!=a+2) PRINTHELP()
- ent.offsets[0]=add_string(line.gettoken_str(a));
- ent.offsets[1]=add_string(line.gettoken_str(a+1));
- string print = string(line.gettoken_str(a)) + "->" + string(line.gettoken_str(a+1));
- ent.offsets[3]=add_string(print.c_str());
- SCRIPT_MSG("Rename: %s%s->%s\n",ent.offsets[2]?"/REBOOTOK ":"",line.gettoken_str(a),line.gettoken_str(a+1));
-
- DefineInnerLangString(NLF_RENAME);
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
- DefineInnerLangString(NLF_RENAME_ON_REBOOT);
-#endif
- }
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_RENAME
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_RENAME not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_RENAME
- case TOK_MESSAGEBOX:
-#ifdef NSIS_SUPPORT_MESSAGEBOX
- {
- #define MBD(x) {x,#x},
- struct
- {
- int id;
- char *str;
- } list[]=
- {
- MBD(MB_ABORTRETRYIGNORE)
- MBD(MB_OK)
- MBD(MB_OKCANCEL)
- MBD(MB_RETRYCANCEL)
- MBD(MB_YESNO)
- MBD(MB_YESNOCANCEL)
- MBD(MB_ICONEXCLAMATION)
- MBD(MB_ICONINFORMATION)
- MBD(MB_ICONQUESTION)
- MBD(MB_ICONSTOP)
- MBD(MB_USERICON)
- MBD(MB_TOPMOST)
- MBD(MB_SETFOREGROUND)
- MBD(MB_RIGHT)
- MBD(MB_RTLREADING)
- MBD(MB_DEFBUTTON1)
- MBD(MB_DEFBUTTON2)
- MBD(MB_DEFBUTTON3)
- MBD(MB_DEFBUTTON4)
- };
- #undef MBD
- int r=0;
- int x;
- char *p=line.gettoken_str(1);
-
- while (*p)
- {
- char *np=p;
- while (*np && *np != '|') np++;
- if (*np) *np++=0;
- for (x = 0 ; (unsigned) x < sizeof(list) / sizeof(list[0]) && strcmpi(list[x].str, p); x++);
- if ((unsigned) x < sizeof(list) / sizeof(list[0]))
- {
- r|=list[x].id;
- }
- else PRINTHELP()
- p=np;
- }
- ent.which=EW_MESSAGEBOX;
- ent.offsets[0]=r;
- ent.offsets[1]=add_string(line.gettoken_str(2));
- int rettab[] =
- {
- 0,IDABORT,IDCANCEL,IDIGNORE,IDNO,IDOK,IDRETRY,IDYES
- };
- const char *retstr="0\0IDABORT\0IDCANCEL\0IDIGNORE\0IDNO\0IDOK\0IDRETRY\0IDYES\0";
- int a=3;
- if (line.getnumtokens() > 3)
- {
- if (!strcmpi(line.gettoken_str(3),"/SD"))
- {
- int k=line.gettoken_enum(4,retstr);
- if (k <= 0) PRINTHELP();
- ent.offsets[0]|=rettab[k]<<21;
- a=5;
- }
- else if (line.getnumtokens() > 7)
- PRINTHELP();
-
- if (line.getnumtokens() > a)
- {
- ent.offsets[2]=line.gettoken_enum(a,retstr);
- if (ent.offsets[2] < 0)
- PRINTHELP();
- ent.offsets[2] = rettab[ent.offsets[2]];
- if (process_jump(line,a+1,&ent.offsets[3]))
- PRINTHELP();
- if (line.getnumtokens() > a+2)
- {
- int v=line.gettoken_enum(a+2,retstr);
- if (v < 0)
- PRINTHELP();
- ent.offsets[4] = rettab[v];
- if (process_jump(line,a+3,&ent.offsets[5]))
- PRINTHELP();
- }
- }
- }
- SCRIPT_MSG("MessageBox: %d: \"%s\"",r,line.gettoken_str(2));
- if (line.getnumtokens()>a+1) SCRIPT_MSG(" (on %s goto %s)",line.gettoken_str(a),line.gettoken_str(a+1));
- SCRIPT_MSG("\n");
- }
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_MESSAGEBOX
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_MESSAGEBOX not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_MESSAGEBOX
- case TOK_CREATESHORTCUT:
-#ifdef NSIS_SUPPORT_CREATESHORTCUT
- ent.which=EW_CREATESHORTCUT;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=add_string(line.gettoken_str(3));
- ent.offsets[3]=add_string(line.gettoken_str(4));
- ent.offsets[5]=add_string(line.gettoken_str(8));
- int s;
- ent.offsets[4]=line.gettoken_int(5,&s)&0xff;
- if (!s)
- {
- if (line.getnumtokens() > 5 && *line.gettoken_str(5))
- {
- ERROR_MSG("CreateShortCut: cannot interpret icon index\n");
- PRINTHELP()
- }
- ent.offsets[4]=0;
- }
- if (line.getnumtokens() > 6 && *line.gettoken_str(6))
- {
- int tab[3]={SW_SHOWNORMAL,SW_SHOWMAXIMIZED,SW_SHOWMINNOACTIVE/*SW_SHOWMINIMIZED doesn't work*/};
- int a=line.gettoken_enum(6,"SW_SHOWNORMAL\0SW_SHOWMAXIMIZED\0SW_SHOWMINIMIZED\0");
- if (a < 0)
- {
- ERROR_MSG("CreateShortCut: unknown show mode \"%s\"\n",line.gettoken_str(6));
- PRINTHELP()
- }
- ent.offsets[4]|=tab[a]<<8;
- }
- if (line.getnumtokens() > 7)
- {
- char *s=(line.gettoken_str(7));
-
- char b[255];
- for (unsigned int spos=0; (spos <= strlen(s)) && (spos <= 255); spos++)
- b[spos]=toupper(*(s+spos));
- strcpy(s,b);
-
- if (*s)
- {
- int c=0;
- if (strstr(s,"ALT|")) ent.offsets[4]|=HOTKEYF_ALT << 24;
- if (strstr(s,"CONTROL|")) ent.offsets[4]|=HOTKEYF_CONTROL << 24;
- if (strstr(s,"EXT|")) ent.offsets[4]|=HOTKEYF_EXT << 24;
- if (strstr(s,"SHIFT|")) ent.offsets[4]|=HOTKEYF_SHIFT << 24;
- while (strstr(s,"|"))
- {
- s=strstr(s,"|")+1;
- }
- if ((s[0] == 'F') && (s[1] >= '1' && s[1] <= '9'))
- {
- c=VK_F1-1+atoi(s+1);
- if (atoi(s+1) < 1 || atoi(s+1) > 24)
- {
- warning_fl("CreateShortCut: F-key \"%s\" out of range",s);
- }
- }
- else if (((s[0] >= 'A' && s[0] <= 'Z') || (s[0] >= '0' && s[0] <= '9')) && !s[1])
- c=s[0];
- else
- {
- c=s[0];
- warning_fl("CreateShortCut: unrecognized hotkey \"%s\"",s);
- }
- ent.offsets[4] |= (c) << 16;
- }
- }
- SCRIPT_MSG("CreateShortCut: \"%s\"->\"%s\" %s icon:%s,%d, showmode=0x%X, hotkey=0x%X, comment=%s\n",
- line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),
- line.gettoken_str(4),ent.offsets[4]&0xff,(ent.offsets[4]>>8)&0xff,ent.offsets[4]>>16,line.gettoken_str(8));
-
- DefineInnerLangString(NLF_CREATE_SHORTCUT);
- DefineInnerLangString(NLF_ERR_CREATING_SHORTCUT);
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_CREATESHORTCUT
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_CREATESHORTCUT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//NSIS_SUPPORT_CREATESHORTCUT
-#ifdef NSIS_SUPPORT_HWNDS
- case TOK_FINDWINDOW:
- ent.which=EW_FINDWINDOW;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- if (ent.offsets[0] < 0) PRINTHELP()
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=add_string(line.gettoken_str(3));
- ent.offsets[3]=add_string(line.gettoken_str(4));
- ent.offsets[4]=add_string(line.gettoken_str(5));
- SCRIPT_MSG("FindWindow: output=%s, class=\"%s\", text=\"%s\" hwndparent=\"%s\" hwndafter=\"%s\"\n",
- line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4),line.gettoken_str(5));
- return add_entry(&ent);
- case TOK_SENDMESSAGE:
- ent.which=EW_SENDMESSAGE;
-
- if (line.gettoken_str(1)[0] == '/' || line.gettoken_str(2)[0] == '/' ||
- line.gettoken_str(3)[0] == '/' || line.gettoken_str(4)[0] == '/')
- {
- PRINTHELP()
- }
-
- SCRIPT_MSG("SendMessage:");
- {
- int a=5;
- ent.offsets[0]=GetUserVarIndex(line, 5);
- if (ent.offsets[0]>=0)
- {
- SCRIPT_MSG("(->%s)",line.gettoken_str(5));
- a++;
- }
-
- if (!strncmp(line.gettoken_str(a),"/TIMEOUT=",9))
- {
- ent.offsets[5]|=atoi(line.gettoken_str(a)+9)<<2;
- SCRIPT_MSG(" (timeout=%d)",ent.offsets[5]>>2);
- a++;
- }
-
- if (line.getnumtokens()>a)
- {
- PRINTHELP()
- }
- }
-
- if (!strncmp(line.gettoken_str(3),"STR:",4))
- {
- ent.offsets[5]|=1;
- ent.offsets[3]=add_string(line.gettoken_str(3)+4);
- }
- else ent.offsets[3]=add_string(line.gettoken_str(3));
- if (!strncmp(line.gettoken_str(4),"STR:",4))
- {
- ent.offsets[5]|=2;
- ent.offsets[4]=add_string(line.gettoken_str(4)+4);
- }
- else ent.offsets[4]=add_string(line.gettoken_str(4));
-
- ent.offsets[1]=add_string(line.gettoken_str(1));
- ent.offsets[2]=add_string(line.gettoken_str(2));
-
- SCRIPT_MSG("(%s,%s,%s,%s)\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
- return add_entry(&ent);
- case TOK_ISWINDOW:
- ent.which=EW_ISWINDOW;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- if (process_jump(line,2,&ent.offsets[1])||
- process_jump(line,3,&ent.offsets[2])) PRINTHELP()
- SCRIPT_MSG("IsWindow(%s): %s:%s\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
- return add_entry(&ent);
-#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
- case TOK_GETDLGITEM:
- ent.which=EW_GETDLGITEM;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- if (ent.offsets[0]<0) PRINTHELP();
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=add_string(line.gettoken_str(3));
- SCRIPT_MSG("GetDlgItem: output=%s dialog=%s item=%s\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
- return add_entry(&ent);
- case TOK_SETCTLCOLORS:
- {
- ctlcolors c={0, };
-
- ent.which=EW_SETCTLCOLORS;
- ent.offsets[0]=add_string(line.gettoken_str(1));
-
- int a = 2;
-
- if (!strcmpi(line.gettoken_str(2),"/BRANDING"))
- a++;
-
- {
- char *p;
-
- if (a == 2 && line.getnumtokens() == 5) {
- ERROR_MSG("Error: SetCtlColors expected 3 parameters, got 4\n");
- return PS_ERROR;
- }
-
- if (!strcmpi(line.gettoken_str(a+1),"transparent")) {
- c.flags|=CC_BKB;
- c.lbStyle=BS_NULL;
- c.bkmode=TRANSPARENT;
- }
- else {
- p=line.gettoken_str(a+1);
- if (*p) {
- int v=strtoul(p,&p,16);
- c.bkc=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16);
- c.flags|=CC_BK|CC_BKB;
- }
-
- c.lbStyle=BS_SOLID;
- c.bkmode=OPAQUE;
- }
-
- p=line.gettoken_str(a);
- if (*p) {
- int v=strtoul(p,&p,16);
- c.text=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16);
- c.flags|=CC_TEXT;
- }
- }
-
- if (a == 3)
- {
- c.flags|=CC_BK|CC_BKB;
- c.lbStyle=BS_NULL;
- if (!*line.gettoken_str(a+1))
- {
- c.bkc=COLOR_BTNFACE;
- c.flags|=CC_BK_SYS;
- }
- c.flags|=CC_TEXT;
- if (!*line.gettoken_str(a))
- {
- c.text=COLOR_BTNFACE;
- c.flags|=CC_TEXT_SYS;
- }
- c.bkmode=OPAQUE;
- }
-
- int i;
- int l=cur_ctlcolors->getlen()/sizeof(ctlcolors);
- for (i=0; i<l; i++) {
- if (!memcmp((ctlcolors*)cur_ctlcolors->get()+i,&c,sizeof(ctlcolors))) {
- ent.offsets[1]=i*sizeof(ctlcolors);
- break;
- }
- }
- if (i>=l) {
- ent.offsets[1]=cur_ctlcolors->add(&c,sizeof(ctlcolors));
- }
-
- SCRIPT_MSG("SetCtlColors: hwnd=%s %stext=%s background=%s\n",line.gettoken_str(1),a==2?"":"/BRANDING ",line.gettoken_str(a),line.gettoken_str(a+1));
- }
- return add_entry(&ent);
- case TOK_CREATEFONT:
- ent.which=EW_CREATEFONT;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- ent.offsets[1]=add_string(line.gettoken_str(2));
- SCRIPT_MSG("CreateFont: output=%s \"%s\"",line.gettoken_str(1),line.gettoken_str(2));
- {
- int height=0;
- int weight=0;
- int flags=0;
- for (int i = 3; i < line.getnumtokens(); i++) {
- char *tok=line.gettoken_str(i);
- if (tok[0]=='/') {
- if (!strcmpi(tok,"/ITALIC")) {
- SCRIPT_MSG(" /ITALIC");
- flags|=1;
- }
- else if (!strcmpi(tok,"/UNDERLINE")) {
- SCRIPT_MSG(" /UNDERLINE");
- flags|=2;
- }
- else if (!strcmpi(tok,"/STRIKE")) {
- SCRIPT_MSG(" /STRIKE");
- flags|=4;
- }
- else {
- SCRIPT_MSG("\n");
- PRINTHELP();
- }
- }
- else {
- if (!height) {
- SCRIPT_MSG(" height=%s",tok);
- height=add_string(tok);
- }
- else if (!weight) {
- SCRIPT_MSG(" weight=%s",tok);
- weight=add_string(tok);
- }
- else {
- SCRIPT_MSG("\n");
- PRINTHELP();
- }
- }
- }
- ent.offsets[2]=height;
- ent.offsets[3]=weight;
- ent.offsets[4]=flags;
- }
- SCRIPT_MSG("\n");
- return add_entry(&ent);
- case TOK_ENABLEWINDOW:
- ent.which=EW_SHOWWINDOW;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[3]=1;
- SCRIPT_MSG("EnableWindow: handle=%s enable=%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_SHOWWINDOW:
- ent.which=EW_SHOWWINDOW;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=add_string(line.gettoken_str(2));
- SCRIPT_MSG("ShowWindow: handle=%s show state=%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_HIDEWINDOW:
- ent.which=EW_SHOWWINDOW;
- ent.offsets[0]=add_string("$HWNDPARENT");
- ent.offsets[1]=add_string("0"/*SW_HIDE*/);
- ent.offsets[2]=1;
- SCRIPT_MSG("HideWindow\n");
- return add_entry(&ent);
- case TOK_BRINGTOFRONT:
- {
- int ret;
- ent.which=EW_SHOWWINDOW;
- ent.offsets[0]=add_string("$HWNDPARENT");
- ent.offsets[1]=add_string("5"/*SW_SHOW*/);
- ret = add_entry(&ent);
- if (ret != PS_OK) return ret;
- ent.which=EW_BRINGTOFRONT;
- ent.offsets[0]=0;
- ent.offsets[1]=0;
- SCRIPT_MSG("BringToFront\n");
- }
- return add_entry(&ent);
-#else//NSIS_CONFIG_ENHANCEDUI_SUPPORT
- case TOK_GETDLGITEM:
- case TOK_SETCTLCOLORS:
- case TOK_SHOWWINDOW:
- case TOK_BRINGTOFRONT:
- case TOK_CREATEFONT:
- case TOK_HIDEWINDOW:
- case TOK_ENABLEWINDOW:
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_ENHANCEDUI_SUPPORT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
-#else//!NSIS_SUPPORT_HWNDS
- case TOK_ISWINDOW:
- case TOK_SENDMESSAGE:
- case TOK_FINDWINDOW:
- case TOK_GETDLGITEM:
- case TOK_SETCTLCOLORS:
- case TOK_SHOWWINDOW:
- case TOK_ENABLEWINDOW:
- case TOK_CREATEFONT:
- case TOK_HIDEWINDOW:
- case TOK_BRINGTOFRONT:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_HWNDS not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_HWNDS
- case TOK_DELETE:
-#ifdef NSIS_SUPPORT_DELETE
- {
- int a=1;
- ent.which=EW_DELETEFILE;
- if (!stricmp(line.gettoken_str(a),"/REBOOTOK"))
- {
- a++;
- ent.offsets[1]=DEL_REBOOT;
-#ifndef NSIS_SUPPORT_MOVEONREBOOT
- ERROR_MSG("Error: /REBOOTOK specified, NSIS_SUPPORT_MOVEONREBOOT not defined\n");
- PRINTHELP()
-#endif
- }
- else if (line.gettoken_str(1)[0]=='/')
- {
- a=line.getnumtokens();
- }
- if (line.getnumtokens() != a+1) PRINTHELP()
- ent.offsets[0]=add_string(line.gettoken_str(a));
- SCRIPT_MSG("Delete: %s\"%s\"\n",ent.offsets[1]?"/REBOOTOK ":"",line.gettoken_str(a));
-
- DefineInnerLangString(NLF_DEL_FILE);
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
- DefineInnerLangString(NLF_DEL_ON_REBOOT);
-#endif
- }
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_DELETE
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_DELETE not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_DELETE
- case TOK_RMDIR:
-#ifdef NSIS_SUPPORT_RMDIR
- {
- int a=1;
- ent.which=EW_RMDIR;
- ent.offsets[1]=DEL_DIR;
- while (line.gettoken_str(a)[0]=='/')
- {
- if (!stricmp(line.gettoken_str(a),"/r"))
- {
- if (a == 3) PRINTHELP();
- a++;
- ent.offsets[1]|=DEL_RECURSE;
- }
- else if (!stricmp(line.gettoken_str(a),"/REBOOTOK"))
- {
- if (a == 3) PRINTHELP();
- a++;
- ent.offsets[1]|=DEL_REBOOT;
- }
- else PRINTHELP();
- }
- if (a < line.getnumtokens() - 1) PRINTHELP();
- ent.offsets[0]=add_string(line.gettoken_str(a));
- SCRIPT_MSG("RMDir: ");
- if (a>1)
- SCRIPT_MSG("%s ",line.gettoken_str(1));
- if (a>2)
- SCRIPT_MSG("%s ",line.gettoken_str(2));
- SCRIPT_MSG("\"%s\"\n",line.gettoken_str(a));
-
- DefineInnerLangString(NLF_REMOVE_DIR);
- DefineInnerLangString(NLF_DEL_FILE);
-#ifdef NSIS_SUPPORT_MOVEONREBOOT
- DefineInnerLangString(NLF_DEL_ON_REBOOT);
-#endif
- }
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_RMDIR
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_RMDIR not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_RMDIR
- case TOK_RESERVEFILE:
- case TOK_FILE:
-#ifdef NSIS_SUPPORT_FILE
- {
- set<string> excluded;
- int a=1,attrib=0,rec=0,fatal=1;
- if (!stricmp(line.gettoken_str(a),"/nonfatal")) {
- fatal=0;
- a++;
- }
- if (which_token == TOK_FILE && !stricmp(line.gettoken_str(a),"/a"))
- {
-#ifdef _WIN32
- attrib=1;
-#else
- warning_fl("%sFile /a is disabled for non Win32 platforms.",(which_token == TOK_FILE)?"":"Reserve");
-#endif
- a++;
- }
- if (!stricmp(line.gettoken_str(a),"/r"))
- {
- rec=1;
- a++;
- }
- else if (which_token == TOK_FILE && !strnicmp(line.gettoken_str(a),"/oname=",7))
- {
- char *on=line.gettoken_str(a)+7;
- a++;
- if (!*on||line.getnumtokens()!=a+1||strstr(on,"*") || strstr(on,"?")) PRINTHELP()
-
- if (on[0]=='"')
- {
- ERROR_MSG("%sFile: output name must not begin with a quote, use \"/oname=name with spaces\".\n",(which_token == TOK_FILE)?"":"Reserve",line.gettoken_str(a));
- PRINTHELP();
- }
-
- int tf=0;
-#ifdef _WIN32
- int v=do_add_file(line.gettoken_str(a), attrib, 0, &tf, on);
-#else
- char *fn = my_convert(line.gettoken_str(a));
- int v=do_add_file(fn, attrib, 0, &tf, on);
- my_convert_free(fn);
-#endif
- if (v != PS_OK) return v;
- if (tf > 1) PRINTHELP()
- if (!tf)
- {
- if (fatal)
- {
- ERROR_MSG("%sFile: \"%s\" -> no files found.\n",(which_token == TOK_FILE)?"":"Reserve",line.gettoken_str(a));
- PRINTHELP()
- }
- else
- {
- warning_fl("%sFile: \"%s\" -> no files found",(which_token == TOK_FILE)?"":"Reserve",line.gettoken_str(a));
-
- // workaround for bug #1299100
- // add a nop opcode so relative jumps will work as expected
- add_entry_direct(EW_NOP);
- }
- }
-
- return PS_OK;
- }
- if (!strnicmp(line.gettoken_str(a),"/x",2))
- {
- while (!strnicmp(line.gettoken_str(a),"/x",2))
- {
- a++;
-
- if (line.getnumtokens() < a+1) PRINTHELP()
-
- excluded.insert(line.gettoken_str(a));
- a++;
- }
- }
-#ifdef _WIN32
- if (line.gettoken_str(a)[0] == '/') PRINTHELP()
-#endif
- if (line.getnumtokens()<a+1) PRINTHELP()
- while (a < line.getnumtokens())
- {
-#ifdef _WIN32
- if (line.gettoken_str(a)[0]=='/') PRINTHELP()
-#endif
- char buf[32];
- char *t=line.gettoken_str(a++);
- if (t[0] && CharNext(t)[0] == ':' && CharNext(t)[1] == '\\' && !CharNext(t)[2])
- {
- strcpy(buf,"X:\\*.*");
- buf[0]=t[0];
- t=buf;
- }
- int tf=0;
-#ifdef _WIN32
- int v=do_add_file(t, attrib, rec, &tf, NULL, which_token == TOK_FILE, NULL, excluded);
-#else
- char *fn = my_convert(t);
- int v=do_add_file(fn, attrib, rec, &tf, NULL, which_token == TOK_FILE, NULL, excluded);
- my_convert_free(fn);
-#endif
- if (v != PS_OK) return v;
- if (!tf)
- {
- if (fatal)
- {
- ERROR_MSG("%sFile: \"%s\" -> no files found.\n",(which_token == TOK_FILE)?"":"Reserve",t);
- PRINTHELP();
- }
- else
- {
- warning_fl("%sFile: \"%s\" -> no files found.",(which_token == TOK_FILE)?"":"Reserve",t);
- }
- }
- }
- }
- return PS_OK;
-#else//!NSIS_SUPPORT_FILE
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_FILE not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_FILE
-#ifdef NSIS_SUPPORT_COPYFILES
- case TOK_COPYFILES:
- {
- ent.which=EW_COPYFILES;
- ent.offsets[2]=FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOERRORUI|FOF_SIMPLEPROGRESS;
-
- int a=1;
- int x;
- for (x = 0; x < 2; x ++)
- {
- if (!stricmp(line.gettoken_str(a),"/SILENT"))
- {
- a++;
- ent.offsets[2]&=~FOF_SIMPLEPROGRESS;
- ent.offsets[2]|=FOF_SILENT;
- }
- else if (!stricmp(line.gettoken_str(a),"/FILESONLY"))
- {
- a++;
- ent.offsets[2]|=FOF_FILESONLY;
- }
- else if (line.gettoken_str(a)[0]=='/') PRINTHELP()
- else break;
- }
- if (line.getnumtokens() < a+2) PRINTHELP()
- ent.offsets[0]=add_string(line.gettoken_str(a));
- ent.offsets[1]=add_string(line.gettoken_str(a+1));
- string copy_to = string("$(^CopyTo)") + line.gettoken_str(a+1);
- ent.offsets[3]=add_string(copy_to.c_str());
- int s;
- int size_kb=line.gettoken_int(a+2,&s);
- if (!s && line.gettoken_str(a+2)[0]) PRINTHELP()
- section_add_size_kb(size_kb);
- SCRIPT_MSG("CopyFiles: %s\"%s\" -> \"%s\", size=%iKB\n",ent.offsets[2]&FOF_SILENT?"(silent) ":"", line.gettoken_str(a),line.gettoken_str(a+1),size_kb);
-
- DefineInnerLangString(NLF_COPY_FAILED);
- DefineInnerLangString(NLF_COPY_TO);
- }
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_COPYFILES
- case TOK_COPYFILES:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_COPYFILES not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_COPYFILES
-
- case TOK_SETFILEATTRIBUTES:
- {
- #define MBD(x) {x,#x},
- struct
- {
- int id;
- char *str;
- } list[]=
- {
- MBD(FILE_ATTRIBUTE_NORMAL)
- MBD(FILE_ATTRIBUTE_ARCHIVE)
- MBD(FILE_ATTRIBUTE_HIDDEN)
- MBD(FILE_ATTRIBUTE_OFFLINE)
- MBD(FILE_ATTRIBUTE_READONLY)
- MBD(FILE_ATTRIBUTE_SYSTEM)
- MBD(FILE_ATTRIBUTE_TEMPORARY)
- {FILE_ATTRIBUTE_NORMAL,"NORMAL"},
- {FILE_ATTRIBUTE_ARCHIVE,"ARCHIVE"},
- {FILE_ATTRIBUTE_HIDDEN,"HIDDEN"},
- {FILE_ATTRIBUTE_OFFLINE,"OFFLINE"},
- {FILE_ATTRIBUTE_READONLY,"READONLY"},
- {FILE_ATTRIBUTE_SYSTEM,"SYSTEM"},
- {FILE_ATTRIBUTE_TEMPORARY,"TEMPORARY"},
- {FILE_ATTRIBUTE_NORMAL,"0"},
- };
- #undef MBD
- int r=0;
- int x;
- char *p=line.gettoken_str(2);
-
- while (*p)
- {
- char *np=p;
- while (*np && *np != '|') np++;
- if (*np) *np++=0;
- for (x = 0 ; (unsigned) x < sizeof(list)/sizeof(list[0]) && stricmp(list[x].str,p); x ++);
-
- if ((unsigned) x < sizeof(list)/sizeof(list[0]))
- {
- r|=list[x].id;
- }
- else PRINTHELP()
- p=np;
- }
- ent.which=EW_SETFILEATTRIBUTES;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=r;
- }
- return add_entry(&ent);
- case TOK_SLEEP:
- {
- ent.which=EW_SLEEP;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- SCRIPT_MSG("Sleep: %s ms\n",line.gettoken_str(1));
- }
- return add_entry(&ent);
- case TOK_IFFILEEXISTS:
- ent.which=EW_IFFILEEXISTS;
- ent.offsets[0] = add_string(line.gettoken_str(1));
- if (process_jump(line,2,&ent.offsets[1]) ||
- process_jump(line,3,&ent.offsets[2])) PRINTHELP()
- SCRIPT_MSG("IfFileExists: \"%s\" ? %s : %s\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
- return add_entry(&ent);
- case TOK_QUIT:
- ent.which=EW_QUIT;
- SCRIPT_MSG("Quit\n");
- return add_entry(&ent);
- case TOK_ABORT:
- ent.which=EW_ABORT;
- ent.offsets[0] = add_string(line.gettoken_str(1));
- SCRIPT_MSG("Abort: \"%s\"\n",line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_SETDETAILSVIEW:
- {
- int v=line.gettoken_enum(1,"hide\0show\0");
- ent.which=EW_CHDETAILSVIEW;
- if (v < 0) PRINTHELP()
- ent.offsets[0] = v?SW_SHOWNA:SW_HIDE;
- ent.offsets[1] = v?SW_HIDE:SW_SHOWNA;
- SCRIPT_MSG("SetDetailsView: %s\n",line.gettoken_str(1));
- }
- return add_entry(&ent);
- case TOK_SETDETAILSPRINT:
- {
- ent.which=EW_SETFLAG;
- ent.offsets[0]=FLAG_OFFSET(status_update);
- int k=line.gettoken_enum(1,"both\0textonly\0listonly\0none\0lastused\0");
- if (k<0) PRINTHELP()
- if (k == 4)
- {
- ent.offsets[2]=1;
- }
- else
- {
- // both 0
- // textonly 2
- // listonly 4
- // none 6
- ent.offsets[1]=add_intstring(k*2);
- }
- SCRIPT_MSG("SetDetailsPrint: %s\n",line.gettoken_str(1));
- }
- return add_entry(&ent);
- case TOK_SETAUTOCLOSE:
- {
- ent.which=EW_SETFLAG;
- ent.offsets[0]=FLAG_OFFSET(autoclose);
- int k=line.gettoken_enum(1,"false\0true\0");
- if (k < 0) PRINTHELP()
- ent.offsets[1]=add_intstring(k);
- SCRIPT_MSG("SetAutoClose: %s\n",line.gettoken_str(1));
- }
- return add_entry(&ent);
- case TOK_IFERRORS:
- ent.which=EW_IFFLAG;
- if (process_jump(line,1,&ent.offsets[0]) ||
- process_jump(line,2,&ent.offsets[1])) PRINTHELP()
- ent.offsets[2]=FLAG_OFFSET(exec_error);
- ent.offsets[3]=0;//new value mask - clean error
- SCRIPT_MSG("IfErrors ?%s:%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_IFABORT:
- ent.which=EW_IFFLAG;
- if (process_jump(line,1,&ent.offsets[0]) ||
- process_jump(line,2,&ent.offsets[1])) PRINTHELP()
- ent.offsets[2]=FLAG_OFFSET(abort);
- ent.offsets[3]=~0;//new value mask - keep flag
- SCRIPT_MSG("IfAbort ?%s:%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_CLEARERRORS:
- ent.which=EW_SETFLAG;
- ent.offsets[0]=FLAG_OFFSET(exec_error);
- ent.offsets[1]=add_intstring(0);
- SCRIPT_MSG("ClearErrors\n");
- return add_entry(&ent);
- case TOK_SETERRORS:
- ent.which=EW_SETFLAG;
- ent.offsets[0]=FLAG_OFFSET(exec_error);
- ent.offsets[1]=add_intstring(1);
- SCRIPT_MSG("SetErrors\n");
- return add_entry(&ent);
- case TOK_SETERRORLEVEL:
- ent.which=EW_SETFLAG;
- ent.offsets[0]=FLAG_OFFSET(errlvl);
- ent.offsets[1]=add_string(line.gettoken_str(1));
- SCRIPT_MSG("SetErrorLevel: %s\n",line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_GETERRORLEVEL:
- ent.which=EW_GETFLAG;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- ent.offsets[1]=FLAG_OFFSET(errlvl);
- if (line.gettoken_str(1)[0] && ent.offsets[0]<0) PRINTHELP()
- SCRIPT_MSG("GetErrorLevel: %s\n",line.gettoken_str(1));
- return add_entry(&ent);
-#ifdef NSIS_SUPPORT_STROPTS
- case TOK_STRLEN:
- ent.which=EW_STRLEN;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- ent.offsets[1]=add_string(line.gettoken_str(2));
- if (ent.offsets[0] < 0) PRINTHELP()
- SCRIPT_MSG("StrLen %s \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_STRCPY:
- ent.which=EW_ASSIGNVAR;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=add_string(line.gettoken_str(3));
- ent.offsets[3]=add_string(line.gettoken_str(4));
-
- if (ent.offsets[0] < 0) PRINTHELP()
- SCRIPT_MSG("StrCpy %s \"%s\" (%s) (%s)\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
- return add_entry(&ent);
- case TOK_GETFUNCTIONADDR:
- ent.which=EW_GETFUNCTIONADDR;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- ent.offsets[1]=ns_func.add(line.gettoken_str(2),0);
- ent.offsets[2]=0;
- ent.offsets[3]=0;
- if (ent.offsets[0] < 0) PRINTHELP()
- SCRIPT_MSG("GetFunctionAddress: %s %s",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_GETLABELADDR:
- ent.which=EW_GETLABELADDR;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- if (ent.offsets[0] < 0 || process_jump(line,2,&ent.offsets[1])) PRINTHELP()
- ent.offsets[2]=0;
- ent.offsets[3]=0;
- SCRIPT_MSG("GetLabelAddress: %s %s",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_GETCURRENTADDR:
- ent.which=EW_ASSIGNVAR;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- {
- char buf[32];
- wsprintf(buf,"%d",1+(cur_header->blocks[NB_ENTRIES].num));
- ent.offsets[1]=add_string(buf);
- }
- if (ent.offsets[0] < 0) PRINTHELP()
- ent.offsets[2]=0;
- ent.offsets[3]=0;
- SCRIPT_MSG("GetCurrentAddress: %s",line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_STRCMP:
- case TOK_STRCMPS:
- ent.which=EW_STRCMP;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[4]=which_token == TOK_STRCMPS;
- if (process_jump(line,3,&ent.offsets[2]) ||
- process_jump(line,4,&ent.offsets[3])) PRINTHELP()
- SCRIPT_MSG("%s \"%s\" \"%s\" equal=%s, nonequal=%s\n",line.gettoken_str(0),line.gettoken_str(1),line.gettoken_str(2), line.gettoken_str(3),line.gettoken_str(4));
- return add_entry(&ent);
- case TOK_GETDLLVERSIONLOCAL:
- {
- DWORD low, high;
- if (!GetDLLVersion(line.gettoken_str(1),high,low))
- {
- ERROR_MSG("GetDLLVersionLocal: error reading version info from \"%s\"\n",line.gettoken_str(1));
- return PS_ERROR;
- }
- ent.which=EW_ASSIGNVAR;
- ent.offsets[0]=GetUserVarIndex(line, 2);
- ent.offsets[1]=add_intstring(high);
- ent.offsets[2]=0;
- ent.offsets[3]=0;
- if (ent.offsets[0]<0) PRINTHELP()
- add_entry(&ent);
-
- ent.offsets[0]=GetUserVarIndex(line, 3);
- ent.offsets[1]=add_intstring(low);
- ent.offsets[2]=0;
- ent.offsets[3]=0;
- if (ent.offsets[0]<0) PRINTHELP()
- SCRIPT_MSG("GetDLLVersionLocal: %s (%u,%u)->(%s,%s)\n",
- line.gettoken_str(1),high,low,line.gettoken_str(2),line.gettoken_str(3));
- }
- return add_entry(&ent);
- case TOK_GETFILETIMELOCAL:
- {
- char buf[129];
- DWORD high=0,low=0;
-#ifdef _WIN32
- int flag=0;
- HANDLE hFile=CreateFile(line.gettoken_str(1),0,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
- if (hFile != INVALID_HANDLE_VALUE)
- {
- FILETIME ft;
- if (GetFileTime(hFile,NULL,NULL,&ft))
- {
- high=ft.dwHighDateTime;
- low=ft.dwLowDateTime;
- flag=1;
- }
- CloseHandle(hFile);
- }
- if (!flag)
- {
- ERROR_MSG("GetFileTimeLocal: error reading date from \"%s\"\n",line.gettoken_str(1));
- return PS_ERROR;
- }
-#else
- struct stat st;
- if (!stat(line.gettoken_str(1), &st))
- {
- unsigned long long ll = (st.st_mtime * 10000000LL) + 116444736000000000LL;
- high = (DWORD) (ll >> 32);
- low = (DWORD) ll;
- }
- else
- {
- ERROR_MSG("GetFileTimeLocal: error reading date from \"%s\"\n",line.gettoken_str(1));
- return PS_ERROR;
- }
-#endif
-
- ent.which=EW_ASSIGNVAR;
- ent.offsets[0]=GetUserVarIndex(line, 2);
- wsprintf(buf,"%u",high);
- ent.offsets[1]=add_string(buf);
- ent.offsets[2]=0;
- ent.offsets[3]=0;
- if (ent.offsets[0]<0) PRINTHELP()
- add_entry(&ent);
-
- ent.offsets[0]=GetUserVarIndex(line, 3);
- wsprintf(buf,"%u",low);
- ent.offsets[1]=add_string(buf);
- ent.offsets[2]=0;
- ent.offsets[3]=0;
- if (ent.offsets[0]<0) PRINTHELP()
- SCRIPT_MSG("GetFileTimeLocal: %s (%u,%u)->(%s,%s)\n",
- line.gettoken_str(1),high,low,line.gettoken_str(2),line.gettoken_str(3));
- }
- return add_entry(&ent);
-
-#else//!NSIS_SUPPORT_STROPTS
- case TOK_GETDLLVERSIONLOCAL:
- case TOK_GETFILETIMELOCAL:
- case TOK_GETFUNCTIONADDR:
- case TOK_GETLABELADDR:
- case TOK_GETCURRENTADDR:
- case TOK_STRLEN:
- case TOK_STRCPY:
- case TOK_STRCMP:
- case TOK_STRCMPS:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_STROPTS not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_STROPTS
-#ifdef NSIS_SUPPORT_INIFILES
- case TOK_DELETEINISEC:
- case TOK_DELETEINISTR:
- {
- char *vname="";
- char *space="";
- ent.which=EW_WRITEINI;
- ent.offsets[0]=add_string(line.gettoken_str(2)); // section name
- if (line.getnumtokens() > 3)
- {
- vname=line.gettoken_str(3);
- ent.offsets[1]=add_string(vname); // value name
- space=" ";
- }
- else ent.offsets[1]=0;
- ent.offsets[2]=0;
- ent.offsets[3]=add_string(line.gettoken_str(1));
- SCRIPT_MSG("DeleteINI%s: [%s] %s%sin %s\n",*vname?"Str":"Sec",
- line.gettoken_str(2),vname,space,line.gettoken_str(1));
- }
- return add_entry(&ent);
- case TOK_FLUSHINI:
- ent.which=EW_WRITEINI;
- ent.offsets[3]=add_string(line.gettoken_str(1));
- SCRIPT_MSG("FlushINI: %s\n",line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_WRITEINISTR:
- ent.which=EW_WRITEINI;
- ent.offsets[0]=add_string(line.gettoken_str(2));
- ent.offsets[1]=add_string(line.gettoken_str(3));
- ent.offsets[2]=add_string(line.gettoken_str(4));
- ent.offsets[3]=add_string(line.gettoken_str(1));
- ent.offsets[4]=1; // write
- SCRIPT_MSG("WriteINIStr: [%s] %s=%s in %s\n",
- line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4),line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_READINISTR:
- ent.which=EW_READINISTR;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- if (ent.offsets[0] < 0) PRINTHELP()
- ent.offsets[1]=add_string(line.gettoken_str(3));
- ent.offsets[2]=add_string(line.gettoken_str(4));
- ent.offsets[3]=add_string(line.gettoken_str(2));
- SCRIPT_MSG("ReadINIStr %s [%s]:%s from %s\n",line.gettoken_str(1),line.gettoken_str(3),line.gettoken_str(4),line.gettoken_str(2));
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_INIFILES
- case TOK_DELETEINISEC:
- case TOK_DELETEINISTR:
- case TOK_FLUSHINI:
- case TOK_WRITEINISTR:
- case TOK_READINISTR:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_INIFILES not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_INIFILES
- case TOK_DETAILPRINT:
- ent.which=EW_UPDATETEXT;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=0;
- SCRIPT_MSG("DetailPrint: \"%s\"\n",line.gettoken_str(1));
- return add_entry(&ent);
-#ifdef NSIS_SUPPORT_FNUTIL
- case TOK_GETTEMPFILENAME:
- ent.which=EW_GETTEMPFILENAME;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- if (line.getnumtokens() == 3)
- ent.offsets[1]=add_string(line.gettoken_str(2));
- else
- ent.offsets[1]=add_string("$TEMP");
- if (ent.offsets[0]<0) PRINTHELP()
- SCRIPT_MSG("GetTempFileName -> %s\n",line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_GETFULLPATHNAME:
- {
- int a=0;
- ent.which=EW_GETFULLPATHNAME;
- if (line.getnumtokens()==4 && !stricmp(line.gettoken_str(1),"/SHORT")) a++;
- else if (line.getnumtokens()==4 || *line.gettoken_str(1)=='/') PRINTHELP()
- ent.offsets[0]=add_string(line.gettoken_str(2+a));
- ent.offsets[1]=GetUserVarIndex(line, 1+a);
- ent.offsets[2]=!a;
- if (ent.offsets[0]<0) PRINTHELP()
- SCRIPT_MSG("GetFullPathName: %s->%s (%d)\n",
- line.gettoken_str(2+a),line.gettoken_str(1+a),a?"sfn":"lfn");
- }
- return add_entry(&ent);
- case TOK_SEARCHPATH:
- ent.which=EW_SEARCHPATH;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- if (ent.offsets[0] < 0) PRINTHELP()
- ent.offsets[1]=add_string(line.gettoken_str(2));
- SCRIPT_MSG("SearchPath %s %s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
-#else
- case TOK_SEARCHPATH:
- case TOK_GETTEMPFILENAME:
- case TOK_GETFULLPATHNAME:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_FNUTIL not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif
- case TOK_GETDLLVERSION:
-#ifdef NSIS_SUPPORT_GETDLLVERSION
- ent.which=EW_GETDLLVERSION;
- ent.offsets[0]=GetUserVarIndex(line, 2);
- ent.offsets[1]=GetUserVarIndex(line, 3);
- ent.offsets[2]=add_string(line.gettoken_str(1));
- if (ent.offsets[0]<0 || ent.offsets[1]<0) PRINTHELP()
- SCRIPT_MSG("GetDLLVersion: %s->%s,%s\n",
- line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_GETDLLVERSION
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_GETDLLVERSION not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_GETDLLVERSION
- case TOK_GETFILETIME:
-#ifdef NSIS_SUPPORT_GETFILETIME
- ent.which=EW_GETFILETIME;
- ent.offsets[0]=GetUserVarIndex(line, 2);
- ent.offsets[1]=GetUserVarIndex(line, 3);
- ent.offsets[2]=add_string(line.gettoken_str(1));
- if (ent.offsets[0]<0 || ent.offsets[1]<0) PRINTHELP()
- SCRIPT_MSG("GetFileTime: %s->%s,%s\n",
- line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_GETFILETIME
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_GETFILETIME not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_GETFILETIME
-#ifdef NSIS_SUPPORT_INTOPTS
- case TOK_INTOP:
- ent.which=EW_INTOP;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- ent.offsets[3]=line.gettoken_enum(3,"+\0-\0*\0/\0|\0&\0^\0!\0||\0&&\0%\0<<\0>>\0~\0");
- if (ent.offsets[0] < 0 || ent.offsets[3] < 0 ||
- ((ent.offsets[3] == 7 || ent.offsets[3] == 13) && line.getnumtokens() > 4))
- PRINTHELP()
- ent.offsets[1]=add_string(line.gettoken_str(2));
- if (ent.offsets[3] != 7 && ent.offsets[3] != 13) ent.offsets[2]=add_string(line.gettoken_str(4));
- if (ent.offsets[3] == 13) {
- ent.offsets[3]=6;
- ent.offsets[2]=add_string("0xFFFFFFFF");
- }
- SCRIPT_MSG("IntOp: %s=%s%s%s\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
- return add_entry(&ent);
- case TOK_INTFMT:
- ent.which=EW_INTFMT;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- if (ent.offsets[0]<0) PRINTHELP()
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=add_string(line.gettoken_str(3));
- SCRIPT_MSG("IntFmt: %s->%s (fmt:%s)\n",line.gettoken_str(3),line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_INTCMP:
- case TOK_INTCMPU:
- ent.which=EW_INTCMP;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[5]=which_token == TOK_INTCMPU;
- if (process_jump(line,3,&ent.offsets[2]) ||
- process_jump(line,4,&ent.offsets[3]) ||
- process_jump(line,5,&ent.offsets[4])) PRINTHELP()
- SCRIPT_MSG("%s %s:%s equal=%s, < %s, > %s\n",line.gettoken_str(0),
- line.gettoken_str(1),line.gettoken_str(2), line.gettoken_str(3),line.gettoken_str(4),line.gettoken_str(5));
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_INTOPTS
- case TOK_INTOP:
- case TOK_INTCMP:
- case TOK_INTFMT:
- case TOK_INTCMPU:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_INTOPTS not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_INTOPTS
-#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
- case TOK_READREGSTR:
- case TOK_READREGDWORD:
- {
- ent.which=EW_READREGSTR;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- int k=line.gettoken_enum(2,rootkeys[0]);
- if (k == -1) k=line.gettoken_enum(2,rootkeys[1]);
- if (ent.offsets[0] == -1 || k == -1) PRINTHELP()
- ent.offsets[1]=(int)rootkey_tab[k];
- ent.offsets[2]=add_string(line.gettoken_str(3));
- ent.offsets[3]=add_string(line.gettoken_str(4));
- if (which_token == TOK_READREGDWORD) ent.offsets[4]=1;
- else ent.offsets[4]=0;
- if (line.gettoken_str(3)[0] == '\\')
- warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0));
-
- SCRIPT_MSG("%s %s %s\\%s\\%s\n",line.gettoken_str(0),
- line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
- }
- return add_entry(&ent);
- case TOK_DELETEREGVALUE:
- case TOK_DELETEREGKEY:
- {
- int a=1;
- if (which_token==TOK_DELETEREGKEY)
- {
- ent.offsets[4]=1;
- char *s=line.gettoken_str(a);
- if (s[0] == '/')
- {
- if (stricmp(s,"/ifempty")) PRINTHELP()
- a++;
- ent.offsets[4]=3;
- }
- if (line.gettoken_str(a+2)[0]) PRINTHELP()
- }
- int k=line.gettoken_enum(a,rootkeys[0]);
- if (k == -1) k=line.gettoken_enum(a,rootkeys[1]);
- if (k == -1) PRINTHELP()
- ent.which=EW_DELREG;
- ent.offsets[1]=(int)rootkey_tab[k];
- ent.offsets[2]=add_string(line.gettoken_str(a+1));
- ent.offsets[3]=(which_token==TOK_DELETEREGKEY)?0:add_string(line.gettoken_str(a+2));
- if (line.gettoken_str(a+1)[0] == '\\')
- warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0));
- if (which_token==TOK_DELETEREGKEY)
- SCRIPT_MSG("DeleteRegKey: %s\\%s\n",line.gettoken_str(a),line.gettoken_str(a+1));
- else
- SCRIPT_MSG("DeleteRegValue: %s\\%s\\%s\n",line.gettoken_str(a),line.gettoken_str(a+1),line.gettoken_str(a+2));
- }
- return add_entry(&ent);
- case TOK_WRITEREGSTR:
- case TOK_WRITEREGEXPANDSTR:
- case TOK_WRITEREGBIN:
- case TOK_WRITEREGDWORD:
- {
- int k=line.gettoken_enum(1,rootkeys[0]);
- if (k == -1) k=line.gettoken_enum(1,rootkeys[1]);
- if (k == -1) PRINTHELP()
- ent.which=EW_WRITEREG;
- ent.offsets[0]=(int)rootkey_tab[k];
- ent.offsets[1]=add_string(line.gettoken_str(2));
- if (line.gettoken_str(2)[0] == '\\')
- warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0));
- ent.offsets[2]=add_string(line.gettoken_str(3));
- if (which_token == TOK_WRITEREGSTR || which_token == TOK_WRITEREGEXPANDSTR)
- {
- SCRIPT_MSG("%s: %s\\%s\\%s=%s\n",
- line.gettoken_str(0),line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
- ent.offsets[3]=add_string(line.gettoken_str(4));
- ent.offsets[4]=ent.offsets[5]=REG_SZ;
- if (which_token == TOK_WRITEREGEXPANDSTR)
- {
- ent.offsets[5]=REG_EXPAND_SZ;
- }
- }
- if (which_token == TOK_WRITEREGBIN)
- {
- char data[3*NSIS_MAX_STRLEN];
- char *p=line.gettoken_str(4);
- int data_len=0;
- while (*p)
- {
- int c;
- int a,b;
- a=*p;
- if (a >= '0' && a <= '9') a-='0';
- else if (a >= 'a' && a <= 'f') a-='a'-10;
- else if (a >= 'A' && a <= 'F') a-='A'-10;
- else break;
- b=*++p;
- if (b >= '0' && b <= '9') b-='0';
- else if (b >= 'a' && b <= 'f') b-='a'-10;
- else if (b >= 'A' && b <= 'F') b-='A'-10;
- else break;
- p++;
- c=(a<<4)|b;
- if (data_len >= 3*NSIS_MAX_STRLEN)
- {
- ERROR_MSG("WriteRegBin: %d bytes of data exceeded\n",3*NSIS_MAX_STRLEN);
- return PS_ERROR;
- }
- data[data_len++]=c;
- }
- if (*p) PRINTHELP()
- SCRIPT_MSG("WriteRegBin: %s\\%s\\%s=%s\n",
- line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
- ent.offsets[3]=add_db_data(data,data_len);
- if (ent.offsets[3] < 0) return PS_ERROR;
- ent.offsets[4]=ent.offsets[5]=REG_BINARY;
- }
- if (which_token == TOK_WRITEREGDWORD)
- {
- ent.offsets[3]=add_string(line.gettoken_str(4));
- ent.offsets[4]=ent.offsets[5]=REG_DWORD;
-
- SCRIPT_MSG("WriteRegDWORD: %s\\%s\\%s=%s\n",
- line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
- }
- }
- return add_entry(&ent);
- case TOK_ENUMREGKEY:
- case TOK_ENUMREGVAL:
- {
- ent.which=EW_REGENUM;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- int k=line.gettoken_enum(2,rootkeys[0]);
- if (k == -1) k=line.gettoken_enum(2,rootkeys[1]);
- if (ent.offsets[0] == -1 || k == -1) PRINTHELP()
- ent.offsets[1]=(int)rootkey_tab[k];
- ent.offsets[2]=add_string(line.gettoken_str(3));
- ent.offsets[3]=add_string(line.gettoken_str(4));
- ent.offsets[4]=which_token == TOK_ENUMREGKEY;
- if (line.gettoken_str(3)[0] == '\\') warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0));
- SCRIPT_MSG("%s %s %s\\%s\\%s\n",which_token == TOK_ENUMREGKEY ? "EnumRegKey" : "EnumRegValue",
- line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
- }
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_REGISTRYFUNCTIONS
- case TOK_READREGSTR:
- case TOK_READREGDWORD:
- case TOK_DELETEREGVALUE:
- case TOK_DELETEREGKEY:
- case TOK_WRITEREGSTR:
- case TOK_WRITEREGEXPANDSTR:
- case TOK_WRITEREGBIN:
- case TOK_WRITEREGDWORD:
- case TOK_ENUMREGKEY:
- case TOK_ENUMREGVAL:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_REGISTRYFUNCTIONS not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_REGISTRYFUNCTIONS
-#ifdef NSIS_SUPPORT_STACK
- case TOK_EXCH:
- {
- int swapitem=1;
- int save=GetUserVarIndex(line, 1);
- ent.which=EW_PUSHPOP;
- if (line.gettoken_str(1)[0] && save<0)
- {
- int s=0;
- swapitem=line.gettoken_int(1,&s);
- if (!s || swapitem <= 0) PRINTHELP()
- }
- if (save>=0)
- {
- SCRIPT_MSG("Exch(%s,0)\n",line.gettoken_str(1));
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=0;
- ent.offsets[2]=0;
- add_entry(&ent);
- }
- else SCRIPT_MSG("Exch(st(%d),0)\n",swapitem);
-
- ent.offsets[0]=0;
- ent.offsets[1]=0;
- ent.offsets[2]=swapitem;
-
- if (save>=0)
- {
- add_entry(&ent);
- ent.offsets[0]=save;
- ent.offsets[1]=1;
- ent.offsets[2]=0;
- }
-
- DefineInnerLangString(NLF_INST_CORRUPTED);
- }
- return add_entry(&ent);
- case TOK_PUSH:
- ent.which=EW_PUSHPOP;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=0;
- SCRIPT_MSG("Push: %s\n",line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_POP:
- ent.which=EW_PUSHPOP;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- ent.offsets[1]=1;
- if (ent.offsets[0] < 0) PRINTHELP()
- SCRIPT_MSG("Pop: %s\n",line.gettoken_str(1));
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_STACK
- case TOK_POP:
- case TOK_PUSH:
- case TOK_EXCH:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_STACK not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_STACK
-#ifdef NSIS_SUPPORT_ENVIRONMENT
- case TOK_READENVSTR:
- ent.which=EW_READENVSTR;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- {
- char str[NSIS_MAX_STRLEN];
- strcpy(str, "%");
- strcat(str, line.gettoken_str(2));
- strcat(str, "%");
- ent.offsets[1]=add_string(str);
- if (ent.offsets[0] < 0 || strlen(line.gettoken_str(2))<1) PRINTHELP()
- }
- ent.offsets[2]=1;
- SCRIPT_MSG("ReadEnvStr: %s->%s\n",line.gettoken_str(2),line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_EXPANDENVSTRS:
- ent.which=EW_READENVSTR;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=0;
- if (ent.offsets[0] < 0) PRINTHELP()
- SCRIPT_MSG("ExpandEnvStrings: %s->%s\n",line.gettoken_str(2),line.gettoken_str(1));
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_ENVIRONMENT
- case TOK_EXPANDENVSTRS:
- case TOK_READENVSTR:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_ENVIRONMENT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_ENVIRONMENT
-#ifdef NSIS_SUPPORT_FINDFIRST
- case TOK_FINDFIRST:
- ent.which=EW_FINDFIRST;
- ent.offsets[0]=GetUserVarIndex(line, 2); // out
- ent.offsets[1]=GetUserVarIndex(line, 1); // handleout
- ent.offsets[2]=add_string(line.gettoken_str(3)); // filespec
- if (ent.offsets[0] < 0 || ent.offsets[1] < 0) PRINTHELP()
- SCRIPT_MSG("FindFirst: spec=\"%s\" handle=%s output=%s\n",line.gettoken_str(3),line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_FINDNEXT:
- ent.which=EW_FINDNEXT;
- ent.offsets[0]=GetUserVarIndex(line, 2);
- ent.offsets[1]=GetUserVarIndex(line, 1);
- if (ent.offsets[0] < 0 || ent.offsets[1] < 0) PRINTHELP()
- SCRIPT_MSG("FindNext: handle=%s output=%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_FINDCLOSE:
- ent.which=EW_FINDCLOSE;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- if (ent.offsets[0] < 0) PRINTHELP()
- SCRIPT_MSG("FindClose: %s\n",line.gettoken_str(1));
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_FINDFIRST
- case TOK_FINDCLOSE:
- case TOK_FINDNEXT:
- case TOK_FINDFIRST:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_FINDFIRST not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-
-#endif//!NSIS_SUPPORT_FINDFIRST
-
-
-#ifdef NSIS_SUPPORT_FILEFUNCTIONS
- case TOK_FILEOPEN:
- {
- ent.which=EW_FOPEN;
- ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
- ent.offsets[3]=add_string(line.gettoken_str(2));
- ent.offsets[1]=0; //openmode
- if (!stricmp(line.gettoken_str(3),"r"))
- {
- ent.offsets[1]=GENERIC_READ;
- ent.offsets[2]=OPEN_EXISTING;
- }
- else if (!stricmp(line.gettoken_str(3),"w"))
- {
- ent.offsets[1]=GENERIC_WRITE;
- ent.offsets[2]=CREATE_ALWAYS;
- }
- else if (!stricmp(line.gettoken_str(3),"a"))
- {
- ent.offsets[1]=GENERIC_WRITE|GENERIC_READ;
- ent.offsets[2]=OPEN_ALWAYS;
- }
-
- if (ent.offsets[0] < 0 || !ent.offsets[1]) PRINTHELP()
- }
- SCRIPT_MSG("FileOpen: %s as %s -> %s\n",line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_FILECLOSE:
- ent.which=EW_FCLOSE;
- ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
- if (ent.offsets[0] < 0) PRINTHELP()
- SCRIPT_MSG("FileClose: %s\n",line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_FILEREAD:
- ent.which=EW_FGETS;
- ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
- ent.offsets[1]=GetUserVarIndex(line, 2); // output string
- if (line.gettoken_str(3)[0])
- ent.offsets[2]=add_string(line.gettoken_str(3));
- else
- ent.offsets[2]=add_intstring(NSIS_MAX_STRLEN-1);
- if (ent.offsets[0]<0 || ent.offsets[1]<0) PRINTHELP()
- SCRIPT_MSG("FileRead: %s->%s (max:%s)\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
- return add_entry(&ent);
- case TOK_FILEWRITE:
- ent.which=EW_FPUTS;
- ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
- ent.offsets[1]=add_string(line.gettoken_str(2));
- if (ent.offsets[0]<0) PRINTHELP()
- SCRIPT_MSG("FileWrite: %s->%s\n",line.gettoken_str(2),line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_FILEREADBYTE:
- ent.which=EW_FGETS;
- ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
- ent.offsets[1]=GetUserVarIndex(line, 2); // output string
- ent.offsets[2]=add_string("1");
- ent.offsets[3]=1;
- if (ent.offsets[0]<0 || ent.offsets[1]<0) PRINTHELP()
- SCRIPT_MSG("FileReadByte: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_FILEWRITEBYTE:
- ent.which=EW_FPUTS;
- ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=1;
- if (ent.offsets[0]<0) PRINTHELP()
- SCRIPT_MSG("FileWriteByte: %s->%s\n",line.gettoken_str(2),line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_FILESEEK:
- {
- char *modestr;
- int tab[3]={FILE_BEGIN,FILE_CURRENT,FILE_END};
- int mode=line.gettoken_enum(3,"SET\0CUR\0END\0");
- ent.which=EW_FSEEK;
- ent.offsets[0]=GetUserVarIndex(line, 1);
- ent.offsets[1]=GetUserVarIndex(line, 4);
- ent.offsets[2]=add_string(line.gettoken_str(2));
-
- if (mode<0 && !line.gettoken_str(3)[0])
- {
- mode=0;
- modestr="SET";
- }
- else modestr=line.gettoken_str(3);
-
- if (mode<0 || ent.offsets[0] < 0 || (ent.offsets[1]<0 && line.gettoken_str(4)[0])) PRINTHELP()
- ent.offsets[3]=tab[mode];
- SCRIPT_MSG("FileSeek: fp=%s, ofs=%s, mode=%s, output=%s\n",
- line.gettoken_str(1),
- line.gettoken_str(2),
- modestr,
- line.gettoken_str(4));
- }
-
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_FILEFUNCTIONS
- case TOK_FILEOPEN:
- case TOK_FILECLOSE:
- case TOK_FILESEEK:
- case TOK_FILEREAD:
- case TOK_FILEWRITE:
- case TOK_FILEREADBYTE:
- case TOK_FILEWRITEBYTE:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_FILEFUNCTIONS not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-
-#endif//!NSIS_SUPPORT_FILEFUNCTIONS
-#ifdef NSIS_SUPPORT_REBOOT
- case TOK_REBOOT:
- {
- int ret = add_entry_direct(EW_REBOOT, 0xbadf00d);
- if (ret != PS_OK) return ret;
-
- ret = add_entry_direct(EW_QUIT);
- if (ret != PS_OK) return ret;
-
- SCRIPT_MSG("Reboot! (WOW)\n");
-
- DefineInnerLangString(NLF_INST_CORRUPTED);
- }
- return PS_OK;
- case TOK_IFREBOOTFLAG:
- ent.which=EW_IFFLAG;
- if (process_jump(line,1,&ent.offsets[0]) ||
- process_jump(line,2,&ent.offsets[1])) PRINTHELP()
- ent.offsets[2]=FLAG_OFFSET(exec_reboot);
- ent.offsets[3]=~0;//new value mask - keep flag
- SCRIPT_MSG("IfRebootFlag ?%s:%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_SETREBOOTFLAG:
- {
- ent.which=EW_SETFLAG;
- ent.offsets[0]=FLAG_OFFSET(exec_reboot);
- int k=line.gettoken_enum(1,"false\0true\0");
- if (k < 0) PRINTHELP()
- ent.offsets[1]=add_intstring(k);
- }
- return add_entry(&ent);
-#else//!NSIS_SUPPORT_REBOOT
- case TOK_REBOOT:
- case TOK_IFREBOOTFLAG:
- case TOK_SETREBOOTFLAG:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_REBOOT not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_REBOOT
-#ifdef NSIS_CONFIG_LOG
- case TOK_LOGSET:
- ent.which=EW_LOG;
- ent.offsets[0]=1;
- ent.offsets[1]=line.gettoken_enum(1,"off\0on\0");
- if (ent.offsets[1]<0) PRINTHELP()
-
- SCRIPT_MSG("LogSet: %s\n",line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_LOGTEXT:
- ent.which=EW_LOG;
- ent.offsets[0]=0;
- ent.offsets[1]=add_string(line.gettoken_str(1));
- SCRIPT_MSG("LogText \"%s\"\n",line.gettoken_str(1));
- return add_entry(&ent);
-#else//!NSIS_CONFIG_LOG
-
- case TOK_LOGSET:
- case TOK_LOGTEXT:
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_LOG not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_CONFIG_LOG
-#ifdef NSIS_CONFIG_COMPONENTPAGE
- case TOK_SECTIONSETTEXT:
- ent.which=EW_SECTIONSET;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[2]=SECTION_FIELD_SET(name_ptr);
- ent.offsets[4]=add_string(line.gettoken_str(2));
- SCRIPT_MSG("SectionSetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_SECTIONGETTEXT:
- ent.which=EW_SECTIONSET;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=GetUserVarIndex(line, 2);
- ent.offsets[2]=SECTION_FIELD_GET(name_ptr);
- if (line.gettoken_str(2)[0] && ent.offsets[1]<0) PRINTHELP()
- SCRIPT_MSG("SectionGetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_SECTIONSETFLAGS:
- ent.which=EW_SECTIONSET;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=SECTION_FIELD_SET(flags);
- ent.offsets[3]=1;
- SCRIPT_MSG("SectionSetFlags: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_SECTIONGETFLAGS:
- ent.which=EW_SECTIONSET;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=GetUserVarIndex(line, 2);
- ent.offsets[2]=SECTION_FIELD_GET(flags);
- if (line.gettoken_str(2)[0] && ent.offsets[1]<0) PRINTHELP()
- SCRIPT_MSG("SectionGetFlags: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_INSTTYPESETTEXT:
- ent.which=EW_INSTTYPESET;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=1;
- SCRIPT_MSG("InstTypeSetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_INSTTYPEGETTEXT:
- ent.which=EW_INSTTYPESET;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=GetUserVarIndex(line, 2);
- ent.offsets[2]=0;
- if (line.gettoken_str(1)[0] && ent.offsets[1]<0) PRINTHELP()
- SCRIPT_MSG("InstTypeGetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_SECTIONSETINSTTYPES:
- ent.which=EW_SECTIONSET;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=SECTION_FIELD_SET(install_types);
- SCRIPT_MSG("SectionSetInstTypes: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_SECTIONGETINSTTYPES:
- ent.which=EW_SECTIONSET;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=GetUserVarIndex(line, 2);
- ent.offsets[2]=SECTION_FIELD_GET(install_types);
- if (line.gettoken_str(2)[0] && ent.offsets[1]<0) PRINTHELP()
- SCRIPT_MSG("SectionGetInstTypes: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_SECTIONSETSIZE:
- ent.which=EW_SECTIONSET;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=add_string(line.gettoken_str(2));
- ent.offsets[2]=SECTION_FIELD_SET(size_kb);
- SCRIPT_MSG("SectionSetSize: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_SECTIONGETSIZE:
- ent.which=EW_SECTIONSET;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=GetUserVarIndex(line, 2);
- ent.offsets[2]=SECTION_FIELD_GET(size_kb);
- if (line.gettoken_str(2)[0] && ent.offsets[1]<0) PRINTHELP()
- SCRIPT_MSG("SectionGetSize: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
- return add_entry(&ent);
- case TOK_SETCURINSTTYPE:
- ent.which=EW_INSTTYPESET;
- ent.offsets[0]=add_string(line.gettoken_str(1));
- ent.offsets[1]=0;
- ent.offsets[2]=1;
- ent.offsets[3]=1;
- SCRIPT_MSG("SetCurInstType: %s\n",line.gettoken_str(1));
- return add_entry(&ent);
- case TOK_GETCURINSTTYPE:
- ent.which=EW_INSTTYPESET;
- ent.offsets[0]=0;
- ent.offsets[1]=GetUserVarIndex(line,1);
- ent.offsets[2]=0;
- ent.offsets[3]=1;
- if (line.gettoken_str(1)[0] && ent.offsets[0]<0) PRINTHELP()
- SCRIPT_MSG("GetCurInstType: %s\n",line.gettoken_str(1));
- return add_entry(&ent);
-#else//!NSIS_CONFIG_COMPONENTPAGE
- case TOK_SECTIONSETTEXT:
- case TOK_SECTIONGETTEXT:
- case TOK_SECTIONSETFLAGS:
- case TOK_SECTIONGETFLAGS:
- case TOK_SECTIONSETSIZE:
- case TOK_SECTIONGETSIZE:
- case TOK_SECTIONSETINSTTYPES:
- case TOK_SECTIONGETINSTTYPES:
- case TOK_SETCURINSTTYPE:
- case TOK_GETCURINSTTYPE:
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_COMPONENTPAGE not defined.\n", line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_CONFIG_COMPONENTPAGE
-#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
- case TOK_SETBRANDINGIMAGE:
- {
- SCRIPT_MSG("SetBrandingImage: ");
- if (!branding_image_found) {
- ERROR_MSG("\nError: no branding image found in chosen UI!\n");
- return PS_ERROR;
- }
- ent.which=EW_SETBRANDINGIMAGE;
- for (int i = 1; i < line.getnumtokens(); i++)
- if (!strnicmp(line.gettoken_str(i),"/IMGID=",7)) {
- ent.offsets[1]=atoi(line.gettoken_str(i)+7);
- SCRIPT_MSG("/IMGID=%d ",ent.offsets[1]);
- }
- else if (!stricmp(line.gettoken_str(i),"/RESIZETOFIT")) {
- ent.offsets[2]=1; // must be 1 or 0
- SCRIPT_MSG("/RESIZETOFIT ");
- }
- else if (!ent.offsets[0]) {
- ent.offsets[0]=add_string(line.gettoken_str(i));
- SCRIPT_MSG("\"%s\" ", line.gettoken_str(i));
- }
- else {
- SCRIPT_MSG("\n");
- PRINTHELP();
- }
-
- if (!ent.offsets[1])
- ent.offsets[1]=branding_image_id;
- SCRIPT_MSG("\n");
- }
- return add_entry(&ent);
-#else//NSIS_CONFIG_ENHANCEDUI_SUPPORT
- case TOK_SETBRANDINGIMAGE:
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_ENHANCEDUI_SUPPORT not defined.\n",line.gettoken_str(0));
- return PS_ERROR;
-#endif//!NSIS_SUPPORT_CREATEFONT
-
- // Added by ramon 3 jun 2003
- case TOK_DEFVAR:
- {
- int a=1;
-
- if (!strcmpi(line.gettoken_str(1),"/GLOBAL"))
- {
- a++;
- }
-
- if (build_cursection)
- {
- if (a==1)
- {
- ERROR_MSG("Var: currently, only global variables can be defined.\n");
- PRINTHELP();
- }
- }
-
- SCRIPT_MSG("Var: \"%s\"\n",line.gettoken_str(a));
-
- int res = DeclaredUserVar(line.gettoken_str(a));
- if (res != PS_OK)
- return res;
-
- }
- return PS_OK;
-
- // Added by ramon 6 jun 2003
-#ifdef NSIS_SUPPORT_VERSION_INFO
- case TOK_VI_ADDKEY:
- {
- LANGID LangID=0;
- int a = 1;
- if (!strnicmp(line.gettoken_str(a),"/LANG=",6))
- LangID=atoi(line.gettoken_str(a++)+6);
- if (line.getnumtokens()!=a+2) PRINTHELP();
- char *pKey = line.gettoken_str(a);
- char *pValue = line.gettoken_str(a+1);
- if ( !(*pKey) )
- {
- ERROR_MSG("Error: empty name for version info key!\n");
- return PS_ERROR;
- }
- else
- {
- SCRIPT_MSG("%s: \"%s\" \"%s\"\n", line.gettoken_str(0), line.gettoken_str(a), line.gettoken_str(a+1));
- LANGID lReaded = LangID;
- if ( a > 1 && lReaded == 0 )
- warning_fl("%s: %s language not loaded, using default \"1033-English\"", line.gettoken_str(0), line.gettoken_str(1));
-
- unsigned int codepage;
- char *lang_name = GetLangNameAndCP(LangID, &codepage);
-
- if ( rVersionInfo.SetKeyValue(LangID, codepage, pKey, pValue) )
- {
- ERROR_MSG("%s: \"%s\" \"%04d-%s\" already defined!\n",line.gettoken_str(0), line.gettoken_str(2), LangID, lang_name);
- return PS_ERROR;
- }
-
- return PS_OK;
- }
- }
- case TOK_VI_SETPRODUCTVERSION:
- if ( version_product_v[0] )
- {
- ERROR_MSG("Error: %s already defined!\n", line.gettoken_str(0));
- return PS_ERROR;
- }
- strcpy(version_product_v, line.gettoken_str(1));
- return PS_OK;
-
-#else
- case TOK_VI_ADDKEY:
- case TOK_VI_SETPRODUCTVERSION:
- ERROR_MSG("Error: %s specified, NSIS_SUPPORT_VERSION_INFO not defined.\n",line.gettoken_str(0));
- return PS_ERROR;
-#endif
-
- // end of instructions
- ///////////////////////////////////////////////////////////////////////////////
-
- // Added by Ximon Eighteen 5th August 2002
-#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
- case TOK_PLUGINDIR:
- {
- if (line.getnumtokens() == 2)
- {
- SCRIPT_MSG("PluginDir: \"%s\"\n",line.gettoken_str(1));
-#ifdef _WIN32
- m_plugins.FindCommands(line.gettoken_str(1), display_info?true:false);
-#else
- char *converted_path = my_convert(line.gettoken_str(1));
- m_plugins.FindCommands(converted_path, display_info?true:false);
- my_convert_free(converted_path);
-#endif
- return PS_OK;
- }
- }
- return PS_ERROR;
- case TOK__PLUGINCOMMAND:
- {
- int ret;
-
- const string command = m_plugins.NormalizedCommand(line.gettoken_str(0));
- const string dllPath = m_plugins.GetPluginPath(command);
- int data_handle = m_plugins.GetPluginHandle(uninstall_mode?true:false, command);
-
- if (uninstall_mode) uninst_plugin_used = true;
- else plugin_used = true;
-
- // Initialize $PLUGINSDIR
- ent.which=EW_CALL;
- ent.offsets[0]=ns_func.add(uninstall_mode?"un.Initialize_____Plugins":"Initialize_____Plugins",0);
- ret=add_entry(&ent);
- if (ret != PS_OK) {
- return ret;
- }
-
- // DLL name on the user machine
- char tempDLL[NSIS_MAX_STRLEN];
- string dllName = get_file_name(dllPath);
- wsprintf(tempDLL, "$PLUGINSDIR\\%s", dllName.c_str());
-
- // Add the DLL to the installer
- if (data_handle == -1)
- {
- int files_added;
- int old_build_allowskipfiles=build_allowskipfiles;
- build_allowskipfiles=1; // on
- int old_build_overwrite=build_overwrite;
- build_overwrite=1; // off
- int old_build_datesave=build_datesave;
- build_datesave=0; // off
- ret=do_add_file(dllPath.c_str(),0,0,&files_added,tempDLL,2,&data_handle); // 2 means no size add
- if (ret != PS_OK) {
- return ret;
- }
- m_plugins.SetDllDataHandle(uninstall_mode?true:false, line.gettoken_str(0), data_handle);
- build_overwrite=old_build_overwrite;
- build_datesave=old_build_datesave;
- // Added by ramon 23 May 2003
- build_allowskipfiles=old_build_allowskipfiles;
- }
- else
- {
- ent.which=EW_EXTRACTFILE;
-
- DefineInnerLangString(NLF_SKIPPED);
- DefineInnerLangString(NLF_ERR_DECOMPRESSING);
- DefineInnerLangString(NLF_ERR_WRITING);
- DefineInnerLangString(NLF_EXTRACT);
- DefineInnerLangString(NLF_CANT_WRITE);
-
- ent.offsets[0]=1; // overwrite off
- ent.offsets[0]|=(MB_RETRYCANCEL|MB_ICONSTOP|(IDCANCEL<<21))<<3;
- ent.offsets[1]=add_string(tempDLL);
- ent.offsets[2]=data_handle;
- ent.offsets[3]=0xffffffff;
- ent.offsets[4]=0xffffffff;
- ent.offsets[5]=DefineInnerLangString(NLF_FILE_ERROR);
- ret=add_entry(&ent);
- if (ret != PS_OK) {
- return ret;
- }
- }
-
- // SetDetailsPrint lastused
- ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1);
- if (ret != PS_OK) {
- return ret;
- }
-
- // Call the DLL
- string funcname = get_string_suffix(command, "::");
- SCRIPT_MSG("Plugin Command: %s",funcname.c_str());
-
- int i = 1;
- int nounload = 0;
- if (!strcmpi(line.gettoken_str(i), "/NOUNLOAD")) {
- i++;
- nounload++;
- }
-
- // First push dll args
-
- int parmst=i; // we push em in reverse order
- int nounloadmisused=0;
- for (; i < line.getnumtokens(); i++) {
- int w=parmst + (line.getnumtokens()-i - 1);
- ent.which=EW_PUSHPOP;
- ent.offsets[0]=add_string(line.gettoken_str(w));
- if (!strcmpi(line.gettoken_str(w), "/NOUNLOAD")) nounloadmisused=1;
- ent.offsets[1]=0;
- ent.offsets[2]=0;
- ret=add_entry(&ent);
- if (ret != PS_OK) {
- return ret;
- }
- SCRIPT_MSG(" %s",line.gettoken_str(i));
- }
- SCRIPT_MSG("\n");
- if (nounloadmisused)
- warning_fl("/NOUNLOAD must come first before any plugin parameter. Unless the plugin you are trying to use has a parameter /NOUNLOAD, you are doing something wrong");
-
- // next, call it
- ent.which=EW_REGISTERDLL;
- ent.offsets[0]=add_string(tempDLL);;
- ent.offsets[1]=add_string(funcname.c_str());
- ent.offsets[2]=0;
- ent.offsets[3]=nounload|build_plugin_unload;
- ent.offsets[4]=1;
- ret=add_entry(&ent);
- if (ret != PS_OK) {
- return ret;
- }
-
- DefineInnerLangString(NLF_SYMBOL_NOT_FOUND);
- DefineInnerLangString(NLF_COULD_NOT_LOAD);
- DefineInnerLangString(NLF_NO_OLE);
- // not used anywhere - DefineInnerLangString(NLF_ERR_REG_DLL);
-
- return PS_OK;
- }
- case TOK_INITPLUGINSDIR:
- {
- int ret;
- SCRIPT_MSG("%s\n",line.gettoken_str(0));
- if (uninstall_mode) uninst_plugin_used = true;
- else plugin_used = true;
- // Call [un.]Initialize_____Plugins
- ent.which=EW_CALL;
- ent.offsets[0]=ns_func.add(uninstall_mode?"un.Initialize_____Plugins":"Initialize_____Plugins",0);
- ret=add_entry(&ent);
- if (ret != PS_OK) return ret;
- // SetDetailsPrint lastused
- ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1);
- if (ret != PS_OK) return ret;
- }
- return PS_OK;
-#else
- case TOK_PLUGINDIR:
- case TOK__PLUGINCOMMAND:
- case TOK_INITPLUGINSDIR:
- {
- ERROR_MSG("Error: %s specified, NSIS_CONFIG_PLUGIN_SUPPORT not defined.\n",line.gettoken_str(0));
- }
- return PS_ERROR;
-#endif// NSIS_CONFIG_PLUGIN_SUPPORT
-
-#ifdef NSIS_LOCKWINDOW_SUPPORT
- case TOK_LOCKWINDOW:
- SCRIPT_MSG("LockWindow: lock state=%d\n",line.gettoken_str(1));
- ent.which=EW_LOCKWINDOW;
- ent.offsets[0]=line.gettoken_enum(1,"on\0off\0");
- if (ent.offsets[0] == -1)
- PRINTHELP();
- return add_entry(&ent);
-#else
- case TOK_LOCKWINDOW:
- {
- ERROR_MSG("Error: %s specified, NSIS_LOCKWINDOW_SUPPORT not defined.\n",line.gettoken_str(0));
- }
- return PS_ERROR;
-#endif // NSIS_LOCKWINDOW_SUPPORT
-
- default: break;
-
- }
- ERROR_MSG("Error: doCommand: Invalid token \"%s\".\n",line.gettoken_str(0));
- return PS_ERROR;
-}
-
-#ifdef NSIS_SUPPORT_FILE
-int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int *total_files, const char *name_override, int generatecode, int *data_handle, const set<string>& excluded, const string& basedir, bool dir_created)
-{
- assert(!name_override || !recurse);
-
- string dir = get_dir_name(lgss);
- string spec;
-
- if (dir == lgss) {
- dir = ".";
- spec = lgss;
- } else {
- spec = string(lgss).substr(dir.length() + 1, string::npos);
- }
-
- if (spec == "") {
- spec = "*";
- }
-
- if (basedir == "") {
- dir_created = true;
-
- if (recurse) {
- // save $OUTDIR into $_OUTDIR [StrCpy $_OUTDIR $OUTDIR]
- if (add_entry_direct(EW_ASSIGNVAR, m_UserVarNames.get("_OUTDIR"), add_string("$OUTDIR")) != PS_OK) {
- return PS_ERROR;
- }
- }
- }
-
- boost::scoped_ptr<dir_reader> dr( new_dir_reader() );
- dr->exclude(excluded);
- dr->read(dir);
-
- // add files in the current directory
- for (dir_reader::iterator files_itr = dr->files().begin();
- files_itr != dr->files().end();
- files_itr++)
- {
- if (!dir_reader::matches(*files_itr, spec))
- continue;
-
- if (!dir_created && generatecode) {
- SCRIPT_MSG("%sFile: Descending to: \"%s\"\n", generatecode ? "" : "Reserve", dir.c_str());
-
- if (do_add_file_create_dir(dir, basedir, attrib) != PS_OK) {
- return PS_ERROR;
- }
-
- dir_created = true;
- }
-
- if (add_file(dir, *files_itr, attrib, name_override, generatecode, data_handle) != PS_OK) {
- return PS_ERROR;
- }
-
- (*total_files)++;
- }
-
- if (!recurse) {
- return PS_OK;
- }
-
- // recurse into directories
- for (dir_reader::iterator dirs_itr = dr->dirs().begin();
- dirs_itr != dr->dirs().end();
- dirs_itr++)
- {
- string new_dir;
- bool created = false;
-
- if (basedir == "") {
- new_dir = *dirs_itr;
- } else {
- new_dir = basedir + '\\' + *dirs_itr;
- }
-
- string new_spec = dir + PLATFORM_PATH_SEPARATOR_STR + *dirs_itr + PLATFORM_PATH_SEPARATOR_STR;
-
- if (!dir_reader::matches(*dirs_itr, spec)) {
- new_spec += spec;
- } else if (generatecode) {
- // always create directories that match
-
- SCRIPT_MSG("%sFile: Descending to: \"%s\"\n", generatecode ? "" : "Reserve", new_spec.c_str());
-
- if (do_add_file_create_dir(dir + '\\' + *dirs_itr, new_dir, attrib) != PS_OK) {
- return PS_ERROR;
- }
-
- created = true;
- }
-
- const char *new_spec_c = new_spec.c_str();
-
- int res = do_add_file(new_spec_c, attrib, 1, total_files, NULL, generatecode, NULL, excluded, new_dir, created);
- if (res != PS_OK) {
- return PS_ERROR;
- }
- }
-
- if (basedir == "") {
- SCRIPT_MSG("%sFile: Returning to: \"%s\"\n", generatecode ? "" : "Reserve", dir.c_str());
-
- // restore $OUTDIR from $_OUTDIR [SetOutPath $_OUTDIR]
- if (add_entry_direct(EW_CREATEDIR, add_string("$_OUTDIR"), 1) != PS_OK) {
- return PS_ERROR;
- }
- }
-
- return PS_OK;
-}
-
-int CEXEBuild::add_file(const string& dir, const string& file, int attrib, const char *name_override, int generatecode, int *data_handle) {
- string newfn_s = dir + PLATFORM_PATH_SEPARATOR_C + file;
- const char *newfn = newfn_s.c_str();
- const char *filename = file.c_str();
-
- MMapFile mmap;
- DWORD len;
-
-#ifdef _WIN32
- HANDLE hFile = CreateFile(
- newfn,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL
- );
- if (hFile == INVALID_HANDLE_VALUE)
- {
- ERROR_MSG("%sFile: failed opening file \"%s\"\n",generatecode?"":"Reserve",newfn);
- return PS_ERROR;
- }
-
- // Will auto-CloseHandle hFile
- MANAGE_WITH(hFile, CloseHandle);
-
- len = GetFileSize(hFile, NULL);
- if (len && !mmap.setfile(hFile, len))
- {
- ERROR_MSG("%sFile: failed creating mmap of \"%s\"\n",generatecode?"":"Reserve",newfn);
- return PS_ERROR;
- }
-#else
- struct stat s;
- if (stat(newfn, &s)) {
- ERROR_MSG("%sFile: failed stating file \"%s\"\n",generatecode?"":"Reserve",newfn);
- return PS_ERROR;
- }
-
- len = (DWORD) s.st_size;
-
- int fd = OPEN(newfn, O_RDONLY);
- if (fd == -1)
- {
- ERROR_MSG("%sFile: failed opening file \"%s\"\n",generatecode?"":"Reserve",newfn);
- return PS_ERROR;
- }
-
- // Will auto-close(2) fd
- MANAGE_WITH(fd, close);
-
- if (len && !mmap.setfile(fd, len))
- {
- ERROR_MSG("%sFile: failed creating mmap of \"%s\"\n",generatecode?"":"Reserve",newfn);
- return PS_ERROR;
- }
-#endif
-
- if (generatecode&1)
- section_add_size_kb((len+1023)/1024);
- if (name_override) SCRIPT_MSG("%sFile: \"%s\"->\"%s\"",generatecode?"":"Reserve",filename,name_override);
- else SCRIPT_MSG("%sFile: \"%s\"",generatecode?"":"Reserve",filename);
- if (!build_compress_whole)
- if (build_compress) SCRIPT_MSG(" [compress]");
- fflush(stdout);
- char buf[1024];
- int last_build_datablock_used=getcurdbsize();
- entry ent={0,};
- if (generatecode)
- {
- ent.which=EW_EXTRACTFILE;
-
- DefineInnerLangString(NLF_SKIPPED);
- DefineInnerLangString(NLF_ERR_DECOMPRESSING);
- DefineInnerLangString(NLF_ERR_WRITING);
- DefineInnerLangString(NLF_EXTRACT);
- DefineInnerLangString(NLF_CANT_WRITE);
-
- ent.offsets[0]=build_overwrite;
- if (name_override)
- {
- ent.offsets[1]=add_string(name_override);
- }
- else
- {
- const char *i=filename;
- char *o=buf;
- while (*i)
- {
- const char c=*i++;
- *o++=c;
- if (c == '$') *o++='$';
- }
- *o=0;
- ent.offsets[1]=add_string(buf);
- }
- }
- ent.offsets[2]=add_db_data(&mmap);
-
- mmap.clear();
-
- if (ent.offsets[2] < 0)
- {
- return PS_ERROR;
- }
-
- if (data_handle)
- {
- *data_handle=ent.offsets[2];
- }
-
- {
- DWORD s=getcurdbsize()-last_build_datablock_used;
- if (s) s-=4;
- if (s != len) SCRIPT_MSG(" %d/%d bytes\n",s,len);
- else SCRIPT_MSG(" %d bytes\n",len);
- }
-
- if (generatecode)
- {
- if (build_datesave || build_overwrite>=0x3 /*ifnewer or ifdiff*/)
- {
-#ifdef _WIN32
- FILETIME ft;
- if (GetFileTime(hFile,NULL,NULL,&ft))
- {
- // FAT write time has a resolution of 2 seconds
- PULONGLONG fti = (PULONGLONG) &ft;
- *fti -= *fti % 20000000;
-
- ent.offsets[3]=ft.dwLowDateTime;
- ent.offsets[4]=ft.dwHighDateTime;
- }
-#else
- struct stat st;
- if (!fstat(fd, &st))
- {
- unsigned long long ll = (st.st_mtime * 10000000LL) + 116444736000000000LL;
-
- // FAT write time has a resolution of 2 seconds
- ll -= ll % 20000000;
-
- ent.offsets[3] = (int) ll;
- ent.offsets[4] = (int) (ll >> 32);
- }
-#endif
- else
- {
- ERROR_MSG("%sFile: failed getting file date from \"%s\"\n",generatecode?"":"Reserve",newfn);
- return PS_ERROR;
- }
- }
- else
- {
- ent.offsets[3]=0xffffffff;
- ent.offsets[4]=0xffffffff;
- }
-
- // overwrite flag can be 0, 1, 2 or 3. in all cases, 2 bits
- int mb = 0;
- if (build_allowskipfiles)
- {
- mb = MB_ABORTRETRYIGNORE | MB_ICONSTOP;
- // default for silent installers
- mb |= IDIGNORE << 21;
- }
- else
- {
- mb = MB_RETRYCANCEL | MB_ICONSTOP;
- // default for silent installers
- mb |= IDCANCEL << 21;
- }
- ent.offsets[0] |= mb << 3;
-
- ent.offsets[5] = DefineInnerLangString(build_allowskipfiles ? NLF_FILE_ERROR : NLF_FILE_ERROR_NOIGNORE);
- }
-
- if (generatecode)
- {
- int a=add_entry(&ent);
- if (a != PS_OK)
- {
- return a;
- }
- if (attrib)
- {
-#ifdef _WIN32
- ent.which=EW_SETFILEATTRIBUTES;
- // $OUTDIR is the working directory
- ent.offsets[0]=add_string(name_override?name_override:buf);
- ent.offsets[1]=GetFileAttributes(newfn);
- ent.offsets[2]=0;
- ent.offsets[3]=0;
- ent.offsets[4]=0;
- ent.offsets[5]=0;
-
- if (ent.offsets[1] != INVALID_FILE_ATTRIBUTES)
- {
- a=add_entry(&ent);
- if (a != PS_OK)
- {
- return a;
- }
- }
-#endif
- }
- }
-
- return PS_OK;
-}
-
-int CEXEBuild::do_add_file_create_dir(const string& local_dir, const string& dir, int attrib) {
- string outdir_s = "$_OUTDIR\\" + dir;
-
- string::size_type pos = 1;
- pos = outdir_s.find('$', pos);
- while (pos != string::npos) {
- outdir_s = outdir_s.insert(pos, "$");
- pos = outdir_s.find('$', pos + 2);
- }
-
- int outdir = add_string(outdir_s.c_str());
-
- if (add_entry_direct(EW_CREATEDIR, outdir, 1) != PS_OK) {
- return PS_ERROR;
- }
-
-#ifdef _WIN32
- if (attrib) {
- int ndc = add_string(".");
-
- DWORD attr = GetFileAttributes(local_dir.c_str());
-
- if (attr != INVALID_FILE_ATTRIBUTES)
- {
- if (add_entry_direct(EW_SETFILEATTRIBUTES, ndc, attr) != PS_OK)
- {
- return PS_ERROR;
- }
- }
- }
-#endif
-
- return PS_OK;
-}
-#endif
+/*
+ * script.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+#include <stdio.h>
+#include <ctype.h>
+#include "tokens.h"
+#include "build.h"
+#include "util.h"
+#include "winchar.h"
+#include "ResourceEditor.h"
+#include "DialogTemplate.h"
+#include "lang.h"
+#include "dirreader.h"
+#include "version.h"
+#include "icon.h"
+#include "exehead/resource.h"
+#include <cassert> // for assert(3)
+#include <time.h>
+#include <string>
+#include <algorithm>
+#include "boost/scoped_ptr.hpp"
+
+using namespace std;
+
+#ifdef _WIN32
+# include <direct.h> // for chdir
+#else
+# include <sys/stat.h> // for stat and umask
+# include <sys/types.h> // for mode_t
+# include <fcntl.h> // for O_RDONLY
+# include <unistd.h>
+# include <stdlib.h> // for mkstemp
+#endif
+
+#define MAX_INCLUDEDEPTH 10
+#define MAX_LINELENGTH 16384
+
+#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
+// Added by Sunil Kamath 11 June 2003
+char *CEXEBuild::set_file_predefine(char *filename)
+{
+ char *oldfilename = definedlist.find("__FILE__");
+ if(oldfilename)
+ {
+ oldfilename = strdup(oldfilename);
+ definedlist.del("__FILE__");
+ }
+ char *p = strrchr(filename,'\\');
+ if(p) {
+ p++;
+ }
+ else {
+ p = curfilename;
+ }
+ definedlist.add("__FILE__",p);
+
+ return oldfilename;
+}
+
+void CEXEBuild::restore_file_predefine(char *oldfilename)
+{
+ definedlist.del("__FILE__");
+ if(oldfilename) {
+ definedlist.add("__FILE__",oldfilename);
+ free(oldfilename);
+ }
+}
+
+char *CEXEBuild::set_timestamp_predefine(char *filename)
+{
+ char *oldtimestamp = definedlist.find("__TIMESTAMP__");
+ if(oldtimestamp) {
+ oldtimestamp = strdup(oldtimestamp);
+ definedlist.del("__TIMESTAMP__");
+ }
+
+#ifdef _WIN32
+ char timestampbuf[256] = "";
+ char datebuf[128] = "";
+ char timebuf[128] = "";
+ WIN32_FIND_DATA fd;
+ FILETIME floctime;
+ SYSTEMTIME stime;
+
+ HANDLE hSearch = FindFirstFile(filename, &fd);
+ if (hSearch != INVALID_HANDLE_VALUE)
+ {
+ FindClose(hSearch);
+
+ FileTimeToLocalFileTime(&fd.ftLastWriteTime, &floctime);
+ FileTimeToSystemTime(&floctime, &stime);
+
+ GetDateFormat(LOCALE_USER_DEFAULT, DATE_LONGDATE, &stime, NULL, datebuf, sizeof(datebuf));
+ GetTimeFormat(LOCALE_USER_DEFAULT, 0, &stime, NULL, timebuf, sizeof(timebuf));
+ wsprintf(timestampbuf,"%s %s",datebuf,timebuf);
+
+ definedlist.add("__TIMESTAMP__",timestampbuf);
+ }
+#else
+ struct stat st;
+ if (!stat(filename, &st))
+ definedlist.add("__TIMESTAMP__",ctime(&st.st_mtime));
+#endif
+
+ return oldtimestamp;
+}
+
+void CEXEBuild::restore_timestamp_predefine(char *oldtimestamp)
+{
+ definedlist.del("__TIMESTAMP__");
+ if(oldtimestamp) {
+ definedlist.add("__TIMESTAMP__",oldtimestamp);
+ free(oldtimestamp);
+ }
+}
+
+char *CEXEBuild::set_line_predefine(int linecnt, BOOL is_macro)
+{
+ char* linebuf = NULL;
+ MANAGE_WITH(linebuf, free);
+
+ char temp[128] = "";
+ sprintf(temp,"%d",linecnt);
+
+ char *oldline = definedlist.find("__LINE__");
+ if(oldline) {
+ oldline = strdup(oldline);
+ definedlist.del("__LINE__");
+ }
+ if(is_macro && oldline) {
+ linebuf = (char *)malloc(strlen(oldline)+strlen(temp)+2);
+ sprintf(linebuf,"%s.%s",oldline,temp);
+ }
+ else {
+ linebuf = strdup(temp);
+ }
+ definedlist.add("__LINE__",linebuf);
+
+ return oldline;
+}
+
+void CEXEBuild::restore_line_predefine(char *oldline)
+{
+ definedlist.del("__LINE__");
+ if(oldline) {
+ definedlist.add("__LINE__",oldline);
+ free(oldline);
+ }
+}
+
+void CEXEBuild::set_date_time_predefines()
+{
+ time_t etime;
+ struct tm * ltime;
+ char datebuf[128];
+ char timebuf[128];
+
+ time(&etime);
+ ltime = localtime(&etime);
+#ifdef _WIN32
+ SYSTEMTIME stime;
+ stime.wYear = ltime->tm_year+1900;
+ stime.wMonth = ltime->tm_mon + 1;
+ stime.wDay = ltime->tm_mday;
+ stime.wHour= ltime->tm_hour;
+ stime.wMinute= ltime->tm_min;
+ stime.wSecond= ltime->tm_sec;
+ stime.wMilliseconds= 0;
+ GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stime, NULL, datebuf, sizeof(datebuf));
+ definedlist.add("__DATE__",(char *)datebuf);
+ GetTimeFormat(LOCALE_USER_DEFAULT, 0, &stime, NULL, timebuf, sizeof(timebuf));
+ definedlist.add("__TIME__",(char *)timebuf);
+#else
+ my_strftime(datebuf, sizeof(datebuf), "%x", ltime);
+ definedlist.add("__DATE__",(char *)datebuf);
+ my_strftime(timebuf, sizeof(timebuf), "%X", ltime);
+ definedlist.add("__TIME__",(char *)timebuf);
+#endif
+}
+
+void CEXEBuild::del_date_time_predefines()
+{
+ definedlist.del("__DATE__");
+ definedlist.del("__TIME__");
+}
+#endif
+
+int CEXEBuild::process_script(FILE *filepointer, char *filename)
+{
+ linecnt = 0;
+ fp = filepointer;
+ curfilename = filename;
+
+ if (has_called_write_output)
+ {
+ ERROR_MSG("Error (process_script): write_output already called, can't continue\n");
+ return PS_ERROR;
+ }
+
+#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
+ // Added by Sunil Kamath 11 June 2003
+ set_date_time_predefines();
+ char *oldfilename = set_file_predefine(curfilename);
+ char *oldtimestamp = set_timestamp_predefine(curfilename);
+#endif
+
+ int ret=parseScript();
+
+#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
+ // Added by Sunil Kamath 11 June 2003
+ restore_file_predefine(oldfilename);
+ restore_timestamp_predefine(oldtimestamp);
+ del_date_time_predefines();
+#endif
+
+ fp = 0;
+ curfilename = 0;
+
+ if (m_linebuild.getlen())
+ {
+ ERROR_MSG("Error: invalid script: last line ended with \\\n");
+ return PS_ERROR;
+ }
+
+ if (ret == PS_EOF && num_ifblock())
+ {
+ ERROR_MSG("!if[macro][n]def: open at EOF - need !endif\n");
+ return PS_ERROR;
+ }
+
+ return ret;
+}
+
+#define PRINTHELP() { print_help(line.gettoken_str(0)); return PS_ERROR; }
+
+void CEXEBuild::start_ifblock()
+{
+ ifblock ib = {0, };
+ if (cur_ifblock)
+ ib.inherited_ignore = cur_ifblock->ignore || cur_ifblock->inherited_ignore;
+ int num = build_preprocessor_data.getlen() / sizeof(ifblock);
+ build_preprocessor_data.add(&ib, sizeof(ifblock));
+ cur_ifblock = (ifblock *) build_preprocessor_data.get() + num;
+}
+
+void CEXEBuild::end_ifblock()
+{
+ if (build_preprocessor_data.getlen())
+ {
+ cur_ifblock--;
+ build_preprocessor_data.resize(build_preprocessor_data.getlen() - sizeof(ifblock));
+ if (!build_preprocessor_data.getlen())
+ cur_ifblock = 0;
+ }
+}
+
+int CEXEBuild::num_ifblock()
+{
+ return build_preprocessor_data.getlen() / sizeof(ifblock);
+}
+
+// Func size: just under 200 lines (orip)
+int CEXEBuild::doParse(const char *str)
+{
+ LineParser line(inside_comment);
+ int res;
+
+ while (*str == ' ' || *str == '\t') str++;
+
+ // remove trailing slash and null, if there's a previous line
+ if (m_linebuild.getlen()>1)
+ m_linebuild.resize(m_linebuild.getlen()-2);
+
+ m_linebuild.add(str,strlen(str)+1);
+
+ // keep waiting for more lines, if this line ends with a backslash
+ if (str[0] && CharPrev(str,str+strlen(str))[0] == '\\')
+ {
+ line.parse((char*)m_linebuild.get());
+ if (line.inComment())
+ {
+ warning_fl("comment contains line-continuation character, following line will be ignored");
+ }
+ return PS_OK;
+ }
+
+ // parse before checking if the line should be ignored, so block comments won't be missed
+
+ // escaped quotes should be ignored for compile time commands that set defines
+ // because defines can be inserted in commands at a later stage
+ bool ignore_escaping = (!strnicmp((char*)m_linebuild.get(),"!define",7) || !strnicmp((char*)m_linebuild.get(),"!insertmacro",12));
+ res=line.parse((char*)m_linebuild.get(), ignore_escaping);
+
+ inside_comment = line.inCommentBlock();
+
+ // if ignoring, ignore all lines that don't begin with an exclamation mark
+ {
+ bool ignore_line = cur_ifblock && (cur_ifblock->ignore || cur_ifblock->inherited_ignore);
+ char first_char = *(char *) m_linebuild.get();
+ if (ignore_line && (first_char!='!' || !is_valid_token(line.gettoken_str(0))))
+ {
+ m_linebuild.resize(0);
+ return PS_OK;
+ }
+ }
+
+ m_linebuild.resize(0);
+
+ if (res)
+ {
+ if (res==-2) ERROR_MSG("Error: unterminated string parsing line at %s:%d\n",curfilename,linecnt);
+ else ERROR_MSG("Error: error parsing line (%s:%d)\n",curfilename,linecnt);
+ return PS_ERROR;
+ }
+
+parse_again:
+ if (line.getnumtokens() < 1) return PS_OK;
+
+ int np,op,pos;
+ int tkid=get_commandtoken(line.gettoken_str(0),&np,&op,&pos);
+ if (tkid == -1)
+ {
+ char *p=line.gettoken_str(0);
+ if (p[0] && p[strlen(p)-1]==':')
+ {
+ if (p[0] == '!' || (p[0] >= '0' && p[0] <= '9') || p[0] == '$' || p[0] == '-' || p[0] == '+')
+ {
+ ERROR_MSG("Invalid label: %s (labels cannot begin with !, $, -, +, or 0-9)\n",line.gettoken_str(0));
+ return PS_ERROR;
+ }
+ if (add_label(line.gettoken_str(0))) return PS_ERROR;
+ line.eattoken();
+ goto parse_again;
+ }
+
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+ // Added by Ximon Eighteen 5th August 2002
+ // We didn't recognise this command, could it be the name of a
+ // function exported from a dll?
+ if (m_plugins.IsPluginCommand(line.gettoken_str(0)))
+ {
+ np = 0; // parameters are optional
+ op = -1; // unlimited number of optional parameters
+ pos = -1; // placement will tested later
+ tkid = TOK__PLUGINCOMMAND;
+ }
+ else
+#endif
+ {
+ ERROR_MSG("Invalid command: %s\n",line.gettoken_str(0));
+ return PS_ERROR;
+ }
+ }
+
+ if (IsTokenPlacedRight(pos, line.gettoken_str(0)) != PS_OK)
+ return PS_ERROR;
+
+ int v=line.getnumtokens()-(np+1);
+ if (v < 0 || (op >= 0 && v > op)) // opt_parms is -1 for unlimited
+ {
+ ERROR_MSG("%s expects %d",line.gettoken_str(0),np);
+ if (op < 0) ERROR_MSG("+");
+ if (op > 0) ERROR_MSG("-%d",op+np);
+ ERROR_MSG(" parameters, got %d.\n",line.getnumtokens()-1);
+ PRINTHELP()
+ }
+
+ int if_from_else = 0;
+
+ if (tkid == TOK_P_ELSE)
+ {
+ if (cur_ifblock && cur_ifblock->inherited_ignore)
+ return PS_OK;
+
+ if (!num_ifblock())
+ {
+ ERROR_MSG("!else: no if block open (!if[macro][n][def])\n");
+ return PS_ERROR;
+ }
+
+ if (cur_ifblock->elseused)
+ {
+ ERROR_MSG("!else: else already used in current if block\n");
+ return PS_ERROR;
+ }
+
+ if (cur_ifblock->hasexeced)
+ {
+ cur_ifblock->ignore++;
+ return PS_OK;
+ }
+
+ if (line.getnumtokens() == 1)
+ {
+ cur_ifblock->ignore = !cur_ifblock->ignore;
+ // if not executed up until now, it will now
+ cur_ifblock->hasexeced++;
+ cur_ifblock->elseused++;
+ return PS_OK;
+ }
+
+ line.eattoken();
+
+ int v=line.gettoken_enum(0,"if\0ifdef\0ifndef\0ifmacrodef\0ifmacrondef\0");
+ if (v < 0) PRINTHELP()
+ if (line.getnumtokens() == 1) PRINTHELP()
+ int cmds[] = {TOK_P_IF, TOK_P_IFDEF, TOK_P_IFNDEF, TOK_P_IFMACRODEF, TOK_P_IFMACRONDEF};
+ tkid = cmds[v];
+ if_from_else++;
+ }
+
+ if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFDEF ||
+ tkid == TOK_P_IFMACRODEF || tkid == TOK_P_IFMACRONDEF ||
+ tkid == TOK_P_IF)
+ {
+ if (!if_from_else)
+ start_ifblock();
+
+ if (cur_ifblock && cur_ifblock->inherited_ignore)
+ {
+ return PS_OK;
+ }
+
+ int istrue=0;
+
+ int mod=0;
+
+ int p=0;
+
+ if (tkid == TOK_P_IF) {
+ if(!strcmp(line.gettoken_str(1),"!")) {
+ p = 1;
+ line.eattoken();
+ }
+
+ if(line.getnumtokens() == 2)
+ istrue = line.gettoken_int(1);
+
+ else if (line.getnumtokens() == 4) {
+ mod = line.gettoken_enum(2,"=\0==\0!=\0<=\0<\0>\0>=\0&\0&&\0|\0||\0");
+
+ switch(mod) {
+ case 0:
+ case 1:
+ istrue = stricmp(line.gettoken_str(1),line.gettoken_str(3)) == 0; break;
+ case 2:
+ istrue = stricmp(line.gettoken_str(1),line.gettoken_str(3)) != 0; break;
+ case 3:
+ istrue = line.gettoken_float(1) <= line.gettoken_float(3); break;
+ case 4:
+ istrue = line.gettoken_float(1) < line.gettoken_float(3); break;
+ case 5:
+ istrue = line.gettoken_float(1) > line.gettoken_float(3); break;
+ case 6:
+ istrue = line.gettoken_float(1) >= line.gettoken_float(3); break;
+ case 7:
+ case 8:
+ istrue = line.gettoken_int(1) && line.gettoken_int(3); break;
+ case 9:
+ case 10:
+ istrue = line.gettoken_int(1) || line.gettoken_int(3); break;
+ default:
+ PRINTHELP()
+ }
+ }
+ else PRINTHELP()
+
+ if(p) istrue = !istrue;
+ }
+
+ else {
+
+ // pure left to right precedence. Not too powerful, but useful.
+ for (p = 1; p < line.getnumtokens(); p ++)
+ {
+ if (p & 1)
+ {
+ int new_s;
+ if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFDEF)
+ new_s=!!definedlist.find(line.gettoken_str(p));
+ else
+ new_s=MacroExists(line.gettoken_str(p));
+ if (tkid == TOK_P_IFNDEF || tkid == TOK_P_IFMACRONDEF)
+ new_s=!new_s;
+
+ if (mod == 0) istrue = istrue || new_s;
+ else istrue = istrue && new_s;
+ }
+ else
+ {
+ mod=line.gettoken_enum(p,"|\0&\0||\0&&\0");
+ if (mod == -1) PRINTHELP()
+ mod &= 1;
+ }
+ }
+ }
+
+ if (istrue)
+ {
+ cur_ifblock->hasexeced++;
+ cur_ifblock->ignore = 0;
+ }
+ else
+ cur_ifblock->ignore++;
+
+ return PS_OK;
+ }
+ if (tkid == TOK_P_ENDIF) {
+ if (!num_ifblock())
+ {
+ ERROR_MSG("!endif: no if block open (!if[macro][n][def])\n");
+ return PS_ERROR;
+ }
+ end_ifblock();
+ return PS_OK;
+ }
+ if (!cur_ifblock || (!cur_ifblock->ignore && !cur_ifblock->inherited_ignore))
+ {
+ return doCommand(tkid,line);
+ }
+
+ return PS_OK;
+}
+
+// Func size: about 140 lines (orip)
+#ifdef NSIS_FIX_DEFINES_IN_STRINGS
+void CEXEBuild::ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist, bool bIgnoreDefines /*= false*/)
+#else
+void CEXEBuild::ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist)
+#endif
+{
+ // convert $\r, $\n to their literals
+ // preprocessor replace ${VAR} and $%VAR% with whatever value
+ // note that if VAR does not exist, ${VAR} or $%VAR% will go through unmodified
+ const char *in=str;
+ while (*in)
+ {
+ int add=1;
+ char *t;
+ char c=*in;
+ t=CharNext(in);
+
+ if (t-in > 1) // handle multibyte chars (no escape)
+ {
+ linedata.add((void*)in,t-in);
+ in=t;
+ continue;
+ }
+ in=t;
+
+ if (c == '$')
+ {
+ if (in[0] == '\\')
+ {
+ if (in[1] == 'r')
+ {
+ in+=2;
+ c='\r';
+ }
+ else if (in[1] == 'n')
+ {
+ in+=2;
+ c='\n';
+ }
+ else if (in[1] == 't')
+ {
+ in+=2;
+ c='\t';
+ }
+ }
+ else if (in[0] == '{')
+ {
+ char *s=strdup(in+1);
+ MANAGE_WITH(s, free);
+ char *t=s;
+ unsigned int bn = 0;
+ while (*t)
+ {
+ if (*t == '{') bn++;
+ if (*t == '}' && bn-- == 0) break;
+ t=CharNext(t);
+ }
+ if (*t && t!=s
+#ifdef NSIS_FIX_DEFINES_IN_STRINGS
+ && !bIgnoreDefines
+#endif
+ )
+ {
+ *t=0;
+ // check for defines inside the define name - ${bla${blo}}
+ GrowBuf defname;
+ ps_addtoline(s,defname,hist);
+ defname.add("",1);
+ t=definedlist.find((char*)defname.get());
+ if (t && hist.find((char*)defname.get(),0)<0)
+ {
+ in+=strlen(s)+2;
+ add=0;
+ hist.add((char*)defname.get(),0);
+#ifdef NSIS_FIX_DEFINES_IN_STRINGS
+ ps_addtoline(t,linedata,hist,true);
+#else
+ ps_addtoline(t,linedata,hist);
+#endif
+ hist.delbypos(hist.find((char*)defname.get(),0));
+ }
+ }
+ }
+ else if (in[0] == '%')
+ {
+ char *s=strdup(in+1);
+ MANAGE_WITH(s, free);
+ char *t=s;
+ while (*t)
+ {
+ if (*t == '%') break;
+ t=CharNext(t);
+ }
+ if (*t && t!=s)
+ {
+ *t=0;
+ // check for defines inside the define name - ${bla${blo}}
+ GrowBuf defname;
+ ps_addtoline(s,defname,hist);
+ defname.add("",1);
+ t=getenv((char*)defname.get());
+ if (t && hist.find((char*)defname.get(),0)<0)
+ {
+ in+=strlen(s)+2;
+ add=0;
+ hist.add((char*)defname.get(),0);
+#ifdef NSIS_FIX_DEFINES_IN_STRINGS
+ ps_addtoline(t,linedata,hist,true);
+#else
+ ps_addtoline(t,linedata,hist);
+#endif
+ hist.delbypos(hist.find((char*)defname.get(),0));
+ }
+ }
+ }
+#ifdef NSIS_FIX_DEFINES_IN_STRINGS
+ else if (in[0] == '$')
+ {
+ if (in[1] == '{') // Found $$ before - Don't replace this define
+ {
+ char *s=strdup(in+2);
+ MANAGE_WITH(s, free);
+ char *t=s;
+ unsigned int bn = 0;
+ while (*t)
+ {
+ if (*t == '{') bn++;
+ if (*t == '}' && bn-- == 0) break;
+ t=CharNext(t);
+ }
+ if (*t && t!=s)
+ {
+ *t=0;
+ // add text unchanged
+ GrowBuf defname;
+ ps_addtoline(s,defname,hist);
+ in++;
+ }
+ }
+ else
+ {
+ linedata.add((void*)&c,1);
+ in++;
+ }
+ }
+#endif
+ }
+ if (add) linedata.add((void*)&c,1);
+ }
+}
+
+int CEXEBuild::parseScript()
+{
+ char str[MAX_LINELENGTH];
+
+ for (;;)
+ {
+ char *p=str;
+ *p=0;
+ fgets(str,MAX_LINELENGTH,fp);
+ linecnt++;
+ if (feof(fp)&&!str[0]) break;
+
+ // remove trailing whitespace
+ while (*p) p++;
+ if (p > str) p--;
+ while (p >= str && (*p == '\r' || *p == '\n' || *p == ' ' || *p == '\t')) p--;
+ *++p=0;
+
+ StringList hist;
+ GrowBuf linedata;
+
+#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
+ // Added by Sunil Kamath 11 June 2003
+ char *oldline = set_line_predefine(linecnt, FALSE);
+#endif
+
+ ps_addtoline(str,linedata,hist);
+ linedata.add((void*)"",1);
+ int ret=doParse((char*)linedata.get());
+
+#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
+ // Added by Sunil Kamath 11 June 2003
+ restore_line_predefine(oldline);
+#endif
+
+ if (ret != PS_OK) return ret;
+ }
+
+ return PS_EOF;
+}
+
+int CEXEBuild::includeScript(char *f)
+{
+ SCRIPT_MSG("!include: \"%s\"\n",f);
+ FILE *incfp=FOPEN(f,"rt");
+ if (!incfp)
+ {
+ ERROR_MSG("!include: could not open file: \"%s\"\n",f);
+ return PS_ERROR;
+ }
+
+ // auto-fclose(3) incfp
+ MANAGE_WITH(incfp, fclose);
+
+ if (build_include_depth >= MAX_INCLUDEDEPTH)
+ {
+ ERROR_MSG("parseScript: too many levels of includes (%d max).\n",MAX_INCLUDEDEPTH);
+ return PS_ERROR;
+ }
+ build_include_depth++;
+
+ int last_linecnt=linecnt;
+ linecnt=0;
+ char *last_filename=curfilename;
+ curfilename=f;
+ FILE *last_fp=fp;
+ fp=incfp;
+
+#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
+ // Added by Sunil Kamath 11 June 2003
+ char *oldfilename = set_file_predefine(curfilename);
+ char *oldtimestamp = set_timestamp_predefine(curfilename);
+#endif
+
+ int r=parseScript();
+
+#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
+ // Added by Sunil Kamath 11 June 2003
+ restore_file_predefine(oldfilename);
+ restore_timestamp_predefine(oldtimestamp);
+#endif
+
+ int errlinecnt=linecnt;
+
+ linecnt=last_linecnt;
+ curfilename=last_filename;
+ fp=last_fp;
+
+ build_include_depth--;
+ if (r != PS_EOF && r != PS_OK)
+ {
+ ERROR_MSG("!include: error in script: \"%s\" on line %d\n",f,errlinecnt);
+ return PS_ERROR;
+ }
+ SCRIPT_MSG("!include: closed: \"%s\"\n",f);
+ return PS_OK;
+}
+
+// !ifmacro[n]def based on Anders Kjersem's code
+int CEXEBuild::MacroExists(const char *macroname)
+{
+ char *m = (char *) m_macros.get();
+
+ while (m && *m)
+ {
+ // check if macroname matches
+ if (!stricmp(m, macroname))
+ return 1;
+
+ // skip macro name
+ m += strlen(m) + 1;
+
+ // skip params
+ while (*m) m += strlen(m) + 1;
+ m++;
+
+ // skip data
+ while (*m) m += strlen(m) + 1;
+ if (m - (char *) m_macros.get() >= m_macros.getlen() - 1) break;
+ m++;
+ }
+ return 0;
+}
+
+int CEXEBuild::process_oneline(char *line, char *filename, int linenum)
+{
+ char *last_filename=curfilename;
+ curfilename=filename;
+ int last_linecnt=linecnt;
+ linecnt=linenum;
+
+ StringList hist;
+ GrowBuf linedata;
+
+#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
+ // Added by Sunil Kamath 11 June 2003
+ char *oldfilename = NULL;
+ char *oldtimestamp = NULL;
+ char *oldline = NULL;
+ BOOL is_commandline = !strcmp(filename,"command line");
+ BOOL is_macro = !strncmp(filename,"macro:",strlen("macro:"));
+
+ if(!is_commandline) { // Don't set the predefines for command line /X option
+ if(!is_macro) {
+ oldfilename = set_file_predefine(curfilename);
+ oldtimestamp = set_timestamp_predefine(curfilename);
+ }
+ oldline = set_line_predefine(linecnt, is_macro);
+ }
+#endif
+
+ ps_addtoline(line,linedata,hist);
+ linedata.add((void*)"",1);
+ int ret=doParse((char*)linedata.get());
+
+#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
+ // Added by Sunil Kamath 11 June 2003
+ if(!is_commandline) { // Don't set the predefines for command line /X option
+ if(!is_macro) {
+ restore_file_predefine(oldfilename);
+ restore_timestamp_predefine(oldtimestamp);
+ }
+ restore_line_predefine(oldline);
+ }
+#endif
+
+ linecnt=last_linecnt;
+ curfilename=last_filename;
+
+ return ret;
+}
+
+int CEXEBuild::process_jump(LineParser &line, int wt, int *offs)
+{
+ const char *s=line.gettoken_str(wt);
+ int v;
+
+ if (!stricmp(s,"0") || !stricmp(s,"")) *offs=0;
+ else if ((v=GetUserVarIndex(line, wt))>=0)
+ {
+ *offs=-v-1; // to jump to a user variable target, -variable_index-1 is stored.
+ }
+ else
+ {
+ if ((s[0] == '-' || s[0] == '+') && !atoi(s+1))
+ {
+ ERROR_MSG("Error: Goto targets beginning with '+' or '-' must be followed by nonzero integer (relative jump)\n");
+ return 1;
+ }
+ if ((s[0] >= '0' && s[0] <= '9') || s[0] == '$' || s[0] == '!')
+ {
+ ERROR_MSG("Error: Goto targets cannot begin with 0-9, $, !\n");
+ return 1;
+ }
+ *offs=ns_label.add(s,0);
+ }
+ return 0;
+}
+
+#define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags, flag)/sizeof(int))
+#define SECTION_FIELD_GET(field) (FIELD_OFFSET(section, field)/sizeof(int))
+#define SECTION_FIELD_SET(field) (-1 - (int)(FIELD_OFFSET(section, field)/sizeof(int)))
+
+// Func size: about 5000 lines (orip)
+int CEXEBuild::doCommand(int which_token, LineParser &line)
+{
+ static const char *rootkeys[2] = {
+ "HKCR\0HKLM\0HKCU\0HKU\0HKCC\0HKDD\0HKPD\0SHCTX\0",
+ "HKEY_CLASSES_ROOT\0HKEY_LOCAL_MACHINE\0HKEY_CURRENT_USER\0HKEY_USERS\0HKEY_CURRENT_CONFIG\0HKEY_DYN_DATA\0HKEY_PERFORMANCE_DATA\0SHELL_CONTEXT\0"
+ };
+ static HKEY rootkey_tab[] = {
+ HKEY_CLASSES_ROOT,HKEY_LOCAL_MACHINE,HKEY_CURRENT_USER,HKEY_USERS,HKEY_CURRENT_CONFIG,HKEY_DYN_DATA,HKEY_PERFORMANCE_DATA,0
+ };
+
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+ build_plugin_table();
+#endif
+
+ multiple_entries_instruction=0;
+
+ entry ent={0,};
+ switch (which_token)
+ {
+ // macro shit
+ ///////////////////////////////////////////////////////////////////////////////
+ case TOK_P_MACRO:
+ {
+ if (!line.gettoken_str(1)[0]) PRINTHELP()
+ char *t=(char *)m_macros.get();
+ while (t && *t)
+ {
+ if (!stricmp(t,line.gettoken_str(1))) break;
+ t+=strlen(t)+1;
+
+ // advance over parameters
+ while (*t) t+=strlen(t)+1;
+ t++;
+
+ // advance over data
+ while (*t) t+=strlen(t)+1;
+ if (t-(char *)m_macros.get() >= m_macros.getlen()-1)
+ break;
+ t++;
+ }
+ if (t && *t)
+ {
+ ERROR_MSG("!macro: macro named \"%s\" already found!\n",line.gettoken_str(1));
+ return PS_ERROR;
+ }
+ m_macros.add(line.gettoken_str(1),strlen(line.gettoken_str(1))+1);
+
+ int pc;
+ for (pc=2; pc < line.getnumtokens(); pc ++)
+ {
+ if (!line.gettoken_str(pc)[0])
+ {
+ ERROR_MSG("!macro: macro parameter %d is empty, not valid!\n",pc-1);
+ return PS_ERROR;
+ }
+ int a;
+ for (a=2; a < pc; a ++)
+ {
+ if (!stricmp(line.gettoken_str(pc),line.gettoken_str(a)))
+ {
+ ERROR_MSG("!macro: macro parameter named %s is used multiple times!\n",
+ line.gettoken_str(pc));
+ return PS_ERROR;
+ }
+ }
+ m_macros.add(line.gettoken_str(pc),strlen(line.gettoken_str(pc))+1);
+ }
+ m_macros.add("",1);
+
+ for (;;)
+ {
+ char str[MAX_LINELENGTH];
+ char *p=str;
+ str[0]=0;
+ fgets(str,MAX_LINELENGTH,fp);
+ //SCRIPT_MSG("%s%s", str, str[strlen(str)-1]=='\n'?"":"\n");
+ if (feof(fp) && !str[0])
+ {
+ ERROR_MSG("!macro \"%s\": unterminated (no !macroend found in file)!\n",line.gettoken_str(1));
+ return PS_ERROR;
+ }
+ // remove trailing whitespace
+ while (*p) p++;
+ if (p > str) p--;
+ while (p >= str && (*p == '\r' || *p == '\n' || *p == ' ' || *p == '\t')) p--;
+ *++p=0;
+ LineParser l2(false);
+ if (!l2.parse(str))
+ {
+ if (!stricmp(l2.gettoken_str(0),"!macroend"))
+ {
+ linecnt++;
+ break;
+ }
+ if (!stricmp(l2.gettoken_str(0),"!macro"))
+ {
+ ERROR_MSG("Error: can't define a macro inside a macro!\n");
+ return PS_ERROR;
+ }
+ }
+ if (str[0]) m_macros.add(str,strlen(str)+1);
+ else m_macros.add(" ",2);
+ linecnt++;
+ }
+ m_macros.add("",1);
+ }
+ return PS_OK;
+ case TOK_P_MACROEND:
+ ERROR_MSG("!macroend: no macro currently open.\n");
+ return PS_ERROR;
+ case TOK_P_INSERTMACRO:
+ {
+ if (!line.gettoken_str(1)[0]) PRINTHELP()
+ char *t=(char *)m_macros.get();
+ char *m=t;
+ while (t && *t)
+ {
+ if (!stricmp(t,line.gettoken_str(1))) break;
+ t+=strlen(t)+1;
+
+ // advance over parms
+ while (*t) t+=strlen(t)+1;
+ t++;
+
+ // advance over data
+ while (*t) t+=strlen(t)+1;
+ if (t-(char *)m_macros.get() >= m_macros.getlen()-1)
+ break;
+ t++;
+ }
+ SCRIPT_MSG("!insertmacro: %s\n",line.gettoken_str(1));
+ if (!t || !*t)
+ {
+ ERROR_MSG("!insertmacro: macro named \"%s\" not found!\n",line.gettoken_str(1));
+ return PS_ERROR;
+ }
+ t+=strlen(t)+1;
+
+
+ GrowBuf l_define_names;
+ DefineList l_define_saves;
+ int npr=0;
+ // advance over parms
+ while (*t)
+ {
+ char *v=definedlist.find(t);
+ if (v)
+ {
+ l_define_saves.add(t,v);
+ definedlist.del(t);
+ }
+ l_define_names.add(t,strlen(t)+1);
+ definedlist.add(t,line.gettoken_str(npr+2));
+
+ npr++;
+ t+=strlen(t)+1;
+ }
+ l_define_names.add("",1);
+ t++;
+ if (npr != line.getnumtokens()-2)
+ {
+ ERROR_MSG("!insertmacro: macro \"%s\" requires %d parameter(s), passed %d!\n",
+ line.gettoken_str(1),npr,line.getnumtokens()-2);
+ return PS_ERROR;
+ }
+
+ int lp=0;
+ char str[1024];
+ if (m_macro_entry.find(line.gettoken_str(1),0)>=0)
+ {
+ ERROR_MSG("!insertmacro: macro \"%s\" already being inserted!\n",line.gettoken_str(1));
+ return PS_ERROR;
+ }
+ int npos=m_macro_entry.add(line.gettoken_str(1),0);
+
+ wsprintf(str,"macro:%s",line.gettoken_str(1));
+ while (*t)
+ {
+ lp++;
+ if (strcmp(t," "))
+ {
+ int ret=process_oneline(t,str,lp);
+ if (ret != PS_OK)
+ {
+ ERROR_MSG("Error in macro %s on macroline %d\n",line.gettoken_str(1),lp);
+ return ret;
+ }
+ }
+ {
+ // fix t if process_oneline changed m_macros
+ char *nm=(char *)m_macros.get();
+ if (nm != m)
+ {
+ t += nm - m;
+ m = nm;
+ }
+ }
+ t+=strlen(t)+1;
+ }
+ m_macro_entry.delbypos(npos);
+ {
+ char *p=(char*)l_define_names.get();
+ while (*p)
+ {
+ definedlist.del(p);
+ char *v;
+ if ((v=l_define_saves.find(p))) definedlist.add(p,v);
+ p+=strlen(p)+1;
+ }
+ }
+ SCRIPT_MSG("!insertmacro: end of %s\n",line.gettoken_str(1));
+ }
+ return PS_OK;
+
+ // preprocessor files fun
+ ///////////////////////////////////////////////////////////////////////////////
+
+ case TOK_P_TEMPFILE:
+ {
+ char *symbol = line.gettoken_str(1);
+ char *fpath;
+
+#ifdef _WIN32
+ char buf[MAX_PATH], buf2[MAX_PATH];
+
+ GetTempPath(MAX_PATH, buf);
+ if (!GetTempFileName(buf, "nst", 0, buf2))
+ {
+ ERROR_MSG("!tempfile: unable to create temporary file.\n");
+ return PS_ERROR;
+ }
+
+ fpath = buf2;
+#else
+ char t[] = "/tmp/makensisXXXXXX";
+
+ mode_t old_umask = umask(0077);
+
+ int fd = mkstemp(t);
+ if (fd == -1) {
+ ERROR_MSG("!tempfile: unable to create temporary file.\n");
+ return PS_ERROR;
+ }
+ close(fd);
+
+ umask(old_umask);
+
+ fpath = t;
+#endif
+
+ if (definedlist.add(symbol, fpath))
+ {
+ ERROR_MSG("!tempfile: \"%s\" already defined!\n", symbol);
+ return PS_ERROR;
+ }
+
+ SCRIPT_MSG("!tempfile: \"%s\"=\"%s\"\n", symbol, fpath);
+ }
+ return PS_OK;
+
+ case TOK_P_DELFILE:
+ {
+ char *file = line.gettoken_str(1);
+#ifndef _WIN32
+ file = my_convert(file);
+#endif
+ int result = unlink(file);
+#ifndef _WIN32
+ my_convert_free(file);
+#endif
+ if (result == -1) {
+ ERROR_MSG("!delfile: \"%s\" couldn't be deleted.\n", line.gettoken_str(1));
+ return PS_ERROR;
+ }
+
+ SCRIPT_MSG("!delfile: \"%s\"\n", line.gettoken_str(1));
+ }
+ return PS_OK;
+
+ case TOK_P_APPENDFILE:
+ {
+ char *file = line.gettoken_str(1);
+ char *text = line.gettoken_str(2);
+
+ FILE *fp = FOPEN(file, "a");
+ if (!fp)
+ {
+ ERROR_MSG("!appendfile: \"%s\" couldn't be opened.\n", file);
+ return PS_ERROR;
+ }
+
+ if (fputs(text, fp) < 0)
+ {
+ ERROR_MSG("!appendfile: error writing to \"%s\".\n", file);
+ return PS_ERROR;
+ }
+
+ fclose(fp);
+
+ SCRIPT_MSG("!appendfile: \"%s\" \"%s\"\n", file, text);
+ }
+ return PS_OK;
+
+ // page ordering shit
+ ///////////////////////////////////////////////////////////////////////////////
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ case TOK_UNINSTPAGE:
+ set_uninstall_mode(1);
+ case TOK_PAGE:
+ {
+ if (!uninstall_mode) {
+ enable_last_page_cancel = 0;
+ if (!stricmp(line.gettoken_str(line.getnumtokens()-1),"/ENABLECANCEL"))
+ enable_last_page_cancel = 1;
+ }
+ else {
+ uenable_last_page_cancel = 0;
+ if (!stricmp(line.gettoken_str(line.getnumtokens()-1),"/ENABLECANCEL"))
+ uenable_last_page_cancel = 1;
+ }
+
+ int k = line.gettoken_enum(1,"custom\0license\0components\0directory\0instfiles\0uninstConfirm\0");
+
+ if (k < 0) PRINTHELP();
+
+ if (add_page(k) != PS_OK)
+ return PS_ERROR;
+
+#ifndef NSIS_SUPPORT_CODECALLBACKS
+ if (!k) {
+ ERROR_MSG("Error: custom page specified, NSIS_SUPPORT_CODECALLBACKS not defined.\n");
+ return PS_ERROR;
+ }
+#endif//!NSIS_SUPPORT_CODECALLBACKS
+
+ if (k) {
+ // not custom
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ switch (line.getnumtokens() - enable_last_page_cancel) {
+ case 6:
+ PRINTHELP();
+ case 5:
+ if (*line.gettoken_str(4))
+ cur_page->leavefunc = ns_func.add(line.gettoken_str(4),0);
+ case 4:
+ if (*line.gettoken_str(3))
+ cur_page->showfunc = ns_func.add(line.gettoken_str(3),0);
+ case 3:
+ if (*line.gettoken_str(2))
+ cur_page->prefunc = ns_func.add(line.gettoken_str(2),0);
+ }
+#endif//NSIS_SUPPORT_CODECALLBACKS
+ }
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ else {
+ // a custom page
+ switch (line.getnumtokens() - enable_last_page_cancel) {
+ case 6:
+ PRINTHELP();
+ case 5:
+ cur_page->caption = add_string(line.gettoken_str(4));
+ case 4:
+ if (*line.gettoken_str(3))
+ cur_page->leavefunc = ns_func.add(line.gettoken_str(3),0);
+ case 3:
+ if (*line.gettoken_str(2))
+ cur_page->prefunc = ns_func.add(line.gettoken_str(2),0);
+ break;
+ case 2:
+ ERROR_MSG("Error: custom page must have a creator function!\n");
+ PRINTHELP();
+ }
+ }
+#endif//NSIS_SUPPORT_CODECALLBACKS
+
+ SCRIPT_MSG("%sPage: %s", uninstall_mode?"Uninst":"", line.gettoken_str(1));
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ if (cur_page->prefunc>=0)
+ SCRIPT_MSG(" (%s:%s)", k?"pre":"creator", line.gettoken_str(2));
+ if (cur_page->showfunc>=0 && k)
+ SCRIPT_MSG(" (show:%s)", line.gettoken_str(3));
+ if (cur_page->leavefunc>=0)
+ SCRIPT_MSG(" (leave:%s)", line.gettoken_str(4-!k));
+ else if (cur_page->caption && !k)
+ SCRIPT_MSG(" (caption:%s)", line.gettoken_str(3));
+#endif
+ SCRIPT_MSG("\n");
+
+ page_end();
+
+ if (k == PAGE_INSTFILES) {
+ add_page(PAGE_COMPLETED);
+ page_end();
+ }
+
+ set_uninstall_mode(0);
+ }
+ return PS_OK;
+
+ // extended page setting
+ case TOK_PAGEEX:
+ {
+ int k = line.gettoken_enum(1,"custom\0license\0components\0directory\0instfiles\0uninstConfirm\0");
+ if (k < 0) {
+ k = line.gettoken_enum(1,"un.custom\0un.license\0un.components\0un.directory\0un.instfiles\0un.uninstConfirm\0");
+ if (k < 0) PRINTHELP();
+ set_uninstall_mode(1);
+ }
+
+ SCRIPT_MSG("PageEx: %s\n", line.gettoken_str(1));
+
+ if (add_page(k) != PS_OK)
+ return PS_ERROR;
+
+ cur_page->flags |= PF_PAGE_EX;
+ }
+ return PS_OK;
+
+ case TOK_PAGEEXEND:
+ {
+ SCRIPT_MSG("PageExEnd\n");
+
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ if (cur_page_type == PAGE_CUSTOM && !cur_page->prefunc) {
+ ERROR_MSG("Error: custom pages must have a creator function.\n");
+ return PS_ERROR;
+ }
+#endif
+
+ page_end();
+
+ if (cur_page_type == PAGE_INSTFILES) {
+ add_page(PAGE_COMPLETED);
+ page_end();
+ }
+
+ set_uninstall_mode(0);
+ }
+ return PS_OK;
+ case TOK_PAGECALLBACKS:
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+ {
+ SCRIPT_MSG("PageCallbacks:");
+
+ if (cur_page_type == PAGE_CUSTOM)
+ {
+ switch (line.getnumtokens())
+ {
+ case 4:
+ {
+ PRINTHELP();
+ }
+ case 3:
+ {
+ if (*line.gettoken_str(2))
+ {
+ if (strnicmp(line.gettoken_str(2), "un.", 3))
+ {
+ if (uninstall_mode)
+ {
+ ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
+ return PS_ERROR;
+ }
+ }
+ else
+ {
+ if (!uninstall_mode)
+ {
+ ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
+ return PS_ERROR;
+ }
+ }
+ cur_page->leavefunc = ns_func.add(line.gettoken_str(2),0);
+ }
+ }
+ case 2:
+ {
+ if (*line.gettoken_str(1))
+ {
+ if (strnicmp(line.gettoken_str(1), "un.", 3))
+ {
+ if (uninstall_mode)
+ {
+ ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
+ return PS_ERROR;
+ }
+ }
+ else
+ {
+ if (!uninstall_mode)
+ {
+ ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
+ return PS_ERROR;
+ }
+ }
+ cur_page->prefunc = ns_func.add(line.gettoken_str(1),0);
+ }
+ }
+ }
+ }
+ else
+ {
+ switch (line.getnumtokens())
+ {
+ case 4:
+ {
+ if (*line.gettoken_str(3))
+ {
+ if (strnicmp(line.gettoken_str(3), "un.", 3))
+ {
+ if (uninstall_mode)
+ {
+ ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
+ return PS_ERROR;
+ }
+ }
+ else
+ {
+ if (!uninstall_mode)
+ {
+ ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
+ return PS_ERROR;
+ }
+ }
+ cur_page->leavefunc = ns_func.add(line.gettoken_str(3),0);
+ }
+ }
+ case 3:
+ {
+ if (*line.gettoken_str(2))
+ {
+ if (strnicmp(line.gettoken_str(2), "un.", 3))
+ {
+ if (uninstall_mode)
+ {
+ ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
+ return PS_ERROR;
+ }
+ }
+ else
+ {
+ if (!uninstall_mode)
+ {
+ ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
+ return PS_ERROR;
+ }
+ }
+ cur_page->showfunc = ns_func.add(line.gettoken_str(2),0);
+ }
+ }
+ case 2:
+ {
+ if (*line.gettoken_str(1))
+ {
+ if (strnicmp(line.gettoken_str(1), "un.", 3))
+ {
+ if (uninstall_mode)
+ {
+ ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
+ return PS_ERROR;
+ }
+ }
+ else
+ {
+ if (!uninstall_mode)
+ {
+ ERROR_MSG("\nError: function names must start with \"un.\" in an uninstall page.\n");
+ return PS_ERROR;
+ }
+ }
+ cur_page->prefunc = ns_func.add(line.gettoken_str(1),0);
+ }
+ }
+ }
+ }
+
+ int custom = cur_page_type == PAGE_CUSTOM ? 1 : 0;
+
+ if (cur_page->prefunc>=0)
+ SCRIPT_MSG(" %s:%s", !custom?"pre":"creator", line.gettoken_str(1));
+ if (cur_page->showfunc>=0 && !custom)
+ SCRIPT_MSG(" show:%s", line.gettoken_str(2));
+ if (cur_page->leavefunc>=0)
+ SCRIPT_MSG(" leave:%s", line.gettoken_str(3-custom));
+
+ SCRIPT_MSG("\n");
+ }
+ return PS_OK;
+#else
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_CODECALLBACKS not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//NSIS_SUPPORT_CODECALLBACKS
+#else
+ case TOK_PAGE:
+ case TOK_UNINSTPAGE:
+ case TOK_PAGEEX:
+ case TOK_PAGEEXEND:
+ case TOK_PAGECALLBACKS:
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//NSIS_CONFIG_VISIBLE_SUPPORT
+ // header flags
+ ///////////////////////////////////////////////////////////////////////////////
+ case TOK_LANGSTRING:
+ {
+ char *name = line.gettoken_str(1);
+ LANGID lang = line.gettoken_int(2);
+ char *str = line.gettoken_str(3);
+ int ret = SetLangString(name, lang, str);
+ if (ret == PS_WARNING)
+ warning_fl("LangString \"%s\" set multiple times for %d, wasting space", name, lang);
+ else if (ret == PS_ERROR) {
+ ERROR_MSG("Error: can't set LangString \"%s\"!\n", name);
+ return PS_ERROR;
+ }
+ SCRIPT_MSG("LangString: \"%s\" %d \"%s\"\n", name, lang, str);
+ }
+ return PS_OK;
+ case TOK_LANGSTRINGUP:
+ SCRIPT_MSG("Error: LangStringUP is obsolete, there are no more unprocessed strings. Use LangString.\n");
+ return PS_ERROR;
+ case TOK_LICENSELANGSTRING:
+ {
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ if (build_header.flags&(CH_FLAGS_SILENT|CH_FLAGS_SILENT_LOG))
+ {
+ warning_fl("LicenseLangString: SilentInstall enabled, wasting space");
+ }
+#endif
+ char *name = line.gettoken_str(1);
+ LANGID lang = line.gettoken_int(2);
+ char *file = line.gettoken_str(3);
+
+ FILE *fp;
+ unsigned int datalen;
+ fp=FOPEN(file,"rb");
+ if (!fp)
+ {
+ ERROR_MSG("LicenseLangString: open failed \"%s\"\n",file);
+ PRINTHELP()
+ }
+ MANAGE_WITH(fp, fclose);
+ fseek(fp,0,SEEK_END);
+ datalen=ftell(fp);
+ if (!datalen)
+ {
+ ERROR_MSG("LicenseLangString: empty license file \"%s\"\n",file);
+ return PS_ERROR;
+ }
+ rewind(fp);
+ char *data=(char*)malloc(datalen+2);
+ if (!data)
+ {
+ ERROR_MSG("Internal compiler error #12345: LicenseData malloc(%d) failed.\n", datalen+2);
+ return PS_ERROR;
+ }
+ MANAGE_WITH(data, free);
+ char *ldata=data+1;
+ if (fread(ldata,1,datalen,fp) != datalen)
+ {
+ ERROR_MSG("LicenseLangString: can't read file.\n");
+ return PS_ERROR;
+ }
+ ldata[datalen]=0;
+ if (!strncmp(ldata,"{\\rtf",sizeof("{\\rtf")-1))
+ *data = SF_RTF;
+ else
+ *data = SF_TEXT;
+
+ int ret = SetLangString(name, lang, data);
+ if (ret == PS_WARNING)
+ warning_fl("LicenseLangString \"%s\" set multiple times for %d, wasting space", name, lang);
+ else if (ret == PS_ERROR)
+ {
+ ERROR_MSG("Error: can't set LicenseLangString \"%s\"!\n", name);
+ return PS_ERROR;
+ }
+
+ SCRIPT_MSG("LicenseLangString: \"%s\" %d \"%s\"\n", name, lang, file);
+ }
+ return PS_OK;
+ case TOK_NAME:
+ {
+ if (SetInnerString(NLF_NAME,line.gettoken_str(1)) == PS_WARNING)
+ warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
+ SetInnerString(NLF_NAME_DA,line.gettoken_str(2));
+ SCRIPT_MSG("Name: \"%s\"",line.gettoken_str(1));
+ if (*line.gettoken_str(2))
+ SCRIPT_MSG(" \"%s\"",line.gettoken_str(2));
+ SCRIPT_MSG("\n");
+ }
+ return PS_OK;
+ case TOK_CAPTION:
+ {
+ if (!cur_page)
+ {
+ if (SetInnerString(NLF_CAPTION,line.gettoken_str(1)) == PS_WARNING)
+ warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
+ }
+ else
+ {
+ cur_page->caption = add_string(line.gettoken_str(1));
+ }
+ SCRIPT_MSG("Caption: \"%s\"\n",line.gettoken_str(1));
+ }
+ return PS_OK;
+ case TOK_ICON:
+ SCRIPT_MSG("Icon: \"%s\"\n",line.gettoken_str(1));
+ try {
+ free_loaded_icon(installer_icon);
+ installer_icon = load_icon_file(line.gettoken_str(1));
+ }
+ catch (exception& err) {
+ ERROR_MSG("Error while loading icon from \"%s\": %s\n", line.gettoken_str(1), err.what());
+ return PS_ERROR;
+ }
+ return PS_OK;
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ case TOK_CHECKBITMAP:
+ SCRIPT_MSG("CheckBitmap: \"%s\"\n",line.gettoken_str(1));
+ try {
+ init_res_editor();
+ int err = update_bitmap(res_editor, IDB_BITMAP1, line.gettoken_str(1), 96, 16, 8);
+ if (err) {
+ switch (err) {
+ case -1:
+ ERROR_MSG("Error: can't find bitmap\n");
+ break;
+ case -2:
+ ERROR_MSG("Error: invalid bitmap file - corrupted or not a bitmap\n");
+ break;
+ case -3:
+ ERROR_MSG("Error: bitmap isn't 96x16 in size\n");
+ break;
+ case -4:
+ ERROR_MSG("Error: bitmap has more than 8bpp\n");
+ break;
+ }
+ return PS_ERROR;
+ }
+ }
+ catch (exception& err) {
+ ERROR_MSG("Error while replacing bitmap: %s\n", err.what());
+ return PS_ERROR;
+ }
+ return PS_OK;
+#else//NSIS_CONFIG_COMPONENTPAGE
+ case TOK_CHECKBITMAP:
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_COMPONENTPAGE not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_CONFIG_COMPONENTPAGE
+ case TOK_DIRTEXT:
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ {
+ if (!cur_page) {
+ if (SetInnerString(NLF_DIR_TEXT, line.gettoken_str(1)) == PS_WARNING)
+ warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
+ if (line.getnumtokens() > 2)
+ SetInnerString(NLF_DIR_SUBTEXT, line.gettoken_str(2));
+ if (line.getnumtokens() > 3)
+ SetInnerString(NLF_BTN_BROWSE, line.gettoken_str(3));
+ if (line.getnumtokens() > 4)
+ SetInnerString(NLF_DIR_BROWSETEXT, line.gettoken_str(4));
+ }
+ else {
+ if (cur_page_type != PAGE_DIRECTORY) {
+ ERROR_MSG("Error: DirText can only be used inside PageEx directory.\n");
+ return PS_ERROR;
+ }
+ cur_page->parms[0] = add_string(line.gettoken_str(1));
+ if (line.getnumtokens() > 2)
+ cur_page->parms[1] = add_string(line.gettoken_str(2));
+ if (line.getnumtokens() > 3)
+ cur_page->parms[2] = add_string(line.gettoken_str(3));
+ if (line.getnumtokens() > 4)
+ cur_page->parms[3] = add_string(line.gettoken_str(4));
+ }
+ SCRIPT_MSG("DirText: \"%s\" \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ }
+ return PS_OK;
+#else//NSIS_CONFIG_VISIBLE_SUPPORT
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_CONFIG_VISIBLE_SUPPORT
+ case TOK_DIRVAR:
+ {
+ if (cur_page_type != PAGE_DIRECTORY && cur_page_type != PAGE_UNINSTCONFIRM) {
+ ERROR_MSG("Error: can't use DirVar outside of PageEx directory|uninstConfirm.\n");
+ return PS_ERROR;
+ }
+ cur_page->parms[4] = GetUserVarIndex(line, 1) + 1;
+ if (cur_page->parms[4] <= 0) PRINTHELP();
+ SCRIPT_MSG("DirVar: %s\n", line.gettoken_str(1));
+ }
+ return PS_OK;
+ case TOK_DIRVERIFY:
+ {
+ if (cur_page_type != PAGE_DIRECTORY) {
+ ERROR_MSG("Error: can't use DirVerify outside of PageEx directory.\n");
+ return PS_ERROR;
+ }
+ cur_page->flags &= ~PF_DIR_NO_BTN_DISABLE;
+ int k = line.gettoken_enum(1,"auto\0leave\0");
+ if (k == -1)
+ PRINTHELP();
+ if (k)
+ cur_page->flags |= PF_DIR_NO_BTN_DISABLE;
+ SCRIPT_MSG("DirVerify: %s\n", line.gettoken_str(1));
+ }
+ return PS_OK;
+ case TOK_GETINSTDIRERROR:
+ ent.which = EW_GETFLAG;
+ ent.offsets[0] = GetUserVarIndex(line, 1);
+ ent.offsets[1] = FLAG_OFFSET(instdir_error);
+ return add_entry(&ent);
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ case TOK_COMPTEXT:
+ {
+ if (!cur_page) {
+ if (SetInnerString(NLF_COMP_TEXT, line.gettoken_str(1)) == PS_WARNING)
+ warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
+ if (line.getnumtokens() > 2)
+ SetInnerString(NLF_COMP_SUBTEXT1, line.gettoken_str(2));
+ if (line.getnumtokens() > 3)
+ SetInnerString(NLF_COMP_SUBTEXT2, line.gettoken_str(3));
+ }
+ else {
+ if (cur_page_type != PAGE_COMPONENTS) {
+ ERROR_MSG("Error: ComponentText can only be used inside PageEx components.\n");
+ return PS_ERROR;
+ }
+ cur_page->parms[0] = add_string(line.gettoken_str(1));
+ cur_page->parms[1] = add_string(line.gettoken_str(2));
+ cur_page->parms[2] = add_string(line.gettoken_str(3));
+ cur_page->parms[3] = cur_page->parms[1];
+ cur_page->parms[4] = cur_page->parms[2];
+ }
+ SCRIPT_MSG("ComponentText: \"%s\" \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
+ }
+ return PS_OK;
+ case TOK_INSTTYPE:
+ {
+ int x;
+
+ if (!stricmp(line.gettoken_str(1),"/NOCUSTOM"))
+ {
+ build_header.flags|=CH_FLAGS_NO_CUSTOM;
+ SCRIPT_MSG("InstType: disabling custom install type\n");
+ }
+ else if (!stricmp(line.gettoken_str(1),"/COMPONENTSONLYONCUSTOM"))
+ {
+ build_header.flags|=CH_FLAGS_COMP_ONLY_ON_CUSTOM;
+ SCRIPT_MSG("InstType: making components viewable only on custom install type\n");
+ }
+ else if (!strnicmp(line.gettoken_str(1),"/CUSTOMSTRING=",14))
+ {
+ SCRIPT_MSG("InstType: setting custom text to: \"%s\"\n",line.gettoken_str(1)+14);
+ if (SetInnerString(NLF_COMP_CUSTOM,line.gettoken_str(1)+14) == PS_WARNING)
+ warning_fl("%s: specified multiple times, wasting space","InstType /CUSTOMSTRING");
+ }
+ else if (line.gettoken_str(1)[0]=='/')
+ {
+ PRINTHELP()
+ }
+ else
+ {
+ char *itname = line.gettoken_str(1);
+
+ if (!strnicmp(itname, "un.", 3)) {
+ set_uninstall_mode(1);
+ itname += 3;
+ }
+
+ for (x = 0; x < NSIS_MAX_INST_TYPES && cur_header->install_types[x]; x ++);
+ if (x == NSIS_MAX_INST_TYPES)
+ {
+ ERROR_MSG("InstType: no more than %d install types allowed. %d specified\n", NSIS_MAX_INST_TYPES, NSIS_MAX_INST_TYPES + 1);
+ return PS_ERROR;
+ }
+ else
+ {
+ cur_header->install_types[x] = add_string(itname);
+ SCRIPT_MSG("InstType: %s%d=\"%s\"\n", uninstall_mode ? "(uninstall) " : "", x+1, itname);
+ }
+
+ set_uninstall_mode(0);
+ }
+ }
+ return PS_OK;
+#else//NSIS_CONFIG_COMPONENTPAGE
+ case TOK_COMPTEXT:
+ case TOK_INSTTYPE:
+ ERROR_MSG("Error: %s specified but NSIS_CONFIG_COMPONENTPAGE not defined\n",line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_CONFIG_COMPONENTPAGE
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ case TOK_LICENSETEXT:
+ {
+ if (!cur_page) {
+ if (SetInnerString(NLF_LICENSE_TEXT, line.gettoken_str(1)) == PS_WARNING)
+ warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
+ SetInnerString(NLF_LICENSE_TEXT_FSRB, line.gettoken_str(1));
+ SetInnerString(NLF_LICENSE_TEXT_FSCB, line.gettoken_str(1));
+ if (line.getnumtokens() > 2)
+ SetInnerString(NLF_BTN_LICENSE, line.gettoken_str(2));
+ }
+ else {
+ if (cur_page_type != PAGE_LICENSE) {
+ ERROR_MSG("Error: LicenseText can only be used inside PageEx license.\n");
+ return PS_ERROR;
+ }
+ cur_page->parms[0] = add_string(line.gettoken_str(1));
+ cur_page->next = add_string(line.gettoken_str(2));
+ }
+ SCRIPT_MSG("LicenseText: \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2));
+ }
+ return PS_OK;
+ case TOK_LICENSEDATA:
+ {
+ int idx = 0;
+ char *file = line.gettoken_str(1);
+ char *data = NULL;
+
+ if (file[0] == '$' && file[1] == '(')
+ {
+ char *cp = strdup(file+2);
+ MANAGE_WITH(cp, free);
+ char *p = strchr(cp, ')');
+ if (p && p[1] == 0) { // if string is only a language str identifier
+ *p = 0;
+ idx = DefineLangString(cp, 0);
+ }
+ data = file;
+ }
+
+ if (!idx)
+ {
+ unsigned int datalen;
+ FILE *fp=FOPEN(file,"rb");
+ if (!fp)
+ {
+ ERROR_MSG("LicenseData: open failed \"%s\"\n",file);
+ PRINTHELP()
+ }
+ MANAGE_WITH(fp, fclose);
+ fseek(fp,0,SEEK_END);
+ datalen=ftell(fp);
+ if (!datalen)
+ {
+ ERROR_MSG("LicenseData: empty license file \"%s\"\n",file);
+ return PS_ERROR;
+ }
+ rewind(fp);
+ data=(char*)malloc(datalen+2);
+ if (!data)
+ {
+ ERROR_MSG("Internal compiler error #12345: LicenseData malloc(%d) failed.\n", datalen+2);
+ return PS_ERROR;
+ }
+ //MANAGE_WITH(data, free);
+ char *ldata=data+1;
+ if (fread(ldata,1,datalen,fp) != datalen) {
+ ERROR_MSG("LicenseData: can't read file.\n");
+ free(data); // TODO: fix later (orip)
+ return PS_ERROR;
+ }
+ ldata[datalen]=0;
+ if (!strncmp(ldata,"{\\rtf",sizeof("{\\rtf")-1))
+ *data = SF_RTF;
+ else
+ *data = SF_TEXT;
+ }
+
+ if (!cur_page) {
+ if (SetInnerString(NLF_LICENSE_DATA,data) == PS_WARNING)
+ warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
+ }
+ else {
+ if (cur_page_type != PAGE_LICENSE) {
+ ERROR_MSG("Error: LicenseData can only be used inside PageEx license.\n");
+ return PS_ERROR;
+ }
+
+ cur_page->parms[1] = add_string(data, 0);
+ }
+
+ if (!idx) free(data); // TODO: fix later (orip)
+
+ SCRIPT_MSG("LicenseData: \"%s\"\n",file);
+ }
+ return PS_OK;
+ case TOK_LICENSEFORCESELECTION:
+ {
+ int k=line.gettoken_enum(1,"off\0checkbox\0radiobuttons\0");
+ if (k == -1) PRINTHELP()
+ if (k < line.getnumtokens() - 2) PRINTHELP()
+
+ if (!cur_page) {
+ switch (line.getnumtokens()) {
+ case 4:
+ SetInnerString(NLF_BTN_LICENSE_DISAGREE, line.gettoken_str(3));
+ case 3:
+ SetInnerString(NLF_BTN_LICENSE_AGREE, line.gettoken_str(2));
+ break;
+ }
+
+ switch (k) {
+ case 0:
+ license_res_id = IDD_LICENSE;
+ break;
+ case 1:
+ license_res_id = IDD_LICENSE_FSCB;
+ break;
+ case 2:
+ license_res_id = IDD_LICENSE_FSRB;
+ break;
+ }
+ }
+ else {
+ if (cur_page_type != PAGE_LICENSE) {
+ ERROR_MSG("Error: LicenseForceSelection can only be used inside PageEx license.\n");
+ return PS_ERROR;
+ }
+ switch (line.getnumtokens()) {
+ case 4:
+ cur_page->parms[3] = add_string(line.gettoken_str(3));
+ case 3:
+ cur_page->parms[2] = add_string(line.gettoken_str(2));
+ break;
+ }
+
+ cur_page->flags &= ~(PF_LICENSE_FORCE_SELECTION | PF_LICENSE_NO_FORCE_SELECTION);
+
+ switch (k) {
+ case 0:
+ cur_page->dlg_id = IDD_LICENSE;
+ cur_page->flags |= PF_LICENSE_NO_FORCE_SELECTION;
+ break;
+ case 1:
+ cur_page->dlg_id = IDD_LICENSE_FSCB;
+ cur_page->flags |= PF_LICENSE_FORCE_SELECTION;
+ break;
+ case 2:
+ cur_page->dlg_id = IDD_LICENSE_FSRB;
+ cur_page->flags |= PF_LICENSE_FORCE_SELECTION;
+ break;
+ }
+ }
+
+ SCRIPT_MSG("LicenseForceSelection: %s \"%s\" \"%s\"\n", line.gettoken_str(1), line.gettoken_str(2), line.gettoken_str(3));
+ }
+ return PS_OK;
+ case TOK_LICENSEBKCOLOR:
+ {
+ char *p = line.gettoken_str(1);
+ if (!strcmpi(p,"/windows"))
+ {
+ build_header.license_bg=-COLOR_WINDOW;
+ SCRIPT_MSG("LicenseBkColor: /windows\n");
+ }
+ else if (!strcmpi(p,"/grey") || !strcmpi(p,"/gray"))
+ {
+ build_header.license_bg=-COLOR_BTNFACE;
+ SCRIPT_MSG("LicenseBkColor: /grey\n");
+ }
+ else
+ {
+ int v=strtoul(p,&p,16);
+ build_header.license_bg=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16);
+ build_uninst.license_bg=build_header.license_bg;
+ SCRIPT_MSG("LicenseBkColor: %06X\n",v);
+ }
+ }
+ return PS_OK;
+#else//!NSIS_CONFIG_LICENSEPAGE
+ case TOK_LICENSETEXT:
+ case TOK_LICENSEDATA:
+ case TOK_LICENSEBKCOLOR:
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_LICENSEPAGE not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_CONFIG_LICENSEPAGE
+#ifdef NSIS_CONFIG_SILENT_SUPPORT
+ case TOK_SILENTINST:
+ {
+ int k=line.gettoken_enum(1,"normal\0silent\0silentlog\0");
+ if (k<0) PRINTHELP()
+#ifndef NSIS_CONFIG_LOG
+ if (k == 2)
+ {
+ ERROR_MSG("SilentInstall: silentlog specified, no log support compiled in (use NSIS_CONFIG_LOG)\n");
+ return PS_ERROR;
+ }
+#endif//NSIS_CONFIG_LOG
+ SCRIPT_MSG("SilentInstall: %s\n",line.gettoken_str(1));
+#ifdef NSIS_CONFIG_LICENSEPAGE
+ if (k && HasUserDefined(NLF_LICENSE_DATA))
+ {
+ warning_fl("SilentInstall: LicenseData already specified. wasting space");
+ }
+ if (k) {
+ build_header.flags|=CH_FLAGS_SILENT;
+ if (k == 2)
+ build_header.flags|=CH_FLAGS_SILENT_LOG;
+ }
+ else {
+ build_header.flags&=~CH_FLAGS_SILENT;
+ build_header.flags&=~CH_FLAGS_SILENT_LOG;
+ }
+#endif//NSIS_CONFIG_LICENSEPAGE
+ }
+ return PS_OK;
+ case TOK_SILENTUNINST:
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ {
+ int k=line.gettoken_enum(1,"normal\0silent\0");
+ if (k<0) PRINTHELP()
+ if (k)
+ build_uninst.flags|=CH_FLAGS_SILENT;
+ else
+ build_uninst.flags&=~CH_FLAGS_SILENT;
+ SCRIPT_MSG("SilentUnInstall: %s\n",line.gettoken_str(1));
+ }
+ return PS_OK;
+#else
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif
+ case TOK_IFSILENT:
+ ent.which=EW_IFFLAG;
+ if (process_jump(line,1,&ent.offsets[0]) ||
+ process_jump(line,2,&ent.offsets[1])) PRINTHELP()
+ ent.offsets[2]=FLAG_OFFSET(silent);
+ ent.offsets[3]=~0;//new value mask - keep flag
+ SCRIPT_MSG("IfSilent ?%s:%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_SETSILENT:
+ {
+ ent.which=EW_SETFLAG;
+ ent.offsets[0]=FLAG_OFFSET(silent);
+ int k=line.gettoken_enum(1,"normal\0silent\0");
+ if (k<0) PRINTHELP()
+ ent.offsets[1]=add_intstring(k);
+ SCRIPT_MSG("SetSilent: %s\n",line.gettoken_str(1));
+ }
+ return add_entry(&ent);
+#else//!NSIS_CONFIG_SILENT_SUPPORT
+ case TOK_SILENTINST:
+ case TOK_SILENTUNINST:
+ case TOK_IFSILENT:
+ case TOK_SETSILENT:
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_SILENT_SUPPORT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//NSIS_CONFIG_SILENT_SUPPORT
+ case TOK_OUTFILE:
+ strncpy(build_output_filename,line.gettoken_str(1),1024-1);
+ SCRIPT_MSG("OutFile: \"%s\"\n",build_output_filename);
+ return PS_OK;
+ case TOK_INSTDIR:
+ {
+ char *p = line.gettoken_str(1);
+ if (build_header.install_directory_ptr)
+ {
+ warning_fl("%s: specified multiple times. wasting space",line.gettoken_str(0));
+ }
+ build_header.install_directory_ptr = add_string(p);
+ build_header.install_directory_auto_append = 0;
+ char *p2 = p + strlen(p);
+ if (*p && *CharPrev(p, p2) != '\\')
+ {
+ // we risk hitting $\r or something like $(bla\ad) or ${bla\ad} here, but it's better
+ // than hitting backslashes in processed strings
+ while (p2 > p && *p2 != '\\')
+ p2 = CharPrev(p, p2);
+ if (*p2 == '\\')
+ {
+ build_header.install_directory_auto_append = add_string(p2 + 1);
+ }
+ }
+ SCRIPT_MSG("InstallDir: \"%s\"\n",line.gettoken_str(1));
+ }
+ return PS_OK;
+ case TOK_INSTALLDIRREGKEY: // InstallDirRegKey
+ {
+ if (build_header.install_reg_key_ptr)
+ {
+ warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
+ }
+ int k=line.gettoken_enum(1,rootkeys[0]);
+ if (k == -1) k=line.gettoken_enum(1,rootkeys[1]);
+ if (k == -1) PRINTHELP()
+ build_header.install_reg_rootkey=(int)rootkey_tab[k];
+ if (!build_header.install_reg_rootkey) PRINTHELP() // SHCTX is invalid here
+ build_header.install_reg_key_ptr = add_string(line.gettoken_str(2),0);
+ if (line.gettoken_str(2)[0] == '\\')
+ warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0));
+ build_header.install_reg_value_ptr = add_string(line.gettoken_str(3),0);
+ SCRIPT_MSG("InstallRegKey: \"%s\\%s\\%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
+ }
+ return PS_OK;
+ case TOK_CRCCHECK:
+ build_crcchk=line.gettoken_enum(1,"off\0on\0force\0");
+ if (build_crcchk==-1) PRINTHELP()
+ SCRIPT_MSG("CRCCheck: %s\n",line.gettoken_str(1));
+ return PS_OK;
+ case TOK_INSTPROGRESSFLAGS:
+ {
+ int x;
+ int smooth=0;
+ build_header.flags&=~CH_FLAGS_PROGRESS_COLORED;
+ for (x = 1; x < line.getnumtokens(); x ++)
+ {
+ if (!stricmp(line.gettoken_str(x),"smooth")) smooth=1;
+ else if (!stricmp(line.gettoken_str(x),"colored")) build_header.flags|=CH_FLAGS_PROGRESS_COLORED;
+ else PRINTHELP()
+ }
+ try {
+ init_res_editor();
+
+ BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(IDD_INSTFILES), NSIS_DEFAULT_LANG);
+ if (!dlg) throw runtime_error("IDD_INSTFILES doesn't exist!");
+ CDialogTemplate dt(dlg,uDefCodePage);
+ free(dlg);
+ DialogItemTemplate* progress = dt.GetItem(IDC_PROGRESS);
+ if (!progress) {
+ throw runtime_error("IDC_PROGRESS doesn't exist!");
+ }
+
+ if (smooth)
+ progress->dwStyle |= PBS_SMOOTH;
+ else
+ progress->dwStyle &= ~PBS_SMOOTH;
+
+ DWORD dwSize;
+ dlg = dt.Save(dwSize);
+ res_editor->UpdateResourceA(RT_DIALOG, MAKEINTRESOURCE(IDD_INSTFILES), NSIS_DEFAULT_LANG, dlg, dwSize);
+ delete [] dlg;
+ }
+ catch (exception& err) {
+ ERROR_MSG("Error setting smooth progress bar: %s\n", err.what());
+ return PS_ERROR;
+ }
+ SCRIPT_MSG("InstProgressFlags: smooth=%d, colored=%d\n",smooth,
+ !!(build_header.flags&CH_FLAGS_PROGRESS_COLORED));
+ }
+ return PS_OK;
+ case TOK_AUTOCLOSE:
+ {
+ int k=line.gettoken_enum(1,"false\0true\0");
+ if (k == -1) PRINTHELP();
+ if (k)
+ build_header.flags|=CH_FLAGS_AUTO_CLOSE;
+ else
+ build_header.flags&=~CH_FLAGS_AUTO_CLOSE;
+ SCRIPT_MSG("AutoCloseWindow: %s\n",k?"true":"false");
+ }
+ return PS_OK;
+ case TOK_WINDOWICON:
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ disable_window_icon=line.gettoken_enum(1,"on\0off\0");
+ if (disable_window_icon == -1) PRINTHELP();
+ SCRIPT_MSG("WindowIcon: %s\n",line.gettoken_str(1));
+ return PS_OK;
+#else
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n",line.gettoken_str(0));
+ return PS_ERROR;
+#endif // NSIS_CONFIG_VISIBLE_SUPPORT
+ case TOK_SHOWDETAILSUNINST:
+#ifndef NSIS_CONFIG_UNINSTALL_SUPPORT
+ ERROR_MSG("Error: ShowUninstDetails specified but NSIS_CONFIG_UNINSTALL_SUPPORT not defined\n");
+ return PS_ERROR;
+#endif
+ case TOK_SHOWDETAILS:
+ {
+ int k=line.gettoken_enum(1,"hide\0show\0nevershow\0");
+ if (k == -1) PRINTHELP()
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (which_token == TOK_SHOWDETAILSUNINST)
+ {
+ build_uninst.flags&=~(CH_FLAGS_DETAILS_NEVERSHOW|CH_FLAGS_DETAILS_SHOWDETAILS);
+ if (k==1)
+ build_uninst.flags|=CH_FLAGS_DETAILS_SHOWDETAILS;
+ else if (k==2)
+ build_uninst.flags|=CH_FLAGS_DETAILS_NEVERSHOW;
+ }
+ else
+#endif
+ {
+ build_header.flags&=~(CH_FLAGS_DETAILS_NEVERSHOW|CH_FLAGS_DETAILS_SHOWDETAILS);
+ if (k==1)
+ build_header.flags|=CH_FLAGS_DETAILS_SHOWDETAILS;
+ else if (k==2)
+ build_header.flags|=CH_FLAGS_DETAILS_NEVERSHOW;
+ }
+ SCRIPT_MSG("%s: %s\n",line.gettoken_str(0),line.gettoken_str(1));
+ }
+ return PS_OK;
+ case TOK_DIRSHOW:
+ /*{
+ int k=line.gettoken_enum(1,"show\0hide\0");
+ if (k == -1) PRINTHELP();
+ if (k)
+ build_header.flags|=CH_FLAGS_DIR_NO_SHOW;
+ else
+ build_header.flags&=~CH_FLAGS_DIR_NO_SHOW;
+ SCRIPT_MSG("DirShow: %s\n",k?"hide":"show");
+ }*/
+ ERROR_MSG("Error: DirShow doesn't currently work\n");
+ return PS_ERROR;
+ case TOK_ROOTDIRINST:
+ {
+ int k=line.gettoken_enum(1,"true\0false\0");
+ if (k == -1) PRINTHELP();
+ if (k)
+ build_header.flags|=CH_FLAGS_NO_ROOT_DIR;
+ else
+ build_header.flags&=~CH_FLAGS_NO_ROOT_DIR;
+ SCRIPT_MSG("AllowRootDirInstall: %s\n",k?"false":"true");
+ }
+ return PS_OK;
+ case TOK_BGFONT:
+#ifndef NSIS_SUPPORT_BGBG
+ ERROR_MSG("Error: BGFont specified but NSIS_SUPPORT_BGBG not defined\n");
+ return PS_ERROR;
+#else//NSIS_SUPPORT_BGBG
+ if (line.getnumtokens()==1)
+ {
+ memcpy(&bg_font,&bg_default_font,sizeof(LOGFONT));
+ SCRIPT_MSG("BGFont: default font\n");
+ return PS_OK;
+ }
+
+ LOGFONT newfont;
+ newfont.lfHeight=40;
+ newfont.lfWidth=0;
+ newfont.lfEscapement=0;
+ newfont.lfOrientation=0;
+ newfont.lfWeight=FW_NORMAL;
+ newfont.lfItalic=FALSE;
+ newfont.lfUnderline=FALSE;
+ newfont.lfStrikeOut=FALSE;
+ newfont.lfCharSet=DEFAULT_CHARSET;
+ newfont.lfOutPrecision=OUT_DEFAULT_PRECIS;
+ newfont.lfClipPrecision=CLIP_DEFAULT_PRECIS;
+ newfont.lfQuality=DEFAULT_QUALITY;
+ newfont.lfPitchAndFamily=DEFAULT_PITCH;
+
+ strncpy(newfont.lfFaceName,line.gettoken_str(1),LF_FACESIZE);
+
+ SCRIPT_MSG("BGFont: \"%s\"",line.gettoken_str(1));
+ {
+ bool height=false;
+ bool weight=false;
+ for (int i = 2; i < line.getnumtokens(); i++) {
+ char *tok=line.gettoken_str(i);
+ if (tok[0]=='/') {
+ if (!strcmpi(tok,"/ITALIC")) {
+ SCRIPT_MSG(" /ITALIC");
+ newfont.lfItalic=TRUE;
+ }
+ else if (!strcmpi(tok,"/UNDERLINE")) {
+ SCRIPT_MSG(" /UNDERLINE");
+ newfont.lfUnderline=TRUE;
+ }
+ else if (!strcmpi(tok,"/STRIKE")) {
+ SCRIPT_MSG(" /STRIKE");
+ newfont.lfStrikeOut=TRUE;
+ }
+ else {
+ SCRIPT_MSG("\n");
+ PRINTHELP();
+ }
+ }
+ else {
+ if (!height) {
+ SCRIPT_MSG(" height=%s",tok);
+ newfont.lfHeight=line.gettoken_int(i);
+ height=true;
+ }
+ else if (!weight) {
+ SCRIPT_MSG(" weight=%s",tok);
+ newfont.lfWeight=line.gettoken_int(i);
+ weight=true;
+ }
+ else {
+ SCRIPT_MSG("\n");
+ PRINTHELP();
+ }
+ }
+ }
+ }
+ SCRIPT_MSG("\n");
+ memcpy(&bg_font, &newfont, sizeof(LOGFONT));
+ return PS_OK;
+#endif//NSIS_SUPPORT_BGBG
+ case TOK_BGGRADIENT:
+#ifndef NSIS_SUPPORT_BGBG
+ ERROR_MSG("Error: BGGradient specified but NSIS_SUPPORT_BGBG not defined\n");
+ return PS_ERROR;
+#else//NSIS_SUPPORT_BGBG
+ if (line.getnumtokens()==1)
+ {
+ SCRIPT_MSG("BGGradient: default colors\n");
+ build_header.bg_color1=0;
+ build_header.bg_color2=RGB(0,0,255);
+ }
+ else if (!stricmp(line.gettoken_str(1),"off"))
+ {
+ build_header.bg_color1=build_header.bg_color2=build_header.bg_textcolor=-1;
+ SCRIPT_MSG("BGGradient: off\n");
+ if (line.getnumtokens()>2) PRINTHELP()
+ }
+ else
+ {
+ char *p = line.gettoken_str(1);
+ int v1,v2,v3=-1;
+ v1=strtoul(p,&p,16);
+ build_header.bg_color1=((v1&0xff)<<16)|(v1&0xff00)|((v1&0xff0000)>>16);
+ p=line.gettoken_str(2);
+ v2=strtoul(p,&p,16);
+ build_header.bg_color2=((v2&0xff)<<16)|(v2&0xff00)|((v2&0xff0000)>>16);
+
+ p=line.gettoken_str(3);
+ if (*p)
+ {
+ if (!stricmp(p,"notext")) build_header.bg_textcolor=-1;
+ else
+ {
+ v3=strtoul(p,&p,16);
+ build_header.bg_textcolor=((v3&0xff)<<16)|(v3&0xff00)|((v3&0xff0000)>>16);
+ }
+ }
+
+ SCRIPT_MSG("BGGradient: 0x%06X->0x%06X (text=0x%06X)\n",v1,v2,v3);
+ }
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ build_uninst.bg_color1=build_header.bg_color1;
+ build_uninst.bg_color2=build_header.bg_color2;
+ build_uninst.bg_textcolor=build_header.bg_textcolor;
+#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
+#endif//NSIS_SUPPORT_BGBG
+ return PS_OK;
+#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
+ case TOK_INSTCOLORS:
+ {
+ char *p = line.gettoken_str(1);
+ if (p[0]=='/')
+ {
+ if (stricmp(p,"/windows") || line.getnumtokens()!=2) PRINTHELP()
+ build_header.lb_fg=build_header.lb_bg=-1;
+ SCRIPT_MSG("InstallColors: windows default colors\n");
+ }
+ else
+ {
+ int v1,v2;
+ if (line.getnumtokens()!=3) PRINTHELP()
+ v1=strtoul(p,&p,16);
+ build_header.lb_fg=((v1&0xff)<<16)|(v1&0xff00)|((v1&0xff0000)>>16);
+ p=line.gettoken_str(2);
+ v2=strtoul(p,&p,16);
+ build_header.lb_bg=((v2&0xff)<<16)|(v2&0xff00)|((v2&0xff0000)>>16);
+ SCRIPT_MSG("InstallColors: fg=%06X bg=%06X\n",v1,v2);
+ }
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ build_uninst.lb_fg=build_header.lb_fg;
+ build_uninst.lb_bg=build_header.lb_bg;
+#endif
+ }
+ return PS_OK;
+ case TOK_XPSTYLE:
+ {
+ int k=line.gettoken_enum(1,"on\0off\0");
+ if (k == -1) PRINTHELP()
+ SCRIPT_MSG("XPStyle: %s\n", line.gettoken_str(1));
+ if (!k)
+ manifest_comctl = manifest::comctl_xp;
+ else
+ manifest_comctl = manifest::comctl_old;
+ }
+ return PS_OK;
+ case TOK_CHANGEUI:
+ try {
+ DWORD dwSize;
+ int k=line.gettoken_enum(1, "all\0IDD_LICENSE\0IDD_DIR\0IDD_SELCOM\0IDD_INST\0IDD_INSTFILES\0IDD_UNINST\0IDD_VERIFY\0IDD_LICENSE_FSRB\0IDD_LICENSE_FSCB\0");
+ if (k<0) PRINTHELP();
+
+ FILE *fui = FOPEN(line.gettoken_str(2), "rb");
+ if (!fui) {
+ ERROR_MSG("Error: Can't open \"%s\"!\n", line.gettoken_str(2));
+ return PS_ERROR;
+ }
+ MANAGE_WITH(fui, fclose);
+
+ fseek(fui, 0, SEEK_END);
+ unsigned int len = ftell(fui);
+ fseek(fui, 0, SEEK_SET);
+ LPBYTE ui = (LPBYTE) malloc(len);
+ if (!ui) {
+ ERROR_MSG("Internal compiler error #12345: malloc(%d) failed\n", len);
+ extern void quit(); quit();
+ }
+ MANAGE_WITH(ui, free);
+ if (fread(ui, 1, len, fui) != len) {
+ ERROR_MSG("Error: Can't read \"%s\"!\n", line.gettoken_str(2));
+ return PS_ERROR;
+ }
+
+ CResourceEditor *uire = new CResourceEditor(ui, len);
+
+ init_res_editor();
+
+ // Search for required items
+ #define GET(x) dlg = uire->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(x), 0); if (!dlg) return PS_ERROR; CDialogTemplate UIDlg(dlg, uDefCodePage);
+ #define SEARCH(x) if (!UIDlg.GetItem(x)) {ERROR_MSG("Error: Can't find %s (%u) in the custom UI!\n", #x, x);delete [] dlg;delete uire;return PS_ERROR;}
+ #define SAVE(x) dwSize = UIDlg.GetSize(); res_editor->UpdateResourceA(RT_DIALOG, x, NSIS_DEFAULT_LANG, dlg, dwSize); delete [] dlg;
+
+ LPBYTE dlg = NULL;
+
+ if (k == 0 || k == 1) {
+ GET(IDD_LICENSE);
+ SEARCH(IDC_EDIT1);
+ SAVE(IDD_LICENSE);
+ }
+
+ if (k == 0 || k == 2) {
+ GET(IDD_DIR);
+ SEARCH(IDC_DIR);
+ SEARCH(IDC_BROWSE);
+#ifdef NSIS_CONFIG_LOG
+ SEARCH(IDC_CHECK1);
+#endif
+ SAVE(IDD_DIR);
+ }
+
+ if (k == 0 || k == 3) {
+ GET(IDD_SELCOM);
+ SEARCH(IDC_TREE1);
+ SEARCH(IDC_COMBO1);
+ SAVE(IDD_SELCOM);
+ }
+
+ if (k == 0 || k == 4) {
+ GET(IDD_INST);
+ SEARCH(IDC_BACK);
+ SEARCH(IDC_CHILDRECT);
+ SEARCH(IDC_VERSTR);
+ SEARCH(IDOK);
+ SEARCH(IDCANCEL);
+
+ // Search for bitmap holder (default for SetBrandingImage)
+ branding_image_found = false;
+ DialogItemTemplate* dlgItem = 0;
+ for (int i = 0; (dlgItem = UIDlg.GetItemByIdx(i)); i++) {
+ bool check = false;
+
+ if (IS_INTRESOURCE(dlgItem->szClass)) {
+ if (dlgItem->szClass == MAKEINTRESOURCEW(0x0082)) {
+ check = true;
+ }
+ } else {
+ char *szClass = winchar_toansi(dlgItem->szClass);
+ check = strcmp(szClass, "Static") == 0;
+ delete [] szClass;
+ }
+
+ if (check) {
+ if ((dlgItem->dwStyle & SS_BITMAP) == SS_BITMAP) {
+ branding_image_found = true;
+ branding_image_id = dlgItem->wId;
+ break;
+ }
+ }
+ }
+
+ SAVE(IDD_INST);
+ }
+
+ if (k == 0 || k == 5) {
+ GET(IDD_INSTFILES);
+ SEARCH(IDC_LIST1);
+ SEARCH(IDC_PROGRESS);
+ SEARCH(IDC_SHOWDETAILS);
+ SAVE(IDD_INSTFILES);
+ }
+
+ if (k == 0 || k == 6) {
+ GET(IDD_UNINST);
+ SEARCH(IDC_EDIT1);
+ SAVE(IDD_UNINST);
+ }
+
+ if (k == 0 || k == 7) {
+ GET(IDD_VERIFY);
+ SEARCH(IDC_STR);
+ SAVE(IDD_VERIFY);
+ }
+
+ if (k == 0 || k == 8) {
+ GET(IDD_LICENSE_FSRB);
+ SEARCH(IDC_EDIT1);
+ SEARCH(IDC_LICENSEAGREE);
+ SEARCH(IDC_LICENSEDISAGREE);
+ SAVE(IDD_LICENSE_FSRB);
+ }
+
+ if (k == 0 || k == 9) {
+ GET(IDD_LICENSE_FSCB);
+ SEARCH(IDC_EDIT1);
+ SEARCH(IDC_LICENSEAGREE);
+ SAVE(IDD_LICENSE_FSCB);
+ }
+
+ delete uire;
+
+ SCRIPT_MSG("ChangeUI: %s %s%s\n", line.gettoken_str(1), line.gettoken_str(2), branding_image_found?" (branding image holder found)":"");
+ }
+ catch (exception& err) {
+ ERROR_MSG("Error while changing UI: %s\n", err.what());
+ return PS_ERROR;
+ }
+ return PS_OK;
+ case TOK_ADDBRANDINGIMAGE:
+#ifdef _WIN32
+ try {
+ int k=line.gettoken_enum(1,"top\0left\0bottom\0right\0");
+ int wh=line.gettoken_int(2);
+ if (k == -1) PRINTHELP();
+ int padding = 2;
+ if (line.getnumtokens() == 4)
+ padding = line.gettoken_int(3);
+
+ init_res_editor();
+ BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), NSIS_DEFAULT_LANG);
+
+ CDialogTemplate dt(dlg, uDefCodePage);
+
+ res_editor->FreeResource(dlg);
+
+ DialogItemTemplate brandingCtl = {0,};
+
+ brandingCtl.dwStyle = SS_BITMAP | WS_CHILD | WS_VISIBLE;
+ brandingCtl.sX = padding;
+ brandingCtl.sY = padding;
+ brandingCtl.szClass = MAKEINTRESOURCEW(0x0082);
+ brandingCtl.szTitle = NULL;
+ brandingCtl.wId = IDC_BRANDIMAGE;
+
+ brandingCtl.sHeight = wh;
+ brandingCtl.sWidth = wh;
+ dt.PixelsToDlgUnits(brandingCtl.sWidth, brandingCtl.sHeight);
+ if (k%2) {
+ // left (1) / right (3)
+
+ if (k & 2) // right
+ brandingCtl.sX += dt.GetWidth();
+ else // left
+ dt.MoveAll(brandingCtl.sWidth + (padding * 2), 0);
+
+ dt.Resize(brandingCtl.sWidth + (padding * 2), 0);
+
+ brandingCtl.sHeight = dt.GetHeight() - (padding * 2);
+ }
+ else {
+ // top (0) / bottom (2)
+
+ if (k & 2) // bottom
+ brandingCtl.sY += dt.GetHeight();
+ else // top
+ dt.MoveAll(0, brandingCtl.sHeight + (padding * 2));
+
+ dt.Resize(0, brandingCtl.sHeight + (padding * 2));
+
+ brandingCtl.sWidth = dt.GetWidth() - (padding * 2);
+ }
+
+ dt.AddItem(brandingCtl);
+
+ DWORD dwDlgSize;
+ dlg = dt.Save(dwDlgSize);
+
+ res_editor->UpdateResourceA(RT_DIALOG, IDD_INST, NSIS_DEFAULT_LANG, dlg, dwDlgSize);
+
+ delete [] dlg;
+
+ dt.DlgUnitsToPixels(brandingCtl.sWidth, brandingCtl.sHeight);
+ SCRIPT_MSG("AddBrandingImage: %s %ux%u\n", line.gettoken_str(1), brandingCtl.sWidth, brandingCtl.sHeight);
+
+ branding_image_found = true;
+ branding_image_id = IDC_BRANDIMAGE;
+ }
+ catch (exception& err) {
+ ERROR_MSG("Error while adding image branding support: %s\n", err.what());
+ return PS_ERROR;
+ }
+ return PS_OK;
+#else
+ ERROR_MSG("Error: AddBrandingImage is disabled for non Win32 platforms.\n");
+ return PS_ERROR;
+#endif
+ case TOK_SETFONT:
+ {
+ if (!strnicmp(line.gettoken_str(1), "/LANG=", 6))
+ {
+ LANGID lang_id = atoi(line.gettoken_str(1) + 6);
+ LanguageTable *table = GetLangTable(lang_id);
+ table->nlf.m_szFont = (char*)malloc(strlen(line.gettoken_str(2))+1);
+ strcpy(table->nlf.m_szFont, line.gettoken_str(2));
+ table->nlf.m_iFontSize = line.gettoken_int(3);
+
+ SCRIPT_MSG("SetFont: lang=%d \"%s\" %s\n", lang_id, line.gettoken_str(2), line.gettoken_str(3));
+ }
+ else
+ {
+ strncpy(build_font, line.gettoken_str(1), sizeof(build_font));
+ build_font_size = line.gettoken_int(2);
+
+ SCRIPT_MSG("SetFont: \"%s\" %s\n", line.gettoken_str(1), line.gettoken_str(2));
+ }
+ }
+ return PS_OK;
+#else
+ case TOK_INSTCOLORS:
+ case TOK_XPSTYLE:
+ case TOK_CHANGEUI:
+ case TOK_ADDBRANDINGIMAGE:
+ case TOK_SETFONT:
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_VISIBLE_SUPPORT not defined.\n",line.gettoken_str(0));
+ return PS_ERROR;
+#endif// NSIS_CONFIG_VISIBLE_SUPPORT
+
+ case TOK_REQEXECLEVEL:
+ {
+ int k=line.gettoken_enum(1,"none\0user\0highest\0admin\0");
+ switch (k)
+ {
+ case 0:
+ manifest_exec_level = manifest::exec_level_none;
+ break;
+ case 1:
+ manifest_exec_level = manifest::exec_level_user;
+ break;
+ case 2:
+ manifest_exec_level = manifest::exec_level_highest;
+ break;
+ case 3:
+ manifest_exec_level = manifest::exec_level_admin;
+ break;
+ default:
+ PRINTHELP();
+ }
+ }
+ return PS_OK;
+
+ // Ability to change compression methods from within the script
+ case TOK_SETCOMPRESSOR:
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ {
+ if (build_compressor_set) {
+ ERROR_MSG("Error: can't change compressor after data already got compressed or header already changed!\n");
+ return PS_ERROR;
+ }
+
+ if (build_compressor_final)
+ {
+ warning_fl("SetCompressor ignored due to previous call with the /FINAL switch");
+ return PS_OK;
+ }
+
+ int a = 1;
+
+ build_compress_whole = false;
+
+ while (line.gettoken_str(a)[0] == '/')
+ {
+ if (!strcmpi(line.gettoken_str(a),"/FINAL"))
+ {
+ build_compressor_final = true;
+ a++;
+ }
+ else if (!strcmpi(line.gettoken_str(a),"/SOLID"))
+ {
+ build_compress_whole = true;
+ a++;
+ }
+ else PRINTHELP();
+ }
+
+ if (a != line.getnumtokens() - 1)
+ {
+ ERROR_MSG("%s expects %d parameters, got %d.\n", line.gettoken_str(0), a + 1, line.getnumtokens());
+ PRINTHELP();
+ }
+
+ int k=line.gettoken_enum(a, "zlib\0bzip2\0lzma\0");
+ switch (k) {
+ case 0:
+ compressor = &zlib_compressor;
+ break;
+
+ case 1:
+ compressor = &bzip2_compressor;
+ break;
+
+ case 2:
+ compressor = &lzma_compressor;
+ break;
+
+ default:
+ PRINTHELP();
+ }
+
+ string compressor_name = line.gettoken_str(a);
+ compressor_name = lowercase(compressor_name);
+
+ if (set_compressor(compressor_name, build_compress_whole) != PS_OK)
+ {
+ SCRIPT_MSG("SetCompressor: error loading stub for \"%s\" compressor.\n", compressor_name.c_str());
+ return PS_ERROR;
+ }
+
+ SCRIPT_MSG("SetCompressor: %s%s%s\n", build_compressor_final ? "/FINAL " : "", build_compress_whole ? "/SOLID " : "", line.gettoken_str(a));
+ }
+ return PS_OK;
+#else//NSIS_CONFIG_COMPRESSION_SUPPORT
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_COMPRESSION_SUPPORT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
+ case TOK_LOADNLF:
+ {
+ SCRIPT_MSG("LoadLanguageFile: %s\n", line.gettoken_str(1));
+
+ LanguageTable *table = LoadLangFile(line.gettoken_str(1));
+
+ if (!table)
+ return PS_ERROR;
+
+ if (!defcodepage_set)
+ {
+ uDefCodePage = table->nlf.m_uCodePage;
+ defcodepage_set = true;
+ }
+
+ last_used_lang = table->lang_id;
+ // define LANG_LangName as "####" (lang id)
+ // for example ${LANG_ENGLISH} = 1033
+ char lang_id[16];
+ char lang_cp[16];
+ char lang_name[1024];
+ wsprintf(lang_name, "LANG_%s", table->nlf.m_szName);
+ wsprintf(lang_id, "%u", table->lang_id);
+ wsprintf(lang_cp, "%u", table->nlf.m_uCodePage);
+ definedlist.add(lang_name, lang_id);
+ wsprintf(lang_name, "LANG_%s_CP", table->nlf.m_szName);
+ definedlist.add(lang_name, lang_cp);
+ }
+ return PS_OK;
+
+ // preprocessor-ish (ifdef/ifndef/else/endif are handled one step out from here)
+ ///////////////////////////////////////////////////////////////////////////////
+ case TOK_P_DEFINE:
+ {
+ char *define=line.gettoken_str(1);
+ char *value;
+ char datebuf[256];
+ char mathbuf[256];
+
+ if (!stricmp(define,"/date") || !stricmp(define,"/utcdate")) {
+ if (line.getnumtokens()!=4) PRINTHELP()
+
+ char *date_type = define;
+
+ define=line.gettoken_str(2);
+ value=line.gettoken_str(3);
+
+ time_t rawtime;
+ time(&rawtime);
+
+ if (!stricmp(date_type,"/utcdate"))
+ rawtime = mktime(gmtime(&rawtime));
+
+ datebuf[0]=0;
+ size_t s=strftime(datebuf,sizeof(datebuf),value,localtime(&rawtime));
+
+ if (s == 0)
+ datebuf[0]=0;
+ else
+ datebuf[max(s,sizeof(datebuf)-1)]=0;
+
+ value=datebuf;
+
+ } else if (!stricmp(define,"/math")) {
+
+ int value1;
+ int value2;
+ char *mathop;
+
+ if (line.getnumtokens()!=6) PRINTHELP()
+
+ define = line.gettoken_str(2);
+ value1 = line.gettoken_int(3);
+ mathop = line.gettoken_str(4);
+ value2 = line.gettoken_int(5);
+ value = mathbuf;
+
+ if (!strcmp(mathop,"+")) {
+ sprintf(value,"%d",value1+value2);
+ } else if (!strcmp(mathop,"-")) {
+ sprintf(value,"%d",value1-value2);
+ } else if (!strcmp(mathop,"*")) {
+ sprintf(value,"%d",value1*value2);
+ } else if (!strcmp(mathop,"&")) {
+ sprintf(value,"%d",value1&value2);
+ } else if (!strcmp(mathop,"|")) {
+ sprintf(value,"%d",value1|value2);
+ } else if (!strcmp(mathop,"^")) {
+ sprintf(value,"%d",value1^value2);
+ } else if (!strcmp(mathop,"/")) {
+ if (value2==0) {
+ ERROR_MSG("!define /math: division by zero! (\"%i / %i\")\n",value1,value2);
+ return PS_ERROR;
+ }
+ sprintf(value,"%d",value1/value2);
+ } else if (!strcmp(mathop,"%")) {
+ if (value2==0) {
+ ERROR_MSG("!define /math: division by zero! (\"%i %% %i\")\n",value1,value2);
+ return PS_ERROR;
+ }
+ sprintf(value,"%d",value1%value2);
+ } else PRINTHELP()
+
+ } else {
+ if (line.getnumtokens()==4) PRINTHELP()
+
+ value=line.gettoken_str(2);
+ }
+
+ if (definedlist.add(define,value))
+ {
+ ERROR_MSG("!define: \"%s\" already defined!\n",define);
+ return PS_ERROR;
+ }
+ SCRIPT_MSG("!define: \"%s\"=\"%s\"\n",define,value);
+ }
+ return PS_OK;
+ case TOK_P_UNDEF:
+ if (definedlist.del(line.gettoken_str(1)))
+ {
+ ERROR_MSG("!undef: \"%s\" not defined!\n",line.gettoken_str(1));
+ return PS_ERROR;
+ }
+ SCRIPT_MSG("!undef: \"%s\"\n",line.gettoken_str(1));
+ return PS_OK;
+ case TOK_P_PACKEXEHEADER:
+ strncpy(build_packname,line.gettoken_str(1),sizeof(build_packname)-1);
+ strncpy(build_packcmd,line.gettoken_str(2),sizeof(build_packcmd)-1);
+ SCRIPT_MSG("!packhdr: filename=\"%s\", command=\"%s\"\n",
+ build_packname, build_packcmd);
+ return PS_OK;
+ case TOK_P_SYSTEMEXEC:
+ {
+ char *exec=line.gettoken_str(1);
+ int comp=line.gettoken_enum(2,"<\0>\0<>\0=\0ignore\0");
+ if (line.getnumtokens() == 2) comp = 4;
+ if (comp == -1 && line.getnumtokens() == 3) comp=4;
+ if (comp == -1) PRINTHELP()
+ int success=0;
+ int cmpv=line.gettoken_int(3,&success);
+ if (!success && comp != 4) PRINTHELP()
+ SCRIPT_MSG("!system: \"%s\"\n",exec);
+#ifdef _WIN32
+ int ret=sane_system(exec);
+#else
+ char *execfixed = my_convert(exec);
+ int ret=system(execfixed);
+ my_convert_free(execfixed);
+#endif
+ if (comp == 0 && ret < cmpv);
+ else if (comp == 1 && ret > cmpv);
+ else if (comp == 2 && ret != cmpv);
+ else if (comp == 3 && ret == cmpv);
+ else if (comp == 4);
+ else
+ {
+ ERROR_MSG("!system: returned %d, aborting\n",ret);
+ return PS_ERROR;
+ }
+ SCRIPT_MSG("!system: returned %d\n",ret);
+ }
+ return PS_OK;
+ case TOK_P_EXECUTE:
+ {
+ char *exec=line.gettoken_str(1);
+#ifdef _WIN32
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si={sizeof(STARTUPINFO),};
+ if (CreateProcess(NULL,exec,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
+ {
+ WaitForSingleObject(pi.hProcess,INFINITE);
+ CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ }
+#else
+ char *execfixed = my_convert(exec);
+ system(execfixed);
+ my_convert_free(execfixed);
+#endif
+ SCRIPT_MSG("!execute: \"%s\"\n",exec);
+ }
+ case TOK_P_ADDINCLUDEDIR:
+#ifdef _WIN32
+ include_dirs.add(line.gettoken_str(1),0);
+#else
+ {
+ char *f = line.gettoken_str(1);
+ char *fc = my_convert(f);
+ include_dirs.add(fc,0);
+ my_convert_free(fc);
+ }
+#endif
+ return PS_OK;
+ case TOK_P_INCLUDE:
+ {
+ bool required = true;
+
+ char *f = line.gettoken_str(1);
+
+ if(!stricmp(f,"/nonfatal")) {
+ if (line.getnumtokens()!=3)
+ PRINTHELP();
+
+ f = line.gettoken_str(2);
+ required = false;
+ } else if (line.getnumtokens()!=2) {
+ PRINTHELP();
+ }
+
+#ifdef _WIN32
+ char *fc = f;
+#else
+ char *fc = my_convert(f);
+#endif
+ int included = 0;
+
+ string dir = get_dir_name(fc);
+ string spec = get_file_name(fc);
+ string basedir = dir + PLATFORM_PATH_SEPARATOR_STR;
+ if (dir == spec) {
+ // no path, just file name
+ dir = ".";
+ basedir = "";
+ }
+
+#ifndef _WIN32
+ my_convert_free(fc);
+#endif
+
+ // search working directory
+ boost::scoped_ptr<dir_reader> dr( new_dir_reader() );
+ dr->read(dir);
+
+ for (dir_reader::iterator files_itr = dr->files().begin();
+ files_itr != dr->files().end();
+ files_itr++)
+ {
+ if (!dir_reader::matches(*files_itr, spec))
+ continue;
+
+ string incfile = basedir + *files_itr;
+
+ if (includeScript((char *) incfile.c_str()) != PS_OK) {
+ return PS_ERROR;
+ }
+
+ included++;
+ }
+
+ if (included)
+ return PS_OK;
+
+ // search include dirs
+ char *incdir = include_dirs.get();
+ int incdirs = include_dirs.getnum();
+
+ for (int i = 0; i < incdirs; i++, incdir += strlen(incdir) + 1) {
+ string curincdir = string(incdir) + PLATFORM_PATH_SEPARATOR_STR + dir;
+
+ boost::scoped_ptr<dir_reader> dr( new_dir_reader() );
+ dr->read(curincdir);
+
+ for (dir_reader::iterator incdir_itr = dr->files().begin();
+ incdir_itr != dr->files().end();
+ incdir_itr++)
+ {
+ if (!dir_reader::matches(*incdir_itr, spec))
+ continue;
+
+ string incfile = string(incdir) + PLATFORM_PATH_SEPARATOR_STR + basedir + *incdir_itr;
+
+ if (includeScript((char *) incfile.c_str()) != PS_OK) {
+ return PS_ERROR;
+ }
+
+ included++;
+ }
+
+ if (included)
+ return PS_OK;
+
+ }
+
+ // nothing found
+ if (!included)
+ {
+ if(required) {
+ ERROR_MSG("!include: could not find: \"%s\"\n",f);
+ return PS_ERROR;
+ } else {
+ warning_fl("!include: could not find: \"%s\"",f);
+ }
+ }
+ }
+ return PS_OK;
+ case TOK_P_CD:
+ if (!line.gettoken_str(1)[0] || chdir(line.gettoken_str(1)))
+ {
+ ERROR_MSG("!cd: error changing to: \"%s\"\n",line.gettoken_str(1));
+ return PS_ERROR;
+ }
+ return PS_OK;
+ case TOK_P_ERROR:
+ ERROR_MSG("!error: %s\n",line.gettoken_str(1));
+ return PS_ERROR;
+ case TOK_P_WARNING:
+ warning_fl("!warning: %s",line.gettoken_str(1));
+ return PS_OK;
+ case TOK_P_ECHO:
+ SCRIPT_MSG("%s (%s:%d)\n", line.gettoken_str(1),curfilename,linecnt);
+ return PS_OK;
+
+ case TOK_P_VERBOSE:
+ {
+ extern int g_display_errors;
+ int k=line.gettoken_enum(1,"push\0pop\0");
+ int v;
+ if (k < 0)
+ // just set
+ v=line.gettoken_int(1);
+ else
+ {
+ if (k)
+ {
+ // pop
+ int l=verbose_stack.getlen();
+ if (l)
+ {
+ v=((int*)verbose_stack.get())[(l/sizeof(int))-1];
+ verbose_stack.resize(l-sizeof(int));
+ }
+ else
+ return PS_OK;
+ }
+ else
+ {
+ // push
+ v=0;
+ if (display_errors)
+ {
+ v++;
+ if (display_warnings)
+ {
+ v++;
+ if (display_info)
+ {
+ v++;
+ if (display_script)
+ {
+ v++;
+ }
+ }
+ }
+ }
+ verbose_stack.add(&v,sizeof(int));
+ return PS_OK;
+ }
+ }
+ display_script=v>3;
+ display_info=v>2;
+ display_warnings=v>1;
+ display_errors=v>0;
+ g_display_errors=display_errors;
+ }
+ return PS_OK;
+
+ case TOK_UNINSTALLEXENAME: PRINTHELP()
+
+
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ case TOK_UNINSTCAPTION:
+ {
+ if (SetInnerString(NLF_UCAPTION,line.gettoken_str(1)) == PS_WARNING)
+ warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
+ SCRIPT_MSG("UninstCaption: \"%s\"\n",line.gettoken_str(1));
+ }
+ return PS_OK;
+ case TOK_UNINSTICON:
+ SCRIPT_MSG("UninstallIcon: \"%s\"\n",line.gettoken_str(1));
+ try {
+ free_loaded_icon(uninstaller_icon);
+ uninstaller_icon = load_icon_file(line.gettoken_str(1));
+ }
+ catch (exception& err) {
+ ERROR_MSG("Error while loading icon from \"%s\": %s\n", line.gettoken_str(1), err.what());
+ return PS_ERROR;
+ }
+ return PS_OK;
+ case TOK_UNINSTTEXT:
+ {
+ if (!cur_page) {
+ if (SetInnerString(NLF_UNINST_TEXT, line.gettoken_str(1)) == PS_WARNING)
+ warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
+ SetInnerString(NLF_UNINST_SUBTEXT, line.gettoken_str(2));
+ }
+ else {
+ if (cur_page_type != PAGE_UNINSTCONFIRM) {
+ ERROR_MSG("Error: UninstallText can only be used inside PageEx uninstConfirm.\n");
+ return PS_ERROR;
+ }
+ cur_page->parms[0] = add_string(line.gettoken_str(1));
+ cur_page->parms[1] = add_string(line.gettoken_str(2));
+ }
+ SCRIPT_MSG("UninstallText: \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2));
+ }
+ return PS_OK;
+ case TOK_UNINSTSUBCAPTION:
+ {
+ int s;
+ int w=line.gettoken_int(1,&s);
+ if (!s || w < 0 || w > 2) PRINTHELP()
+ SetInnerString(NLF_USUBCAPTION_CONFIRM+w,line.gettoken_str(2));
+ SCRIPT_MSG("UninstSubCaption: page:%d, text=%s\n",w,line.gettoken_str(2));
+ }
+ return PS_OK;
+ case TOK_WRITEUNINSTALLER:
+ {
+ if (uninstall_mode)
+ {
+ ERROR_MSG("WriteUninstaller only valid from install, not from uninstall.\n");
+ PRINTHELP()
+ }
+ uninstaller_writes_used++;
+ ent.which=EW_WRITEUNINSTALLER;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ string full = string("$INSTDIR\\") + string(line.gettoken_str(1));
+ ent.offsets[3]=add_string(full.c_str());
+ // ent.offsets[1] and ent.offsets[2] are set in CEXEBuild::uninstall_generate()
+ if (!ent.offsets[0]) PRINTHELP()
+ SCRIPT_MSG("WriteUninstaller: \"%s\"\n",line.gettoken_str(1));
+
+ DefineInnerLangString(NLF_ERR_CREATING);
+ DefineInnerLangString(NLF_CREATED_UNINST);
+ }
+ return add_entry(&ent);
+#else//!NSIS_CONFIG_UNINSTALL_SUPPORT
+ case TOK_WRITEUNINSTALLER:
+ case TOK_UNINSTCAPTION:
+ case TOK_UNINSTICON:
+ case TOK_UNINSTTEXT:
+ case TOK_UNINSTSUBCAPTION:
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif
+
+
+
+ // section/function shit
+ ///////////////////////////////////////////////////////////////////////////////
+
+ case TOK_SECTION:
+ {
+ int a=1,unselected = 0;
+ if (!strcmpi(line.gettoken_str(1),"/o"))
+ {
+ unselected = 1;
+ a++;
+ }
+ else if (line.getnumtokens() > 3)
+ PRINTHELP();
+ SCRIPT_MSG("Section: \"%s\"",line.gettoken_str(a));
+ if (line.gettoken_str(a+1)[0]) SCRIPT_MSG(" ->(%s)",line.gettoken_str(a+1));
+ SCRIPT_MSG("\n");
+#ifndef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (!stricmp(line.gettoken_str(a),"uninstall"))
+ {
+ ERROR_MSG("Error: Uninstall section declared, no NSIS_CONFIG_UNINSTALL_SUPPORT\n");
+ return PS_ERROR;
+ }
+#endif
+
+ int ret;
+
+ if (line.gettoken_str(a)[0]=='-')
+ {
+ if (!strnicmp(line.gettoken_str(a)+1,"un.",3))
+ ret=add_section("un.",line.gettoken_str(a+1));
+ else
+ ret=add_section("",line.gettoken_str(a+1));
+ }
+ else ret=add_section(line.gettoken_str(a),line.gettoken_str(a+1));
+ if (ret != PS_OK) return ret;
+
+ if (unselected)
+ build_cursection->flags &= ~SF_SELECTED;
+
+ return PS_OK;
+ }
+ case TOK_SECTIONEND:
+ SCRIPT_MSG("SectionEnd\n");
+ return section_end();
+ case TOK_SECTIONIN:
+ {
+ SCRIPT_MSG("SectionIn: ");
+ int wt;
+ for (wt = 1; wt < line.getnumtokens(); wt ++)
+ {
+ char *p=line.gettoken_str(wt);
+ if (!stricmp(p, "RO"))
+ {
+ if (section_add_flags(SF_RO) != PS_OK) return PS_ERROR;
+ SCRIPT_MSG("[RO] ");
+ }
+ else
+ {
+ int x=atoi(p)-1;
+ if (x >= 0 && x < NSIS_MAX_INST_TYPES)
+ {
+ if (section_add_install_type(1<<x) != PS_OK) return PS_ERROR;
+ SCRIPT_MSG("[%d] ",x);
+ }
+ else if (x < 0)
+ {
+ PRINTHELP()
+ }
+ else
+ {
+ ERROR_MSG("Error: SectionIn section %d out of range 1-%d\n",x+1,NSIS_MAX_INST_TYPES);
+ return PS_ERROR;
+ }
+ p++;
+ }
+ }
+ SCRIPT_MSG("\n");
+ }
+ return PS_OK;
+ case TOK_SECTIONGROUPEND:
+ case TOK_SUBSECTIONEND:
+ case TOK_SECTIONGROUP:
+ case TOK_SUBSECTION:
+ {
+ char buf[1024];
+ int a=1,ex = 0;
+ if (!strcmpi(line.gettoken_str(1),"/e"))
+ {
+ ex = 1;
+ a++;
+ }
+ wsprintf(buf,"-%s",line.gettoken_str(a));
+ if (which_token == TOK_SECTIONGROUP || which_token == TOK_SUBSECTION)
+ {
+ char *s = line.gettoken_str(a);
+ if (!s[0] || (!strcmpi(s, "un.") && !s[3]))
+ PRINTHELP();
+ }
+
+ SCRIPT_MSG("%s %s",line.gettoken_str(0),line.gettoken_str(a));
+ if (line.gettoken_str(a+1)[0]) SCRIPT_MSG(" ->(%s)",line.gettoken_str(a+1));
+ SCRIPT_MSG("\n");
+ return add_section(buf,line.gettoken_str(a+1),ex);
+ }
+ case TOK_FUNCTION:
+ if (!line.gettoken_str(1)[0]) PRINTHELP()
+ if (line.gettoken_str(1)[0]==':' || line.gettoken_str(1)[0]=='/')
+ {
+ ERROR_MSG("Function: function name cannot begin with : or /.\n");
+ PRINTHELP()
+ }
+ SCRIPT_MSG("Function: \"%s\"\n",line.gettoken_str(1));
+#ifndef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (!strnicmp(line.gettoken_str(1),"un.",3))
+ {
+ ERROR_MSG("Error: Uninstall function declared, no NSIS_CONFIG_UNINSTALL_SUPPORT\n");
+ return PS_ERROR;
+ }
+#endif
+ return add_function(line.gettoken_str(1));
+ case TOK_FUNCTIONEND:
+ SCRIPT_MSG("FunctionEnd\n");
+ return function_end();
+
+ // flag setters
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // BEGIN - Added by ramon 23 May 2003
+ case TOK_ALLOWSKIPFILES:
+ build_allowskipfiles=line.gettoken_enum(1,"off\0on\0");
+ if (build_allowskipfiles==-1) PRINTHELP()
+ SCRIPT_MSG("AllowSkipFiles: %s\n",line.gettoken_str(1));
+ return PS_OK;
+ // END - Added by ramon 23 May 2003
+ case TOK_SETDATESAVE:
+ build_datesave=line.gettoken_enum(1,"off\0on\0");
+ if (build_datesave==-1) PRINTHELP()
+ SCRIPT_MSG("SetDateSave: %s\n",line.gettoken_str(1));
+ return PS_OK;
+ case TOK_SETOVERWRITE:
+ {
+ int k=line.gettoken_enum(1,"on\0off\0try\0ifnewer\0ifdiff\0lastused\0");
+ if (k==-1) PRINTHELP()
+ if (k==5)
+ {
+ k=build_overwrite;
+ build_overwrite=build_last_overwrite;
+ build_last_overwrite=k;
+ }
+ else
+ {
+ build_last_overwrite=build_overwrite;
+ build_overwrite=k;
+ }
+ SCRIPT_MSG("SetOverwrite: %s\n",line.gettoken_str(1));
+ }
+ return PS_OK;
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+ case TOK_SETPLUGINUNLOAD:
+ build_plugin_unload=line.gettoken_enum(1,"manual\0alwaysoff\0");
+ if (build_plugin_unload==-1) PRINTHELP()
+ SCRIPT_MSG("SetPluginUnload: %s\n",line.gettoken_str(1));
+ return PS_OK;
+#endif //NSIS_CONFIG_PLUGIN_SUPPORT
+ case TOK_SETCOMPRESS:
+ build_compress=line.gettoken_enum(1,"off\0auto\0force\0");
+ if (build_compress==-1) PRINTHELP()
+ if (build_compress==0 && build_compress_whole)
+ {
+ warning_fl("'SetCompress off' encountered, and in whole compression mode. Effectively ignored.");
+ }
+ SCRIPT_MSG("SetCompress: %s\n",line.gettoken_str(1));
+ return PS_OK;
+ case TOK_DBOPTIMIZE:
+ build_optimize_datablock=line.gettoken_enum(1,"off\0on\0");
+ if (build_optimize_datablock==-1) PRINTHELP()
+ SCRIPT_MSG("SetDatablockOptimize: %s\n",line.gettoken_str(1));
+ return PS_OK;
+ case TOK_FILEBUFSIZE:
+ build_filebuflen=line.gettoken_int(1);
+ build_filebuflen<<=20;
+ if (build_filebuflen<=0)
+ {
+ ERROR_MSG("Error: FileBufSize: invalid buffer size -- %d\n",build_filebuflen);
+ return PS_ERROR;
+ }
+ SCRIPT_MSG("FileBufSize: %smb (%d bytes)\n",line.gettoken_str(1),build_filebuflen);
+ return PS_OK;
+#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
+ case TOK_SETCOMPRESSIONLEVEL:
+ {
+ if (compressor == &lzma_compressor)
+ warning_fl("SetCompressionLevel: compressor is set to LZMA. Effectively ignored.");
+ if (build_compressor_set && build_compress_whole)
+ warning_fl("SetCompressionLevel: data already compressed in compress whole mode. Effectively ignored.");
+
+ int s;
+ build_compress_level=line.gettoken_int(1,&s);
+ if (!s || build_compress_level < 0 || build_compress_level > 9) PRINTHELP();
+ SCRIPT_MSG("SetCompressionLevel: %u\n", build_compress_level);
+ }
+ return PS_OK;
+ case TOK_SETCOMPRESSORDICTSIZE:
+ {
+ if (compressor != &lzma_compressor)
+ warning_fl("SetCompressorDictSize: compressor is not set to LZMA. Effectively ignored.");
+ if (build_compressor_set && build_compress_whole)
+ warning_fl("SetCompressorDictSize: data already compressed in compress whole mode. Effectively ignored.");
+
+ int s;
+ build_compress_dict_size=line.gettoken_int(1,&s);
+ if (!s) PRINTHELP();
+ SCRIPT_MSG("SetCompressorDictSize: %u mb\n", build_compress_dict_size);
+ build_compress_dict_size <<= 20;
+ }
+ return PS_OK;
+#else
+ case TOK_SETCOMPRESSIONLEVEL:
+ case TOK_SETCOMPRESSORDICTSIZE:
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_COMPRESSION_SUPPORT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
+ case TOK_ADDSIZE:
+ {
+ int s;
+ int size_kb=line.gettoken_int(1,&s);
+ if (!s) PRINTHELP()
+ SCRIPT_MSG("AddSize: %d kb\n",size_kb);
+ section_add_size_kb(size_kb);
+ }
+ return PS_OK;
+ case TOK_SUBCAPTION:
+ {
+ int s;
+ int w=line.gettoken_int(1,&s);
+ if (!s || w < 0 || w > 4) PRINTHELP()
+ SetInnerString(NLF_SUBCAPTION_LICENSE+w,line.gettoken_str(2));
+ SCRIPT_MSG("SubCaption: page:%d, text=%s\n",w,line.gettoken_str(2));
+ }
+ return PS_OK;
+ case TOK_FILEERRORTEXT:
+#ifdef NSIS_SUPPORT_FILE
+ {
+ SetInnerString(NLF_FILE_ERROR,line.gettoken_str(1));
+ SetInnerString(NLF_FILE_ERROR_NOIGNORE,line.gettoken_str(2));
+ SCRIPT_MSG("FileErrorText: \"%s\" \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2));
+ }
+ return PS_OK;
+#else
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_FILE not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif
+ case TOK_BRANDINGTEXT:
+ {
+ int a = 1;
+ int trim = 0;
+ while (line.gettoken_str(a)[0] == '/') {
+ if (!strnicmp(line.gettoken_str(a),"/TRIM",5)) {
+ if (!stricmp(line.gettoken_str(a)+5,"LEFT")) trim = 1;
+ else if (!stricmp(line.gettoken_str(a)+5,"RIGHT")) trim = 2;
+ else if (!stricmp(line.gettoken_str(a)+5,"CENTER")) trim = 3;
+ else PRINTHELP();
+ a++;
+ }
+ else break;
+ }
+ if (line.getnumtokens()!=a+1 && !trim) PRINTHELP();
+ if (line.getnumtokens()==a+1)
+ SetInnerString(NLF_BRANDING,line.gettoken_str(a));
+#ifdef _WIN32
+ if (trim) try {
+ init_res_editor();
+
+ BYTE* dlg = res_editor->GetResourceA(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), NSIS_DEFAULT_LANG);
+ CDialogTemplate td(dlg,uDefCodePage);
+ free(dlg);
+
+ if (trim) {
+ char str[512];
+ if (line.getnumtokens()==a+1 && line.gettoken_str(a)[0])
+ strcpy(str, line.gettoken_str(a));
+ else
+ wsprintf(str, "Nullsoft Install System %s", NSIS_VERSION);
+
+ short old_width = td.GetItem(IDC_VERSTR)->sWidth;
+
+ switch (trim) {
+ case 1: td.LTrimToString(IDC_VERSTR, str, 4); break;
+ case 2: td.RTrimToString(IDC_VERSTR, str, 4); break;
+ case 3: td.CTrimToString(IDC_VERSTR, str, 4); break;
+ }
+
+ if (td.GetItem(IDC_VERSTR)->sWidth > old_width)
+ {
+ warning_fl("BrandingText: \"%s\" is too long, trimming has expanded the label", str);
+ }
+ }
+
+ DWORD dwSize;
+ dlg = td.Save(dwSize);
+ res_editor->UpdateResourceA(RT_DIALOG, MAKEINTRESOURCE(IDD_INST), NSIS_DEFAULT_LANG, dlg, dwSize);
+ res_editor->FreeResource(dlg);
+ }
+ catch (exception& err) {
+ ERROR_MSG("Error while triming branding text control: %s\n", err.what());
+ return PS_ERROR;
+ }
+#else
+ if (trim)
+ {
+ ERROR_MSG("Error: BrandingText /TRIM* is disabled for non Win32 platforms.\n");
+ return PS_ERROR;
+ }
+#endif
+ SCRIPT_MSG("BrandingText: \"%s\"\n",line.gettoken_str(a));
+ }
+ return PS_OK;
+ case TOK_MISCBUTTONTEXT:
+ {
+ SetInnerString(NLF_BTN_BACK,line.gettoken_str(1));
+ SetInnerString(NLF_BTN_NEXT,line.gettoken_str(2));
+ SetInnerString(NLF_BTN_CANCEL,line.gettoken_str(3));
+ SetInnerString(NLF_BTN_CLOSE,line.gettoken_str(4));
+ SCRIPT_MSG("MiscButtonText: back=\"%s\" next=\"%s\" cancel=\"%s\" close=\"%s\"\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ }
+ return PS_OK;
+ case TOK_SPACETEXTS:
+ {
+ if (!strcmpi(line.gettoken_str(1), "none")) {
+ no_space_texts=true;
+ SCRIPT_MSG("SpaceTexts: none\n");
+ }
+ else {
+ no_space_texts=false;
+ SetInnerString(NLF_SPACE_REQ,line.gettoken_str(1));
+ SetInnerString(NLF_SPACE_AVAIL,line.gettoken_str(2));
+ SCRIPT_MSG("SpaceTexts: required=\"%s\" available=\"%s\"\n",line.gettoken_str(1),line.gettoken_str(2));
+ }
+ }
+ return PS_OK;
+ case TOK_INSTBUTTONTEXT:
+ {
+ SetInnerString(NLF_BTN_INSTALL,line.gettoken_str(1));
+ SCRIPT_MSG("InstallButtonText: \"%s\"\n",line.gettoken_str(1));
+ }
+ return PS_OK;
+ case TOK_DETAILSBUTTONTEXT:
+ {
+ if (!cur_page) {
+ if (SetInnerString(NLF_BTN_DETAILS,line.gettoken_str(1)) == PS_WARNING)
+ warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
+ }
+ else {
+ if (cur_page_type != PAGE_INSTFILES) {
+ ERROR_MSG("Error: DetailsButtonText can only be used inside PageEx instfiles.\n");
+ return PS_ERROR;
+ }
+ cur_page->parms[1] = add_string(line.gettoken_str(1));
+ }
+ SCRIPT_MSG("DetailsButtonText: \"%s\"\n",line.gettoken_str(1));
+ }
+ return PS_OK;
+ case TOK_COMPLETEDTEXT:
+ {
+ if (!cur_page) {
+ if (SetInnerString(NLF_COMPLETED,line.gettoken_str(1)) == PS_WARNING)
+ warning_fl("%s: specified multiple times, wasting space",line.gettoken_str(0));
+ }
+ else {
+ if (cur_page_type != PAGE_INSTFILES) {
+ ERROR_MSG("Error: CompletedText can only be used inside PageEx instfiles.\n");
+ return PS_ERROR;
+ }
+ cur_page->parms[2] = add_string(line.gettoken_str(1));
+ }
+ SCRIPT_MSG("CompletedText: \"%s\"\n",line.gettoken_str(1));
+ }
+ return PS_OK;
+ case TOK_UNINSTBUTTONTEXT:
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ {
+ SetInnerString(NLF_BTN_UNINSTALL,line.gettoken_str(1));
+ SCRIPT_MSG("UninstButtonText: \"%s\"\n",line.gettoken_str(1));
+ }
+ return PS_OK;
+#else
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif
+
+ // instructions
+ ///////////////////////////////////////////////////////////////////////////////
+ case TOK_NOP:
+ SCRIPT_MSG("Nop\n");
+ ent.which=EW_NOP;
+ return add_entry(&ent);
+ case TOK_GOTO:
+ ent.which=EW_NOP;
+ if (process_jump(line,1,&ent.offsets[0])) PRINTHELP()
+ SCRIPT_MSG("Goto: %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_SETREGVIEW:
+ {
+ ent.which=EW_SETFLAG;
+ ent.offsets[0]=FLAG_OFFSET(alter_reg_view);
+ // "64" results in setting the flag to 1 which alters the view
+ int k=line.gettoken_enum(1,"32\0" "64\0lastused\0");
+ if (k<0) PRINTHELP()
+ if (k == 0) // 32
+ ent.offsets[1]=add_intstring(0);
+ else if (k == 1) // 64
+ ent.offsets[1]=add_intstring(KEY_WOW64_64KEY);
+ else if (k == 2) // last used
+ ent.offsets[2]=1;
+ SCRIPT_MSG("SetRegView: %s\n",line.gettoken_str(1));
+ }
+ return add_entry(&ent);
+ case TOK_SETSHELLVARCONTEXT:
+ {
+ ent.which=EW_SETFLAG;
+ ent.offsets[0]=FLAG_OFFSET(all_user_var);
+ int k=line.gettoken_enum(1,"current\0all\0");
+ if (k<0) PRINTHELP()
+ ent.offsets[1]=add_intstring(k);
+ SCRIPT_MSG("SetShellVarContext: %s\n",line.gettoken_str(1));
+ }
+ return add_entry(&ent);
+ case TOK_RET:
+ SCRIPT_MSG("Return\n");
+ ent.which=EW_RET;
+ return add_entry(&ent);
+ case TOK_CALL:
+ if (!line.gettoken_str(1)[0] || (line.gettoken_str(1)[0]==':' && !line.gettoken_str(1)[1] )) PRINTHELP()
+#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
+ if (uninstall_mode && strnicmp(line.gettoken_str(1),"un.",3)
+ && (GetUserVarIndex(line,1) < 0) && line.gettoken_str(1)[0]!=':')
+ {
+ ERROR_MSG("Call must be used with function names starting with \"un.\" in the uninstall section.\n");
+ PRINTHELP()
+ }
+ if (!uninstall_mode && !strnicmp(line.gettoken_str(1),"un.",3))
+ {
+ ERROR_MSG("Call must not be used with functions starting with \"un.\" in the non-uninstall sections.\n");
+ PRINTHELP()
+ }
+#endif
+ ent.which=EW_CALL;
+ ent.offsets[1]=0;
+ {
+ int v;
+ if ((v=GetUserVarIndex(line, 1))>=0)
+ {
+ ent.offsets[0]=-v-2;
+ }
+ else
+ {
+ if (line.gettoken_str(1)[0] == ':')
+ {
+ ent.offsets[1]=1;
+ ent.offsets[0]=ns_label.add(line.gettoken_str(1)+1,0);
+ }
+ else ent.offsets[0]=ns_func.add(line.gettoken_str(1),0);
+ }
+ }
+ SCRIPT_MSG("Call \"%s\"\n",line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_SETOUTPATH:
+ {
+ char *op=line.gettoken_str(1);
+ if (!strcmp(op,"-"))
+ {
+ op="$INSTDIR";
+ }
+ SCRIPT_MSG("SetOutPath: \"%s\"\n",op);
+ ent.which=EW_CREATEDIR;
+ ent.offsets[0]=add_string(op);
+ ent.offsets[1]=1;
+
+ DefineInnerLangString(NLF_OUTPUT_DIR);
+ }
+ return add_entry(&ent);
+ case TOK_CREATEDIR:
+ {
+ char out_path[1024];
+ char *p=line.gettoken_str(1);
+ if (*p == '-') out_path[0]=0;
+ else
+ {
+ if (p[0] == '\\' && p[1] != '\\') p++;
+ strncpy(out_path,p,1024-1);
+ if (*CharPrev(out_path,out_path+strlen(out_path))=='\\')
+ *CharPrev(out_path,out_path+strlen(out_path))=0; // remove trailing slash
+ }
+ if (!*out_path) PRINTHELP()
+ SCRIPT_MSG("CreateDirectory: \"%s\"\n",out_path);
+ ent.which=EW_CREATEDIR;
+ ent.offsets[0]=add_string(out_path);
+
+ DefineInnerLangString(NLF_CREATE_DIR);
+ }
+ return add_entry(&ent);
+ case TOK_EXEC:
+ case TOK_EXECWAIT:
+#ifdef NSIS_SUPPORT_EXECUTE
+ ent.which=EW_EXECUTE;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[2]=0;
+ if (which_token == TOK_EXECWAIT)
+ {
+ ent.offsets[2]=1;
+ ent.offsets[1]=GetUserVarIndex(line, 2);
+ if (line.gettoken_str(2)[0] && ent.offsets[1]<0) PRINTHELP()
+ }
+ SCRIPT_MSG("%s: \"%s\" (->%s)\n",ent.offsets[2]?"ExecWait":"Exec",line.gettoken_str(1),line.gettoken_str(2));
+
+ DefineInnerLangString(NLF_EXEC);
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_EXECUTE
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_EXECUTE not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_EXECUTE
+ case TOK_EXECSHELL: // this uses improvements of Andras Varga
+#ifdef NSIS_SUPPORT_SHELLEXECUTE
+ {
+ ent.which=EW_SHELLEXEC;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=add_string(line.gettoken_str(3));
+ ent.offsets[3]=SW_SHOWNORMAL;
+ if (line.getnumtokens() > 4)
+ {
+ int tab[4]={SW_SHOWNORMAL,SW_SHOWMAXIMIZED,SW_SHOWMINIMIZED,SW_HIDE};
+ int a=line.gettoken_enum(4,"SW_SHOWNORMAL\0SW_SHOWMAXIMIZED\0SW_SHOWMINIMIZED\0SW_HIDE\0");
+ if (a < 0) PRINTHELP()
+ ent.offsets[3]=tab[a];
+ }
+ string detail=string(line.gettoken_str(1))+" "+string(line.gettoken_str(2));
+ ent.offsets[5]=add_string(detail.c_str());
+ SCRIPT_MSG("ExecShell: %s: \"%s\" \"%s\" %s\n",line.gettoken_str(1),line.gettoken_str(2),
+ line.gettoken_str(3),line.gettoken_str(4));
+
+ DefineInnerLangString(NLF_EXEC_SHELL);
+ }
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_SHELLEXECUTE
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_SHELLEXECUTE not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_SHELLEXECUTE
+ case TOK_CALLINSTDLL:
+ case TOK_REGDLL:
+ case TOK_UNREGDLL:
+#ifndef NSIS_SUPPORT_ACTIVEXREG
+ ERROR_MSG("%s: support not compiled in (NSIS_SUPPORT_ACTIVEXREG)\n",line.gettoken_str(0));
+ return PS_ERROR;
+#else//NSIS_SUPPORT_ACTIVEXREG
+ ent.which=EW_REGISTERDLL;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ if (which_token == TOK_UNREGDLL)
+ {
+ ent.offsets[1]=add_string("DllUnregisterServer");
+ ent.offsets[2]=DefineInnerLangString(NLF_UNREGISTERING);
+ }
+ else if (which_token == TOK_CALLINSTDLL)
+ {
+ int a = 2;
+ if (!stricmp(line.gettoken_str(a), "/NOUNLOAD")) {
+ ent.offsets[3]=1;
+ a++;
+ }
+ if (a+1 != line.getnumtokens()) PRINTHELP();
+ ent.offsets[1]=add_string(line.gettoken_str(a));
+ if (!ent.offsets[1]) PRINTHELP()
+ ent.offsets[2]=0;
+ }
+ else // register
+ {
+ ent.offsets[1] = add_string(line.gettoken_str(2));
+ if (!ent.offsets[1]) ent.offsets[1]=add_string("DllRegisterServer");
+ ent.offsets[2]=DefineInnerLangString(NLF_REGISTERING);
+ }
+
+ SCRIPT_MSG("%s: \"%s\" %s\n",line.gettoken_str(0),line.gettoken_str(1), line.gettoken_str(ent.offsets[3]?3:2));
+
+ DefineInnerLangString(NLF_SYMBOL_NOT_FOUND);
+ DefineInnerLangString(NLF_COULD_NOT_LOAD);
+ DefineInnerLangString(NLF_NO_OLE);
+ // not used anywhere - DefineInnerLangString(NLF_ERR_REG_DLL);
+ return add_entry(&ent);
+#endif//NSIS_SUPPORT_ACTIVEXREG
+ case TOK_RENAME:
+#ifdef NSIS_SUPPORT_RENAME
+ {
+ int a=1;
+ ent.which=EW_RENAME;
+ if (!stricmp(line.gettoken_str(1),"/REBOOTOK"))
+ {
+ ent.offsets[2]=1;
+ a++;
+#ifndef NSIS_SUPPORT_MOVEONREBOOT
+ ERROR_MSG("Error: /REBOOTOK specified, NSIS_SUPPORT_MOVEONREBOOT not defined\n");
+ PRINTHELP()
+#endif
+ }
+ else if (line.gettoken_str(1)[0]=='/')
+ {
+ a=line.getnumtokens(); // cause usage to go here:
+ }
+ if (line.getnumtokens()!=a+2) PRINTHELP()
+ ent.offsets[0]=add_string(line.gettoken_str(a));
+ ent.offsets[1]=add_string(line.gettoken_str(a+1));
+ string print = string(line.gettoken_str(a)) + "->" + string(line.gettoken_str(a+1));
+ ent.offsets[3]=add_string(print.c_str());
+ SCRIPT_MSG("Rename: %s%s->%s\n",ent.offsets[2]?"/REBOOTOK ":"",line.gettoken_str(a),line.gettoken_str(a+1));
+
+ DefineInnerLangString(NLF_RENAME);
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+ DefineInnerLangString(NLF_RENAME_ON_REBOOT);
+#endif
+ }
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_RENAME
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_RENAME not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_RENAME
+ case TOK_MESSAGEBOX:
+#ifdef NSIS_SUPPORT_MESSAGEBOX
+ {
+ #define MBD(x) {x,#x},
+ struct
+ {
+ int id;
+ char *str;
+ } list[]=
+ {
+ MBD(MB_ABORTRETRYIGNORE)
+ MBD(MB_OK)
+ MBD(MB_OKCANCEL)
+ MBD(MB_RETRYCANCEL)
+ MBD(MB_YESNO)
+ MBD(MB_YESNOCANCEL)
+ MBD(MB_ICONEXCLAMATION)
+ MBD(MB_ICONINFORMATION)
+ MBD(MB_ICONQUESTION)
+ MBD(MB_ICONSTOP)
+ MBD(MB_USERICON)
+ MBD(MB_TOPMOST)
+ MBD(MB_SETFOREGROUND)
+ MBD(MB_RIGHT)
+ MBD(MB_RTLREADING)
+ MBD(MB_DEFBUTTON1)
+ MBD(MB_DEFBUTTON2)
+ MBD(MB_DEFBUTTON3)
+ MBD(MB_DEFBUTTON4)
+ };
+ #undef MBD
+ int r=0;
+ int x;
+ char *p=line.gettoken_str(1);
+
+ while (*p)
+ {
+ char *np=p;
+ while (*np && *np != '|') np++;
+ if (*np) *np++=0;
+ for (x = 0 ; (unsigned) x < sizeof(list) / sizeof(list[0]) && strcmpi(list[x].str, p); x++);
+ if ((unsigned) x < sizeof(list) / sizeof(list[0]))
+ {
+ r|=list[x].id;
+ }
+ else PRINTHELP()
+ p=np;
+ }
+ ent.which=EW_MESSAGEBOX;
+ ent.offsets[0]=r;
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ int rettab[] =
+ {
+ 0,IDABORT,IDCANCEL,IDIGNORE,IDNO,IDOK,IDRETRY,IDYES
+ };
+ const char *retstr="0\0IDABORT\0IDCANCEL\0IDIGNORE\0IDNO\0IDOK\0IDRETRY\0IDYES\0";
+ int a=3;
+ if (line.getnumtokens() > 3)
+ {
+ if (!strcmpi(line.gettoken_str(3),"/SD"))
+ {
+ int k=line.gettoken_enum(4,retstr);
+ if (k <= 0) PRINTHELP();
+ ent.offsets[0]|=rettab[k]<<21;
+ a=5;
+ }
+ else if (line.getnumtokens() > 7)
+ PRINTHELP();
+
+ if (line.getnumtokens() > a)
+ {
+ ent.offsets[2]=line.gettoken_enum(a,retstr);
+ if (ent.offsets[2] < 0)
+ PRINTHELP();
+ ent.offsets[2] = rettab[ent.offsets[2]];
+ if (process_jump(line,a+1,&ent.offsets[3]))
+ PRINTHELP();
+ if (line.getnumtokens() > a+2)
+ {
+ int v=line.gettoken_enum(a+2,retstr);
+ if (v < 0)
+ PRINTHELP();
+ ent.offsets[4] = rettab[v];
+ if (process_jump(line,a+3,&ent.offsets[5]))
+ PRINTHELP();
+ }
+ }
+ }
+ SCRIPT_MSG("MessageBox: %d: \"%s\"",r,line.gettoken_str(2));
+ if (line.getnumtokens()>a+1) SCRIPT_MSG(" (on %s goto %s)",line.gettoken_str(a),line.gettoken_str(a+1));
+ SCRIPT_MSG("\n");
+ }
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_MESSAGEBOX
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_MESSAGEBOX not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_MESSAGEBOX
+ case TOK_CREATESHORTCUT:
+#ifdef NSIS_SUPPORT_CREATESHORTCUT
+ ent.which=EW_CREATESHORTCUT;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=add_string(line.gettoken_str(3));
+ ent.offsets[3]=add_string(line.gettoken_str(4));
+ ent.offsets[5]=add_string(line.gettoken_str(8));
+ int s;
+ ent.offsets[4]=line.gettoken_int(5,&s)&0xff;
+ if (!s)
+ {
+ if (line.getnumtokens() > 5 && *line.gettoken_str(5))
+ {
+ ERROR_MSG("CreateShortCut: cannot interpret icon index\n");
+ PRINTHELP()
+ }
+ ent.offsets[4]=0;
+ }
+ if (line.getnumtokens() > 6 && *line.gettoken_str(6))
+ {
+ int tab[3]={SW_SHOWNORMAL,SW_SHOWMAXIMIZED,SW_SHOWMINNOACTIVE/*SW_SHOWMINIMIZED doesn't work*/};
+ int a=line.gettoken_enum(6,"SW_SHOWNORMAL\0SW_SHOWMAXIMIZED\0SW_SHOWMINIMIZED\0");
+ if (a < 0)
+ {
+ ERROR_MSG("CreateShortCut: unknown show mode \"%s\"\n",line.gettoken_str(6));
+ PRINTHELP()
+ }
+ ent.offsets[4]|=tab[a]<<8;
+ }
+ if (line.getnumtokens() > 7)
+ {
+ char *s=(line.gettoken_str(7));
+
+ char b[255];
+ for (unsigned int spos=0; (spos <= strlen(s)) && (spos <= 255); spos++)
+ b[spos]=toupper(*(s+spos));
+ strcpy(s,b);
+
+ if (*s)
+ {
+ int c=0;
+ if (strstr(s,"ALT|")) ent.offsets[4]|=HOTKEYF_ALT << 24;
+ if (strstr(s,"CONTROL|")) ent.offsets[4]|=HOTKEYF_CONTROL << 24;
+ if (strstr(s,"EXT|")) ent.offsets[4]|=HOTKEYF_EXT << 24;
+ if (strstr(s,"SHIFT|")) ent.offsets[4]|=HOTKEYF_SHIFT << 24;
+ while (strstr(s,"|"))
+ {
+ s=strstr(s,"|")+1;
+ }
+ if ((s[0] == 'F') && (s[1] >= '1' && s[1] <= '9'))
+ {
+ c=VK_F1-1+atoi(s+1);
+ if (atoi(s+1) < 1 || atoi(s+1) > 24)
+ {
+ warning_fl("CreateShortCut: F-key \"%s\" out of range",s);
+ }
+ }
+ else if (((s[0] >= 'A' && s[0] <= 'Z') || (s[0] >= '0' && s[0] <= '9')) && !s[1])
+ c=s[0];
+ else
+ {
+ c=s[0];
+ warning_fl("CreateShortCut: unrecognized hotkey \"%s\"",s);
+ }
+ ent.offsets[4] |= (c) << 16;
+ }
+ }
+ SCRIPT_MSG("CreateShortCut: \"%s\"->\"%s\" %s icon:%s,%d, showmode=0x%X, hotkey=0x%X, comment=%s\n",
+ line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),
+ line.gettoken_str(4),ent.offsets[4]&0xff,(ent.offsets[4]>>8)&0xff,ent.offsets[4]>>16,line.gettoken_str(8));
+
+ DefineInnerLangString(NLF_CREATE_SHORTCUT);
+ DefineInnerLangString(NLF_ERR_CREATING_SHORTCUT);
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_CREATESHORTCUT
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_CREATESHORTCUT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//NSIS_SUPPORT_CREATESHORTCUT
+#ifdef NSIS_SUPPORT_HWNDS
+ case TOK_FINDWINDOW:
+ ent.which=EW_FINDWINDOW;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ if (ent.offsets[0] < 0) PRINTHELP()
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=add_string(line.gettoken_str(3));
+ ent.offsets[3]=add_string(line.gettoken_str(4));
+ ent.offsets[4]=add_string(line.gettoken_str(5));
+ SCRIPT_MSG("FindWindow: output=%s, class=\"%s\", text=\"%s\" hwndparent=\"%s\" hwndafter=\"%s\"\n",
+ line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4),line.gettoken_str(5));
+ return add_entry(&ent);
+ case TOK_SENDMESSAGE:
+ ent.which=EW_SENDMESSAGE;
+
+ if (line.gettoken_str(1)[0] == '/' || line.gettoken_str(2)[0] == '/' ||
+ line.gettoken_str(3)[0] == '/' || line.gettoken_str(4)[0] == '/')
+ {
+ PRINTHELP()
+ }
+
+ SCRIPT_MSG("SendMessage:");
+ {
+ int a=5;
+ ent.offsets[0]=GetUserVarIndex(line, 5);
+ if (ent.offsets[0]>=0)
+ {
+ SCRIPT_MSG("(->%s)",line.gettoken_str(5));
+ a++;
+ }
+
+ if (!strncmp(line.gettoken_str(a),"/TIMEOUT=",9))
+ {
+ ent.offsets[5]|=atoi(line.gettoken_str(a)+9)<<2;
+ SCRIPT_MSG(" (timeout=%d)",ent.offsets[5]>>2);
+ a++;
+ }
+
+ if (line.getnumtokens()>a)
+ {
+ PRINTHELP()
+ }
+ }
+
+ if (!strncmp(line.gettoken_str(3),"STR:",4))
+ {
+ ent.offsets[5]|=1;
+ ent.offsets[3]=add_string(line.gettoken_str(3)+4);
+ }
+ else ent.offsets[3]=add_string(line.gettoken_str(3));
+ if (!strncmp(line.gettoken_str(4),"STR:",4))
+ {
+ ent.offsets[5]|=2;
+ ent.offsets[4]=add_string(line.gettoken_str(4)+4);
+ }
+ else ent.offsets[4]=add_string(line.gettoken_str(4));
+
+ ent.offsets[1]=add_string(line.gettoken_str(1));
+ ent.offsets[2]=add_string(line.gettoken_str(2));
+
+ SCRIPT_MSG("(%s,%s,%s,%s)\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ return add_entry(&ent);
+ case TOK_ISWINDOW:
+ ent.which=EW_ISWINDOW;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ if (process_jump(line,2,&ent.offsets[1])||
+ process_jump(line,3,&ent.offsets[2])) PRINTHELP()
+ SCRIPT_MSG("IsWindow(%s): %s:%s\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
+ return add_entry(&ent);
+#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ case TOK_GETDLGITEM:
+ ent.which=EW_GETDLGITEM;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ if (ent.offsets[0]<0) PRINTHELP();
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=add_string(line.gettoken_str(3));
+ SCRIPT_MSG("GetDlgItem: output=%s dialog=%s item=%s\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
+ return add_entry(&ent);
+ case TOK_SETCTLCOLORS:
+ {
+ ctlcolors c={0, };
+
+ ent.which=EW_SETCTLCOLORS;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+
+ int a = 2;
+
+ if (!strcmpi(line.gettoken_str(2),"/BRANDING"))
+ a++;
+
+ {
+ char *p;
+
+ if (a == 2 && line.getnumtokens() == 5) {
+ ERROR_MSG("Error: SetCtlColors expected 3 parameters, got 4\n");
+ return PS_ERROR;
+ }
+
+ if (!strcmpi(line.gettoken_str(a+1),"transparent")) {
+ c.flags|=CC_BKB;
+ c.lbStyle=BS_NULL;
+ c.bkmode=TRANSPARENT;
+ }
+ else {
+ p=line.gettoken_str(a+1);
+ if (*p) {
+ int v=strtoul(p,&p,16);
+ c.bkc=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16);
+ c.flags|=CC_BK|CC_BKB;
+ }
+
+ c.lbStyle=BS_SOLID;
+ c.bkmode=OPAQUE;
+ }
+
+ p=line.gettoken_str(a);
+ if (*p) {
+ int v=strtoul(p,&p,16);
+ c.text=((v&0xff)<<16)|(v&0xff00)|((v&0xff0000)>>16);
+ c.flags|=CC_TEXT;
+ }
+ }
+
+ if (a == 3)
+ {
+ c.flags|=CC_BK|CC_BKB;
+ c.lbStyle=BS_NULL;
+ if (!*line.gettoken_str(a+1))
+ {
+ c.bkc=COLOR_BTNFACE;
+ c.flags|=CC_BK_SYS;
+ }
+ c.flags|=CC_TEXT;
+ if (!*line.gettoken_str(a))
+ {
+ c.text=COLOR_BTNFACE;
+ c.flags|=CC_TEXT_SYS;
+ }
+ c.bkmode=OPAQUE;
+ }
+
+ int i;
+ int l=cur_ctlcolors->getlen()/sizeof(ctlcolors);
+ for (i=0; i<l; i++) {
+ if (!memcmp((ctlcolors*)cur_ctlcolors->get()+i,&c,sizeof(ctlcolors))) {
+ ent.offsets[1]=i*sizeof(ctlcolors);
+ break;
+ }
+ }
+ if (i>=l) {
+ ent.offsets[1]=cur_ctlcolors->add(&c,sizeof(ctlcolors));
+ }
+
+ SCRIPT_MSG("SetCtlColors: hwnd=%s %stext=%s background=%s\n",line.gettoken_str(1),a==2?"":"/BRANDING ",line.gettoken_str(a),line.gettoken_str(a+1));
+ }
+ return add_entry(&ent);
+ case TOK_CREATEFONT:
+ ent.which=EW_CREATEFONT;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ SCRIPT_MSG("CreateFont: output=%s \"%s\"",line.gettoken_str(1),line.gettoken_str(2));
+ {
+ int height=0;
+ int weight=0;
+ int flags=0;
+ for (int i = 3; i < line.getnumtokens(); i++) {
+ char *tok=line.gettoken_str(i);
+ if (tok[0]=='/') {
+ if (!strcmpi(tok,"/ITALIC")) {
+ SCRIPT_MSG(" /ITALIC");
+ flags|=1;
+ }
+ else if (!strcmpi(tok,"/UNDERLINE")) {
+ SCRIPT_MSG(" /UNDERLINE");
+ flags|=2;
+ }
+ else if (!strcmpi(tok,"/STRIKE")) {
+ SCRIPT_MSG(" /STRIKE");
+ flags|=4;
+ }
+ else {
+ SCRIPT_MSG("\n");
+ PRINTHELP();
+ }
+ }
+ else {
+ if (!height) {
+ SCRIPT_MSG(" height=%s",tok);
+ height=add_string(tok);
+ }
+ else if (!weight) {
+ SCRIPT_MSG(" weight=%s",tok);
+ weight=add_string(tok);
+ }
+ else {
+ SCRIPT_MSG("\n");
+ PRINTHELP();
+ }
+ }
+ }
+ ent.offsets[2]=height;
+ ent.offsets[3]=weight;
+ ent.offsets[4]=flags;
+ }
+ SCRIPT_MSG("\n");
+ return add_entry(&ent);
+ case TOK_ENABLEWINDOW:
+ ent.which=EW_SHOWWINDOW;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[3]=1;
+ SCRIPT_MSG("EnableWindow: handle=%s enable=%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_SHOWWINDOW:
+ ent.which=EW_SHOWWINDOW;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ SCRIPT_MSG("ShowWindow: handle=%s show state=%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_HIDEWINDOW:
+ ent.which=EW_SHOWWINDOW;
+ ent.offsets[0]=add_string("$HWNDPARENT");
+ ent.offsets[1]=add_string("0"/*SW_HIDE*/);
+ ent.offsets[2]=1;
+ SCRIPT_MSG("HideWindow\n");
+ return add_entry(&ent);
+ case TOK_BRINGTOFRONT:
+ {
+ int ret;
+ ent.which=EW_SHOWWINDOW;
+ ent.offsets[0]=add_string("$HWNDPARENT");
+ ent.offsets[1]=add_string("5"/*SW_SHOW*/);
+ ret = add_entry(&ent);
+ if (ret != PS_OK) return ret;
+ ent.which=EW_BRINGTOFRONT;
+ ent.offsets[0]=0;
+ ent.offsets[1]=0;
+ SCRIPT_MSG("BringToFront\n");
+ }
+ return add_entry(&ent);
+#else//NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ case TOK_GETDLGITEM:
+ case TOK_SETCTLCOLORS:
+ case TOK_SHOWWINDOW:
+ case TOK_BRINGTOFRONT:
+ case TOK_CREATEFONT:
+ case TOK_HIDEWINDOW:
+ case TOK_ENABLEWINDOW:
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_ENHANCEDUI_SUPPORT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//NSIS_CONFIG_ENHANCEDUI_SUPPORT
+#else//!NSIS_SUPPORT_HWNDS
+ case TOK_ISWINDOW:
+ case TOK_SENDMESSAGE:
+ case TOK_FINDWINDOW:
+ case TOK_GETDLGITEM:
+ case TOK_SETCTLCOLORS:
+ case TOK_SHOWWINDOW:
+ case TOK_ENABLEWINDOW:
+ case TOK_CREATEFONT:
+ case TOK_HIDEWINDOW:
+ case TOK_BRINGTOFRONT:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_HWNDS not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_HWNDS
+ case TOK_DELETE:
+#ifdef NSIS_SUPPORT_DELETE
+ {
+ int a=1;
+ ent.which=EW_DELETEFILE;
+ if (!stricmp(line.gettoken_str(a),"/REBOOTOK"))
+ {
+ a++;
+ ent.offsets[1]=DEL_REBOOT;
+#ifndef NSIS_SUPPORT_MOVEONREBOOT
+ ERROR_MSG("Error: /REBOOTOK specified, NSIS_SUPPORT_MOVEONREBOOT not defined\n");
+ PRINTHELP()
+#endif
+ }
+ else if (line.gettoken_str(1)[0]=='/')
+ {
+ a=line.getnumtokens();
+ }
+ if (line.getnumtokens() != a+1) PRINTHELP()
+ ent.offsets[0]=add_string(line.gettoken_str(a));
+ SCRIPT_MSG("Delete: %s\"%s\"\n",ent.offsets[1]?"/REBOOTOK ":"",line.gettoken_str(a));
+
+ DefineInnerLangString(NLF_DEL_FILE);
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+ DefineInnerLangString(NLF_DEL_ON_REBOOT);
+#endif
+ }
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_DELETE
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_DELETE not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_DELETE
+ case TOK_RMDIR:
+#ifdef NSIS_SUPPORT_RMDIR
+ {
+ int a=1;
+ ent.which=EW_RMDIR;
+ ent.offsets[1]=DEL_DIR;
+ while (line.gettoken_str(a)[0]=='/')
+ {
+ if (!stricmp(line.gettoken_str(a),"/r"))
+ {
+ if (a == 3) PRINTHELP();
+ a++;
+ ent.offsets[1]|=DEL_RECURSE;
+ }
+ else if (!stricmp(line.gettoken_str(a),"/REBOOTOK"))
+ {
+ if (a == 3) PRINTHELP();
+ a++;
+ ent.offsets[1]|=DEL_REBOOT;
+ }
+ else PRINTHELP();
+ }
+ if (a < line.getnumtokens() - 1) PRINTHELP();
+ ent.offsets[0]=add_string(line.gettoken_str(a));
+ SCRIPT_MSG("RMDir: ");
+ if (a>1)
+ SCRIPT_MSG("%s ",line.gettoken_str(1));
+ if (a>2)
+ SCRIPT_MSG("%s ",line.gettoken_str(2));
+ SCRIPT_MSG("\"%s\"\n",line.gettoken_str(a));
+
+ DefineInnerLangString(NLF_REMOVE_DIR);
+ DefineInnerLangString(NLF_DEL_FILE);
+#ifdef NSIS_SUPPORT_MOVEONREBOOT
+ DefineInnerLangString(NLF_DEL_ON_REBOOT);
+#endif
+ }
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_RMDIR
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_RMDIR not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_RMDIR
+ case TOK_RESERVEFILE:
+ case TOK_FILE:
+#ifdef NSIS_SUPPORT_FILE
+ {
+ set<string> excluded;
+ int a=1,attrib=0,rec=0,fatal=1;
+ if (!stricmp(line.gettoken_str(a),"/nonfatal")) {
+ fatal=0;
+ a++;
+ }
+ if (which_token == TOK_FILE && !stricmp(line.gettoken_str(a),"/a"))
+ {
+#ifdef _WIN32
+ attrib=1;
+#else
+ warning_fl("%sFile /a is disabled for non Win32 platforms.",(which_token == TOK_FILE)?"":"Reserve");
+#endif
+ a++;
+ }
+ if (!stricmp(line.gettoken_str(a),"/r"))
+ {
+ rec=1;
+ a++;
+ }
+ else if (which_token == TOK_FILE && !strnicmp(line.gettoken_str(a),"/oname=",7))
+ {
+ char *on=line.gettoken_str(a)+7;
+ a++;
+ if (!*on||line.getnumtokens()!=a+1||strstr(on,"*") || strstr(on,"?")) PRINTHELP()
+
+ if (on[0]=='"')
+ {
+ ERROR_MSG("%sFile: output name must not begin with a quote, use \"/oname=name with spaces\".\n",(which_token == TOK_FILE)?"":"Reserve",line.gettoken_str(a));
+ PRINTHELP();
+ }
+
+ int tf=0;
+#ifdef _WIN32
+ int v=do_add_file(line.gettoken_str(a), attrib, 0, &tf, on);
+#else
+ char *fn = my_convert(line.gettoken_str(a));
+ int v=do_add_file(fn, attrib, 0, &tf, on);
+ my_convert_free(fn);
+#endif
+ if (v != PS_OK) return v;
+ if (tf > 1) PRINTHELP()
+ if (!tf)
+ {
+ if (fatal)
+ {
+ ERROR_MSG("%sFile: \"%s\" -> no files found.\n",(which_token == TOK_FILE)?"":"Reserve",line.gettoken_str(a));
+ PRINTHELP()
+ }
+ else
+ {
+ warning_fl("%sFile: \"%s\" -> no files found",(which_token == TOK_FILE)?"":"Reserve",line.gettoken_str(a));
+
+ // workaround for bug #1299100
+ // add a nop opcode so relative jumps will work as expected
+ add_entry_direct(EW_NOP);
+ }
+ }
+
+ return PS_OK;
+ }
+ if (!strnicmp(line.gettoken_str(a),"/x",2))
+ {
+ while (!strnicmp(line.gettoken_str(a),"/x",2))
+ {
+ a++;
+
+ if (line.getnumtokens() < a+1) PRINTHELP()
+
+ excluded.insert(line.gettoken_str(a));
+ a++;
+ }
+ }
+#ifdef _WIN32
+ if (line.gettoken_str(a)[0] == '/') PRINTHELP()
+#endif
+ if (line.getnumtokens()<a+1) PRINTHELP()
+ while (a < line.getnumtokens())
+ {
+#ifdef _WIN32
+ if (line.gettoken_str(a)[0]=='/') PRINTHELP()
+#endif
+ char buf[32];
+ char *t=line.gettoken_str(a++);
+ if (t[0] && CharNext(t)[0] == ':' && CharNext(t)[1] == '\\' && !CharNext(t)[2])
+ {
+ strcpy(buf,"X:\\*.*");
+ buf[0]=t[0];
+ t=buf;
+ }
+ int tf=0;
+#ifdef _WIN32
+ int v=do_add_file(t, attrib, rec, &tf, NULL, which_token == TOK_FILE, NULL, excluded);
+#else
+ char *fn = my_convert(t);
+ int v=do_add_file(fn, attrib, rec, &tf, NULL, which_token == TOK_FILE, NULL, excluded);
+ my_convert_free(fn);
+#endif
+ if (v != PS_OK) return v;
+ if (!tf)
+ {
+ if (fatal)
+ {
+ ERROR_MSG("%sFile: \"%s\" -> no files found.\n",(which_token == TOK_FILE)?"":"Reserve",t);
+ PRINTHELP();
+ }
+ else
+ {
+ warning_fl("%sFile: \"%s\" -> no files found.",(which_token == TOK_FILE)?"":"Reserve",t);
+ }
+ }
+ }
+ }
+ return PS_OK;
+#else//!NSIS_SUPPORT_FILE
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_FILE not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_FILE
+#ifdef NSIS_SUPPORT_COPYFILES
+ case TOK_COPYFILES:
+ {
+ ent.which=EW_COPYFILES;
+ ent.offsets[2]=FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_NOERRORUI|FOF_SIMPLEPROGRESS;
+
+ int a=1;
+ int x;
+ for (x = 0; x < 2; x ++)
+ {
+ if (!stricmp(line.gettoken_str(a),"/SILENT"))
+ {
+ a++;
+ ent.offsets[2]&=~FOF_SIMPLEPROGRESS;
+ ent.offsets[2]|=FOF_SILENT;
+ }
+ else if (!stricmp(line.gettoken_str(a),"/FILESONLY"))
+ {
+ a++;
+ ent.offsets[2]|=FOF_FILESONLY;
+ }
+ else if (line.gettoken_str(a)[0]=='/') PRINTHELP()
+ else break;
+ }
+ if (line.getnumtokens() < a+2) PRINTHELP()
+ ent.offsets[0]=add_string(line.gettoken_str(a));
+ ent.offsets[1]=add_string(line.gettoken_str(a+1));
+ string copy_to = string("$(^CopyTo)") + line.gettoken_str(a+1);
+ ent.offsets[3]=add_string(copy_to.c_str());
+ int s;
+ int size_kb=line.gettoken_int(a+2,&s);
+ if (!s && line.gettoken_str(a+2)[0]) PRINTHELP()
+ section_add_size_kb(size_kb);
+ SCRIPT_MSG("CopyFiles: %s\"%s\" -> \"%s\", size=%iKB\n",ent.offsets[2]&FOF_SILENT?"(silent) ":"", line.gettoken_str(a),line.gettoken_str(a+1),size_kb);
+
+ DefineInnerLangString(NLF_COPY_FAILED);
+ DefineInnerLangString(NLF_COPY_TO);
+ }
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_COPYFILES
+ case TOK_COPYFILES:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_COPYFILES not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_COPYFILES
+
+ case TOK_SETFILEATTRIBUTES:
+ {
+ #define MBD(x) {x,#x},
+ struct
+ {
+ int id;
+ char *str;
+ } list[]=
+ {
+ MBD(FILE_ATTRIBUTE_NORMAL)
+ MBD(FILE_ATTRIBUTE_ARCHIVE)
+ MBD(FILE_ATTRIBUTE_HIDDEN)
+ MBD(FILE_ATTRIBUTE_OFFLINE)
+ MBD(FILE_ATTRIBUTE_READONLY)
+ MBD(FILE_ATTRIBUTE_SYSTEM)
+ MBD(FILE_ATTRIBUTE_TEMPORARY)
+ {FILE_ATTRIBUTE_NORMAL,"NORMAL"},
+ {FILE_ATTRIBUTE_ARCHIVE,"ARCHIVE"},
+ {FILE_ATTRIBUTE_HIDDEN,"HIDDEN"},
+ {FILE_ATTRIBUTE_OFFLINE,"OFFLINE"},
+ {FILE_ATTRIBUTE_READONLY,"READONLY"},
+ {FILE_ATTRIBUTE_SYSTEM,"SYSTEM"},
+ {FILE_ATTRIBUTE_TEMPORARY,"TEMPORARY"},
+ {FILE_ATTRIBUTE_NORMAL,"0"},
+ };
+ #undef MBD
+ int r=0;
+ int x;
+ char *p=line.gettoken_str(2);
+
+ while (*p)
+ {
+ char *np=p;
+ while (*np && *np != '|') np++;
+ if (*np) *np++=0;
+ for (x = 0 ; (unsigned) x < sizeof(list)/sizeof(list[0]) && stricmp(list[x].str,p); x ++);
+
+ if ((unsigned) x < sizeof(list)/sizeof(list[0]))
+ {
+ r|=list[x].id;
+ }
+ else PRINTHELP()
+ p=np;
+ }
+ ent.which=EW_SETFILEATTRIBUTES;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=r;
+ }
+ return add_entry(&ent);
+ case TOK_SLEEP:
+ {
+ ent.which=EW_SLEEP;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ SCRIPT_MSG("Sleep: %s ms\n",line.gettoken_str(1));
+ }
+ return add_entry(&ent);
+ case TOK_IFFILEEXISTS:
+ ent.which=EW_IFFILEEXISTS;
+ ent.offsets[0] = add_string(line.gettoken_str(1));
+ if (process_jump(line,2,&ent.offsets[1]) ||
+ process_jump(line,3,&ent.offsets[2])) PRINTHELP()
+ SCRIPT_MSG("IfFileExists: \"%s\" ? %s : %s\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
+ return add_entry(&ent);
+ case TOK_QUIT:
+ ent.which=EW_QUIT;
+ SCRIPT_MSG("Quit\n");
+ return add_entry(&ent);
+ case TOK_ABORT:
+ ent.which=EW_ABORT;
+ ent.offsets[0] = add_string(line.gettoken_str(1));
+ SCRIPT_MSG("Abort: \"%s\"\n",line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_SETDETAILSVIEW:
+ {
+ int v=line.gettoken_enum(1,"hide\0show\0");
+ ent.which=EW_CHDETAILSVIEW;
+ if (v < 0) PRINTHELP()
+ ent.offsets[0] = v?SW_SHOWNA:SW_HIDE;
+ ent.offsets[1] = v?SW_HIDE:SW_SHOWNA;
+ SCRIPT_MSG("SetDetailsView: %s\n",line.gettoken_str(1));
+ }
+ return add_entry(&ent);
+ case TOK_SETDETAILSPRINT:
+ {
+ ent.which=EW_SETFLAG;
+ ent.offsets[0]=FLAG_OFFSET(status_update);
+ int k=line.gettoken_enum(1,"both\0textonly\0listonly\0none\0lastused\0");
+ if (k<0) PRINTHELP()
+ if (k == 4)
+ {
+ ent.offsets[2]=1;
+ }
+ else
+ {
+ // both 0
+ // textonly 2
+ // listonly 4
+ // none 6
+ ent.offsets[1]=add_intstring(k*2);
+ }
+ SCRIPT_MSG("SetDetailsPrint: %s\n",line.gettoken_str(1));
+ }
+ return add_entry(&ent);
+ case TOK_SETAUTOCLOSE:
+ {
+ ent.which=EW_SETFLAG;
+ ent.offsets[0]=FLAG_OFFSET(autoclose);
+ int k=line.gettoken_enum(1,"false\0true\0");
+ if (k < 0) PRINTHELP()
+ ent.offsets[1]=add_intstring(k);
+ SCRIPT_MSG("SetAutoClose: %s\n",line.gettoken_str(1));
+ }
+ return add_entry(&ent);
+ case TOK_IFERRORS:
+ ent.which=EW_IFFLAG;
+ if (process_jump(line,1,&ent.offsets[0]) ||
+ process_jump(line,2,&ent.offsets[1])) PRINTHELP()
+ ent.offsets[2]=FLAG_OFFSET(exec_error);
+ ent.offsets[3]=0;//new value mask - clean error
+ SCRIPT_MSG("IfErrors ?%s:%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_IFABORT:
+ ent.which=EW_IFFLAG;
+ if (process_jump(line,1,&ent.offsets[0]) ||
+ process_jump(line,2,&ent.offsets[1])) PRINTHELP()
+ ent.offsets[2]=FLAG_OFFSET(abort);
+ ent.offsets[3]=~0;//new value mask - keep flag
+ SCRIPT_MSG("IfAbort ?%s:%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_CLEARERRORS:
+ ent.which=EW_SETFLAG;
+ ent.offsets[0]=FLAG_OFFSET(exec_error);
+ ent.offsets[1]=add_intstring(0);
+ SCRIPT_MSG("ClearErrors\n");
+ return add_entry(&ent);
+ case TOK_SETERRORS:
+ ent.which=EW_SETFLAG;
+ ent.offsets[0]=FLAG_OFFSET(exec_error);
+ ent.offsets[1]=add_intstring(1);
+ SCRIPT_MSG("SetErrors\n");
+ return add_entry(&ent);
+ case TOK_SETERRORLEVEL:
+ ent.which=EW_SETFLAG;
+ ent.offsets[0]=FLAG_OFFSET(errlvl);
+ ent.offsets[1]=add_string(line.gettoken_str(1));
+ SCRIPT_MSG("SetErrorLevel: %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_GETERRORLEVEL:
+ ent.which=EW_GETFLAG;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ ent.offsets[1]=FLAG_OFFSET(errlvl);
+ if (line.gettoken_str(1)[0] && ent.offsets[0]<0) PRINTHELP()
+ SCRIPT_MSG("GetErrorLevel: %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+#ifdef NSIS_SUPPORT_STROPTS
+ case TOK_STRLEN:
+ ent.which=EW_STRLEN;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ if (ent.offsets[0] < 0) PRINTHELP()
+ SCRIPT_MSG("StrLen %s \"%s\"\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_STRCPY:
+ ent.which=EW_ASSIGNVAR;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=add_string(line.gettoken_str(3));
+ ent.offsets[3]=add_string(line.gettoken_str(4));
+
+ if (ent.offsets[0] < 0) PRINTHELP()
+ SCRIPT_MSG("StrCpy %s \"%s\" (%s) (%s)\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ return add_entry(&ent);
+ case TOK_GETFUNCTIONADDR:
+ ent.which=EW_GETFUNCTIONADDR;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ ent.offsets[1]=ns_func.add(line.gettoken_str(2),0);
+ ent.offsets[2]=0;
+ ent.offsets[3]=0;
+ if (ent.offsets[0] < 0) PRINTHELP()
+ SCRIPT_MSG("GetFunctionAddress: %s %s",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_GETLABELADDR:
+ ent.which=EW_GETLABELADDR;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ if (ent.offsets[0] < 0 || process_jump(line,2,&ent.offsets[1])) PRINTHELP()
+ ent.offsets[2]=0;
+ ent.offsets[3]=0;
+ SCRIPT_MSG("GetLabelAddress: %s %s",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_GETCURRENTADDR:
+ ent.which=EW_ASSIGNVAR;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ {
+ char buf[32];
+ wsprintf(buf,"%d",1+(cur_header->blocks[NB_ENTRIES].num));
+ ent.offsets[1]=add_string(buf);
+ }
+ if (ent.offsets[0] < 0) PRINTHELP()
+ ent.offsets[2]=0;
+ ent.offsets[3]=0;
+ SCRIPT_MSG("GetCurrentAddress: %s",line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_STRCMP:
+ case TOK_STRCMPS:
+ ent.which=EW_STRCMP;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[4]=which_token == TOK_STRCMPS;
+ if (process_jump(line,3,&ent.offsets[2]) ||
+ process_jump(line,4,&ent.offsets[3])) PRINTHELP()
+ SCRIPT_MSG("%s \"%s\" \"%s\" equal=%s, nonequal=%s\n",line.gettoken_str(0),line.gettoken_str(1),line.gettoken_str(2), line.gettoken_str(3),line.gettoken_str(4));
+ return add_entry(&ent);
+ case TOK_GETDLLVERSIONLOCAL:
+ {
+ DWORD low, high;
+ if (!GetDLLVersion(line.gettoken_str(1),high,low))
+ {
+ ERROR_MSG("GetDLLVersionLocal: error reading version info from \"%s\"\n",line.gettoken_str(1));
+ return PS_ERROR;
+ }
+ ent.which=EW_ASSIGNVAR;
+ ent.offsets[0]=GetUserVarIndex(line, 2);
+ ent.offsets[1]=add_intstring(high);
+ ent.offsets[2]=0;
+ ent.offsets[3]=0;
+ if (ent.offsets[0]<0) PRINTHELP()
+ add_entry(&ent);
+
+ ent.offsets[0]=GetUserVarIndex(line, 3);
+ ent.offsets[1]=add_intstring(low);
+ ent.offsets[2]=0;
+ ent.offsets[3]=0;
+ if (ent.offsets[0]<0) PRINTHELP()
+ SCRIPT_MSG("GetDLLVersionLocal: %s (%u,%u)->(%s,%s)\n",
+ line.gettoken_str(1),high,low,line.gettoken_str(2),line.gettoken_str(3));
+ }
+ return add_entry(&ent);
+ case TOK_GETFILETIMELOCAL:
+ {
+ char buf[129];
+ DWORD high=0,low=0;
+#ifdef _WIN32
+ int flag=0;
+ HANDLE hFile=CreateFile(line.gettoken_str(1),0,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ FILETIME ft;
+ if (GetFileTime(hFile,NULL,NULL,&ft))
+ {
+ high=ft.dwHighDateTime;
+ low=ft.dwLowDateTime;
+ flag=1;
+ }
+ CloseHandle(hFile);
+ }
+ if (!flag)
+ {
+ ERROR_MSG("GetFileTimeLocal: error reading date from \"%s\"\n",line.gettoken_str(1));
+ return PS_ERROR;
+ }
+#else
+ struct stat st;
+ if (!stat(line.gettoken_str(1), &st))
+ {
+ unsigned long long ll = (st.st_mtime * 10000000LL) + 116444736000000000LL;
+ high = (DWORD) (ll >> 32);
+ low = (DWORD) ll;
+ }
+ else
+ {
+ ERROR_MSG("GetFileTimeLocal: error reading date from \"%s\"\n",line.gettoken_str(1));
+ return PS_ERROR;
+ }
+#endif
+
+ ent.which=EW_ASSIGNVAR;
+ ent.offsets[0]=GetUserVarIndex(line, 2);
+ wsprintf(buf,"%u",high);
+ ent.offsets[1]=add_string(buf);
+ ent.offsets[2]=0;
+ ent.offsets[3]=0;
+ if (ent.offsets[0]<0) PRINTHELP()
+ add_entry(&ent);
+
+ ent.offsets[0]=GetUserVarIndex(line, 3);
+ wsprintf(buf,"%u",low);
+ ent.offsets[1]=add_string(buf);
+ ent.offsets[2]=0;
+ ent.offsets[3]=0;
+ if (ent.offsets[0]<0) PRINTHELP()
+ SCRIPT_MSG("GetFileTimeLocal: %s (%u,%u)->(%s,%s)\n",
+ line.gettoken_str(1),high,low,line.gettoken_str(2),line.gettoken_str(3));
+ }
+ return add_entry(&ent);
+
+#else//!NSIS_SUPPORT_STROPTS
+ case TOK_GETDLLVERSIONLOCAL:
+ case TOK_GETFILETIMELOCAL:
+ case TOK_GETFUNCTIONADDR:
+ case TOK_GETLABELADDR:
+ case TOK_GETCURRENTADDR:
+ case TOK_STRLEN:
+ case TOK_STRCPY:
+ case TOK_STRCMP:
+ case TOK_STRCMPS:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_STROPTS not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_STROPTS
+#ifdef NSIS_SUPPORT_INIFILES
+ case TOK_DELETEINISEC:
+ case TOK_DELETEINISTR:
+ {
+ char *vname="";
+ char *space="";
+ ent.which=EW_WRITEINI;
+ ent.offsets[0]=add_string(line.gettoken_str(2)); // section name
+ if (line.getnumtokens() > 3)
+ {
+ vname=line.gettoken_str(3);
+ ent.offsets[1]=add_string(vname); // value name
+ space=" ";
+ }
+ else ent.offsets[1]=0;
+ ent.offsets[2]=0;
+ ent.offsets[3]=add_string(line.gettoken_str(1));
+ SCRIPT_MSG("DeleteINI%s: [%s] %s%sin %s\n",*vname?"Str":"Sec",
+ line.gettoken_str(2),vname,space,line.gettoken_str(1));
+ }
+ return add_entry(&ent);
+ case TOK_FLUSHINI:
+ ent.which=EW_WRITEINI;
+ ent.offsets[3]=add_string(line.gettoken_str(1));
+ SCRIPT_MSG("FlushINI: %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_WRITEINISTR:
+ ent.which=EW_WRITEINI;
+ ent.offsets[0]=add_string(line.gettoken_str(2));
+ ent.offsets[1]=add_string(line.gettoken_str(3));
+ ent.offsets[2]=add_string(line.gettoken_str(4));
+ ent.offsets[3]=add_string(line.gettoken_str(1));
+ ent.offsets[4]=1; // write
+ SCRIPT_MSG("WriteINIStr: [%s] %s=%s in %s\n",
+ line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4),line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_READINISTR:
+ ent.which=EW_READINISTR;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ if (ent.offsets[0] < 0) PRINTHELP()
+ ent.offsets[1]=add_string(line.gettoken_str(3));
+ ent.offsets[2]=add_string(line.gettoken_str(4));
+ ent.offsets[3]=add_string(line.gettoken_str(2));
+ SCRIPT_MSG("ReadINIStr %s [%s]:%s from %s\n",line.gettoken_str(1),line.gettoken_str(3),line.gettoken_str(4),line.gettoken_str(2));
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_INIFILES
+ case TOK_DELETEINISEC:
+ case TOK_DELETEINISTR:
+ case TOK_FLUSHINI:
+ case TOK_WRITEINISTR:
+ case TOK_READINISTR:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_INIFILES not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_INIFILES
+ case TOK_DETAILPRINT:
+ ent.which=EW_UPDATETEXT;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=0;
+ SCRIPT_MSG("DetailPrint: \"%s\"\n",line.gettoken_str(1));
+ return add_entry(&ent);
+#ifdef NSIS_SUPPORT_FNUTIL
+ case TOK_GETTEMPFILENAME:
+ ent.which=EW_GETTEMPFILENAME;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ if (line.getnumtokens() == 3)
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ else
+ ent.offsets[1]=add_string("$TEMP");
+ if (ent.offsets[0]<0) PRINTHELP()
+ SCRIPT_MSG("GetTempFileName -> %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_GETFULLPATHNAME:
+ {
+ int a=0;
+ ent.which=EW_GETFULLPATHNAME;
+ if (line.getnumtokens()==4 && !stricmp(line.gettoken_str(1),"/SHORT")) a++;
+ else if (line.getnumtokens()==4 || *line.gettoken_str(1)=='/') PRINTHELP()
+ ent.offsets[0]=add_string(line.gettoken_str(2+a));
+ ent.offsets[1]=GetUserVarIndex(line, 1+a);
+ ent.offsets[2]=!a;
+ if (ent.offsets[0]<0) PRINTHELP()
+ SCRIPT_MSG("GetFullPathName: %s->%s (%d)\n",
+ line.gettoken_str(2+a),line.gettoken_str(1+a),a?"sfn":"lfn");
+ }
+ return add_entry(&ent);
+ case TOK_SEARCHPATH:
+ ent.which=EW_SEARCHPATH;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ if (ent.offsets[0] < 0) PRINTHELP()
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ SCRIPT_MSG("SearchPath %s %s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+#else
+ case TOK_SEARCHPATH:
+ case TOK_GETTEMPFILENAME:
+ case TOK_GETFULLPATHNAME:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_FNUTIL not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif
+ case TOK_GETDLLVERSION:
+#ifdef NSIS_SUPPORT_GETDLLVERSION
+ ent.which=EW_GETDLLVERSION;
+ ent.offsets[0]=GetUserVarIndex(line, 2);
+ ent.offsets[1]=GetUserVarIndex(line, 3);
+ ent.offsets[2]=add_string(line.gettoken_str(1));
+ if (ent.offsets[0]<0 || ent.offsets[1]<0) PRINTHELP()
+ SCRIPT_MSG("GetDLLVersion: %s->%s,%s\n",
+ line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_GETDLLVERSION
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_GETDLLVERSION not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_GETDLLVERSION
+ case TOK_GETFILETIME:
+#ifdef NSIS_SUPPORT_GETFILETIME
+ ent.which=EW_GETFILETIME;
+ ent.offsets[0]=GetUserVarIndex(line, 2);
+ ent.offsets[1]=GetUserVarIndex(line, 3);
+ ent.offsets[2]=add_string(line.gettoken_str(1));
+ if (ent.offsets[0]<0 || ent.offsets[1]<0) PRINTHELP()
+ SCRIPT_MSG("GetFileTime: %s->%s,%s\n",
+ line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_GETFILETIME
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_GETFILETIME not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_GETFILETIME
+#ifdef NSIS_SUPPORT_INTOPTS
+ case TOK_INTOP:
+ ent.which=EW_INTOP;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ ent.offsets[3]=line.gettoken_enum(3,"+\0-\0*\0/\0|\0&\0^\0!\0||\0&&\0%\0<<\0>>\0~\0");
+ if (ent.offsets[0] < 0 || ent.offsets[3] < 0 ||
+ ((ent.offsets[3] == 7 || ent.offsets[3] == 13) && line.getnumtokens() > 4))
+ PRINTHELP()
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ if (ent.offsets[3] != 7 && ent.offsets[3] != 13) ent.offsets[2]=add_string(line.gettoken_str(4));
+ if (ent.offsets[3] == 13) {
+ ent.offsets[3]=6;
+ ent.offsets[2]=add_string("0xFFFFFFFF");
+ }
+ SCRIPT_MSG("IntOp: %s=%s%s%s\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ return add_entry(&ent);
+ case TOK_INTFMT:
+ ent.which=EW_INTFMT;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ if (ent.offsets[0]<0) PRINTHELP()
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=add_string(line.gettoken_str(3));
+ SCRIPT_MSG("IntFmt: %s->%s (fmt:%s)\n",line.gettoken_str(3),line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_INTCMP:
+ case TOK_INTCMPU:
+ ent.which=EW_INTCMP;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[5]=which_token == TOK_INTCMPU;
+ if (process_jump(line,3,&ent.offsets[2]) ||
+ process_jump(line,4,&ent.offsets[3]) ||
+ process_jump(line,5,&ent.offsets[4])) PRINTHELP()
+ SCRIPT_MSG("%s %s:%s equal=%s, < %s, > %s\n",line.gettoken_str(0),
+ line.gettoken_str(1),line.gettoken_str(2), line.gettoken_str(3),line.gettoken_str(4),line.gettoken_str(5));
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_INTOPTS
+ case TOK_INTOP:
+ case TOK_INTCMP:
+ case TOK_INTFMT:
+ case TOK_INTCMPU:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_INTOPTS not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_INTOPTS
+#ifdef NSIS_SUPPORT_REGISTRYFUNCTIONS
+ case TOK_READREGSTR:
+ case TOK_READREGDWORD:
+ {
+ ent.which=EW_READREGSTR;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ int k=line.gettoken_enum(2,rootkeys[0]);
+ if (k == -1) k=line.gettoken_enum(2,rootkeys[1]);
+ if (ent.offsets[0] == -1 || k == -1) PRINTHELP()
+ ent.offsets[1]=(int)rootkey_tab[k];
+ ent.offsets[2]=add_string(line.gettoken_str(3));
+ ent.offsets[3]=add_string(line.gettoken_str(4));
+ if (which_token == TOK_READREGDWORD) ent.offsets[4]=1;
+ else ent.offsets[4]=0;
+ if (line.gettoken_str(3)[0] == '\\')
+ warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0));
+
+ SCRIPT_MSG("%s %s %s\\%s\\%s\n",line.gettoken_str(0),
+ line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ }
+ return add_entry(&ent);
+ case TOK_DELETEREGVALUE:
+ case TOK_DELETEREGKEY:
+ {
+ int a=1;
+ if (which_token==TOK_DELETEREGKEY)
+ {
+ ent.offsets[4]=1;
+ char *s=line.gettoken_str(a);
+ if (s[0] == '/')
+ {
+ if (stricmp(s,"/ifempty")) PRINTHELP()
+ a++;
+ ent.offsets[4]=3;
+ }
+ if (line.gettoken_str(a+2)[0]) PRINTHELP()
+ }
+ int k=line.gettoken_enum(a,rootkeys[0]);
+ if (k == -1) k=line.gettoken_enum(a,rootkeys[1]);
+ if (k == -1) PRINTHELP()
+ ent.which=EW_DELREG;
+ ent.offsets[1]=(int)rootkey_tab[k];
+ ent.offsets[2]=add_string(line.gettoken_str(a+1));
+ ent.offsets[3]=(which_token==TOK_DELETEREGKEY)?0:add_string(line.gettoken_str(a+2));
+ if (line.gettoken_str(a+1)[0] == '\\')
+ warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0));
+ if (which_token==TOK_DELETEREGKEY)
+ SCRIPT_MSG("DeleteRegKey: %s\\%s\n",line.gettoken_str(a),line.gettoken_str(a+1));
+ else
+ SCRIPT_MSG("DeleteRegValue: %s\\%s\\%s\n",line.gettoken_str(a),line.gettoken_str(a+1),line.gettoken_str(a+2));
+ }
+ return add_entry(&ent);
+ case TOK_WRITEREGSTR:
+ case TOK_WRITEREGEXPANDSTR:
+ case TOK_WRITEREGBIN:
+ case TOK_WRITEREGDWORD:
+ {
+ int k=line.gettoken_enum(1,rootkeys[0]);
+ if (k == -1) k=line.gettoken_enum(1,rootkeys[1]);
+ if (k == -1) PRINTHELP()
+ ent.which=EW_WRITEREG;
+ ent.offsets[0]=(int)rootkey_tab[k];
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ if (line.gettoken_str(2)[0] == '\\')
+ warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0));
+ ent.offsets[2]=add_string(line.gettoken_str(3));
+ if (which_token == TOK_WRITEREGSTR || which_token == TOK_WRITEREGEXPANDSTR)
+ {
+ SCRIPT_MSG("%s: %s\\%s\\%s=%s\n",
+ line.gettoken_str(0),line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ ent.offsets[3]=add_string(line.gettoken_str(4));
+ ent.offsets[4]=ent.offsets[5]=REG_SZ;
+ if (which_token == TOK_WRITEREGEXPANDSTR)
+ {
+ ent.offsets[5]=REG_EXPAND_SZ;
+ }
+ }
+ if (which_token == TOK_WRITEREGBIN)
+ {
+ char data[3*NSIS_MAX_STRLEN];
+ char *p=line.gettoken_str(4);
+ int data_len=0;
+ while (*p)
+ {
+ int c;
+ int a,b;
+ a=*p;
+ if (a >= '0' && a <= '9') a-='0';
+ else if (a >= 'a' && a <= 'f') a-='a'-10;
+ else if (a >= 'A' && a <= 'F') a-='A'-10;
+ else break;
+ b=*++p;
+ if (b >= '0' && b <= '9') b-='0';
+ else if (b >= 'a' && b <= 'f') b-='a'-10;
+ else if (b >= 'A' && b <= 'F') b-='A'-10;
+ else break;
+ p++;
+ c=(a<<4)|b;
+ if (data_len >= 3*NSIS_MAX_STRLEN)
+ {
+ ERROR_MSG("WriteRegBin: %d bytes of data exceeded\n",3*NSIS_MAX_STRLEN);
+ return PS_ERROR;
+ }
+ data[data_len++]=c;
+ }
+ if (*p) PRINTHELP()
+ SCRIPT_MSG("WriteRegBin: %s\\%s\\%s=%s\n",
+ line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ ent.offsets[3]=add_db_data(data,data_len);
+ if (ent.offsets[3] < 0) return PS_ERROR;
+ ent.offsets[4]=ent.offsets[5]=REG_BINARY;
+ }
+ if (which_token == TOK_WRITEREGDWORD)
+ {
+ ent.offsets[3]=add_string(line.gettoken_str(4));
+ ent.offsets[4]=ent.offsets[5]=REG_DWORD;
+
+ SCRIPT_MSG("WriteRegDWORD: %s\\%s\\%s=%s\n",
+ line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ }
+ }
+ return add_entry(&ent);
+ case TOK_ENUMREGKEY:
+ case TOK_ENUMREGVAL:
+ {
+ ent.which=EW_REGENUM;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ int k=line.gettoken_enum(2,rootkeys[0]);
+ if (k == -1) k=line.gettoken_enum(2,rootkeys[1]);
+ if (ent.offsets[0] == -1 || k == -1) PRINTHELP()
+ ent.offsets[1]=(int)rootkey_tab[k];
+ ent.offsets[2]=add_string(line.gettoken_str(3));
+ ent.offsets[3]=add_string(line.gettoken_str(4));
+ ent.offsets[4]=which_token == TOK_ENUMREGKEY;
+ if (line.gettoken_str(3)[0] == '\\') warning_fl("%s: registry path name begins with \'\\\', may cause problems",line.gettoken_str(0));
+ SCRIPT_MSG("%s %s %s\\%s\\%s\n",which_token == TOK_ENUMREGKEY ? "EnumRegKey" : "EnumRegValue",
+ line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
+ }
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_REGISTRYFUNCTIONS
+ case TOK_READREGSTR:
+ case TOK_READREGDWORD:
+ case TOK_DELETEREGVALUE:
+ case TOK_DELETEREGKEY:
+ case TOK_WRITEREGSTR:
+ case TOK_WRITEREGEXPANDSTR:
+ case TOK_WRITEREGBIN:
+ case TOK_WRITEREGDWORD:
+ case TOK_ENUMREGKEY:
+ case TOK_ENUMREGVAL:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_REGISTRYFUNCTIONS not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_REGISTRYFUNCTIONS
+#ifdef NSIS_SUPPORT_STACK
+ case TOK_EXCH:
+ {
+ int swapitem=1;
+ int save=GetUserVarIndex(line, 1);
+ ent.which=EW_PUSHPOP;
+ if (line.gettoken_str(1)[0] && save<0)
+ {
+ int s=0;
+ swapitem=line.gettoken_int(1,&s);
+ if (!s || swapitem <= 0) PRINTHELP()
+ }
+ if (save>=0)
+ {
+ SCRIPT_MSG("Exch(%s,0)\n",line.gettoken_str(1));
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=0;
+ ent.offsets[2]=0;
+ add_entry(&ent);
+ }
+ else SCRIPT_MSG("Exch(st(%d),0)\n",swapitem);
+
+ ent.offsets[0]=0;
+ ent.offsets[1]=0;
+ ent.offsets[2]=swapitem;
+
+ if (save>=0)
+ {
+ add_entry(&ent);
+ ent.offsets[0]=save;
+ ent.offsets[1]=1;
+ ent.offsets[2]=0;
+ }
+
+ DefineInnerLangString(NLF_INST_CORRUPTED);
+ }
+ return add_entry(&ent);
+ case TOK_PUSH:
+ ent.which=EW_PUSHPOP;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=0;
+ SCRIPT_MSG("Push: %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_POP:
+ ent.which=EW_PUSHPOP;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ ent.offsets[1]=1;
+ if (ent.offsets[0] < 0) PRINTHELP()
+ SCRIPT_MSG("Pop: %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_STACK
+ case TOK_POP:
+ case TOK_PUSH:
+ case TOK_EXCH:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_STACK not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_STACK
+#ifdef NSIS_SUPPORT_ENVIRONMENT
+ case TOK_READENVSTR:
+ ent.which=EW_READENVSTR;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ {
+ char str[NSIS_MAX_STRLEN];
+ strcpy(str, "%");
+ strcat(str, line.gettoken_str(2));
+ strcat(str, "%");
+ ent.offsets[1]=add_string(str);
+ if (ent.offsets[0] < 0 || strlen(line.gettoken_str(2))<1) PRINTHELP()
+ }
+ ent.offsets[2]=1;
+ SCRIPT_MSG("ReadEnvStr: %s->%s\n",line.gettoken_str(2),line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_EXPANDENVSTRS:
+ ent.which=EW_READENVSTR;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=0;
+ if (ent.offsets[0] < 0) PRINTHELP()
+ SCRIPT_MSG("ExpandEnvStrings: %s->%s\n",line.gettoken_str(2),line.gettoken_str(1));
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_ENVIRONMENT
+ case TOK_EXPANDENVSTRS:
+ case TOK_READENVSTR:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_ENVIRONMENT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_ENVIRONMENT
+#ifdef NSIS_SUPPORT_FINDFIRST
+ case TOK_FINDFIRST:
+ ent.which=EW_FINDFIRST;
+ ent.offsets[0]=GetUserVarIndex(line, 2); // out
+ ent.offsets[1]=GetUserVarIndex(line, 1); // handleout
+ ent.offsets[2]=add_string(line.gettoken_str(3)); // filespec
+ if (ent.offsets[0] < 0 || ent.offsets[1] < 0) PRINTHELP()
+ SCRIPT_MSG("FindFirst: spec=\"%s\" handle=%s output=%s\n",line.gettoken_str(3),line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_FINDNEXT:
+ ent.which=EW_FINDNEXT;
+ ent.offsets[0]=GetUserVarIndex(line, 2);
+ ent.offsets[1]=GetUserVarIndex(line, 1);
+ if (ent.offsets[0] < 0 || ent.offsets[1] < 0) PRINTHELP()
+ SCRIPT_MSG("FindNext: handle=%s output=%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_FINDCLOSE:
+ ent.which=EW_FINDCLOSE;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ if (ent.offsets[0] < 0) PRINTHELP()
+ SCRIPT_MSG("FindClose: %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_FINDFIRST
+ case TOK_FINDCLOSE:
+ case TOK_FINDNEXT:
+ case TOK_FINDFIRST:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_FINDFIRST not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+
+#endif//!NSIS_SUPPORT_FINDFIRST
+
+
+#ifdef NSIS_SUPPORT_FILEFUNCTIONS
+ case TOK_FILEOPEN:
+ {
+ ent.which=EW_FOPEN;
+ ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
+ ent.offsets[3]=add_string(line.gettoken_str(2));
+ ent.offsets[1]=0; //openmode
+ if (!stricmp(line.gettoken_str(3),"r"))
+ {
+ ent.offsets[1]=GENERIC_READ;
+ ent.offsets[2]=OPEN_EXISTING;
+ }
+ else if (!stricmp(line.gettoken_str(3),"w"))
+ {
+ ent.offsets[1]=GENERIC_WRITE;
+ ent.offsets[2]=CREATE_ALWAYS;
+ }
+ else if (!stricmp(line.gettoken_str(3),"a"))
+ {
+ ent.offsets[1]=GENERIC_WRITE|GENERIC_READ;
+ ent.offsets[2]=OPEN_ALWAYS;
+ }
+
+ if (ent.offsets[0] < 0 || !ent.offsets[1]) PRINTHELP()
+ }
+ SCRIPT_MSG("FileOpen: %s as %s -> %s\n",line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_FILECLOSE:
+ ent.which=EW_FCLOSE;
+ ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
+ if (ent.offsets[0] < 0) PRINTHELP()
+ SCRIPT_MSG("FileClose: %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_FILEREAD:
+ ent.which=EW_FGETS;
+ ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
+ ent.offsets[1]=GetUserVarIndex(line, 2); // output string
+ if (line.gettoken_str(3)[0])
+ ent.offsets[2]=add_string(line.gettoken_str(3));
+ else
+ ent.offsets[2]=add_intstring(NSIS_MAX_STRLEN-1);
+ if (ent.offsets[0]<0 || ent.offsets[1]<0) PRINTHELP()
+ SCRIPT_MSG("FileRead: %s->%s (max:%s)\n",line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3));
+ return add_entry(&ent);
+ case TOK_FILEWRITE:
+ ent.which=EW_FPUTS;
+ ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ if (ent.offsets[0]<0) PRINTHELP()
+ SCRIPT_MSG("FileWrite: %s->%s\n",line.gettoken_str(2),line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_FILEREADBYTE:
+ ent.which=EW_FGETS;
+ ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
+ ent.offsets[1]=GetUserVarIndex(line, 2); // output string
+ ent.offsets[2]=add_string("1");
+ ent.offsets[3]=1;
+ if (ent.offsets[0]<0 || ent.offsets[1]<0) PRINTHELP()
+ SCRIPT_MSG("FileReadByte: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_FILEWRITEBYTE:
+ ent.which=EW_FPUTS;
+ ent.offsets[0]=GetUserVarIndex(line, 1); // file handle
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=1;
+ if (ent.offsets[0]<0) PRINTHELP()
+ SCRIPT_MSG("FileWriteByte: %s->%s\n",line.gettoken_str(2),line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_FILESEEK:
+ {
+ char *modestr;
+ int tab[3]={FILE_BEGIN,FILE_CURRENT,FILE_END};
+ int mode=line.gettoken_enum(3,"SET\0CUR\0END\0");
+ ent.which=EW_FSEEK;
+ ent.offsets[0]=GetUserVarIndex(line, 1);
+ ent.offsets[1]=GetUserVarIndex(line, 4);
+ ent.offsets[2]=add_string(line.gettoken_str(2));
+
+ if (mode<0 && !line.gettoken_str(3)[0])
+ {
+ mode=0;
+ modestr="SET";
+ }
+ else modestr=line.gettoken_str(3);
+
+ if (mode<0 || ent.offsets[0] < 0 || (ent.offsets[1]<0 && line.gettoken_str(4)[0])) PRINTHELP()
+ ent.offsets[3]=tab[mode];
+ SCRIPT_MSG("FileSeek: fp=%s, ofs=%s, mode=%s, output=%s\n",
+ line.gettoken_str(1),
+ line.gettoken_str(2),
+ modestr,
+ line.gettoken_str(4));
+ }
+
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_FILEFUNCTIONS
+ case TOK_FILEOPEN:
+ case TOK_FILECLOSE:
+ case TOK_FILESEEK:
+ case TOK_FILEREAD:
+ case TOK_FILEWRITE:
+ case TOK_FILEREADBYTE:
+ case TOK_FILEWRITEBYTE:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_FILEFUNCTIONS not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+
+#endif//!NSIS_SUPPORT_FILEFUNCTIONS
+#ifdef NSIS_SUPPORT_REBOOT
+ case TOK_REBOOT:
+ {
+ int ret = add_entry_direct(EW_REBOOT, 0xbadf00d);
+ if (ret != PS_OK) return ret;
+
+ ret = add_entry_direct(EW_QUIT);
+ if (ret != PS_OK) return ret;
+
+ SCRIPT_MSG("Reboot! (WOW)\n");
+
+ DefineInnerLangString(NLF_INST_CORRUPTED);
+ }
+ return PS_OK;
+ case TOK_IFREBOOTFLAG:
+ ent.which=EW_IFFLAG;
+ if (process_jump(line,1,&ent.offsets[0]) ||
+ process_jump(line,2,&ent.offsets[1])) PRINTHELP()
+ ent.offsets[2]=FLAG_OFFSET(exec_reboot);
+ ent.offsets[3]=~0;//new value mask - keep flag
+ SCRIPT_MSG("IfRebootFlag ?%s:%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_SETREBOOTFLAG:
+ {
+ ent.which=EW_SETFLAG;
+ ent.offsets[0]=FLAG_OFFSET(exec_reboot);
+ int k=line.gettoken_enum(1,"false\0true\0");
+ if (k < 0) PRINTHELP()
+ ent.offsets[1]=add_intstring(k);
+ }
+ return add_entry(&ent);
+#else//!NSIS_SUPPORT_REBOOT
+ case TOK_REBOOT:
+ case TOK_IFREBOOTFLAG:
+ case TOK_SETREBOOTFLAG:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_REBOOT not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_REBOOT
+#ifdef NSIS_CONFIG_LOG
+ case TOK_LOGSET:
+ ent.which=EW_LOG;
+ ent.offsets[0]=1;
+ ent.offsets[1]=line.gettoken_enum(1,"off\0on\0");
+ if (ent.offsets[1]<0) PRINTHELP()
+
+ SCRIPT_MSG("LogSet: %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_LOGTEXT:
+ ent.which=EW_LOG;
+ ent.offsets[0]=0;
+ ent.offsets[1]=add_string(line.gettoken_str(1));
+ SCRIPT_MSG("LogText \"%s\"\n",line.gettoken_str(1));
+ return add_entry(&ent);
+#else//!NSIS_CONFIG_LOG
+
+ case TOK_LOGSET:
+ case TOK_LOGTEXT:
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_LOG not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_CONFIG_LOG
+#ifdef NSIS_CONFIG_COMPONENTPAGE
+ case TOK_SECTIONSETTEXT:
+ ent.which=EW_SECTIONSET;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[2]=SECTION_FIELD_SET(name_ptr);
+ ent.offsets[4]=add_string(line.gettoken_str(2));
+ SCRIPT_MSG("SectionSetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_SECTIONGETTEXT:
+ ent.which=EW_SECTIONSET;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=GetUserVarIndex(line, 2);
+ ent.offsets[2]=SECTION_FIELD_GET(name_ptr);
+ if (line.gettoken_str(2)[0] && ent.offsets[1]<0) PRINTHELP()
+ SCRIPT_MSG("SectionGetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_SECTIONSETFLAGS:
+ ent.which=EW_SECTIONSET;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=SECTION_FIELD_SET(flags);
+ ent.offsets[3]=1;
+ SCRIPT_MSG("SectionSetFlags: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_SECTIONGETFLAGS:
+ ent.which=EW_SECTIONSET;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=GetUserVarIndex(line, 2);
+ ent.offsets[2]=SECTION_FIELD_GET(flags);
+ if (line.gettoken_str(2)[0] && ent.offsets[1]<0) PRINTHELP()
+ SCRIPT_MSG("SectionGetFlags: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_INSTTYPESETTEXT:
+ ent.which=EW_INSTTYPESET;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=1;
+ SCRIPT_MSG("InstTypeSetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_INSTTYPEGETTEXT:
+ ent.which=EW_INSTTYPESET;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=GetUserVarIndex(line, 2);
+ ent.offsets[2]=0;
+ if (line.gettoken_str(1)[0] && ent.offsets[1]<0) PRINTHELP()
+ SCRIPT_MSG("InstTypeGetText: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_SECTIONSETINSTTYPES:
+ ent.which=EW_SECTIONSET;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=SECTION_FIELD_SET(install_types);
+ SCRIPT_MSG("SectionSetInstTypes: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_SECTIONGETINSTTYPES:
+ ent.which=EW_SECTIONSET;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=GetUserVarIndex(line, 2);
+ ent.offsets[2]=SECTION_FIELD_GET(install_types);
+ if (line.gettoken_str(2)[0] && ent.offsets[1]<0) PRINTHELP()
+ SCRIPT_MSG("SectionGetInstTypes: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_SECTIONSETSIZE:
+ ent.which=EW_SECTIONSET;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=add_string(line.gettoken_str(2));
+ ent.offsets[2]=SECTION_FIELD_SET(size_kb);
+ SCRIPT_MSG("SectionSetSize: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_SECTIONGETSIZE:
+ ent.which=EW_SECTIONSET;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=GetUserVarIndex(line, 2);
+ ent.offsets[2]=SECTION_FIELD_GET(size_kb);
+ if (line.gettoken_str(2)[0] && ent.offsets[1]<0) PRINTHELP()
+ SCRIPT_MSG("SectionGetSize: %s->%s\n",line.gettoken_str(1),line.gettoken_str(2));
+ return add_entry(&ent);
+ case TOK_SETCURINSTTYPE:
+ ent.which=EW_INSTTYPESET;
+ ent.offsets[0]=add_string(line.gettoken_str(1));
+ ent.offsets[1]=0;
+ ent.offsets[2]=1;
+ ent.offsets[3]=1;
+ SCRIPT_MSG("SetCurInstType: %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+ case TOK_GETCURINSTTYPE:
+ ent.which=EW_INSTTYPESET;
+ ent.offsets[0]=0;
+ ent.offsets[1]=GetUserVarIndex(line,1);
+ ent.offsets[2]=0;
+ ent.offsets[3]=1;
+ if (line.gettoken_str(1)[0] && ent.offsets[0]<0) PRINTHELP()
+ SCRIPT_MSG("GetCurInstType: %s\n",line.gettoken_str(1));
+ return add_entry(&ent);
+#else//!NSIS_CONFIG_COMPONENTPAGE
+ case TOK_SECTIONSETTEXT:
+ case TOK_SECTIONGETTEXT:
+ case TOK_SECTIONSETFLAGS:
+ case TOK_SECTIONGETFLAGS:
+ case TOK_SECTIONSETSIZE:
+ case TOK_SECTIONGETSIZE:
+ case TOK_SECTIONSETINSTTYPES:
+ case TOK_SECTIONGETINSTTYPES:
+ case TOK_SETCURINSTTYPE:
+ case TOK_GETCURINSTTYPE:
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_COMPONENTPAGE not defined.\n", line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_CONFIG_COMPONENTPAGE
+#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ case TOK_SETBRANDINGIMAGE:
+ {
+ SCRIPT_MSG("SetBrandingImage: ");
+ if (!branding_image_found) {
+ ERROR_MSG("\nError: no branding image found in chosen UI!\n");
+ return PS_ERROR;
+ }
+ ent.which=EW_SETBRANDINGIMAGE;
+ for (int i = 1; i < line.getnumtokens(); i++)
+ if (!strnicmp(line.gettoken_str(i),"/IMGID=",7)) {
+ ent.offsets[1]=atoi(line.gettoken_str(i)+7);
+ SCRIPT_MSG("/IMGID=%d ",ent.offsets[1]);
+ }
+ else if (!stricmp(line.gettoken_str(i),"/RESIZETOFIT")) {
+ ent.offsets[2]=1; // must be 1 or 0
+ SCRIPT_MSG("/RESIZETOFIT ");
+ }
+ else if (!ent.offsets[0]) {
+ ent.offsets[0]=add_string(line.gettoken_str(i));
+ SCRIPT_MSG("\"%s\" ", line.gettoken_str(i));
+ }
+ else {
+ SCRIPT_MSG("\n");
+ PRINTHELP();
+ }
+
+ if (!ent.offsets[1])
+ ent.offsets[1]=branding_image_id;
+ SCRIPT_MSG("\n");
+ }
+ return add_entry(&ent);
+#else//NSIS_CONFIG_ENHANCEDUI_SUPPORT
+ case TOK_SETBRANDINGIMAGE:
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_ENHANCEDUI_SUPPORT not defined.\n",line.gettoken_str(0));
+ return PS_ERROR;
+#endif//!NSIS_SUPPORT_CREATEFONT
+
+ // Added by ramon 3 jun 2003
+ case TOK_DEFVAR:
+ {
+ int a=1;
+
+ if (!strcmpi(line.gettoken_str(1),"/GLOBAL"))
+ {
+ a++;
+ }
+ else if (line.getnumtokens() == 3)
+ {
+ PRINTHELP();
+ }
+
+ if (build_cursection)
+ {
+ if (a==1)
+ {
+ ERROR_MSG("Var: currently, only global variables can be defined.\n");
+ PRINTHELP();
+ }
+ }
+
+ SCRIPT_MSG("Var: \"%s\"\n",line.gettoken_str(a));
+
+ int res = DeclaredUserVar(line.gettoken_str(a));
+ if (res != PS_OK)
+ return res;
+
+ }
+ return PS_OK;
+
+ // Added by ramon 6 jun 2003
+#ifdef NSIS_SUPPORT_VERSION_INFO
+ case TOK_VI_ADDKEY:
+ {
+ LANGID LangID=0;
+ int a = 1;
+ if (!strnicmp(line.gettoken_str(a),"/LANG=",6))
+ LangID=atoi(line.gettoken_str(a++)+6);
+ if (line.getnumtokens()!=a+2) PRINTHELP();
+ char *pKey = line.gettoken_str(a);
+ char *pValue = line.gettoken_str(a+1);
+ if ( !(*pKey) )
+ {
+ ERROR_MSG("Error: empty name for version info key!\n");
+ return PS_ERROR;
+ }
+ else
+ {
+ SCRIPT_MSG("%s: \"%s\" \"%s\"\n", line.gettoken_str(0), line.gettoken_str(a), line.gettoken_str(a+1));
+ LANGID lReaded = LangID;
+ if ( a > 1 && lReaded == 0 )
+ warning_fl("%s: %s language not loaded, using default \"1033-English\"", line.gettoken_str(0), line.gettoken_str(1));
+
+ unsigned int codepage;
+ char *lang_name = GetLangNameAndCP(LangID, &codepage);
+
+ if ( rVersionInfo.SetKeyValue(LangID, codepage, pKey, pValue) )
+ {
+ ERROR_MSG("%s: \"%s\" \"%04d-%s\" already defined!\n",line.gettoken_str(0), line.gettoken_str(2), LangID, lang_name);
+ return PS_ERROR;
+ }
+
+ return PS_OK;
+ }
+ }
+ case TOK_VI_SETPRODUCTVERSION:
+ if ( version_product_v[0] )
+ {
+ ERROR_MSG("Error: %s already defined!\n", line.gettoken_str(0));
+ return PS_ERROR;
+ }
+ strcpy(version_product_v, line.gettoken_str(1));
+ return PS_OK;
+
+#else
+ case TOK_VI_ADDKEY:
+ case TOK_VI_SETPRODUCTVERSION:
+ ERROR_MSG("Error: %s specified, NSIS_SUPPORT_VERSION_INFO not defined.\n",line.gettoken_str(0));
+ return PS_ERROR;
+#endif
+
+ // end of instructions
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Added by Ximon Eighteen 5th August 2002
+#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
+ case TOK_PLUGINDIR:
+ {
+ if (line.getnumtokens() == 2)
+ {
+ SCRIPT_MSG("PluginDir: \"%s\"\n",line.gettoken_str(1));
+#ifdef _WIN32
+ m_plugins.FindCommands(line.gettoken_str(1), display_info?true:false);
+#else
+ char *converted_path = my_convert(line.gettoken_str(1));
+ m_plugins.FindCommands(converted_path, display_info?true:false);
+ my_convert_free(converted_path);
+#endif
+ return PS_OK;
+ }
+ }
+ return PS_ERROR;
+ case TOK__PLUGINCOMMAND:
+ {
+ int ret;
+
+ const string command = m_plugins.NormalizedCommand(line.gettoken_str(0));
+ const string dllPath = m_plugins.GetPluginPath(command);
+ int data_handle = m_plugins.GetPluginHandle(uninstall_mode?true:false, command);
+
+ if (uninstall_mode) uninst_plugin_used = true;
+ else plugin_used = true;
+
+ // Initialize $PLUGINSDIR
+ ent.which=EW_CALL;
+ ent.offsets[0]=ns_func.add(uninstall_mode?"un.Initialize_____Plugins":"Initialize_____Plugins",0);
+ ret=add_entry(&ent);
+ if (ret != PS_OK) {
+ return ret;
+ }
+
+ // DLL name on the user machine
+ char tempDLL[NSIS_MAX_STRLEN];
+ string dllName = get_file_name(dllPath);
+ wsprintf(tempDLL, "$PLUGINSDIR\\%s", dllName.c_str());
+
+ // Add the DLL to the installer
+ if (data_handle == -1)
+ {
+ int files_added;
+ int old_build_allowskipfiles=build_allowskipfiles;
+ build_allowskipfiles=1; // on
+ int old_build_overwrite=build_overwrite;
+ build_overwrite=1; // off
+ int old_build_datesave=build_datesave;
+ build_datesave=0; // off
+ ret=do_add_file(dllPath.c_str(),0,0,&files_added,tempDLL,2,&data_handle); // 2 means no size add
+ if (ret != PS_OK) {
+ return ret;
+ }
+ m_plugins.SetDllDataHandle(uninstall_mode?true:false, line.gettoken_str(0), data_handle);
+ build_overwrite=old_build_overwrite;
+ build_datesave=old_build_datesave;
+ // Added by ramon 23 May 2003
+ build_allowskipfiles=old_build_allowskipfiles;
+ }
+ else
+ {
+ ent.which=EW_EXTRACTFILE;
+
+ DefineInnerLangString(NLF_SKIPPED);
+ DefineInnerLangString(NLF_ERR_DECOMPRESSING);
+ DefineInnerLangString(NLF_ERR_WRITING);
+ DefineInnerLangString(NLF_EXTRACT);
+ DefineInnerLangString(NLF_CANT_WRITE);
+
+ ent.offsets[0]=1; // overwrite off
+ ent.offsets[0]|=(MB_RETRYCANCEL|MB_ICONSTOP|(IDCANCEL<<21))<<3;
+ ent.offsets[1]=add_string(tempDLL);
+ ent.offsets[2]=data_handle;
+ ent.offsets[3]=0xffffffff;
+ ent.offsets[4]=0xffffffff;
+ ent.offsets[5]=DefineInnerLangString(NLF_FILE_ERROR);
+ ret=add_entry(&ent);
+ if (ret != PS_OK) {
+ return ret;
+ }
+ }
+
+ // SetDetailsPrint lastused
+ ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1);
+ if (ret != PS_OK) {
+ return ret;
+ }
+
+ // Call the DLL
+ string funcname = get_string_suffix(command, "::");
+ SCRIPT_MSG("Plugin Command: %s",funcname.c_str());
+
+ int i = 1;
+ int nounload = 0;
+ if (!strcmpi(line.gettoken_str(i), "/NOUNLOAD")) {
+ i++;
+ nounload++;
+ }
+
+ // First push dll args
+
+ int parmst=i; // we push em in reverse order
+ int nounloadmisused=0;
+ for (; i < line.getnumtokens(); i++) {
+ int w=parmst + (line.getnumtokens()-i - 1);
+ ent.which=EW_PUSHPOP;
+ ent.offsets[0]=add_string(line.gettoken_str(w));
+ if (!strcmpi(line.gettoken_str(w), "/NOUNLOAD")) nounloadmisused=1;
+ ent.offsets[1]=0;
+ ent.offsets[2]=0;
+ ret=add_entry(&ent);
+ if (ret != PS_OK) {
+ return ret;
+ }
+ SCRIPT_MSG(" %s",line.gettoken_str(i));
+ }
+ SCRIPT_MSG("\n");
+ if (nounloadmisused)
+ warning_fl("/NOUNLOAD must come first before any plugin parameter. Unless the plugin you are trying to use has a parameter /NOUNLOAD, you are doing something wrong");
+
+ // next, call it
+ ent.which=EW_REGISTERDLL;
+ ent.offsets[0]=add_string(tempDLL);;
+ ent.offsets[1]=add_string(funcname.c_str());
+ ent.offsets[2]=0;
+ ent.offsets[3]=nounload|build_plugin_unload;
+ ent.offsets[4]=1;
+ ret=add_entry(&ent);
+ if (ret != PS_OK) {
+ return ret;
+ }
+
+ DefineInnerLangString(NLF_SYMBOL_NOT_FOUND);
+ DefineInnerLangString(NLF_COULD_NOT_LOAD);
+ DefineInnerLangString(NLF_NO_OLE);
+ // not used anywhere - DefineInnerLangString(NLF_ERR_REG_DLL);
+
+ return PS_OK;
+ }
+ case TOK_INITPLUGINSDIR:
+ {
+ int ret;
+ SCRIPT_MSG("%s\n",line.gettoken_str(0));
+ if (uninstall_mode) uninst_plugin_used = true;
+ else plugin_used = true;
+ // Call [un.]Initialize_____Plugins
+ ent.which=EW_CALL;
+ ent.offsets[0]=ns_func.add(uninstall_mode?"un.Initialize_____Plugins":"Initialize_____Plugins",0);
+ ret=add_entry(&ent);
+ if (ret != PS_OK) return ret;
+ // SetDetailsPrint lastused
+ ret=add_entry_direct(EW_SETFLAG, FLAG_OFFSET(status_update), 0, 1);
+ if (ret != PS_OK) return ret;
+ }
+ return PS_OK;
+#else
+ case TOK_PLUGINDIR:
+ case TOK__PLUGINCOMMAND:
+ case TOK_INITPLUGINSDIR:
+ {
+ ERROR_MSG("Error: %s specified, NSIS_CONFIG_PLUGIN_SUPPORT not defined.\n",line.gettoken_str(0));
+ }
+ return PS_ERROR;
+#endif// NSIS_CONFIG_PLUGIN_SUPPORT
+
+#ifdef NSIS_LOCKWINDOW_SUPPORT
+ case TOK_LOCKWINDOW:
+ SCRIPT_MSG("LockWindow: lock state=%d\n",line.gettoken_str(1));
+ ent.which=EW_LOCKWINDOW;
+ ent.offsets[0]=line.gettoken_enum(1,"on\0off\0");
+ if (ent.offsets[0] == -1)
+ PRINTHELP();
+ return add_entry(&ent);
+#else
+ case TOK_LOCKWINDOW:
+ {
+ ERROR_MSG("Error: %s specified, NSIS_LOCKWINDOW_SUPPORT not defined.\n",line.gettoken_str(0));
+ }
+ return PS_ERROR;
+#endif // NSIS_LOCKWINDOW_SUPPORT
+
+ default: break;
+
+ }
+ ERROR_MSG("Error: doCommand: Invalid token \"%s\".\n",line.gettoken_str(0));
+ return PS_ERROR;
+}
+
+#ifdef NSIS_SUPPORT_FILE
+int CEXEBuild::do_add_file(const char *lgss, int attrib, int recurse, int *total_files, const char *name_override, int generatecode, int *data_handle, const set<string>& excluded, const string& basedir, bool dir_created)
+{
+ assert(!name_override || !recurse);
+
+ string dir = get_dir_name(lgss);
+ string spec;
+
+ if (dir == lgss) {
+ dir = ".";
+ spec = lgss;
+ } else {
+ spec = string(lgss).substr(dir.length() + 1, string::npos);
+ }
+
+ if (spec == "") {
+ spec = "*";
+ }
+
+ if (basedir == "") {
+ dir_created = true;
+
+ if (recurse) {
+ // save $OUTDIR into $_OUTDIR [StrCpy $_OUTDIR $OUTDIR]
+ if (add_entry_direct(EW_ASSIGNVAR, m_UserVarNames.get("_OUTDIR"), add_string("$OUTDIR")) != PS_OK) {
+ return PS_ERROR;
+ }
+ }
+ }
+
+ boost::scoped_ptr<dir_reader> dr( new_dir_reader() );
+ dr->exclude(excluded);
+ dr->read(dir);
+
+ // add files in the current directory
+ for (dir_reader::iterator files_itr = dr->files().begin();
+ files_itr != dr->files().end();
+ files_itr++)
+ {
+ if (!dir_reader::matches(*files_itr, spec))
+ continue;
+
+ if (!dir_created && generatecode) {
+ SCRIPT_MSG("%sFile: Descending to: \"%s\"\n", generatecode ? "" : "Reserve", dir.c_str());
+
+ if (do_add_file_create_dir(dir, basedir, attrib) != PS_OK) {
+ return PS_ERROR;
+ }
+
+ dir_created = true;
+ }
+
+ if (add_file(dir, *files_itr, attrib, name_override, generatecode, data_handle) != PS_OK) {
+ return PS_ERROR;
+ }
+
+ (*total_files)++;
+ }
+
+ if (!recurse) {
+ return PS_OK;
+ }
+
+ // recurse into directories
+ for (dir_reader::iterator dirs_itr = dr->dirs().begin();
+ dirs_itr != dr->dirs().end();
+ dirs_itr++)
+ {
+ string new_dir;
+ bool created = false;
+
+ if (basedir == "") {
+ new_dir = *dirs_itr;
+ } else {
+ new_dir = basedir + '\\' + *dirs_itr;
+ }
+
+ string new_spec = dir + PLATFORM_PATH_SEPARATOR_STR + *dirs_itr + PLATFORM_PATH_SEPARATOR_STR;
+
+ if (!dir_reader::matches(*dirs_itr, spec)) {
+ new_spec += spec;
+ } else if (generatecode) {
+ // always create directories that match
+
+ SCRIPT_MSG("%sFile: Descending to: \"%s\"\n", generatecode ? "" : "Reserve", new_spec.c_str());
+
+ if (do_add_file_create_dir(dir + '\\' + *dirs_itr, new_dir, attrib) != PS_OK) {
+ return PS_ERROR;
+ }
+
+ created = true;
+ }
+
+ const char *new_spec_c = new_spec.c_str();
+
+ int res = do_add_file(new_spec_c, attrib, 1, total_files, NULL, generatecode, NULL, excluded, new_dir, created);
+ if (res != PS_OK) {
+ return PS_ERROR;
+ }
+ }
+
+ if (basedir == "") {
+ SCRIPT_MSG("%sFile: Returning to: \"%s\"\n", generatecode ? "" : "Reserve", dir.c_str());
+
+ // restore $OUTDIR from $_OUTDIR [SetOutPath $_OUTDIR]
+ if (add_entry_direct(EW_CREATEDIR, add_string("$_OUTDIR"), 1) != PS_OK) {
+ return PS_ERROR;
+ }
+ }
+
+ return PS_OK;
+}
+
+int CEXEBuild::add_file(const string& dir, const string& file, int attrib, const char *name_override, int generatecode, int *data_handle) {
+ string newfn_s = dir + PLATFORM_PATH_SEPARATOR_C + file;
+ const char *newfn = newfn_s.c_str();
+ const char *filename = file.c_str();
+
+ MMapFile mmap;
+ DWORD len;
+
+#ifdef _WIN32
+ HANDLE hFile = CreateFile(
+ newfn,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
+ NULL
+ );
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ ERROR_MSG("%sFile: failed opening file \"%s\"\n",generatecode?"":"Reserve",newfn);
+ return PS_ERROR;
+ }
+
+ // Will auto-CloseHandle hFile
+ MANAGE_WITH(hFile, CloseHandle);
+
+ len = GetFileSize(hFile, NULL);
+ if (len && !mmap.setfile(hFile, len))
+ {
+ ERROR_MSG("%sFile: failed creating mmap of \"%s\"\n",generatecode?"":"Reserve",newfn);
+ return PS_ERROR;
+ }
+#else
+ struct stat s;
+ if (stat(newfn, &s)) {
+ ERROR_MSG("%sFile: failed stating file \"%s\"\n",generatecode?"":"Reserve",newfn);
+ return PS_ERROR;
+ }
+
+ len = (DWORD) s.st_size;
+
+ int fd = OPEN(newfn, O_RDONLY);
+ if (fd == -1)
+ {
+ ERROR_MSG("%sFile: failed opening file \"%s\"\n",generatecode?"":"Reserve",newfn);
+ return PS_ERROR;
+ }
+
+ // Will auto-close(2) fd
+ MANAGE_WITH(fd, close);
+
+ if (len && !mmap.setfile(fd, len))
+ {
+ ERROR_MSG("%sFile: failed creating mmap of \"%s\"\n",generatecode?"":"Reserve",newfn);
+ return PS_ERROR;
+ }
+#endif
+
+ if (generatecode&1)
+ section_add_size_kb((len+1023)/1024);
+ if (name_override) SCRIPT_MSG("%sFile: \"%s\"->\"%s\"",generatecode?"":"Reserve",filename,name_override);
+ else SCRIPT_MSG("%sFile: \"%s\"",generatecode?"":"Reserve",filename);
+ if (!build_compress_whole)
+ if (build_compress) SCRIPT_MSG(" [compress]");
+ fflush(stdout);
+ char buf[1024];
+ int last_build_datablock_used=getcurdbsize();
+ entry ent={0,};
+ if (generatecode)
+ {
+ ent.which=EW_EXTRACTFILE;
+
+ DefineInnerLangString(NLF_SKIPPED);
+ DefineInnerLangString(NLF_ERR_DECOMPRESSING);
+ DefineInnerLangString(NLF_ERR_WRITING);
+ DefineInnerLangString(NLF_EXTRACT);
+ DefineInnerLangString(NLF_CANT_WRITE);
+
+ ent.offsets[0]=build_overwrite;
+ if (name_override)
+ {
+ ent.offsets[1]=add_string(name_override);
+ }
+ else
+ {
+ const char *i=filename;
+ char *o=buf;
+ while (*i)
+ {
+ const char c=*i++;
+ *o++=c;
+ if (c == '$') *o++='$';
+ }
+ *o=0;
+ ent.offsets[1]=add_string(buf);
+ }
+ }
+ ent.offsets[2]=add_db_data(&mmap);
+
+ mmap.clear();
+
+ if (ent.offsets[2] < 0)
+ {
+ return PS_ERROR;
+ }
+
+ if (data_handle)
+ {
+ *data_handle=ent.offsets[2];
+ }
+
+ {
+ DWORD s=getcurdbsize()-last_build_datablock_used;
+ if (s) s-=4;
+ if (s != len) SCRIPT_MSG(" %d/%d bytes\n",s,len);
+ else SCRIPT_MSG(" %d bytes\n",len);
+ }
+
+ if (generatecode)
+ {
+ if (build_datesave || build_overwrite>=0x3 /*ifnewer or ifdiff*/)
+ {
+#ifdef _WIN32
+ FILETIME ft;
+ if (GetFileTime(hFile,NULL,NULL,&ft))
+ {
+ // FAT write time has a resolution of 2 seconds
+ PULONGLONG fti = (PULONGLONG) &ft;
+ *fti -= *fti % 20000000;
+
+ ent.offsets[3]=ft.dwLowDateTime;
+ ent.offsets[4]=ft.dwHighDateTime;
+ }
+#else
+ struct stat st;
+ if (!fstat(fd, &st))
+ {
+ unsigned long long ll = (st.st_mtime * 10000000LL) + 116444736000000000LL;
+
+ // FAT write time has a resolution of 2 seconds
+ ll -= ll % 20000000;
+
+ ent.offsets[3] = (int) ll;
+ ent.offsets[4] = (int) (ll >> 32);
+ }
+#endif
+ else
+ {
+ ERROR_MSG("%sFile: failed getting file date from \"%s\"\n",generatecode?"":"Reserve",newfn);
+ return PS_ERROR;
+ }
+ }
+ else
+ {
+ ent.offsets[3]=0xffffffff;
+ ent.offsets[4]=0xffffffff;
+ }
+
+ // overwrite flag can be 0, 1, 2 or 3. in all cases, 2 bits
+ int mb = 0;
+ if (build_allowskipfiles)
+ {
+ mb = MB_ABORTRETRYIGNORE | MB_ICONSTOP;
+ // default for silent installers
+ mb |= IDIGNORE << 21;
+ }
+ else
+ {
+ mb = MB_RETRYCANCEL | MB_ICONSTOP;
+ // default for silent installers
+ mb |= IDCANCEL << 21;
+ }
+ ent.offsets[0] |= mb << 3;
+
+ ent.offsets[5] = DefineInnerLangString(build_allowskipfiles ? NLF_FILE_ERROR : NLF_FILE_ERROR_NOIGNORE);
+ }
+
+ if (generatecode)
+ {
+ int a=add_entry(&ent);
+ if (a != PS_OK)
+ {
+ return a;
+ }
+ if (attrib)
+ {
+#ifdef _WIN32
+ ent.which=EW_SETFILEATTRIBUTES;
+ // $OUTDIR is the working directory
+ ent.offsets[0]=add_string(name_override?name_override:buf);
+ ent.offsets[1]=GetFileAttributes(newfn);
+ ent.offsets[2]=0;
+ ent.offsets[3]=0;
+ ent.offsets[4]=0;
+ ent.offsets[5]=0;
+
+ if (ent.offsets[1] != INVALID_FILE_ATTRIBUTES)
+ {
+ a=add_entry(&ent);
+ if (a != PS_OK)
+ {
+ return a;
+ }
+ }
+#endif
+ }
+ }
+
+ return PS_OK;
+}
+
+int CEXEBuild::do_add_file_create_dir(const string& local_dir, const string& dir, int attrib) {
+ string outdir_s = "$_OUTDIR\\" + dir;
+
+ string::size_type pos = 1;
+ pos = outdir_s.find('$', pos);
+ while (pos != string::npos) {
+ outdir_s = outdir_s.insert(pos, "$");
+ pos = outdir_s.find('$', pos + 2);
+ }
+
+ int outdir = add_string(outdir_s.c_str());
+
+ if (add_entry_direct(EW_CREATEDIR, outdir, 1) != PS_OK) {
+ return PS_ERROR;
+ }
+
+#ifdef _WIN32
+ if (attrib) {
+ int ndc = add_string(".");
+
+ DWORD attr = GetFileAttributes(local_dir.c_str());
+
+ if (attr != INVALID_FILE_ATTRIBUTES)
+ {
+ if (add_entry_direct(EW_SETFILEATTRIBUTES, ndc, attr) != PS_OK)
+ {
+ return PS_ERROR;
+ }
+ }
+ }
+#endif
+
+ return PS_OK;
+}
+#endif
diff --git a/Source/strlist.cpp b/Source/strlist.cpp
index f61fa0b..4af6959 100755
--- a/Source/strlist.cpp
+++ b/Source/strlist.cpp
@@ -1,204 +1,204 @@
-/*
- * strlist.cpp: Implementation of the StringList class.
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "strlist.h"
-
-int StringList::add(const char *str, int case_sensitive)
-{
- int a=find(str,case_sensitive);
- if (a >= 0 && case_sensitive!=-1) return a;
- return gr.add(str,strlen(str)+1);
-}
-
-// use 2 for case sensitive end-of-string matches too
-int StringList::find(const char *str, int case_sensitive, int *idx/*=NULL*/) const // returns -1 if not found
-{
- const char *s=get();
- int ml=getlen();
- int offs=0;
- if (idx) *idx=0;
- while (offs < ml)
- {
- if ((case_sensitive && !strcmp(s+offs,str)) ||
- (!case_sensitive && !stricmp(s+offs,str)))
- {
- return offs;
- }
- if (case_sensitive==2 &&
- strlen(str) < strlen(s+offs) && // check for end of string
- !strcmp(s+offs+strlen(s+offs)-strlen(str),str))
- {
- return offs+strlen(s+offs)-strlen(str);
- }
- offs+=strlen(s+offs)+1;
- if (idx) (*idx)++;
- }
- return -1;
-}
-
-void StringList::delbypos(int pos)
-{
- char *s=(char*)gr.get();
- int len=strlen(s+pos)+1;
- if (pos+len < gr.getlen()) memcpy(s+pos,s+pos+len,gr.getlen()-(pos+len));
- gr.resize(gr.getlen()-len);
-}
-
-int StringList::idx2pos(int idx) const
-{
- char *s=(char*)gr.get();
- int offs=0;
- int cnt=0;
- if (idx>=0) while (offs < gr.getlen())
- {
- if (cnt++ == idx) return offs;
- offs+=strlen(s+offs)+1;
- }
- return -1;
-}
-
-int StringList::getnum() const
-{
- char *s=(char*)gr.get();
- int ml=gr.getlen();
- int offs=0;
- int idx=0;
- while (offs < ml)
- {
- offs+=strlen(s+offs)+1;
- idx++;
- }
- return idx;
-}
-
-const char *StringList::get() const
-{
- return (const char*)gr.get();
-}
-
-int StringList::getlen() const
-{
- return gr.getlen();
-}
-
-// ==========
-// DefineList
-// ==========
-
-DefineList::~DefineList()
-{
- struct define *s=(struct define*)gr.get();
- int num=gr.getlen()/sizeof(struct define);
-
- for (int i=0; i<num; i++) {
- free(s[i].value);
- }
-}
-
-int DefineList::add(const char *name, const char *value/*=""*/)
-{
- int pos=SortedStringList<struct define>::add(name);
- if (pos == -1)
- {
- return 1;
- }
-
- char **newvalue=&(((struct define*)gr.get())[pos].value);
- *newvalue=(char*)malloc(strlen(value)+1);
- if (!(*newvalue))
- {
- extern FILE *g_output;
- extern int g_display_errors;
- extern void quit();
- if (g_display_errors)
- {
- fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%lu) failed.\n",(unsigned long)strlen(value)+1);
- fflush(g_output);
- }
- quit();
- }
- strcpy(*newvalue,value);
- return 0;
-}
-
-char *DefineList::find(const char *name)
-{
- int v=SortedStringList<struct define>::find(name);
- if (v==-1)
- {
- return NULL;
- }
- return ((struct define*)gr.get())[v].value;
-}
-
-// returns 0 on success, 1 otherwise
-int DefineList::del(const char *str)
-{
- int pos=SortedStringList<struct define>::find(str);
- if (pos==-1) return 1;
-
- struct define *db=(struct define *)gr.get();
- free(db[pos].value);
- delbypos(pos);
-
- return 0;
-}
-
-int DefineList::getnum()
-{
- return gr.getlen()/sizeof(define);
-}
-
-char *DefineList::getname(int num)
-{
- if ((unsigned int)getnum() <= (unsigned int)num)
- return 0;
- return ((struct define*)gr.get())[num].name;
-}
-
-char *DefineList::getvalue(int num)
-{
- if ((unsigned int)getnum() <= (unsigned int)num)
- return 0;
- return ((struct define*)gr.get())[num].value;
-}
-
-// ==============
-// FastStringList
-// ==============
-
-int FastStringList::add(const char *name, int case_sensitive/*=0*/)
-{
- int pos = SortedStringListND<struct string_t>::add(name, case_sensitive);
- if (pos == -1) return -1;
- return ((struct string_t*)gr.get())[pos].name;
-}
-
-char *FastStringList::get() const
-{
- return (char*)strings.get();
-}
-
-int FastStringList::getlen() const
-{
- return strings.getlen();
-}
-
-int FastStringList::getnum() const
-{
- return gr.getlen()/sizeof(struct string_t);
-}
-
+/*
+ * strlist.cpp: Implementation of the StringList class.
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "strlist.h"
+
+int StringList::add(const char *str, int case_sensitive)
+{
+ int a=find(str,case_sensitive);
+ if (a >= 0 && case_sensitive!=-1) return a;
+ return gr.add(str,strlen(str)+1);
+}
+
+// use 2 for case sensitive end-of-string matches too
+int StringList::find(const char *str, int case_sensitive, int *idx/*=NULL*/) const // returns -1 if not found
+{
+ const char *s=get();
+ int ml=getlen();
+ int offs=0;
+ if (idx) *idx=0;
+ while (offs < ml)
+ {
+ if ((case_sensitive && !strcmp(s+offs,str)) ||
+ (!case_sensitive && !stricmp(s+offs,str)))
+ {
+ return offs;
+ }
+ if (case_sensitive==2 &&
+ strlen(str) < strlen(s+offs) && // check for end of string
+ !strcmp(s+offs+strlen(s+offs)-strlen(str),str))
+ {
+ return offs+strlen(s+offs)-strlen(str);
+ }
+ offs+=strlen(s+offs)+1;
+ if (idx) (*idx)++;
+ }
+ return -1;
+}
+
+void StringList::delbypos(int pos)
+{
+ char *s=(char*)gr.get();
+ int len=strlen(s+pos)+1;
+ if (pos+len < gr.getlen()) memcpy(s+pos,s+pos+len,gr.getlen()-(pos+len));
+ gr.resize(gr.getlen()-len);
+}
+
+int StringList::idx2pos(int idx) const
+{
+ char *s=(char*)gr.get();
+ int offs=0;
+ int cnt=0;
+ if (idx>=0) while (offs < gr.getlen())
+ {
+ if (cnt++ == idx) return offs;
+ offs+=strlen(s+offs)+1;
+ }
+ return -1;
+}
+
+int StringList::getnum() const
+{
+ char *s=(char*)gr.get();
+ int ml=gr.getlen();
+ int offs=0;
+ int idx=0;
+ while (offs < ml)
+ {
+ offs+=strlen(s+offs)+1;
+ idx++;
+ }
+ return idx;
+}
+
+const char *StringList::get() const
+{
+ return (const char*)gr.get();
+}
+
+int StringList::getlen() const
+{
+ return gr.getlen();
+}
+
+// ==========
+// DefineList
+// ==========
+
+DefineList::~DefineList()
+{
+ struct define *s=(struct define*)gr.get();
+ int num=gr.getlen()/sizeof(struct define);
+
+ for (int i=0; i<num; i++) {
+ free(s[i].value);
+ }
+}
+
+int DefineList::add(const char *name, const char *value/*=""*/)
+{
+ int pos=SortedStringList<struct define>::add(name);
+ if (pos == -1)
+ {
+ return 1;
+ }
+
+ char **newvalue=&(((struct define*)gr.get())[pos].value);
+ *newvalue=(char*)malloc(strlen(value)+1);
+ if (!(*newvalue))
+ {
+ extern FILE *g_output;
+ extern int g_display_errors;
+ extern void quit();
+ if (g_display_errors)
+ {
+ fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%lu) failed.\n",(unsigned long)strlen(value)+1);
+ fflush(g_output);
+ }
+ quit();
+ }
+ strcpy(*newvalue,value);
+ return 0;
+}
+
+char *DefineList::find(const char *name)
+{
+ int v=SortedStringList<struct define>::find(name);
+ if (v==-1)
+ {
+ return NULL;
+ }
+ return ((struct define*)gr.get())[v].value;
+}
+
+// returns 0 on success, 1 otherwise
+int DefineList::del(const char *str)
+{
+ int pos=SortedStringList<struct define>::find(str);
+ if (pos==-1) return 1;
+
+ struct define *db=(struct define *)gr.get();
+ free(db[pos].value);
+ delbypos(pos);
+
+ return 0;
+}
+
+int DefineList::getnum()
+{
+ return gr.getlen()/sizeof(define);
+}
+
+char *DefineList::getname(int num)
+{
+ if ((unsigned int)getnum() <= (unsigned int)num)
+ return 0;
+ return ((struct define*)gr.get())[num].name;
+}
+
+char *DefineList::getvalue(int num)
+{
+ if ((unsigned int)getnum() <= (unsigned int)num)
+ return 0;
+ return ((struct define*)gr.get())[num].value;
+}
+
+// ==============
+// FastStringList
+// ==============
+
+int FastStringList::add(const char *name, int case_sensitive/*=0*/)
+{
+ int pos = SortedStringListND<struct string_t>::add(name, case_sensitive);
+ if (pos == -1) return -1;
+ return ((struct string_t*)gr.get())[pos].name;
+}
+
+char *FastStringList::get() const
+{
+ return (char*)strings.get();
+}
+
+int FastStringList::getlen() const
+{
+ return strings.getlen();
+}
+
+int FastStringList::getnum() const
+{
+ return gr.getlen()/sizeof(struct string_t);
+}
+
diff --git a/Source/strlist.h b/Source/strlist.h
index 0c2a633..dd08855 100755
--- a/Source/strlist.h
+++ b/Source/strlist.h
@@ -1,258 +1,258 @@
-/*
- * strlist.h: Implementation of the StringList class.
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef _STRLIST_H_
-#define _STRLIST_H_
-
-#include "Platform.h"
-#include <cstdio>
-#include "growbuf.h"
-
-class StringList
-{
-private: // don't copy instances
- StringList(const StringList&);
- void operator=(const StringList&);
-
-public:
- StringList() {}
- ~StringList() {}
-
- int add(const char *str, int case_sensitive);
- // use 2 for case sensitive end-of-string matches too
- int find(const char *str, int case_sensitive, int *idx=NULL) const; // returns -1 if not found
- void delbypos(int pos);
- int idx2pos(int idx) const;
- int getnum() const;
- const char *get() const;
- int getlen() const;
-
-private:
- GrowBuf gr;
-};
-
-template <class T>
-class SortedStringList
-{
- public:
- virtual ~SortedStringList()
- {
- T *s=(T*)gr.get();
- size_t num=gr.getlen()/sizeof(T);
-
- for (size_t i=0; i<num; i++) {
- free(s[i].name);
- }
- }
-
- // returns -1 when name already exists and pos if added
- int add(const char *name, int case_sensitive=0)
- {
- T newstruct={0,};
- int pos=find(name,case_sensitive,1);
- if (pos==-1) return -1;
- newstruct.name=(char*)malloc(strlen(name)+1);
- if (!newstruct.name)
- {
- extern FILE *g_output;
- extern int g_display_errors;
- extern void quit();
- if (g_display_errors)
- {
- fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%lu) failed.\n",(unsigned long)strlen(name)+1);
- fflush(g_output);
- }
- quit();
- }
- strcpy(newstruct.name,name);
- gr.add(&newstruct,sizeof(T));
-
- T *s=(T*)gr.get();
- memmove(s+pos+1,s+pos,gr.getlen()-((pos+1)*sizeof(T)));
- memcpy(s+pos,&newstruct,sizeof(T));
-
- return pos;
- }
-
- // returns -1 if not found, position if found
- // if returnbestpos=1 returns -1 if found, best pos to insert if not found
- int find(const char *str, int case_sensitive=0, int returnbestpos=0)
- {
- T *data=(T *)gr.get();
- int ul=gr.getlen()/sizeof(T);
- int ll=0;
- int nextpos=(ul+ll)/2;
-
- while (ul > ll)
- {
- int res;
- if (case_sensitive)
- res=strcmp(str, data[nextpos].name);
- else
- res=stricmp(str, data[nextpos].name);
- if (res==0) return returnbestpos ? -1 : nextpos;
- if (res<0) ul=nextpos;
- else ll=nextpos+1;
- nextpos=(ul+ll)/2;
- }
-
- return returnbestpos ? nextpos : -1;
- }
-
- // returns 0 on success, 1 otherwise
- int del(const char *str, int case_sensitive=0)
- {
- int pos=find(str, case_sensitive);
- if (pos==-1) return 1;
-
- delbypos(pos);
-
- return 0;
- }
-
- void delbypos(int pos)
- {
- T *db=(T *)gr.get();
- free(db[pos].name);
- memmove(db+pos,db+pos+1,gr.getlen()-(pos*sizeof(T))-sizeof(T));
- gr.resize(gr.getlen()-sizeof(T));
- }
-
- protected:
- TinyGrowBuf gr;
-};
-
-#define mymin(x, y) ((x < y) ? x : y)
-
-template <class T>
-class SortedStringListND // no delete - can be placed in GrowBuf
-{
- public:
- SortedStringListND() { }
- virtual ~SortedStringListND() { }
-
- // returns -1 when name already exists and pos if added
- int add(const char *name, int case_sensitive=0, int alwaysreturnpos=0)
- {
- int where=0;
- T newstruct={0,};
- int pos=find(name,-1,case_sensitive,1,&where);
- if (pos==-1) return alwaysreturnpos ? where : -1;
- newstruct.name=strings.add(name,strlen(name)+1);
-
- gr.add(&newstruct,sizeof(T));
- T *s=(T*)gr.get();
- memmove(s+pos+1,s+pos,gr.getlen()-((pos+1)*sizeof(T)));
- memcpy(s+pos,&newstruct,sizeof(T));
-
- return pos;
- }
-
- // returns -1 if not found, position if found
- // if returnbestpos=1 returns -1 if found, best pos to insert if not found
- // if n_chars equal to -1 all string is tested
- int find(const char *str, int n_chars=-1, int case_sensitive=0, int returnbestpos=0, int *where=0)
- {
- T *data=(T *)gr.get();
- int ul=gr.getlen()/sizeof(T);
- int ll=0;
- int nextpos=(ul+ll)/2;
-
- while (ul > ll)
- {
- int res;
- const char *pCurr = (char*)strings.get() + data[nextpos].name;
- if (n_chars < 0)
- {
- if (case_sensitive)
- res = strcmp(str, pCurr);
- else
- res = stricmp(str, pCurr);
- }
- else
- {
- if (case_sensitive)
- res=strncmp(str, pCurr, mymin((unsigned int) n_chars, strlen(pCurr)));
- else
- res=strnicmp(str, pCurr, mymin((unsigned int) n_chars, strlen(pCurr)));
- if (res == 0 && n_chars != -1 && (unsigned int) n_chars != strlen(pCurr))
- res = n_chars - strlen(pCurr);
- }
-
- if (res==0)
- {
- if (where) *where = nextpos;
- return returnbestpos ? (case_sensitive!=-1 ? -1 : nextpos) : nextpos;
- }
- if (res<0) ul=nextpos;
- else ll=nextpos+1;
- nextpos=(ul+ll)/2;
- }
-
- return returnbestpos ? nextpos : -1;
- }
-
- protected:
- TinyGrowBuf gr;
- GrowBuf strings;
-};
-
-struct define {
- char *name;
- char *value;
-};
-
-class DefineList : public SortedStringList<struct define>
-{
- private: // don't copy instances
- DefineList(const DefineList&);
- void operator=(const DefineList&);
-
- public:
- DefineList() {} // VC6 complains otherwise
- virtual ~DefineList();
-
- int add(const char *name, const char *value="");
- char *find(const char *name);
-
- // returns 0 on success, 1 otherwise
- int del(const char *str);
- int getnum();
- char *getname(int num);
- char *getvalue(int num);
-};
-
-struct string_t {
- int name;
-};
-
-class FastStringList : public SortedStringListND<struct string_t>
-{
- private: // don't copy instances
- FastStringList(const FastStringList&);
- void operator=(const FastStringList&);
-
- public:
- FastStringList() {} // VC6 complains otherwise
- virtual ~FastStringList() {}
-
- int add(const char *name, int case_sensitive=0);
- char *get() const;
- int getlen() const;
- int getnum() const;
-};
-
-#endif//_STRLIST_H_
+/*
+ * strlist.h: Implementation of the StringList class.
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef _STRLIST_H_
+#define _STRLIST_H_
+
+#include "Platform.h"
+#include <cstdio>
+#include "growbuf.h"
+
+class StringList
+{
+private: // don't copy instances
+ StringList(const StringList&);
+ void operator=(const StringList&);
+
+public:
+ StringList() {}
+ ~StringList() {}
+
+ int add(const char *str, int case_sensitive);
+ // use 2 for case sensitive end-of-string matches too
+ int find(const char *str, int case_sensitive, int *idx=NULL) const; // returns -1 if not found
+ void delbypos(int pos);
+ int idx2pos(int idx) const;
+ int getnum() const;
+ const char *get() const;
+ int getlen() const;
+
+private:
+ GrowBuf gr;
+};
+
+template <class T>
+class SortedStringList
+{
+ public:
+ virtual ~SortedStringList()
+ {
+ T *s=(T*)gr.get();
+ size_t num=gr.getlen()/sizeof(T);
+
+ for (size_t i=0; i<num; i++) {
+ free(s[i].name);
+ }
+ }
+
+ // returns -1 when name already exists and pos if added
+ int add(const char *name, int case_sensitive=0)
+ {
+ T newstruct={0,};
+ int pos=find(name,case_sensitive,1);
+ if (pos==-1) return -1;
+ newstruct.name=(char*)malloc(strlen(name)+1);
+ if (!newstruct.name)
+ {
+ extern FILE *g_output;
+ extern int g_display_errors;
+ extern void quit();
+ if (g_display_errors)
+ {
+ fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%lu) failed.\n",(unsigned long)strlen(name)+1);
+ fflush(g_output);
+ }
+ quit();
+ }
+ strcpy(newstruct.name,name);
+ gr.add(&newstruct,sizeof(T));
+
+ T *s=(T*)gr.get();
+ memmove(s+pos+1,s+pos,gr.getlen()-((pos+1)*sizeof(T)));
+ memcpy(s+pos,&newstruct,sizeof(T));
+
+ return pos;
+ }
+
+ // returns -1 if not found, position if found
+ // if returnbestpos=1 returns -1 if found, best pos to insert if not found
+ int find(const char *str, int case_sensitive=0, int returnbestpos=0)
+ {
+ T *data=(T *)gr.get();
+ int ul=gr.getlen()/sizeof(T);
+ int ll=0;
+ int nextpos=(ul+ll)/2;
+
+ while (ul > ll)
+ {
+ int res;
+ if (case_sensitive)
+ res=strcmp(str, data[nextpos].name);
+ else
+ res=stricmp(str, data[nextpos].name);
+ if (res==0) return returnbestpos ? -1 : nextpos;
+ if (res<0) ul=nextpos;
+ else ll=nextpos+1;
+ nextpos=(ul+ll)/2;
+ }
+
+ return returnbestpos ? nextpos : -1;
+ }
+
+ // returns 0 on success, 1 otherwise
+ int del(const char *str, int case_sensitive=0)
+ {
+ int pos=find(str, case_sensitive);
+ if (pos==-1) return 1;
+
+ delbypos(pos);
+
+ return 0;
+ }
+
+ void delbypos(int pos)
+ {
+ T *db=(T *)gr.get();
+ free(db[pos].name);
+ memmove(db+pos,db+pos+1,gr.getlen()-(pos*sizeof(T))-sizeof(T));
+ gr.resize(gr.getlen()-sizeof(T));
+ }
+
+ protected:
+ TinyGrowBuf gr;
+};
+
+#define mymin(x, y) ((x < y) ? x : y)
+
+template <class T>
+class SortedStringListND // no delete - can be placed in GrowBuf
+{
+ public:
+ SortedStringListND() { }
+ virtual ~SortedStringListND() { }
+
+ // returns -1 when name already exists and pos if added
+ int add(const char *name, int case_sensitive=0, int alwaysreturnpos=0)
+ {
+ int where=0;
+ T newstruct={0,};
+ int pos=find(name,-1,case_sensitive,1,&where);
+ if (pos==-1) return alwaysreturnpos ? where : -1;
+ newstruct.name=strings.add(name,strlen(name)+1);
+
+ gr.add(&newstruct,sizeof(T));
+ T *s=(T*)gr.get();
+ memmove(s+pos+1,s+pos,gr.getlen()-((pos+1)*sizeof(T)));
+ memcpy(s+pos,&newstruct,sizeof(T));
+
+ return pos;
+ }
+
+ // returns -1 if not found, position if found
+ // if returnbestpos=1 returns -1 if found, best pos to insert if not found
+ // if n_chars equal to -1 all string is tested
+ int find(const char *str, int n_chars=-1, int case_sensitive=0, int returnbestpos=0, int *where=0)
+ {
+ T *data=(T *)gr.get();
+ int ul=gr.getlen()/sizeof(T);
+ int ll=0;
+ int nextpos=(ul+ll)/2;
+
+ while (ul > ll)
+ {
+ int res;
+ const char *pCurr = (char*)strings.get() + data[nextpos].name;
+ if (n_chars < 0)
+ {
+ if (case_sensitive)
+ res = strcmp(str, pCurr);
+ else
+ res = stricmp(str, pCurr);
+ }
+ else
+ {
+ if (case_sensitive)
+ res=strncmp(str, pCurr, mymin((unsigned int) n_chars, strlen(pCurr)));
+ else
+ res=strnicmp(str, pCurr, mymin((unsigned int) n_chars, strlen(pCurr)));
+ if (res == 0 && n_chars != -1 && (unsigned int) n_chars != strlen(pCurr))
+ res = n_chars - strlen(pCurr);
+ }
+
+ if (res==0)
+ {
+ if (where) *where = nextpos;
+ return returnbestpos ? (case_sensitive!=-1 ? -1 : nextpos) : nextpos;
+ }
+ if (res<0) ul=nextpos;
+ else ll=nextpos+1;
+ nextpos=(ul+ll)/2;
+ }
+
+ return returnbestpos ? nextpos : -1;
+ }
+
+ protected:
+ TinyGrowBuf gr;
+ GrowBuf strings;
+};
+
+struct define {
+ char *name;
+ char *value;
+};
+
+class DefineList : public SortedStringList<struct define>
+{
+ private: // don't copy instances
+ DefineList(const DefineList&);
+ void operator=(const DefineList&);
+
+ public:
+ DefineList() {} // VC6 complains otherwise
+ virtual ~DefineList();
+
+ int add(const char *name, const char *value="");
+ char *find(const char *name);
+
+ // returns 0 on success, 1 otherwise
+ int del(const char *str);
+ int getnum();
+ char *getname(int num);
+ char *getvalue(int num);
+};
+
+struct string_t {
+ int name;
+};
+
+class FastStringList : public SortedStringListND<struct string_t>
+{
+ private: // don't copy instances
+ FastStringList(const FastStringList&);
+ void operator=(const FastStringList&);
+
+ public:
+ FastStringList() {} // VC6 complains otherwise
+ virtual ~FastStringList() {}
+
+ int add(const char *name, int case_sensitive=0);
+ char *get() const;
+ int getlen() const;
+ int getnum() const;
+};
+
+#endif//_STRLIST_H_
diff --git a/Source/tokens.cpp b/Source/tokens.cpp
index 2f38aa7..7d9ee4b 100755
--- a/Source/tokens.cpp
+++ b/Source/tokens.cpp
@@ -1,397 +1,397 @@
-/*
- * tokens.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "build.h"
-#include "tokens.h"
-
-typedef struct
-{
- int id;
- char *name;
- int num_parms; // minimum number of parameters
- int opt_parms; // optional parmaters, usually 0, can be -1 for unlimited.
- char *usage_str;
- int placement; // where the token can be placed
-} tokenType;
-
-
-static tokenType tokenlist[TOK__LAST] =
-{
-{TOK_ABORT,"Abort",0,1,"[message]",TP_CODE},
-{TOK_ADDBRANDINGIMAGE,"AddBrandingImage",2,1,"(top|left|bottom|right) (height|width) [padding]",TP_GLOBAL},
-{TOK_ADDSIZE,"AddSize",1,0,"size_to_add_to_section_in_kb",TP_SEC},
-{TOK_AUTOCLOSE,"AutoCloseWindow",1,0,"(false|true)",TP_GLOBAL},
-{TOK_BGFONT,"BGFont",0,6,"[font_face [height [wieght] [/ITALIC] [/UNDERLINE] [/STRIKE]]]",TP_GLOBAL},
-{TOK_BGGRADIENT,"BGGradient",0,3,"(off | [top_color [bottom_color [text_color]]])",TP_GLOBAL},
-{TOK_BRANDINGTEXT,"BrandingText",1,1,"[/TRIM(LEFT|RIGHT|CENTER)] installer_text",TP_GLOBAL},
-{TOK_BRINGTOFRONT,"BringToFront",0,0,"",TP_CODE},
-{TOK_CALL,"Call",1,0,"function_name | [:label_name]",TP_CODE},
-{TOK_CALLINSTDLL,"CallInstDLL",2,1,"dll_path_on_target.dll [/NOUNLOAD] function",TP_CODE},
-{TOK_CAPTION,"Caption",1,0,"installer_caption",TP_GLOBAL|TP_PAGEEX},
-{TOK_CHANGEUI,"ChangeUI",2,0,"(all|dlg_id) ui_file.exe",TP_GLOBAL},
-{TOK_CLEARERRORS,"ClearErrors",0,0,"",TP_CODE},
-{TOK_COMPTEXT,"ComponentText",0,3,"[component_page_description] [component_subtext1] [component_subtext2]",TP_PG},
-{TOK_GETDLLVERSION,"GetDLLVersion",3,0,"filename $(user_var: high output) $(user_var: low output)",TP_CODE},
-{TOK_GETDLLVERSIONLOCAL,"GetDLLVersionLocal",3,0,"localfilename $(user_var: high output) $(user_var: low output)",TP_CODE},
-{TOK_GETFILETIME,"GetFileTime",3,0,"file $(user_var: high output) $(user_var: low output)",TP_CODE},
-{TOK_GETFILETIMELOCAL,"GetFileTimeLocal",3,0,"localfile $(user_var: high output) $(user_var: low output)",TP_CODE},
-{TOK_COPYFILES,"CopyFiles",2,3,"[/SILENT] [/FILESONLY] source_path destination_path [total_size_in_kb]",TP_CODE},
-{TOK_CRCCHECK,"CRCCheck",1,0,"(on|force|off)",TP_GLOBAL},
-{TOK_CREATEDIR,"CreateDirectory",1,0,"directory_name",TP_CODE},
-{TOK_CREATEFONT,"CreateFont",2,5,"$(user_var: handle output) face_name [height wieght /ITALIC /UNDERLINE /STRIKE]",TP_CODE},
-{TOK_CREATESHORTCUT,"CreateShortCut",2,6,"shortcut_name.lnk shortcut_target [parameters [icon_file [icon index [showmode [hotkey [comment]]]]]]\n showmode=(SW_SHOWNORMAL|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED)\n hotkey=(ALT|CONTROL|EXT|SHIFT)|(F1-F24|A-Z)",TP_CODE},
-{TOK_DBOPTIMIZE,"SetDatablockOptimize",1,0,"(off|on)",TP_ALL},
-{TOK_DELETEINISEC,"DeleteINISec",2,0,"ini_file section_name",TP_CODE},
-{TOK_DELETEINISTR,"DeleteINIStr",3,0,"ini_file section_name entry_name",TP_CODE},
-{TOK_DELETEREGKEY,"DeleteRegKey",2,1,"[/ifempty] root_key subkey\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
-{TOK_DELETEREGVALUE,"DeleteRegValue",3,0,"root_key subkey entry_name\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
-{TOK_DELETE,"Delete",1,1,"[/REBOOTOK] filespec",TP_CODE},
-{TOK_DETAILPRINT,"DetailPrint",1,0,"message",TP_CODE},
-{TOK_DIRTEXT,"DirText",0,4,"[directory_page_description] [directory_page_subtext] [browse_button_text] [browse_dlg_text]",TP_PG},
-//{TOK_DIRSHOW,"DirShow",1,0,"(show|hide)",TP_PG},
-{TOK_DIRSHOW,"DirShow",0,0,"doesn't currently work",TP_ALL},
-{TOK_DIRVAR,"DirVar",1,0,"$(user_var: dir in/out))",TP_PAGEEX},
-{TOK_DIRVERIFY,"DirVerify",1,0,"auto|leave",TP_PAGEEX},
-{TOK_GETINSTDIRERROR,"GetInstDirError",1,0,"$(user_var: error output)",TP_CODE},
-{TOK_ROOTDIRINST,"AllowRootDirInstall",1,0,"(true|false)",TP_GLOBAL},
-{TOK_CHECKBITMAP,"CheckBitmap",1,0,"local_bitmap.bmp",TP_GLOBAL},
-{TOK_ENABLEWINDOW,"EnableWindow",2,0,"hwnd (1|0)",TP_CODE},
-{TOK_ENUMREGKEY,"EnumRegKey",4,0,"$(user_var: output) rootkey subkey index\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
-{TOK_ENUMREGVAL,"EnumRegValue",4,0,"$(user_var: output) rootkey subkey index\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
-{TOK_EXCH,"Exch",0,1,"[$(user_var)] | [stack_item_index]",TP_CODE},
-{TOK_EXEC,"Exec",1,0,"command_line",TP_CODE},
-{TOK_EXECWAIT,"ExecWait",1,1,"command_line [$(user_var: return value)]",TP_CODE},
-{TOK_EXECSHELL,"ExecShell",2,2,"(open|print|etc) command_line [parameters [showmode]]\n showmode=(SW_SHOWNORMAL|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_HIDE)",TP_CODE},
-{TOK_EXPANDENVSTRS,"ExpandEnvStrings",2,0,"$(user_var: output) string",TP_CODE},
-{TOK_FINDWINDOW,"FindWindow",2,3,"$(user_var: handle output) WindowClass [WindowTitle] [Window_Parent] [Child_After]",TP_CODE},
-{TOK_FINDCLOSE,"FindClose",1,0,"$(user_var: handle input)",TP_CODE},
-{TOK_FINDFIRST,"FindFirst",3,0,"$(user_var: handle output) $(user_var: filename output) filespec",TP_CODE},
-{TOK_FINDNEXT,"FindNext",2,0,"$(user_var: handle input) $(user_var: filename output)",TP_CODE},
-{TOK_FILE,"File",1,-1,"[/nonfatal] [/a] ([/r] [/x filespec [...]] filespec [...] |\n /oname=outfile one_file_only)",TP_CODE},
-{TOK_FILEBUFSIZE,"FileBufSize",1,0,"buf_size_mb",TP_ALL},
-{TOK_FLUSHINI,"FlushINI",1,0,"ini_file",TP_CODE},
-{TOK_RESERVEFILE,"ReserveFile",1,-1,"[/nonfatal] [/r] [/x filespec [...]] file [file...]",TP_ALL},
-{TOK_FILECLOSE,"FileClose",1,0,"$(user_var: handle input)",TP_CODE},
-{TOK_FILEERRORTEXT,"FileErrorText",0,2,"[text (can contain $0)] [text without ignore (can contain $0)]",TP_GLOBAL},
-{TOK_FILEOPEN,"FileOpen",3,0,"$(user_var: handle output) filename openmode\n openmode=r|w|a",TP_CODE},
-{TOK_FILEREAD,"FileRead",2,1,"$(user_var: handle input) $(user_var: text output) [maxlen]",TP_CODE},
-{TOK_FILEWRITE,"FileWrite",2,0,"$(user_var: handle input) text",TP_CODE},
-{TOK_FILEREADBYTE,"FileReadByte",2,0,"$(user_var: handle input) $(user_var: bytevalue output)",TP_CODE},
-{TOK_FILEWRITEBYTE,"FileWriteByte",2,0,"$(user_var: handle input) bytevalue",TP_CODE},
-{TOK_FILESEEK,"FileSeek",2,2,"$(user_var: handle input) offset [mode] [$(user_var: new position output)]\n mode=SET|CUR|END",TP_CODE},
-{TOK_FUNCTION,"Function",1,0,"function_name",TP_GLOBAL},
-{TOK_FUNCTIONEND,"FunctionEnd",0,0,"",TP_FUNC},
-{TOK_GETDLGITEM,"GetDlgItem",3,0,"$(user_var: handle output) dialog item_id",TP_CODE},
-{TOK_GETFULLPATHNAME,"GetFullPathName",2,1,"[/SHORT] $(user_var: result) path_or_file",TP_CODE},
-{TOK_GETTEMPFILENAME,"GetTempFileName",1,1,"$(user_var: name output) [base_dir]",TP_CODE},
-{TOK_HIDEWINDOW,"HideWindow",0,0,"",TP_CODE},
-{TOK_ICON,"Icon",1,0,"local_icon.ico",TP_GLOBAL},
-{TOK_IFABORT,"IfAbort",1,1,"label_to_goto_if_abort [label_to_goto_if_no_abort]",TP_CODE},
-{TOK_IFERRORS,"IfErrors",1,1,"label_to_goto_if_errors [label_to_goto_if_no_errors]",TP_CODE},
-{TOK_IFFILEEXISTS,"IfFileExists",2,1,"filename label_to_goto_if_file_exists [label_to_goto_otherwise]",TP_CODE},
-{TOK_IFREBOOTFLAG,"IfRebootFlag",1,1,"jump_if_set [jump_if_not_set]",TP_CODE},
-{TOK_IFSILENT,"IfSilent",1,1,"jump_if_silent [jump_if_not_silent]",TP_CODE},
-{TOK_INSTALLDIRREGKEY,"InstallDirRegKey",3,0,"root_key subkey entry_name\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)",TP_GLOBAL},
-{TOK_INSTCOLORS,"InstallColors",1,1,"(/windows | (foreground_color background_color))",TP_GLOBAL},
-{TOK_INSTDIR,"InstallDir",1,0,"default_install_directory",TP_GLOBAL},
-{TOK_INSTPROGRESSFLAGS,"InstProgressFlags",0,-1,"[flag [...]]\n flag={smooth|colored}",TP_GLOBAL},
-{TOK_INSTTYPE,"InstType",1,0,"[un.]install_type_name | /NOCUSTOM | /CUSTOMSTRING=str | /COMPONENTSONLYONCUSTOM",TP_GLOBAL},
-{TOK_INTOP,"IntOp",3,1,"$(user_var: result) val1 OP [val2]\n OP=(+ - * / % | & ^ ~ ! || && << >>)",TP_CODE},
-{TOK_INTCMP,"IntCmp",3,2,"val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]",TP_CODE},
-{TOK_INTCMPU,"IntCmpU",3,2,"val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]",TP_CODE},
-{TOK_INTFMT,"IntFmt",3,0,"$(user_var: output) format_string input",TP_CODE},
-{TOK_ISWINDOW,"IsWindow",2,1,"hwnd jump_if_window [jump_if_not_window]",TP_CODE},
-{TOK_GOTO,"Goto",1,0,"label",TP_CODE},
-{TOK_LANGSTRING,"LangString",3,0,"[un.]name lang_id string",TP_GLOBAL},
-{TOK_LANGSTRINGUP,"LangStringUP",0,0,"obsolete, use LangString.",TP_ALL},
-{TOK_LICENSEDATA,"LicenseData",1,0,"local_file_that_has_license_text | license_lang_string",TP_PG},
-{TOK_LICENSEFORCESELECTION,"LicenseForceSelection",1,2,"(checkbox [accept_text] | radiobuttons [accept_text] [decline_text] | off)",TP_PG},
-{TOK_LICENSELANGSTRING,"LicenseLangString",3,0,"name lang_id license_path",TP_GLOBAL},
-{TOK_LICENSETEXT,"LicenseText",1,1,"license_page_description [license_button_text]",TP_PG},
-{TOK_LICENSEBKCOLOR,"LicenseBkColor",1,0,"background_color",TP_GLOBAL},
-{TOK_LOADNLF,"LoadLanguageFile",1,0,"language.nlf",TP_GLOBAL},
-{TOK_LOGSET,"LogSet",1,0,"on|off",TP_CODE},
-{TOK_LOGTEXT,"LogText",1,0,"text",TP_CODE},
-{TOK_MESSAGEBOX,"MessageBox",2,6,"mode messagebox_text [/SD return] [return_check label_to_goto_if_equal [return_check2 label2]]\n mode=modeflag[|modeflag[|modeflag[...]]]\n "
- "modeflag=(MB_ABORTRETRYIGNORE|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_YESNO|MB_YESNOCANCEL|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_USERICON|MB_TOPMOST|MB_SETFOREGROUND|MB_RIGHT",TP_CODE},
-{TOK_NOP,"Nop",0,0,"",TP_CODE},
-{TOK_NAME,"Name",1,1,"installer_name installer_name_doubled_ampersands",TP_GLOBAL},
-{TOK_OUTFILE,"OutFile",1,0,"install_output.exe",TP_GLOBAL},
-#ifdef NSIS_SUPPORT_CODECALLBACKS
-{TOK_PAGE,"Page",1,4,"((custom [creator_function] [leave_function] [caption]) | ((license|components|directory|instfiles|uninstConfirm) [pre_function] [show_function] [leave_function])) [/ENABLECANCEL]",TP_GLOBAL},
-#else
-{TOK_PAGE,"Page",1,1,"license|components|directory|instfiles|uninstConfirm [/ENABLECANCEL]",TP_GLOBAL},
-#endif
-{TOK_PAGECALLBACKS,"PageCallbacks",0,3,"([creator_function] [leave_function]) | ([pre_function] [show_function] [leave_function])",TP_PAGEEX},
-{TOK_PAGEEX,"PageEx",1,0,"[un.](custom|uninstConfirm|license|components|directory|instfiles)",TP_GLOBAL},
-{TOK_PAGEEXEND,"PageExEnd",0,0,"",TP_PAGEEX},
-{TOK_POP,"Pop",1,0,"$(user_var: output)",TP_CODE},
-{TOK_PUSH,"Push",1,0,"string",TP_CODE},
-{TOK_QUIT,"Quit",0,0,"",TP_CODE},
-{TOK_READINISTR,"ReadINIStr",4,0,"$(user_var: output) ini_file section entry_name",TP_CODE},
-{TOK_READREGDWORD,"ReadRegDWORD",4,0,"$(user_var: output) rootkey subkey entry\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
-{TOK_READREGSTR,"ReadRegStr",4,0,"$(user_var: output) rootkey subkey entry\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
-{TOK_READENVSTR,"ReadEnvStr",2,0,"$(user_var: output) name",TP_CODE},
-{TOK_REBOOT,"Reboot",0,0,"",TP_CODE},
-{TOK_REGDLL,"RegDLL",1,1,"dll_path_on_target.dll [entrypoint_symbol]",TP_CODE},
-{TOK_RENAME,"Rename",2,1,"[/REBOOTOK] source_file destination_file",TP_CODE},
-{TOK_RET,"Return",0,0,"",TP_CODE},
-{TOK_RMDIR,"RMDir",1,2,"[/r] [/REBOOTOK] directory_name",TP_CODE},
-{TOK_SECTION,"Section",0,3,"[/o] [-][un.][section_name] [section index output]",TP_GLOBAL},
-{TOK_SECTIONEND,"SectionEnd",0,0,"",TP_SEC},
-{TOK_SECTIONIN,"SectionIn",1,-1,"InstTypeIdx [InstTypeIdx [...]]",TP_SEC},
-{TOK_SUBSECTION,"SubSection",1,2,"deprecated - use SectionGroup",TP_GLOBAL},
-{TOK_SECTIONGROUP,"SectionGroup",1,2,"[/e] [un.]section_group_name [section index output]",TP_GLOBAL},
-{TOK_SUBSECTIONEND,"SubSectionEnd",0,0,"deprecated - use SectionGroupEnd",TP_GLOBAL},
-{TOK_SECTIONGROUPEND,"SectionGroupEnd",0,0,"",TP_GLOBAL},
-{TOK_SEARCHPATH,"SearchPath",2,0,"$(user_var: result) filename",TP_CODE},
-{TOK_SECTIONSETFLAGS,"SectionSetFlags",2,0,"section_index flags",TP_CODE},
-{TOK_SECTIONGETFLAGS,"SectionGetFlags",2,0,"section_index $(user_var: output flags)",TP_CODE},
-{TOK_SECTIONSETINSTTYPES,"SectionSetInstTypes",2,0,"section_index inst_types",TP_CODE},
-{TOK_SECTIONGETINSTTYPES,"SectionGetInstTypes",2,0,"section_index $(user_var: output inst_types)",TP_CODE},
-{TOK_SECTIONGETTEXT,"SectionGetText",2,0,"section_index $(user_var: output text)",TP_CODE},
-{TOK_SECTIONSETTEXT,"SectionSetText",2,0,"section_index text_string",TP_CODE},
-{TOK_SECTIONGETSIZE,"SectionGetSize",2,0,"section_index $(user_var: output size)",TP_CODE},
-{TOK_SECTIONSETSIZE,"SectionSetSize",2,0,"section_index new_size",TP_CODE},
-{TOK_GETCURINSTTYPE,"GetCurInstType",1,0,"$(user_var: output inst_type_idx)",TP_CODE},
-{TOK_SETCURINSTTYPE,"SetCurInstType",1,0,"inst_type_idx",TP_CODE},
-{TOK_INSTTYPESETTEXT,"InstTypeSetText",2,0,"insttype_index flags",TP_CODE},
-{TOK_INSTTYPEGETTEXT,"InstTypeGetText",2,0,"insttype_index $(user_var: output flags)",TP_CODE},
-{TOK_SENDMESSAGE,"SendMessage",4,2,"hwnd message [wparam|STR:wParam] [lparam|STR:lParam] [$(user_var: return value)] [/TIMEOUT=X]",TP_CODE},
-{TOK_SETAUTOCLOSE,"SetAutoClose",1,0,"(false|true)",TP_CODE},
-{TOK_SETCTLCOLORS,"SetCtlColors",2,2,"hwnd [/BRANDING] [text_color] [transparent|bg_color]",TP_CODE},
-{TOK_SETBRANDINGIMAGE,"SetBrandingImage",1,2,"[/IMGID=image_item_id_in_dialog] [/RESIZETOFIT] bitmap.bmp",TP_CODE},
-{TOK_SETCOMPRESS,"SetCompress",1,0,"(off|auto|force)",TP_ALL},
-{TOK_SETCOMPRESSOR,"SetCompressor",1,2,"[/FINAL] [/SOLID] (zlib|bzip2|lzma)",TP_GLOBAL},
-{TOK_SETCOMPRESSORDICTSIZE,"SetCompressorDictSize",1,0,"dict_size_mb",TP_ALL},
-{TOK_SETCOMPRESSIONLEVEL,"SetCompressionLevel",1,0,"level_0-9",TP_ALL},
-{TOK_SETDATESAVE,"SetDateSave",1,0,"(off|on)",TP_ALL},
-{TOK_SETDETAILSVIEW,"SetDetailsView",1,0,"(hide|show)",TP_CODE},
-{TOK_SETDETAILSPRINT,"SetDetailsPrint",1,0,"(none|listonly|textonly|both)",TP_CODE},
-{TOK_SETERRORS,"SetErrors",0,0,"",TP_CODE},
-{TOK_SETERRORLEVEL,"SetErrorLevel",1,0,"error_level",TP_CODE},
-{TOK_GETERRORLEVEL,"GetErrorLevel",1,0,"$(user_var: output)",TP_CODE},
-{TOK_SETFILEATTRIBUTES,"SetFileAttributes",2,0,"file attribute[|attribute[...]]\n attribute=(NORMAL|ARCHIVE|HIDDEN|OFFLINE|READONLY|SYSTEM|TEMPORARY|0)",TP_CODE},
-{TOK_SETFONT,"SetFont",2,1,"[/LANG=lang_id] font_face_name font_size",TP_GLOBAL},
-{TOK_SETOUTPATH,"SetOutPath",1,0,"output_path",TP_CODE},
-{TOK_SETOVERWRITE,"SetOverwrite",1,0,"on|off|try|ifnewer|ifdiff",TP_ALL},
-{TOK_SETPLUGINUNLOAD,"SetPluginUnload",1,0,"(manual|alwaysoff)",TP_ALL},
-{TOK_SETREBOOTFLAG,"SetRebootFlag",1,0,"true|false",TP_CODE},
-{TOK_SETREGVIEW,"SetRegView",1,0,"32|64|lastused",TP_CODE},
-{TOK_SETSHELLVARCONTEXT,"SetShellVarContext",1,0,"all|current",TP_CODE},
-{TOK_SETSILENT,"SetSilent",1,0,"silent|normal",TP_CODE},
-{TOK_SHOWDETAILS,"ShowInstDetails",1,0,"(hide|show|nevershow)",TP_GLOBAL},
-{TOK_SHOWDETAILSUNINST,"ShowUninstDetails",1,0,"(hide|show|nevershow)",TP_GLOBAL},
-{TOK_SHOWWINDOW,"ShowWindow",2,0,"hwnd show_state",TP_CODE},
-{TOK_SILENTINST,"SilentInstall",1,0,"(normal|silent|silentlog)",TP_GLOBAL},
-{TOK_SILENTUNINST,"SilentUnInstall",1,0,"(normal|silent)",TP_GLOBAL},
-{TOK_SLEEP,"Sleep",1,0,"sleep_time_in_ms",TP_CODE},
-{TOK_STRCMP,"StrCmp",3,1,"str1 str2 label_to_goto_if_equal [label_to_goto_if_not]",TP_CODE},
-{TOK_STRCMPS,"StrCmpS",3,1,"str1 str2 label_to_goto_if_equal [label_to_goto_if_not]",TP_CODE},
-{TOK_STRCPY,"StrCpy",2,2,"$(user_var: output) str [maxlen] [startoffset]",TP_CODE},
-{TOK_STRLEN,"StrLen",2,0,"$(user_var: length output) str",TP_CODE},
-{TOK_SUBCAPTION,"SubCaption",2,0,"page_number(0-4) new_subcaption",TP_GLOBAL},
-{TOK_UNINSTALLEXENAME,"UninstallExeName",0,0,"no longer supported, use WriteUninstaller from section.",TP_ALL},
-{TOK_UNINSTCAPTION,"UninstallCaption",1,0,"uninstaller_caption",TP_GLOBAL},
-{TOK_UNINSTICON,"UninstallIcon",1,0,"icon_on_local_system.ico",TP_GLOBAL},
-#ifdef NSIS_SUPPORT_CODECALLBACKS
-{TOK_UNINSTPAGE,"UninstPage",1,4,"((custom [creator_function] [leave_function] [caption]) | ((license|components|directory|instfiles|uninstConfirm) [pre_function] [show_function] [leave_function])) [/ENABLECANCEL]",TP_GLOBAL},
-#else
-{TOK_UNINSTPAGE,"UninstPage",1,1,"license|components|directory|instfiles|uninstConfirm [/ENABLECANCEL]",TP_GLOBAL},
-#endif
-{TOK_UNINSTTEXT,"UninstallText",1,1,"Text_to_go_on_uninstall_page [subtext]",TP_PG},
-{TOK_UNINSTSUBCAPTION,"UninstallSubCaption",2,0,"page_number(0-2) new_subcaption",TP_GLOBAL},
-{TOK_UNREGDLL,"UnRegDLL",1,0,"dll_path_on_target.dll",TP_CODE},
-{TOK_WINDOWICON,"WindowIcon",1,0,"on|off",TP_GLOBAL},
-{TOK_WRITEINISTR,"WriteINIStr",4,0,"ini_file section_name entry_name new_value",TP_CODE},
-{TOK_WRITEREGBIN,"WriteRegBin",4,0,"rootkey subkey entry_name hex_string_like_12848412AB\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
-{TOK_WRITEREGDWORD,"WriteRegDWORD",4,0,"rootkey subkey entry_name new_value_dword\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
-{TOK_WRITEREGSTR,"WriteRegStr",4,0,"rootkey subkey entry_name new_value_string\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
-{TOK_WRITEREGEXPANDSTR,"WriteRegExpandStr",4,0,"rootkey subkey entry_name new_value_string\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
-{TOK_WRITEUNINSTALLER,"WriteUninstaller",1,0,"uninstall_exe_name",TP_CODE},
-{TOK_XPSTYLE, "XPStyle",1,0,"(on|off)",TP_GLOBAL},
-{TOK_REQEXECLEVEL, "RequestExecutionLevel",1,0,"none|user|highest|admin",TP_GLOBAL},
-{TOK_P_PACKEXEHEADER,"!packhdr",2,0,"temp_file_name command_line_to_compress_that_temp_file",TP_ALL},
-{TOK_P_SYSTEMEXEC,"!system",1,2,"command [<|>|<>|=) retval]",TP_ALL},
-{TOK_P_EXECUTE,"!execute",1,0,"command",TP_ALL},
-{TOK_P_ADDINCLUDEDIR,"!AddIncludeDir",1,0,"dir",TP_ALL},
-{TOK_P_INCLUDE,"!include",1,1,"[/NONFATAL] filename.nsh",TP_ALL},
-{TOK_P_CD,"!cd",1,0,"absolute_or_relative_new_directory",TP_ALL},
-{TOK_P_IF,"!if",1,3,"[!] value [(==,!=,<=,<,>,>=,&&,||) value2] [...]",TP_ALL},
-{TOK_P_IFDEF,"!ifdef",1,-1,"symbol [| symbol2 [& symbol3 [...]]]",TP_ALL},
-{TOK_P_IFNDEF,"!ifndef",1,-1,"symbol [| symbol2 [& symbol3 [...]]]",TP_ALL},
-{TOK_P_ENDIF,"!endif",0,0,"",TP_ALL},
-{TOK_P_DEFINE,"!define",1,4,"([/date|/utcdate] symbol [value]) | (/math symbol val1 OP val2)\n OP=(+ - * / % & | ^)",TP_ALL},
-{TOK_P_UNDEF,"!undef",1,1,"symbol [value]",TP_ALL},
-{TOK_P_ELSE,"!else",0,-1,"[if[macro][n][def] ...]",TP_ALL},
-{TOK_P_ECHO,"!echo",1,0,"message",TP_ALL},
-{TOK_P_WARNING,"!warning",0,1,"[warning_message]",TP_ALL},
-{TOK_P_ERROR,"!error",0,1,"[error_message]",TP_ALL},
-
-{TOK_P_VERBOSE,"!verbose",1,0,"verbose_level | push | pop",TP_ALL},
-
-{TOK_P_MACRO,"!macro",1,-1,"macroname [parms ...]",TP_ALL},
-{TOK_P_MACROEND,"!macroend",0,0,"",TP_ALL},
-{TOK_P_INSERTMACRO,"!insertmacro",1,-1,"macroname [parms ...]",TP_ALL},
-{TOK_P_IFMACRODEF,"!ifmacrodef",1,-1,"macro [| macro2 [& macro3 [...]]]",TP_ALL},
-{TOK_P_IFMACRONDEF,"!ifmacrondef",1,-1,"macro [| macro2 [& macro3 [...]]]",TP_ALL},
-
-{TOK_P_TEMPFILE,"!tempfile",1,0,"symbol",TP_ALL},
-{TOK_P_DELFILE,"!delfile",1,0,"file",TP_ALL},
-{TOK_P_APPENDFILE,"!appendfile",2,0,"file appended_line",TP_ALL},
-
-{TOK_MISCBUTTONTEXT,"MiscButtonText",0,4,"[back button text] [next button text] [cancel button text] [close button text]",TP_GLOBAL},
-{TOK_DETAILSBUTTONTEXT,"DetailsButtonText",0,1,"[details button text]",TP_PG},
-{TOK_UNINSTBUTTONTEXT,"UninstallButtonText",0,1,"[uninstall button text]",TP_GLOBAL},
-{TOK_INSTBUTTONTEXT,"InstallButtonText",0,1,"[install button text]",TP_GLOBAL},
-{TOK_SPACETEXTS,"SpaceTexts",0,2,"none | ([space required text] [space available text])",TP_GLOBAL},
-{TOK_COMPLETEDTEXT,"CompletedText",0,1,"[completed text]",TP_PG},
-
-{TOK_GETFUNCTIONADDR,"GetFunctionAddress",2,0,"output function",TP_CODE},
-{TOK_GETLABELADDR,"GetLabelAddress",2,0,"output label",TP_CODE},
-{TOK_GETCURRENTADDR,"GetCurrentAddress",1,0,"output",TP_CODE},
-
-{TOK_PLUGINDIR,"!AddPluginDir",1,0,"new_plugin_directory",TP_ALL},
-{TOK_INITPLUGINSDIR,"InitPluginsDir",0,0,"",TP_CODE},
-// Added by ramon 23 May 2003
-{TOK_ALLOWSKIPFILES,"AllowSkipFiles",1,0,"(off|on)",TP_ALL},
-// Added by ramon 3 jun 2003
-{TOK_DEFVAR,"Var",1,1,"[/GLOBAL] var_name",TP_ALL},
-// Added by ramon 6 jun 2003
-{TOK_VI_ADDKEY,"VIAddVersionKey",2,1,"/LANG=lang_id keyname value",TP_GLOBAL},
-{TOK_VI_SETPRODUCTVERSION,"VIProductVersion",1,0,"[version_string_X.X.X.X]",TP_GLOBAL},
-{TOK_LOCKWINDOW,"LockWindow",1,0,"(on|off)",TP_CODE},
-};
-
-void CEXEBuild::print_help(char *commandname)
-{
- int x;
- for (x = 0; x < TOK__LAST; x ++)
- {
- if (!commandname || !stricmp(tokenlist[x].name,commandname))
- {
- ERROR_MSG("%s%s %s\n",commandname?"Usage: ":"",tokenlist[x].name,tokenlist[x].usage_str);
- if (commandname) break;
- }
- }
- if (x == TOK__LAST && commandname)
- {
- ERROR_MSG("Invalid command \"%s\"\n",commandname);
- }
-
-}
-
-bool CEXEBuild::is_valid_token(char *s)
-{
- for (int x = 0; x < TOK__LAST; x ++)
- if (!stricmp(tokenlist[x].name,s))
- return true;
- return false;
-}
-
-int CEXEBuild::get_commandtoken(char *s, int *np, int *op, int *pos)
-{
- int x;
- for (x = 0; x < TOK__LAST; x ++)
- if (!stricmp(tokenlist[x].name,s))
- {
- *np=tokenlist[x].num_parms;
- *op=tokenlist[x].opt_parms;
- *pos=x;
- return tokenlist[x].id;
- }
- return -1;
-}
-
-int CEXEBuild::GetCurrentTokenPlace()
-{
- if (build_cursection)
- {
- if (build_cursection_isfunc)
- {
- return TP_FUNC;
- }
- else
- {
- return TP_SEC;
- }
- }
-
- if (cur_page)
- return TP_PAGEEX;
-
- return TP_GLOBAL;
-}
-
-int CEXEBuild::IsTokenPlacedRight(int pos, char *tok)
-{
- if ((unsigned int) pos > (sizeof(tokenlist) / sizeof(tokenType)))
- return PS_OK;
-
- int tp = tokenlist[pos].placement;
- int cp = GetCurrentTokenPlace();
- if (tp & cp) {
- return PS_OK;
- }
- else {
- char err[1024];
- if (cp == TP_SEC) {
- strcpy(err, "Error: command %s not valid in Section\n");
- }
- else if (cp == TP_FUNC) {
- strcpy(err, "Error: command %s not valid in Function\n");
- }
- else if (cp == TP_PAGEEX) {
- strcpy(err, "Error: command %s not valid in PageEx\n");
- }
- else
- {
- strcpy(err, "Error: command %s not valid outside ");
- if (tp & TP_SEC)
- strcat(err, "Section");
- if (tp & TP_FUNC)
- {
- if (tp & TP_SEC)
- {
- if (tp & TP_PAGEEX)
- {
- strcat(err, ", ");
- }
- else
- {
- strcat(err, " or ");
- }
- }
- strcat(err, "Function");
- }
- if (tp & TP_PAGEEX)
- {
- if (tp & TP_CODE)
- {
- strcat(err, " or ");
- }
- strcat(err, "PageEx");
- }
- strcat(err, "\n");
- }
- ERROR_MSG(err, tok);
- return PS_ERROR;
- }
-}
+/*
+ * tokens.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "build.h"
+#include "tokens.h"
+
+typedef struct
+{
+ int id;
+ char *name;
+ int num_parms; // minimum number of parameters
+ int opt_parms; // optional parmaters, usually 0, can be -1 for unlimited.
+ char *usage_str;
+ int placement; // where the token can be placed
+} tokenType;
+
+
+static tokenType tokenlist[TOK__LAST] =
+{
+{TOK_ABORT,"Abort",0,1,"[message]",TP_CODE},
+{TOK_ADDBRANDINGIMAGE,"AddBrandingImage",2,1,"(top|left|bottom|right) (height|width) [padding]",TP_GLOBAL},
+{TOK_ADDSIZE,"AddSize",1,0,"size_to_add_to_section_in_kb",TP_SEC},
+{TOK_AUTOCLOSE,"AutoCloseWindow",1,0,"(false|true)",TP_GLOBAL},
+{TOK_BGFONT,"BGFont",0,6,"[font_face [height [wieght] [/ITALIC] [/UNDERLINE] [/STRIKE]]]",TP_GLOBAL},
+{TOK_BGGRADIENT,"BGGradient",0,3,"(off | [top_color [bottom_color [text_color]]])",TP_GLOBAL},
+{TOK_BRANDINGTEXT,"BrandingText",1,1,"[/TRIM(LEFT|RIGHT|CENTER)] installer_text",TP_GLOBAL},
+{TOK_BRINGTOFRONT,"BringToFront",0,0,"",TP_CODE},
+{TOK_CALL,"Call",1,0,"function_name | [:label_name]",TP_CODE},
+{TOK_CALLINSTDLL,"CallInstDLL",2,1,"dll_path_on_target.dll [/NOUNLOAD] function",TP_CODE},
+{TOK_CAPTION,"Caption",1,0,"installer_caption",TP_GLOBAL|TP_PAGEEX},
+{TOK_CHANGEUI,"ChangeUI",2,0,"(all|dlg_id) ui_file.exe",TP_GLOBAL},
+{TOK_CLEARERRORS,"ClearErrors",0,0,"",TP_CODE},
+{TOK_COMPTEXT,"ComponentText",0,3,"[component_page_description] [component_subtext1] [component_subtext2]",TP_PG},
+{TOK_GETDLLVERSION,"GetDLLVersion",3,0,"filename $(user_var: high output) $(user_var: low output)",TP_CODE},
+{TOK_GETDLLVERSIONLOCAL,"GetDLLVersionLocal",3,0,"localfilename $(user_var: high output) $(user_var: low output)",TP_CODE},
+{TOK_GETFILETIME,"GetFileTime",3,0,"file $(user_var: high output) $(user_var: low output)",TP_CODE},
+{TOK_GETFILETIMELOCAL,"GetFileTimeLocal",3,0,"localfile $(user_var: high output) $(user_var: low output)",TP_CODE},
+{TOK_COPYFILES,"CopyFiles",2,3,"[/SILENT] [/FILESONLY] source_path destination_path [total_size_in_kb]",TP_CODE},
+{TOK_CRCCHECK,"CRCCheck",1,0,"(on|force|off)",TP_GLOBAL},
+{TOK_CREATEDIR,"CreateDirectory",1,0,"directory_name",TP_CODE},
+{TOK_CREATEFONT,"CreateFont",2,5,"$(user_var: handle output) face_name [height wieght /ITALIC /UNDERLINE /STRIKE]",TP_CODE},
+{TOK_CREATESHORTCUT,"CreateShortCut",2,6,"shortcut_name.lnk shortcut_target [parameters [icon_file [icon index [showmode [hotkey [comment]]]]]]\n showmode=(SW_SHOWNORMAL|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED)\n hotkey=(ALT|CONTROL|EXT|SHIFT)|(F1-F24|A-Z)",TP_CODE},
+{TOK_DBOPTIMIZE,"SetDatablockOptimize",1,0,"(off|on)",TP_ALL},
+{TOK_DELETEINISEC,"DeleteINISec",2,0,"ini_file section_name",TP_CODE},
+{TOK_DELETEINISTR,"DeleteINIStr",3,0,"ini_file section_name entry_name",TP_CODE},
+{TOK_DELETEREGKEY,"DeleteRegKey",2,1,"[/ifempty] root_key subkey\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
+{TOK_DELETEREGVALUE,"DeleteRegValue",3,0,"root_key subkey entry_name\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
+{TOK_DELETE,"Delete",1,1,"[/REBOOTOK] filespec",TP_CODE},
+{TOK_DETAILPRINT,"DetailPrint",1,0,"message",TP_CODE},
+{TOK_DIRTEXT,"DirText",0,4,"[directory_page_description] [directory_page_subtext] [browse_button_text] [browse_dlg_text]",TP_PG},
+//{TOK_DIRSHOW,"DirShow",1,0,"(show|hide)",TP_PG},
+{TOK_DIRSHOW,"DirShow",0,0,"doesn't currently work",TP_ALL},
+{TOK_DIRVAR,"DirVar",1,0,"$(user_var: dir in/out))",TP_PAGEEX},
+{TOK_DIRVERIFY,"DirVerify",1,0,"auto|leave",TP_PAGEEX},
+{TOK_GETINSTDIRERROR,"GetInstDirError",1,0,"$(user_var: error output)",TP_CODE},
+{TOK_ROOTDIRINST,"AllowRootDirInstall",1,0,"(true|false)",TP_GLOBAL},
+{TOK_CHECKBITMAP,"CheckBitmap",1,0,"local_bitmap.bmp",TP_GLOBAL},
+{TOK_ENABLEWINDOW,"EnableWindow",2,0,"hwnd (1|0)",TP_CODE},
+{TOK_ENUMREGKEY,"EnumRegKey",4,0,"$(user_var: output) rootkey subkey index\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
+{TOK_ENUMREGVAL,"EnumRegValue",4,0,"$(user_var: output) rootkey subkey index\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
+{TOK_EXCH,"Exch",0,1,"[$(user_var)] | [stack_item_index]",TP_CODE},
+{TOK_EXEC,"Exec",1,0,"command_line",TP_CODE},
+{TOK_EXECWAIT,"ExecWait",1,1,"command_line [$(user_var: return value)]",TP_CODE},
+{TOK_EXECSHELL,"ExecShell",2,2,"(open|print|etc) command_line [parameters [showmode]]\n showmode=(SW_SHOWNORMAL|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_HIDE)",TP_CODE},
+{TOK_EXPANDENVSTRS,"ExpandEnvStrings",2,0,"$(user_var: output) string",TP_CODE},
+{TOK_FINDWINDOW,"FindWindow",2,3,"$(user_var: handle output) WindowClass [WindowTitle] [Window_Parent] [Child_After]",TP_CODE},
+{TOK_FINDCLOSE,"FindClose",1,0,"$(user_var: handle input)",TP_CODE},
+{TOK_FINDFIRST,"FindFirst",3,0,"$(user_var: handle output) $(user_var: filename output) filespec",TP_CODE},
+{TOK_FINDNEXT,"FindNext",2,0,"$(user_var: handle input) $(user_var: filename output)",TP_CODE},
+{TOK_FILE,"File",1,-1,"[/nonfatal] [/a] ([/r] [/x filespec [...]] filespec [...] |\n /oname=outfile one_file_only)",TP_CODE},
+{TOK_FILEBUFSIZE,"FileBufSize",1,0,"buf_size_mb",TP_ALL},
+{TOK_FLUSHINI,"FlushINI",1,0,"ini_file",TP_CODE},
+{TOK_RESERVEFILE,"ReserveFile",1,-1,"[/nonfatal] [/r] [/x filespec [...]] file [file...]",TP_ALL},
+{TOK_FILECLOSE,"FileClose",1,0,"$(user_var: handle input)",TP_CODE},
+{TOK_FILEERRORTEXT,"FileErrorText",0,2,"[text (can contain $0)] [text without ignore (can contain $0)]",TP_GLOBAL},
+{TOK_FILEOPEN,"FileOpen",3,0,"$(user_var: handle output) filename openmode\n openmode=r|w|a",TP_CODE},
+{TOK_FILEREAD,"FileRead",2,1,"$(user_var: handle input) $(user_var: text output) [maxlen]",TP_CODE},
+{TOK_FILEWRITE,"FileWrite",2,0,"$(user_var: handle input) text",TP_CODE},
+{TOK_FILEREADBYTE,"FileReadByte",2,0,"$(user_var: handle input) $(user_var: bytevalue output)",TP_CODE},
+{TOK_FILEWRITEBYTE,"FileWriteByte",2,0,"$(user_var: handle input) bytevalue",TP_CODE},
+{TOK_FILESEEK,"FileSeek",2,2,"$(user_var: handle input) offset [mode] [$(user_var: new position output)]\n mode=SET|CUR|END",TP_CODE},
+{TOK_FUNCTION,"Function",1,0,"function_name",TP_GLOBAL},
+{TOK_FUNCTIONEND,"FunctionEnd",0,0,"",TP_FUNC},
+{TOK_GETDLGITEM,"GetDlgItem",3,0,"$(user_var: handle output) dialog item_id",TP_CODE},
+{TOK_GETFULLPATHNAME,"GetFullPathName",2,1,"[/SHORT] $(user_var: result) path_or_file",TP_CODE},
+{TOK_GETTEMPFILENAME,"GetTempFileName",1,1,"$(user_var: name output) [base_dir]",TP_CODE},
+{TOK_HIDEWINDOW,"HideWindow",0,0,"",TP_CODE},
+{TOK_ICON,"Icon",1,0,"local_icon.ico",TP_GLOBAL},
+{TOK_IFABORT,"IfAbort",1,1,"label_to_goto_if_abort [label_to_goto_if_no_abort]",TP_CODE},
+{TOK_IFERRORS,"IfErrors",1,1,"label_to_goto_if_errors [label_to_goto_if_no_errors]",TP_CODE},
+{TOK_IFFILEEXISTS,"IfFileExists",2,1,"filename label_to_goto_if_file_exists [label_to_goto_otherwise]",TP_CODE},
+{TOK_IFREBOOTFLAG,"IfRebootFlag",1,1,"jump_if_set [jump_if_not_set]",TP_CODE},
+{TOK_IFSILENT,"IfSilent",1,1,"jump_if_silent [jump_if_not_silent]",TP_CODE},
+{TOK_INSTALLDIRREGKEY,"InstallDirRegKey",3,0,"root_key subkey entry_name\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)",TP_GLOBAL},
+{TOK_INSTCOLORS,"InstallColors",1,1,"(/windows | (foreground_color background_color))",TP_GLOBAL},
+{TOK_INSTDIR,"InstallDir",1,0,"default_install_directory",TP_GLOBAL},
+{TOK_INSTPROGRESSFLAGS,"InstProgressFlags",0,-1,"[flag [...]]\n flag={smooth|colored}",TP_GLOBAL},
+{TOK_INSTTYPE,"InstType",1,0,"[un.]install_type_name | /NOCUSTOM | /CUSTOMSTRING=str | /COMPONENTSONLYONCUSTOM",TP_GLOBAL},
+{TOK_INTOP,"IntOp",3,1,"$(user_var: result) val1 OP [val2]\n OP=(+ - * / % | & ^ ~ ! || && << >>)",TP_CODE},
+{TOK_INTCMP,"IntCmp",3,2,"val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]",TP_CODE},
+{TOK_INTCMPU,"IntCmpU",3,2,"val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]",TP_CODE},
+{TOK_INTFMT,"IntFmt",3,0,"$(user_var: output) format_string input",TP_CODE},
+{TOK_ISWINDOW,"IsWindow",2,1,"hwnd jump_if_window [jump_if_not_window]",TP_CODE},
+{TOK_GOTO,"Goto",1,0,"label",TP_CODE},
+{TOK_LANGSTRING,"LangString",3,0,"[un.]name lang_id string",TP_GLOBAL},
+{TOK_LANGSTRINGUP,"LangStringUP",0,0,"obsolete, use LangString.",TP_ALL},
+{TOK_LICENSEDATA,"LicenseData",1,0,"local_file_that_has_license_text | license_lang_string",TP_PG},
+{TOK_LICENSEFORCESELECTION,"LicenseForceSelection",1,2,"(checkbox [accept_text] | radiobuttons [accept_text] [decline_text] | off)",TP_PG},
+{TOK_LICENSELANGSTRING,"LicenseLangString",3,0,"name lang_id license_path",TP_GLOBAL},
+{TOK_LICENSETEXT,"LicenseText",1,1,"license_page_description [license_button_text]",TP_PG},
+{TOK_LICENSEBKCOLOR,"LicenseBkColor",1,0,"background_color",TP_GLOBAL},
+{TOK_LOADNLF,"LoadLanguageFile",1,0,"language.nlf",TP_GLOBAL},
+{TOK_LOGSET,"LogSet",1,0,"on|off",TP_CODE},
+{TOK_LOGTEXT,"LogText",1,0,"text",TP_CODE},
+{TOK_MESSAGEBOX,"MessageBox",2,6,"mode messagebox_text [/SD return] [return_check label_to_goto_if_equal [return_check2 label2]]\n mode=modeflag[|modeflag[|modeflag[...]]]\n "
+ "modeflag=(MB_ABORTRETRYIGNORE|MB_OK|MB_OKCANCEL|MB_RETRYCANCEL|MB_YESNO|MB_YESNOCANCEL|MB_ICONEXCLAMATION|MB_ICONINFORMATION|MB_ICONQUESTION|MB_ICONSTOP|MB_USERICON|MB_TOPMOST|MB_SETFOREGROUND|MB_RIGHT",TP_CODE},
+{TOK_NOP,"Nop",0,0,"",TP_CODE},
+{TOK_NAME,"Name",1,1,"installer_name installer_name_doubled_ampersands",TP_GLOBAL},
+{TOK_OUTFILE,"OutFile",1,0,"install_output.exe",TP_GLOBAL},
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+{TOK_PAGE,"Page",1,4,"((custom [creator_function] [leave_function] [caption]) | ((license|components|directory|instfiles|uninstConfirm) [pre_function] [show_function] [leave_function])) [/ENABLECANCEL]",TP_GLOBAL},
+#else
+{TOK_PAGE,"Page",1,1,"license|components|directory|instfiles|uninstConfirm [/ENABLECANCEL]",TP_GLOBAL},
+#endif
+{TOK_PAGECALLBACKS,"PageCallbacks",0,3,"([creator_function] [leave_function]) | ([pre_function] [show_function] [leave_function])",TP_PAGEEX},
+{TOK_PAGEEX,"PageEx",1,0,"[un.](custom|uninstConfirm|license|components|directory|instfiles)",TP_GLOBAL},
+{TOK_PAGEEXEND,"PageExEnd",0,0,"",TP_PAGEEX},
+{TOK_POP,"Pop",1,0,"$(user_var: output)",TP_CODE},
+{TOK_PUSH,"Push",1,0,"string",TP_CODE},
+{TOK_QUIT,"Quit",0,0,"",TP_CODE},
+{TOK_READINISTR,"ReadINIStr",4,0,"$(user_var: output) ini_file section entry_name",TP_CODE},
+{TOK_READREGDWORD,"ReadRegDWORD",4,0,"$(user_var: output) rootkey subkey entry\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
+{TOK_READREGSTR,"ReadRegStr",4,0,"$(user_var: output) rootkey subkey entry\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
+{TOK_READENVSTR,"ReadEnvStr",2,0,"$(user_var: output) name",TP_CODE},
+{TOK_REBOOT,"Reboot",0,0,"",TP_CODE},
+{TOK_REGDLL,"RegDLL",1,1,"dll_path_on_target.dll [entrypoint_symbol]",TP_CODE},
+{TOK_RENAME,"Rename",2,1,"[/REBOOTOK] source_file destination_file",TP_CODE},
+{TOK_RET,"Return",0,0,"",TP_CODE},
+{TOK_RMDIR,"RMDir",1,2,"[/r] [/REBOOTOK] directory_name",TP_CODE},
+{TOK_SECTION,"Section",0,3,"[/o] [-][un.][section_name] [section index output]",TP_GLOBAL},
+{TOK_SECTIONEND,"SectionEnd",0,0,"",TP_SEC},
+{TOK_SECTIONIN,"SectionIn",1,-1,"InstTypeIdx [InstTypeIdx [...]]",TP_SEC},
+{TOK_SUBSECTION,"SubSection",1,2,"deprecated - use SectionGroup",TP_GLOBAL},
+{TOK_SECTIONGROUP,"SectionGroup",1,2,"[/e] [un.]section_group_name [section index output]",TP_GLOBAL},
+{TOK_SUBSECTIONEND,"SubSectionEnd",0,0,"deprecated - use SectionGroupEnd",TP_GLOBAL},
+{TOK_SECTIONGROUPEND,"SectionGroupEnd",0,0,"",TP_GLOBAL},
+{TOK_SEARCHPATH,"SearchPath",2,0,"$(user_var: result) filename",TP_CODE},
+{TOK_SECTIONSETFLAGS,"SectionSetFlags",2,0,"section_index flags",TP_CODE},
+{TOK_SECTIONGETFLAGS,"SectionGetFlags",2,0,"section_index $(user_var: output flags)",TP_CODE},
+{TOK_SECTIONSETINSTTYPES,"SectionSetInstTypes",2,0,"section_index inst_types",TP_CODE},
+{TOK_SECTIONGETINSTTYPES,"SectionGetInstTypes",2,0,"section_index $(user_var: output inst_types)",TP_CODE},
+{TOK_SECTIONGETTEXT,"SectionGetText",2,0,"section_index $(user_var: output text)",TP_CODE},
+{TOK_SECTIONSETTEXT,"SectionSetText",2,0,"section_index text_string",TP_CODE},
+{TOK_SECTIONGETSIZE,"SectionGetSize",2,0,"section_index $(user_var: output size)",TP_CODE},
+{TOK_SECTIONSETSIZE,"SectionSetSize",2,0,"section_index new_size",TP_CODE},
+{TOK_GETCURINSTTYPE,"GetCurInstType",1,0,"$(user_var: output inst_type_idx)",TP_CODE},
+{TOK_SETCURINSTTYPE,"SetCurInstType",1,0,"inst_type_idx",TP_CODE},
+{TOK_INSTTYPESETTEXT,"InstTypeSetText",2,0,"insttype_index flags",TP_CODE},
+{TOK_INSTTYPEGETTEXT,"InstTypeGetText",2,0,"insttype_index $(user_var: output flags)",TP_CODE},
+{TOK_SENDMESSAGE,"SendMessage",4,2,"hwnd message [wparam|STR:wParam] [lparam|STR:lParam] [$(user_var: return value)] [/TIMEOUT=X]",TP_CODE},
+{TOK_SETAUTOCLOSE,"SetAutoClose",1,0,"(false|true)",TP_CODE},
+{TOK_SETCTLCOLORS,"SetCtlColors",2,2,"hwnd [/BRANDING] [text_color] [transparent|bg_color]",TP_CODE},
+{TOK_SETBRANDINGIMAGE,"SetBrandingImage",1,2,"[/IMGID=image_item_id_in_dialog] [/RESIZETOFIT] bitmap.bmp",TP_CODE},
+{TOK_SETCOMPRESS,"SetCompress",1,0,"(off|auto|force)",TP_ALL},
+{TOK_SETCOMPRESSOR,"SetCompressor",1,2,"[/FINAL] [/SOLID] (zlib|bzip2|lzma)",TP_GLOBAL},
+{TOK_SETCOMPRESSORDICTSIZE,"SetCompressorDictSize",1,0,"dict_size_mb",TP_ALL},
+{TOK_SETCOMPRESSIONLEVEL,"SetCompressionLevel",1,0,"level_0-9",TP_ALL},
+{TOK_SETDATESAVE,"SetDateSave",1,0,"(off|on)",TP_ALL},
+{TOK_SETDETAILSVIEW,"SetDetailsView",1,0,"(hide|show)",TP_CODE},
+{TOK_SETDETAILSPRINT,"SetDetailsPrint",1,0,"(none|listonly|textonly|both)",TP_CODE},
+{TOK_SETERRORS,"SetErrors",0,0,"",TP_CODE},
+{TOK_SETERRORLEVEL,"SetErrorLevel",1,0,"error_level",TP_CODE},
+{TOK_GETERRORLEVEL,"GetErrorLevel",1,0,"$(user_var: output)",TP_CODE},
+{TOK_SETFILEATTRIBUTES,"SetFileAttributes",2,0,"file attribute[|attribute[...]]\n attribute=(NORMAL|ARCHIVE|HIDDEN|OFFLINE|READONLY|SYSTEM|TEMPORARY|0)",TP_CODE},
+{TOK_SETFONT,"SetFont",2,1,"[/LANG=lang_id] font_face_name font_size",TP_GLOBAL},
+{TOK_SETOUTPATH,"SetOutPath",1,0,"output_path",TP_CODE},
+{TOK_SETOVERWRITE,"SetOverwrite",1,0,"on|off|try|ifnewer|ifdiff",TP_ALL},
+{TOK_SETPLUGINUNLOAD,"SetPluginUnload",1,0,"(manual|alwaysoff)",TP_ALL},
+{TOK_SETREBOOTFLAG,"SetRebootFlag",1,0,"true|false",TP_CODE},
+{TOK_SETREGVIEW,"SetRegView",1,0,"32|64|lastused",TP_CODE},
+{TOK_SETSHELLVARCONTEXT,"SetShellVarContext",1,0,"all|current",TP_CODE},
+{TOK_SETSILENT,"SetSilent",1,0,"silent|normal",TP_CODE},
+{TOK_SHOWDETAILS,"ShowInstDetails",1,0,"(hide|show|nevershow)",TP_GLOBAL},
+{TOK_SHOWDETAILSUNINST,"ShowUninstDetails",1,0,"(hide|show|nevershow)",TP_GLOBAL},
+{TOK_SHOWWINDOW,"ShowWindow",2,0,"hwnd show_state",TP_CODE},
+{TOK_SILENTINST,"SilentInstall",1,0,"(normal|silent|silentlog)",TP_GLOBAL},
+{TOK_SILENTUNINST,"SilentUnInstall",1,0,"(normal|silent)",TP_GLOBAL},
+{TOK_SLEEP,"Sleep",1,0,"sleep_time_in_ms",TP_CODE},
+{TOK_STRCMP,"StrCmp",3,1,"str1 str2 label_to_goto_if_equal [label_to_goto_if_not]",TP_CODE},
+{TOK_STRCMPS,"StrCmpS",3,1,"str1 str2 label_to_goto_if_equal [label_to_goto_if_not]",TP_CODE},
+{TOK_STRCPY,"StrCpy",2,2,"$(user_var: output) str [maxlen] [startoffset]",TP_CODE},
+{TOK_STRLEN,"StrLen",2,0,"$(user_var: length output) str",TP_CODE},
+{TOK_SUBCAPTION,"SubCaption",2,0,"page_number(0-4) new_subcaption",TP_GLOBAL},
+{TOK_UNINSTALLEXENAME,"UninstallExeName",0,0,"no longer supported, use WriteUninstaller from section.",TP_ALL},
+{TOK_UNINSTCAPTION,"UninstallCaption",1,0,"uninstaller_caption",TP_GLOBAL},
+{TOK_UNINSTICON,"UninstallIcon",1,0,"icon_on_local_system.ico",TP_GLOBAL},
+#ifdef NSIS_SUPPORT_CODECALLBACKS
+{TOK_UNINSTPAGE,"UninstPage",1,4,"((custom [creator_function] [leave_function] [caption]) | ((license|components|directory|instfiles|uninstConfirm) [pre_function] [show_function] [leave_function])) [/ENABLECANCEL]",TP_GLOBAL},
+#else
+{TOK_UNINSTPAGE,"UninstPage",1,1,"license|components|directory|instfiles|uninstConfirm [/ENABLECANCEL]",TP_GLOBAL},
+#endif
+{TOK_UNINSTTEXT,"UninstallText",1,1,"Text_to_go_on_uninstall_page [subtext]",TP_PG},
+{TOK_UNINSTSUBCAPTION,"UninstallSubCaption",2,0,"page_number(0-2) new_subcaption",TP_GLOBAL},
+{TOK_UNREGDLL,"UnRegDLL",1,0,"dll_path_on_target.dll",TP_CODE},
+{TOK_WINDOWICON,"WindowIcon",1,0,"on|off",TP_GLOBAL},
+{TOK_WRITEINISTR,"WriteINIStr",4,0,"ini_file section_name entry_name new_value",TP_CODE},
+{TOK_WRITEREGBIN,"WriteRegBin",4,0,"rootkey subkey entry_name hex_string_like_12848412AB\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
+{TOK_WRITEREGDWORD,"WriteRegDWORD",4,0,"rootkey subkey entry_name new_value_dword\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
+{TOK_WRITEREGSTR,"WriteRegStr",4,0,"rootkey subkey entry_name new_value_string\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
+{TOK_WRITEREGEXPANDSTR,"WriteRegExpandStr",4,0,"rootkey subkey entry_name new_value_string\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD|SHCTX)",TP_CODE},
+{TOK_WRITEUNINSTALLER,"WriteUninstaller",1,0,"uninstall_exe_name",TP_CODE},
+{TOK_XPSTYLE, "XPStyle",1,0,"(on|off)",TP_GLOBAL},
+{TOK_REQEXECLEVEL, "RequestExecutionLevel",1,0,"none|user|highest|admin",TP_GLOBAL},
+{TOK_P_PACKEXEHEADER,"!packhdr",2,0,"temp_file_name command_line_to_compress_that_temp_file",TP_ALL},
+{TOK_P_SYSTEMEXEC,"!system",1,2,"command [<|>|<>|=) retval]",TP_ALL},
+{TOK_P_EXECUTE,"!execute",1,0,"command",TP_ALL},
+{TOK_P_ADDINCLUDEDIR,"!AddIncludeDir",1,0,"dir",TP_ALL},
+{TOK_P_INCLUDE,"!include",1,1,"[/NONFATAL] filename.nsh",TP_ALL},
+{TOK_P_CD,"!cd",1,0,"absolute_or_relative_new_directory",TP_ALL},
+{TOK_P_IF,"!if",1,3,"[!] value [(==,!=,<=,<,>,>=,&&,||) value2] [...]",TP_ALL},
+{TOK_P_IFDEF,"!ifdef",1,-1,"symbol [| symbol2 [& symbol3 [...]]]",TP_ALL},
+{TOK_P_IFNDEF,"!ifndef",1,-1,"symbol [| symbol2 [& symbol3 [...]]]",TP_ALL},
+{TOK_P_ENDIF,"!endif",0,0,"",TP_ALL},
+{TOK_P_DEFINE,"!define",1,4,"([/date|/utcdate] symbol [value]) | (/math symbol val1 OP val2)\n OP=(+ - * / % & | ^)",TP_ALL},
+{TOK_P_UNDEF,"!undef",1,1,"symbol [value]",TP_ALL},
+{TOK_P_ELSE,"!else",0,-1,"[if[macro][n][def] ...]",TP_ALL},
+{TOK_P_ECHO,"!echo",1,0,"message",TP_ALL},
+{TOK_P_WARNING,"!warning",0,1,"[warning_message]",TP_ALL},
+{TOK_P_ERROR,"!error",0,1,"[error_message]",TP_ALL},
+
+{TOK_P_VERBOSE,"!verbose",1,0,"verbose_level | push | pop",TP_ALL},
+
+{TOK_P_MACRO,"!macro",1,-1,"macroname [parms ...]",TP_ALL},
+{TOK_P_MACROEND,"!macroend",0,0,"",TP_ALL},
+{TOK_P_INSERTMACRO,"!insertmacro",1,-1,"macroname [parms ...]",TP_ALL},
+{TOK_P_IFMACRODEF,"!ifmacrodef",1,-1,"macro [| macro2 [& macro3 [...]]]",TP_ALL},
+{TOK_P_IFMACRONDEF,"!ifmacrondef",1,-1,"macro [| macro2 [& macro3 [...]]]",TP_ALL},
+
+{TOK_P_TEMPFILE,"!tempfile",1,0,"symbol",TP_ALL},
+{TOK_P_DELFILE,"!delfile",1,0,"file",TP_ALL},
+{TOK_P_APPENDFILE,"!appendfile",2,0,"file appended_line",TP_ALL},
+
+{TOK_MISCBUTTONTEXT,"MiscButtonText",0,4,"[back button text] [next button text] [cancel button text] [close button text]",TP_GLOBAL},
+{TOK_DETAILSBUTTONTEXT,"DetailsButtonText",0,1,"[details button text]",TP_PG},
+{TOK_UNINSTBUTTONTEXT,"UninstallButtonText",0,1,"[uninstall button text]",TP_GLOBAL},
+{TOK_INSTBUTTONTEXT,"InstallButtonText",0,1,"[install button text]",TP_GLOBAL},
+{TOK_SPACETEXTS,"SpaceTexts",0,2,"none | ([space required text] [space available text])",TP_GLOBAL},
+{TOK_COMPLETEDTEXT,"CompletedText",0,1,"[completed text]",TP_PG},
+
+{TOK_GETFUNCTIONADDR,"GetFunctionAddress",2,0,"output function",TP_CODE},
+{TOK_GETLABELADDR,"GetLabelAddress",2,0,"output label",TP_CODE},
+{TOK_GETCURRENTADDR,"GetCurrentAddress",1,0,"output",TP_CODE},
+
+{TOK_PLUGINDIR,"!AddPluginDir",1,0,"new_plugin_directory",TP_ALL},
+{TOK_INITPLUGINSDIR,"InitPluginsDir",0,0,"",TP_CODE},
+// Added by ramon 23 May 2003
+{TOK_ALLOWSKIPFILES,"AllowSkipFiles",1,0,"(off|on)",TP_ALL},
+// Added by ramon 3 jun 2003
+{TOK_DEFVAR,"Var",1,1,"[/GLOBAL] var_name",TP_ALL},
+// Added by ramon 6 jun 2003
+{TOK_VI_ADDKEY,"VIAddVersionKey",2,1,"/LANG=lang_id keyname value",TP_GLOBAL},
+{TOK_VI_SETPRODUCTVERSION,"VIProductVersion",1,0,"[version_string_X.X.X.X]",TP_GLOBAL},
+{TOK_LOCKWINDOW,"LockWindow",1,0,"(on|off)",TP_CODE},
+};
+
+void CEXEBuild::print_help(char *commandname)
+{
+ int x;
+ for (x = 0; x < TOK__LAST; x ++)
+ {
+ if (!commandname || !stricmp(tokenlist[x].name,commandname))
+ {
+ ERROR_MSG("%s%s %s\n",commandname?"Usage: ":"",tokenlist[x].name,tokenlist[x].usage_str);
+ if (commandname) break;
+ }
+ }
+ if (x == TOK__LAST && commandname)
+ {
+ ERROR_MSG("Invalid command \"%s\"\n",commandname);
+ }
+
+}
+
+bool CEXEBuild::is_valid_token(char *s)
+{
+ for (int x = 0; x < TOK__LAST; x ++)
+ if (!stricmp(tokenlist[x].name,s))
+ return true;
+ return false;
+}
+
+int CEXEBuild::get_commandtoken(char *s, int *np, int *op, int *pos)
+{
+ int x;
+ for (x = 0; x < TOK__LAST; x ++)
+ if (!stricmp(tokenlist[x].name,s))
+ {
+ *np=tokenlist[x].num_parms;
+ *op=tokenlist[x].opt_parms;
+ *pos=x;
+ return tokenlist[x].id;
+ }
+ return -1;
+}
+
+int CEXEBuild::GetCurrentTokenPlace()
+{
+ if (build_cursection)
+ {
+ if (build_cursection_isfunc)
+ {
+ return TP_FUNC;
+ }
+ else
+ {
+ return TP_SEC;
+ }
+ }
+
+ if (cur_page)
+ return TP_PAGEEX;
+
+ return TP_GLOBAL;
+}
+
+int CEXEBuild::IsTokenPlacedRight(int pos, char *tok)
+{
+ if ((unsigned int) pos > (sizeof(tokenlist) / sizeof(tokenType)))
+ return PS_OK;
+
+ int tp = tokenlist[pos].placement;
+ int cp = GetCurrentTokenPlace();
+ if (tp & cp) {
+ return PS_OK;
+ }
+ else {
+ char err[1024];
+ if (cp == TP_SEC) {
+ strcpy(err, "Error: command %s not valid in Section\n");
+ }
+ else if (cp == TP_FUNC) {
+ strcpy(err, "Error: command %s not valid in Function\n");
+ }
+ else if (cp == TP_PAGEEX) {
+ strcpy(err, "Error: command %s not valid in PageEx\n");
+ }
+ else
+ {
+ strcpy(err, "Error: command %s not valid outside ");
+ if (tp & TP_SEC)
+ strcat(err, "Section");
+ if (tp & TP_FUNC)
+ {
+ if (tp & TP_SEC)
+ {
+ if (tp & TP_PAGEEX)
+ {
+ strcat(err, ", ");
+ }
+ else
+ {
+ strcat(err, " or ");
+ }
+ }
+ strcat(err, "Function");
+ }
+ if (tp & TP_PAGEEX)
+ {
+ if (tp & TP_CODE)
+ {
+ strcat(err, " or ");
+ }
+ strcat(err, "PageEx");
+ }
+ strcat(err, "\n");
+ }
+ ERROR_MSG(err, tok);
+ return PS_ERROR;
+ }
+}
diff --git a/Source/tokens.h b/Source/tokens.h
index 0f78add..65c415a 100755
--- a/Source/tokens.h
+++ b/Source/tokens.h
@@ -1,274 +1,274 @@
-/*
- * tokens.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef _TOKENS_H_
-#define _TOKENS_H_
-
-// the order of these two lists no longer needs to match. -J
-enum
-{
- // header setting tokens
- TOK_NAME,
- TOK_CAPTION,
- TOK_UNINSTCAPTION,
- TOK_ICON,
- TOK_UNINSTICON,
- TOK_CHECKBITMAP,
- TOK_WINDOWICON,
- TOK_DIRTEXT,
- TOK_COMPTEXT,
- TOK_LICENSEBKCOLOR,
- TOK_LICENSEDATA,
- TOK_LICENSEFORCESELECTION,
- TOK_LICENSELANGSTRING,
- TOK_LICENSETEXT,
- TOK_UNINSTTEXT,
- TOK_SILENTINST,
- TOK_SILENTUNINST,
- TOK_INSTTYPE,
- TOK_OUTFILE,
- TOK_INSTDIR,
- TOK_INSTALLDIRREGKEY,
- TOK_UNINSTALLEXENAME,
- TOK_CRCCHECK,
- TOK_AUTOCLOSE,
- TOK_SHOWDETAILS,
- TOK_SHOWDETAILSUNINST,
- TOK_DIRSHOW,
- TOK_ROOTDIRINST,
- TOK_BGFONT,
- TOK_BGGRADIENT,
- TOK_INSTCOLORS,
- TOK_SUBCAPTION,
- TOK_UNINSTSUBCAPTION,
- TOK_BRANDINGTEXT,
- TOK_FILEERRORTEXT,
- TOK_INSTPROGRESSFLAGS,
- TOK_XPSTYLE,
- TOK_REQEXECLEVEL,
- TOK_CHANGEUI,
- TOK_ADDBRANDINGIMAGE,
- TOK_SETFONT,
- TOK_LOADNLF,
- TOK_RESERVEFILE,
- TOK_ALLOWSKIPFILES,
- TOK_DEFVAR,
- TOK_VI_ADDKEY,
- TOK_VI_SETPRODUCTVERSION,
-
- TOK_MISCBUTTONTEXT,
- TOK_DETAILSBUTTONTEXT,
- TOK_UNINSTBUTTONTEXT,
- TOK_INSTBUTTONTEXT,
- TOK_SPACETEXTS,
- TOK_COMPLETEDTEXT,
-
- TOK_LANGSTRING,
- TOK_LANGSTRINGUP,
-
- // comrpession stuff
- TOK_SETCOMPRESS,
- TOK_DBOPTIMIZE,
- TOK_SETCOMPRESSOR,
- TOK_SETCOMPRESSORDICTSIZE,
- TOK_SETCOMPRESSIONLEVEL,
- TOK_FILEBUFSIZE,
-
- // system "preprocessor"ish tokens
- TOK_P_IF,
- TOK_P_IFDEF,
- TOK_P_IFNDEF,
- TOK_P_ELSE,
- TOK_P_ENDIF,
- TOK_P_DEFINE,
- TOK_P_UNDEF,
- TOK_P_PACKEXEHEADER,
- TOK_P_SYSTEMEXEC,
- TOK_P_EXECUTE,
- TOK_P_ADDINCLUDEDIR,
- TOK_P_INCLUDE,
- TOK_P_CD,
- TOK_P_ECHO,
- TOK_P_WARNING,
- TOK_P_ERROR,
-
- TOK_P_VERBOSE,
-
- TOK_P_MACRO,
- TOK_P_MACROEND,
- TOK_P_INSERTMACRO,
- TOK_P_IFMACRODEF,
- TOK_P_IFMACRONDEF,
-
- TOK_P_TEMPFILE,
- TOK_P_DELFILE,
- TOK_P_APPENDFILE,
-
- // section/function shit
- TOK_SECTION,
- TOK_SECTIONEND,
- TOK_SECTIONIN,
- TOK_SECTIONGROUP,
- TOK_SECTIONGROUPEND,
- TOK_SUBSECTION,
- TOK_SUBSECTIONEND,
- TOK_FUNCTION,
- TOK_FUNCTIONEND,
- TOK_ADDSIZE,
-
- // page oredering shit
- TOK_PAGE,
- TOK_UNINSTPAGE,
-
- // PageEx stuff
- TOK_PAGEEX,
- TOK_PAGEEXEND,
- TOK_DIRVAR,
- TOK_DIRVERIFY,
- TOK_PAGECALLBACKS,
-
- TOK_GETINSTDIRERROR,
-
- // flag setters
- TOK_SETDATESAVE,
- TOK_SETOVERWRITE,
- TOK_SETPLUGINUNLOAD,
-
- // instructions
- TOK_NOP,
- TOK_GOTO,
- TOK_RET,
- TOK_CALL,
- TOK_SETOUTPATH,
- TOK_CREATEDIR,
- TOK_EXEC,
- TOK_EXECWAIT,
- TOK_EXECSHELL,
- TOK_CALLINSTDLL,
- TOK_REGDLL,
- TOK_UNREGDLL,
- TOK_RENAME,
- TOK_MESSAGEBOX,
- TOK_DELETEREGVALUE,
- TOK_DELETEREGKEY,
- TOK_WRITEREGSTR,
- TOK_WRITEREGEXPANDSTR,
- TOK_WRITEREGBIN,
- TOK_WRITEREGDWORD,
- TOK_DELETEINISEC,
- TOK_DELETEINISTR,
- TOK_FLUSHINI,
- TOK_WRITEINISTR,
- TOK_CREATESHORTCUT,
- TOK_FINDWINDOW,
- TOK_DELETE,
- TOK_RMDIR,
- TOK_FILE,
- TOK_COPYFILES,
- TOK_SETFILEATTRIBUTES,
- TOK_SLEEP,
- TOK_BRINGTOFRONT,
- TOK_HIDEWINDOW,
- TOK_IFFILEEXISTS,
- TOK_ABORT,
- TOK_QUIT,
- TOK_SETDETAILSVIEW,
- TOK_SETDETAILSPRINT,
- TOK_SETAUTOCLOSE,
- TOK_IFERRORS,
- TOK_CLEARERRORS,
- TOK_SETERRORS,
- TOK_IFABORT,
- TOK_STRCPY,
- TOK_STRCMP,
- TOK_STRCMPS,
- TOK_GETTEMPFILENAME,
- TOK_GETFUNCTIONADDR,
- TOK_GETLABELADDR,
- TOK_GETCURRENTADDR,
- TOK_READINISTR,
- TOK_READREGSTR,
- TOK_READREGDWORD,
- TOK_READENVSTR,
- TOK_EXPANDENVSTRS,
- TOK_DETAILPRINT,
- TOK_SEARCHPATH,
- TOK_GETDLLVERSION,
- TOK_GETDLLVERSIONLOCAL,
- TOK_GETFILETIME,
- TOK_GETFILETIMELOCAL,
- TOK_STRLEN,
- TOK_INTOP,
- TOK_INTCMP,
- TOK_INTCMPU,
- TOK_INTFMT,
- TOK_ENUMREGKEY,
- TOK_ENUMREGVAL,
- TOK_PUSH,
- TOK_POP,
- TOK_EXCH,
- TOK_SENDMESSAGE,
- TOK_ISWINDOW,
- TOK_GETDLGITEM,
- TOK_SETCTLCOLORS,
- TOK_FINDFIRST,
- TOK_FINDNEXT,
- TOK_FINDCLOSE,
- TOK_FILEOPEN,
- TOK_FILECLOSE,
- TOK_FILEREAD,
- TOK_FILEWRITE,
- TOK_FILEREADBYTE,
- TOK_FILEWRITEBYTE,
- TOK_FILESEEK,
- TOK_GETFULLPATHNAME,
- TOK_REBOOT,
- TOK_IFREBOOTFLAG,
- TOK_SETREBOOTFLAG,
- TOK_WRITEUNINSTALLER,
- TOK_LOGSET,
- TOK_LOGTEXT,
- TOK_SETBRANDINGIMAGE,
- TOK_SECTIONSETTEXT,
- TOK_SECTIONGETTEXT,
- TOK_SECTIONSETFLAGS,
- TOK_SECTIONGETFLAGS,
- TOK_SECTIONSETINSTTYPES,
- TOK_SECTIONGETINSTTYPES,
- TOK_SECTIONSETSIZE,
- TOK_SECTIONGETSIZE,
- TOK_INSTTYPESETTEXT,
- TOK_INSTTYPEGETTEXT,
- TOK_GETCURINSTTYPE,
- TOK_SETCURINSTTYPE,
- TOK_SETREGVIEW,
- TOK_SETSHELLVARCONTEXT,
- TOK_PLUGINDIR,
- TOK_INITPLUGINSDIR,
- TOK_CREATEFONT,
- TOK_SHOWWINDOW,
- TOK_ENABLEWINDOW,
- TOK_SETSILENT,
- TOK_IFSILENT,
- TOK_SETERRORLEVEL,
- TOK_GETERRORLEVEL,
- TOK_LOCKWINDOW,
-
- TOK__LAST,
- TOK__PLUGINCOMMAND
-};
-
-#endif//_TOKENS_H_
+/*
+ * tokens.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef _TOKENS_H_
+#define _TOKENS_H_
+
+// the order of these two lists no longer needs to match. -J
+enum
+{
+ // header setting tokens
+ TOK_NAME,
+ TOK_CAPTION,
+ TOK_UNINSTCAPTION,
+ TOK_ICON,
+ TOK_UNINSTICON,
+ TOK_CHECKBITMAP,
+ TOK_WINDOWICON,
+ TOK_DIRTEXT,
+ TOK_COMPTEXT,
+ TOK_LICENSEBKCOLOR,
+ TOK_LICENSEDATA,
+ TOK_LICENSEFORCESELECTION,
+ TOK_LICENSELANGSTRING,
+ TOK_LICENSETEXT,
+ TOK_UNINSTTEXT,
+ TOK_SILENTINST,
+ TOK_SILENTUNINST,
+ TOK_INSTTYPE,
+ TOK_OUTFILE,
+ TOK_INSTDIR,
+ TOK_INSTALLDIRREGKEY,
+ TOK_UNINSTALLEXENAME,
+ TOK_CRCCHECK,
+ TOK_AUTOCLOSE,
+ TOK_SHOWDETAILS,
+ TOK_SHOWDETAILSUNINST,
+ TOK_DIRSHOW,
+ TOK_ROOTDIRINST,
+ TOK_BGFONT,
+ TOK_BGGRADIENT,
+ TOK_INSTCOLORS,
+ TOK_SUBCAPTION,
+ TOK_UNINSTSUBCAPTION,
+ TOK_BRANDINGTEXT,
+ TOK_FILEERRORTEXT,
+ TOK_INSTPROGRESSFLAGS,
+ TOK_XPSTYLE,
+ TOK_REQEXECLEVEL,
+ TOK_CHANGEUI,
+ TOK_ADDBRANDINGIMAGE,
+ TOK_SETFONT,
+ TOK_LOADNLF,
+ TOK_RESERVEFILE,
+ TOK_ALLOWSKIPFILES,
+ TOK_DEFVAR,
+ TOK_VI_ADDKEY,
+ TOK_VI_SETPRODUCTVERSION,
+
+ TOK_MISCBUTTONTEXT,
+ TOK_DETAILSBUTTONTEXT,
+ TOK_UNINSTBUTTONTEXT,
+ TOK_INSTBUTTONTEXT,
+ TOK_SPACETEXTS,
+ TOK_COMPLETEDTEXT,
+
+ TOK_LANGSTRING,
+ TOK_LANGSTRINGUP,
+
+ // comrpession stuff
+ TOK_SETCOMPRESS,
+ TOK_DBOPTIMIZE,
+ TOK_SETCOMPRESSOR,
+ TOK_SETCOMPRESSORDICTSIZE,
+ TOK_SETCOMPRESSIONLEVEL,
+ TOK_FILEBUFSIZE,
+
+ // system "preprocessor"ish tokens
+ TOK_P_IF,
+ TOK_P_IFDEF,
+ TOK_P_IFNDEF,
+ TOK_P_ELSE,
+ TOK_P_ENDIF,
+ TOK_P_DEFINE,
+ TOK_P_UNDEF,
+ TOK_P_PACKEXEHEADER,
+ TOK_P_SYSTEMEXEC,
+ TOK_P_EXECUTE,
+ TOK_P_ADDINCLUDEDIR,
+ TOK_P_INCLUDE,
+ TOK_P_CD,
+ TOK_P_ECHO,
+ TOK_P_WARNING,
+ TOK_P_ERROR,
+
+ TOK_P_VERBOSE,
+
+ TOK_P_MACRO,
+ TOK_P_MACROEND,
+ TOK_P_INSERTMACRO,
+ TOK_P_IFMACRODEF,
+ TOK_P_IFMACRONDEF,
+
+ TOK_P_TEMPFILE,
+ TOK_P_DELFILE,
+ TOK_P_APPENDFILE,
+
+ // section/function shit
+ TOK_SECTION,
+ TOK_SECTIONEND,
+ TOK_SECTIONIN,
+ TOK_SECTIONGROUP,
+ TOK_SECTIONGROUPEND,
+ TOK_SUBSECTION,
+ TOK_SUBSECTIONEND,
+ TOK_FUNCTION,
+ TOK_FUNCTIONEND,
+ TOK_ADDSIZE,
+
+ // page oredering shit
+ TOK_PAGE,
+ TOK_UNINSTPAGE,
+
+ // PageEx stuff
+ TOK_PAGEEX,
+ TOK_PAGEEXEND,
+ TOK_DIRVAR,
+ TOK_DIRVERIFY,
+ TOK_PAGECALLBACKS,
+
+ TOK_GETINSTDIRERROR,
+
+ // flag setters
+ TOK_SETDATESAVE,
+ TOK_SETOVERWRITE,
+ TOK_SETPLUGINUNLOAD,
+
+ // instructions
+ TOK_NOP,
+ TOK_GOTO,
+ TOK_RET,
+ TOK_CALL,
+ TOK_SETOUTPATH,
+ TOK_CREATEDIR,
+ TOK_EXEC,
+ TOK_EXECWAIT,
+ TOK_EXECSHELL,
+ TOK_CALLINSTDLL,
+ TOK_REGDLL,
+ TOK_UNREGDLL,
+ TOK_RENAME,
+ TOK_MESSAGEBOX,
+ TOK_DELETEREGVALUE,
+ TOK_DELETEREGKEY,
+ TOK_WRITEREGSTR,
+ TOK_WRITEREGEXPANDSTR,
+ TOK_WRITEREGBIN,
+ TOK_WRITEREGDWORD,
+ TOK_DELETEINISEC,
+ TOK_DELETEINISTR,
+ TOK_FLUSHINI,
+ TOK_WRITEINISTR,
+ TOK_CREATESHORTCUT,
+ TOK_FINDWINDOW,
+ TOK_DELETE,
+ TOK_RMDIR,
+ TOK_FILE,
+ TOK_COPYFILES,
+ TOK_SETFILEATTRIBUTES,
+ TOK_SLEEP,
+ TOK_BRINGTOFRONT,
+ TOK_HIDEWINDOW,
+ TOK_IFFILEEXISTS,
+ TOK_ABORT,
+ TOK_QUIT,
+ TOK_SETDETAILSVIEW,
+ TOK_SETDETAILSPRINT,
+ TOK_SETAUTOCLOSE,
+ TOK_IFERRORS,
+ TOK_CLEARERRORS,
+ TOK_SETERRORS,
+ TOK_IFABORT,
+ TOK_STRCPY,
+ TOK_STRCMP,
+ TOK_STRCMPS,
+ TOK_GETTEMPFILENAME,
+ TOK_GETFUNCTIONADDR,
+ TOK_GETLABELADDR,
+ TOK_GETCURRENTADDR,
+ TOK_READINISTR,
+ TOK_READREGSTR,
+ TOK_READREGDWORD,
+ TOK_READENVSTR,
+ TOK_EXPANDENVSTRS,
+ TOK_DETAILPRINT,
+ TOK_SEARCHPATH,
+ TOK_GETDLLVERSION,
+ TOK_GETDLLVERSIONLOCAL,
+ TOK_GETFILETIME,
+ TOK_GETFILETIMELOCAL,
+ TOK_STRLEN,
+ TOK_INTOP,
+ TOK_INTCMP,
+ TOK_INTCMPU,
+ TOK_INTFMT,
+ TOK_ENUMREGKEY,
+ TOK_ENUMREGVAL,
+ TOK_PUSH,
+ TOK_POP,
+ TOK_EXCH,
+ TOK_SENDMESSAGE,
+ TOK_ISWINDOW,
+ TOK_GETDLGITEM,
+ TOK_SETCTLCOLORS,
+ TOK_FINDFIRST,
+ TOK_FINDNEXT,
+ TOK_FINDCLOSE,
+ TOK_FILEOPEN,
+ TOK_FILECLOSE,
+ TOK_FILEREAD,
+ TOK_FILEWRITE,
+ TOK_FILEREADBYTE,
+ TOK_FILEWRITEBYTE,
+ TOK_FILESEEK,
+ TOK_GETFULLPATHNAME,
+ TOK_REBOOT,
+ TOK_IFREBOOTFLAG,
+ TOK_SETREBOOTFLAG,
+ TOK_WRITEUNINSTALLER,
+ TOK_LOGSET,
+ TOK_LOGTEXT,
+ TOK_SETBRANDINGIMAGE,
+ TOK_SECTIONSETTEXT,
+ TOK_SECTIONGETTEXT,
+ TOK_SECTIONSETFLAGS,
+ TOK_SECTIONGETFLAGS,
+ TOK_SECTIONSETINSTTYPES,
+ TOK_SECTIONGETINSTTYPES,
+ TOK_SECTIONSETSIZE,
+ TOK_SECTIONGETSIZE,
+ TOK_INSTTYPESETTEXT,
+ TOK_INSTTYPEGETTEXT,
+ TOK_GETCURINSTTYPE,
+ TOK_SETCURINSTTYPE,
+ TOK_SETREGVIEW,
+ TOK_SETSHELLVARCONTEXT,
+ TOK_PLUGINDIR,
+ TOK_INITPLUGINSDIR,
+ TOK_CREATEFONT,
+ TOK_SHOWWINDOW,
+ TOK_ENABLEWINDOW,
+ TOK_SETSILENT,
+ TOK_IFSILENT,
+ TOK_SETERRORLEVEL,
+ TOK_GETERRORLEVEL,
+ TOK_LOCKWINDOW,
+
+ TOK__LAST,
+ TOK__PLUGINCOMMAND
+};
+
+#endif//_TOKENS_H_
diff --git a/Source/uservars.h b/Source/uservars.h
index d559a4c..2a5c21e 100755
--- a/Source/uservars.h
+++ b/Source/uservars.h
@@ -1,103 +1,103 @@
-/*
- * uservars.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 2003 Ramon
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef ___USERVARS___H_____
-#define ___USERVARS___H_____
-
-#include "lang.h"
-
-struct uservarstring {
- int name;
- int index;
- int pos;
- int reference;
-};
-
-class UserVarsStringList : public SortedStringListND<struct uservarstring>
-{
- public:
- UserVarsStringList()
- {
- index = 0;
- }
- ~UserVarsStringList() { }
-
- int add(const char *name, int ref_count = 0 )
- {
- int pos=SortedStringListND<struct uservarstring>::add(name);
- if (pos == -1) return -1;
-
- ((struct uservarstring*)gr.get())[pos].index = index;
- ((struct uservarstring*)gr.get())[pos].pos = pos;
- ((struct uservarstring*)gr.get())[pos].reference = ref_count;
-
- int temp = index;
- index++;
-
- return temp;
- }
-
- int get(char *name, int n_chars = -1)
- {
- int v=SortedStringListND<struct uservarstring>::find(name, n_chars);
- if (v==-1) return -1;
- return (((struct uservarstring*)gr.get())[v].index);
- }
-
- int getnum()
- {
- return index;
- }
-
- int get_reference(int idx)
- {
- int pos=get_internal_idx(idx);
- if (pos==-1) return -1;
- return (((struct uservarstring*)gr.get())[pos].reference);
- }
-
- int inc_reference(int idx)
- {
- int pos=get_internal_idx(idx);
- ((struct uservarstring*)gr.get())[pos].reference++;
- return (((struct uservarstring*)gr.get())[pos].reference)-1;
- }
-
- char *idx2name(int idx)
- {
- int pos=get_internal_idx(idx);
- if (pos==-1) return NULL;
- struct uservarstring *data=(struct uservarstring *)gr.get();
- return ((char*)strings.get() + data[pos].name);
- }
-
- private:
- int index;
- int get_internal_idx(int idx)
- {
- struct uservarstring *data=(struct uservarstring *)gr.get();
- for (int i = 0; i < index; i++)
- {
- if (data[i].index == idx)
- {
- return i;
- }
- }
- return -1;
- }
-};
-
-#endif
+/*
+ * uservars.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 2003 Ramon
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef ___USERVARS___H_____
+#define ___USERVARS___H_____
+
+#include "lang.h"
+
+struct uservarstring {
+ int name;
+ int index;
+ int pos;
+ int reference;
+};
+
+class UserVarsStringList : public SortedStringListND<struct uservarstring>
+{
+ public:
+ UserVarsStringList()
+ {
+ index = 0;
+ }
+ ~UserVarsStringList() { }
+
+ int add(const char *name, int ref_count = 0 )
+ {
+ int pos=SortedStringListND<struct uservarstring>::add(name);
+ if (pos == -1) return -1;
+
+ ((struct uservarstring*)gr.get())[pos].index = index;
+ ((struct uservarstring*)gr.get())[pos].pos = pos;
+ ((struct uservarstring*)gr.get())[pos].reference = ref_count;
+
+ int temp = index;
+ index++;
+
+ return temp;
+ }
+
+ int get(char *name, int n_chars = -1)
+ {
+ int v=SortedStringListND<struct uservarstring>::find(name, n_chars);
+ if (v==-1) return -1;
+ return (((struct uservarstring*)gr.get())[v].index);
+ }
+
+ int getnum()
+ {
+ return index;
+ }
+
+ int get_reference(int idx)
+ {
+ int pos=get_internal_idx(idx);
+ if (pos==-1) return -1;
+ return (((struct uservarstring*)gr.get())[pos].reference);
+ }
+
+ int inc_reference(int idx)
+ {
+ int pos=get_internal_idx(idx);
+ ((struct uservarstring*)gr.get())[pos].reference++;
+ return (((struct uservarstring*)gr.get())[pos].reference)-1;
+ }
+
+ char *idx2name(int idx)
+ {
+ int pos=get_internal_idx(idx);
+ if (pos==-1) return NULL;
+ struct uservarstring *data=(struct uservarstring *)gr.get();
+ return ((char*)strings.get() + data[pos].name);
+ }
+
+ private:
+ int index;
+ int get_internal_idx(int idx)
+ {
+ struct uservarstring *data=(struct uservarstring *)gr.get();
+ for (int i = 0; i < index; i++)
+ {
+ if (data[i].index == idx)
+ {
+ return i;
+ }
+ }
+ return -1;
+ }
+};
+
+#endif
diff --git a/Source/util.cpp b/Source/util.cpp
index cd0b757..25e515e 100755
--- a/Source/util.cpp
+++ b/Source/util.cpp
@@ -1,1095 +1,832 @@
-/*
- * util.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-#include <stdio.h>
-#include <stdarg.h>
-#include <time.h>
-#include <string.h>
-#include "exehead/fileform.h"
-#include "util.h"
-#include "strlist.h"
-#include "winchar.h"
-
-#ifndef _WIN32
-# include <ctype.h>
-# include <unistd.h> // for close(2)
-# include <fcntl.h> // for open(2)
-# include <iconv.h>
-#endif
-
-#ifdef __APPLE__
-namespace Apple { // defines struct section
-# include <mach-o/dyld.h> // for _NSGetExecutablePath
-};
-# include <sys/param.h> // for MAXPATHLEN
-#endif
-
-#include <cassert> // for assert
-#include <algorithm>
-#include <stdexcept>
-
-using namespace std;
-
-int g_dopause=0;
-extern int g_display_errors;
-extern FILE *g_output;
-
-void dopause(void)
-{
- if (g_dopause)
- {
- if (g_display_errors) fprintf(g_output,"MakeNSIS done - hit enter to close...");
- fflush(stdout);
- int a;
- while ((a=getchar()) != '\r' && a != '\n' && a != 27/*esc*/);
- }
-}
-
-// Returns 0 if everything is OK
-// Returns -1 if can't find the file
-// Returns -2 if the file is an invalid bitmap
-// Returns -3 if the size doesn't match
-// Returns -4 if the bpp doesn't match
-int update_bitmap(CResourceEditor* re, WORD id, const char* filename, int width/*=0*/, int height/*=0*/, int maxbpp/*=0*/) {
- FILE *f = FOPEN(filename, "rb");
- if (!f) return -1;
-
- if (fgetc(f) != 'B' || fgetc(f) != 'M') {
- fclose(f);
- return -2;
- }
-
- if (width != 0) {
- LONG biWidth;
- fseek(f, 18, SEEK_SET); // Seek to the width member of the header
- fread(&biWidth, sizeof(LONG), 1, f);
- FIX_ENDIAN_INT32_INPLACE(biWidth);
- if (width != biWidth) {
- fclose(f);
- return -3;
- }
- }
-
- if (height != 0) {
- LONG biHeight;
- fseek(f, 22, SEEK_SET); // Seek to the height member of the header
- fread(&biHeight, sizeof(LONG), 1, f);
- FIX_ENDIAN_INT32_INPLACE(biHeight);
- // Bitmap height can be negative too...
- if (height != abs(biHeight)) {
- fclose(f);
- return -3;
- }
- }
-
- if (maxbpp != 0) {
- WORD biBitCount;
- fseek(f, 28, SEEK_SET); // Seek to the height member of the header
- fread(&biBitCount, sizeof(WORD), 1, f);
- FIX_ENDIAN_INT16_INPLACE(biBitCount);
- if (biBitCount > maxbpp) {
- fclose(f);
- return -4;
- }
- }
-
- DWORD dwSize;
- fseek(f, 2, SEEK_SET);
- fread(&dwSize, sizeof(DWORD), 1, f);
- FIX_ENDIAN_INT32_INPLACE(dwSize);
- dwSize -= 14;
-
- unsigned char* bitmap = (unsigned char*)malloc(dwSize);
- if (!bitmap) throw bad_alloc();
-
- fseek(f, 14, SEEK_SET);
- if (fread(bitmap, 1, dwSize, f) != dwSize) {
- fclose(f);
- return -2;
- }
- fclose(f);
-
- re->UpdateResourceA(RT_BITMAP, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG, bitmap, dwSize);
-
- free(bitmap);
-
- return 0;
-}
-
-// Added by Amir Szekely 8th July 2002
-// Icon editing structures
-typedef struct {
- WORD wReserved;
- WORD wIsIcon;
- WORD wCount;
-} IconGroupHeader;
-
-typedef struct {
- BYTE bWidth;
- BYTE bHeight;
- BYTE bPaletteEntries;
- BYTE bReserved;
- WORD wPlanes;
- WORD wBitsPerPixel;
- DWORD dwRawSize;
- DWORD dwImageOffset;
-} FileIconGroupEntry;
-
-typedef struct {
- BYTE bWidth;
- BYTE bHeight;
- BYTE bPaletteEntries;
- BYTE bReserved;
- WORD wPlanes;
- WORD wBitsPerPixel;
- DWORD dwRawSize;
- WORD wRsrcId;
-} RsrcIconGroupEntry;
-
-#define SIZEOF_RSRC_ICON_GROUP_ENTRY 14
-
-static FILE * open_icon(const char* filename, IconGroupHeader *igh)
-{
- FILE* f = FOPEN(filename, "rb");
- if (!f)
- throw runtime_error("can't open file");
-
- if (!fread(igh, sizeof(IconGroupHeader), 1, f))
- throw runtime_error("unable to read file");
-
- FIX_ENDIAN_INT16_INPLACE(igh->wIsIcon);
- FIX_ENDIAN_INT16_INPLACE(igh->wReserved);
- FIX_ENDIAN_INT16_INPLACE(igh->wCount);
-
- if (igh->wIsIcon != 1 || igh->wReserved != 0)
- throw runtime_error("invalid icon file");
-
- return f;
-}
-
-// replace_icon, must get an initialized resource editor
-void replace_icon(CResourceEditor* re, WORD wIconId, const char* filename)
-{
- IconGroupHeader igh, *new_igh;
- FILE *f = open_icon(filename, &igh);
-
- BYTE* rsrcIconGroup = (BYTE*)malloc(sizeof(IconGroupHeader) + igh.wCount*SIZEOF_RSRC_ICON_GROUP_ENTRY);
- if (!rsrcIconGroup) throw bad_alloc();
-
- CopyMemory(rsrcIconGroup, &igh, sizeof(IconGroupHeader));
-
- new_igh = (IconGroupHeader *) rsrcIconGroup;
- FIX_ENDIAN_INT16_INPLACE(new_igh->wIsIcon);
- FIX_ENDIAN_INT16_INPLACE(new_igh->wReserved);
- FIX_ENDIAN_INT16_INPLACE(new_igh->wCount);
-
- RsrcIconGroupEntry* ige = (RsrcIconGroupEntry*)(rsrcIconGroup + sizeof(IconGroupHeader));
-
- int i = 1;
-
- // Delete old icons
- while (re->UpdateResourceA(RT_ICON, MAKEINTRESOURCE(i++), NSIS_DEFAULT_LANG, 0, 0));
-
- for (i = 0; i < igh.wCount; i++) {
- fread(ige, sizeof(FileIconGroupEntry)-sizeof(DWORD), 1, f);
-
- DWORD dwRawSize = FIX_ENDIAN_INT32(ige->dwRawSize);
-
- ige->wRsrcId = FIX_ENDIAN_INT16(i + 1);
-
- DWORD dwOffset;
- fread(&dwOffset, sizeof(DWORD), 1, f);
-
- FIX_ENDIAN_INT32_INPLACE(dwOffset);
-
- fpos_t pos;
- fgetpos(f, &pos);
-
- if (fseek(f, dwOffset, SEEK_SET)) {
- free(rsrcIconGroup);
- throw runtime_error("corrupted icon file, too small");
- }
- BYTE* iconData = (BYTE*)malloc(dwRawSize);
- if (!iconData) {
- free(rsrcIconGroup);
- throw bad_alloc();
- }
- fread(iconData, sizeof(BYTE), dwRawSize, f);
- re->UpdateResourceA(RT_ICON, MAKEINTRESOURCE(i+1), NSIS_DEFAULT_LANG, iconData, dwRawSize);
- free(iconData);
-
- fsetpos(f, &pos);
-
- // Seems like the compiler refuses to increase the pointer by just 14.
- // If you'll replace this line by ige++ you will get unwanted results.
- ige = (RsrcIconGroupEntry*)((BYTE*)ige + SIZEOF_RSRC_ICON_GROUP_ENTRY);
- }
-
- fclose(f);
-
- re->UpdateResourceA(RT_GROUP_ICON, MAKEINTRESOURCE(wIconId), NSIS_DEFAULT_LANG, rsrcIconGroup, sizeof(IconGroupHeader) + igh.wCount*SIZEOF_RSRC_ICON_GROUP_ENTRY);
-
- free(rsrcIconGroup);
-}
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
-// returns the data of the uninstaller icon that should replace the installer icon data
-unsigned char* generate_uninstall_icon_data(const char* filename, size_t &size)
-{
- int i;
-
- IconGroupHeader igh;
- FILE *f = open_icon(filename, &igh);
-
- int iNewIconSize = 0;
- FileIconGroupEntry ige;
-
- DWORD* offsets = (DWORD*)malloc(sizeof(DWORD)*igh.wCount);
- DWORD* rawSizes = (DWORD*)malloc(sizeof(DWORD)*igh.wCount);
- if (!offsets || !rawSizes) throw bad_alloc();
-
- for (i = 0; i < igh.wCount; i++) {
- if (!fread(&ige, sizeof(FileIconGroupEntry), 1, f)) throw runtime_error("unable to read file");
- offsets[i] = ige.dwImageOffset;
- rawSizes[i] = ige.dwRawSize;
- iNewIconSize += FIX_ENDIAN_INT32(ige.dwRawSize);
- }
-
- // Before each icon come two DWORDs, one for size and the other for offset (set later)
- // The last size is 0, no offset
- iNewIconSize += sizeof(DWORD)*(1 + igh.wCount*2);
-
- BYTE* pbUninstIcon = (BYTE*)malloc(iNewIconSize);
- if (!pbUninstIcon) throw bad_alloc();
-
- BYTE* seeker = pbUninstIcon;
-
- for (i = 0; i < igh.wCount; i++) {
- *(DWORD*)seeker = rawSizes[i];
- seeker += sizeof(DWORD);
- *(DWORD*)seeker = 0;
- seeker += sizeof(DWORD);
- fseek(f, FIX_ENDIAN_INT32(offsets[i]), SEEK_SET);
- fread(seeker, 1, FIX_ENDIAN_INT32(rawSizes[i]), f);
- seeker += FIX_ENDIAN_INT32(rawSizes[i]);
- }
-
- // This is how we know there are no more icons (size = 0)
- *(DWORD*)seeker = 0;
-
- free(offsets);
- free(rawSizes);
-
- size = iNewIconSize;
-
- return pbUninstIcon;
-}
-
-// Added by Amir Szekely 11th July 2002
-#define MY_ASSERT(x, y) if (x) {if (g_display_errors) fprintf(g_output,"\nError finding icon resources: %s -- failing!\n", y);return 0;}
-
-int find_in_dir(PRESOURCE_DIRECTORY rd, WORD id) {
- WORD i = FIX_ENDIAN_INT16(rd->Header.NumberOfNamedEntries);
- WORD l = i + FIX_ENDIAN_INT16(rd->Header.NumberOfIdEntries);
-
- for (; i < l; i++) {
- if (FIX_ENDIAN_INT16(rd->Entries[i].UName.Id) == id) {
- return i;
- }
- }
-
- return -1;
-}
-
-// Fill the array of icons for uninstall with their offsets
-// Returns zero on failure
-int generate_unicons_offsets(unsigned char* exeHeader, size_t exeHeaderSize, unsigned char* uninstIconData) {
- DWORD dwResourceSectionVA;
-
- PIMAGE_NT_HEADERS ntHeaders = CResourceEditor::GetNTHeaders(exeHeader);
- PRESOURCE_DIRECTORY rdRoot = CResourceEditor::GetResourceDirectory(exeHeader, exeHeaderSize, ntHeaders, &dwResourceSectionVA);
-
- int idx = find_in_dir(rdRoot, (WORD) (long) RT_ICON);
- MY_ASSERT(idx < 0, "no icons found");
- MY_IMAGE_RESOURCE_DIRECTORY_ENTRY rdEntry = rdRoot->Entries[idx];
- FIX_ENDIAN_INT32_INPLACE(rdEntry.UOffset.OffsetToData);
- MY_ASSERT(!rdEntry.UOffset.DirectoryOffset.DataIsDirectory, "bad resource directory");
-
- PRESOURCE_DIRECTORY rdIcons = PRESOURCE_DIRECTORY(rdEntry.UOffset.DirectoryOffset.OffsetToDirectory + DWORD(rdRoot));
-
- MY_ASSERT((size_t)rdIcons - (size_t)exeHeader > exeHeaderSize, "corrupted EXE - invalid pointer");
-
- WORD wNumberOfEntries = FIX_ENDIAN_INT16(rdIcons->Header.NumberOfIdEntries);
-
- MY_ASSERT(wNumberOfEntries == 0, "no icons found");
-
- for (WORD i = 0; i < wNumberOfEntries; i++) { // Icons dir can't have named entries
- MY_IMAGE_RESOURCE_DIRECTORY_ENTRY icoEntry = rdIcons->Entries[i];
- FIX_ENDIAN_INT32_INPLACE(icoEntry.UOffset.OffsetToData);
-
- MY_ASSERT(!icoEntry.UOffset.DirectoryOffset.DataIsDirectory, "bad resource directory");
- PRESOURCE_DIRECTORY rd = PRESOURCE_DIRECTORY(icoEntry.UOffset.DirectoryOffset.OffsetToDirectory + DWORD(rdRoot));
-
- MY_ASSERT((size_t)rd - (size_t)exeHeader > exeHeaderSize, "corrupted EXE - invalid pointer");
-
- MY_IMAGE_RESOURCE_DIRECTORY_ENTRY datEntry = rd->Entries[0];
- FIX_ENDIAN_INT32_INPLACE(datEntry.UOffset.OffsetToData);
-
- MY_ASSERT(datEntry.UOffset.DirectoryOffset.DataIsDirectory, "bad resource directory");
-
- PIMAGE_RESOURCE_DATA_ENTRY rde = PIMAGE_RESOURCE_DATA_ENTRY(datEntry.UOffset.OffsetToData + DWORD(rdRoot));
-
- MY_ASSERT((size_t)rde - (size_t)exeHeader > exeHeaderSize, "corrupted EXE - invalid pointer");
-
- // find icon to replace
- LPBYTE seeker = uninstIconData;
- while (*seeker) {
- DWORD dwSize = *(DWORD*)seeker;
- seeker += sizeof(DWORD);
- DWORD dwOffset = *(DWORD*)seeker;
- // if we haven't set the offset yet and the size is the same, it's a match
- if (!dwOffset && dwSize == rde->Size)
- break;
-
- seeker += FIX_ENDIAN_INT32(dwSize) + sizeof(DWORD);
-
- // reached the end of the list and no match
- MY_ASSERT(!*seeker, "installer, uninstaller icon size mismatch - see the Icon instruction's documentation for more information");
- }
-
- // Set offset
- DWORD dwOffset = FIX_ENDIAN_INT32(rde->OffsetToData) + DWORD(rdRoot) - dwResourceSectionVA - DWORD(exeHeader);
- *(LPDWORD) seeker = FIX_ENDIAN_INT32(dwOffset);
-
- MY_ASSERT(dwOffset > exeHeaderSize || dwOffset < (DWORD)rdRoot - (DWORD)exeHeader, "invalid data offset - icon resource probably compressed");
- }
-
- LPBYTE seeker = uninstIconData;
- while (*seeker) {
- DWORD dwSize = *(DWORD*)seeker;
- seeker += sizeof(DWORD);
- DWORD dwOffset = *(DWORD*)seeker;
- seeker += sizeof(DWORD);
- // offset isn't set which means we found no match for this one
- MY_ASSERT(!dwOffset, "installer, uninstaller number of icons doesn't match - see the Icon instruction's documentation for more information");
- seeker += FIX_ENDIAN_INT32(dwSize);
- }
-
- return 1;
-}
-#endif // NSIS_CONFIG_UNINSTALL_SUPPORT
-
-#ifndef _WIN32
-char *CharPrev(const char *s, const char *p) {
- if (!s || !p || p < s)
- return NULL;
- while (*s) {
- char *n = CharNext(s);
- if (n >= p)
- break;
- s = n;
- }
- return (char *) s;
-}
-
-char *CharNext(const char *s) {
- int l = 0;
- if (s && *s)
- l = max(1, mblen(s, MB_CUR_MAX));
- return (char *) s + l;
-}
-
-char *CharNextExA(WORD codepage, const char *s, int flags) {
- char buf[1024];
- snprintf(buf, 1024, "CP%d", codepage);
- setlocale(LC_CTYPE, buf);
-
- const char* np;
- int len = mblen(s, strlen(s));
- if (len > 0)
- np = s + len;
- else
- np = s + 1;
-
- setlocale(LC_CTYPE, "");
-
- return (char *) np;
-}
-
-int wsprintf(char *s, const char *format, ...) {
- va_list val;
- va_start(val, format);
- int res = vsnprintf(s, 1024, format, val);
- va_end(val);
- return res;
-}
-
-// iconv const inconsistency workaround by Alexandre Oliva
-template <typename T>
-inline size_t __iconv_adaptor
- (size_t (*iconv_func)(iconv_t, T, size_t *, char**,size_t*),
- iconv_t cd, char **inbuf, size_t *inbytesleft,
- char **outbuf, size_t *outbytesleft)
-{
- return iconv_func (cd, (T)inbuf, inbytesleft, outbuf, outbytesleft);
-}
-
-void static create_code_page_string(char *buf, size_t len, UINT code_page) {
- if (code_page == CP_ACP)
- code_page = 1252;
-
- snprintf(buf, len, "CP%d", code_page);
-}
-
-int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr,
- int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar,
- LPBOOL lpUsedDefaultChar) {
- static char buffer[4096];
-
- char cp[128];
- create_code_page_string(cp, sizeof(cp), CodePage);
-
- iconv_t cd = iconv_open(cp, "UCS-2LE");
- if (cd == (iconv_t) -1) {
- return 0;
- }
-
- if (cchWideChar < 0) {
- cchWideChar = (int) winchar_strlen(lpWideCharStr) + 1;
- }
-
- if (cbMultiByte == 0) {
- cbMultiByte = sizeof(buffer);
- lpMultiByteStr = buffer;
- }
-
- char *in = (char *) lpWideCharStr;
- char *out = lpMultiByteStr;
- size_t inbytes = cchWideChar * sizeof(WCHAR);
- size_t outbytes = cbMultiByte;
-
- if (__iconv_adaptor(iconv, cd, &in, &inbytes, &out, &outbytes) == (size_t) -1) {
- iconv_close(cd);
- return 0;
- }
-
- iconv_close(cd);
-
- return cbMultiByte - outbytes;
-}
-
-int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
- int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar) {
- static WCHAR buffer[4096];
-
- char cp[128];
- create_code_page_string(cp, sizeof(cp), CodePage);
-
- iconv_t cd = iconv_open("UCS-2LE", cp);
- if (cd == (iconv_t) -1) {
- return 0;
- }
-
- if (cbMultiByte < 0) {
- cbMultiByte = strlen(lpMultiByteStr) + 1;
- }
-
- if (cchWideChar == 0) {
- cchWideChar = sizeof(buffer);
- lpWideCharStr = buffer;
- }
-
- char *in = (char *) lpMultiByteStr;
- char *out = (char *) lpWideCharStr;
- size_t inbytes = cbMultiByte;
- size_t outbytes = cchWideChar * sizeof(WCHAR);
-
- if (__iconv_adaptor(iconv, cd, &in, &inbytes, &out, &outbytes) == (size_t) -1) {
- iconv_close(cd);
- return 0;
- }
-
- iconv_close(cd);
-
- return cchWideChar - (outbytes / sizeof (WCHAR));
-}
-
-BOOL IsValidCodePage(UINT CodePage)
-{
- char cp[128];
- create_code_page_string(cp, sizeof(cp), CodePage);
-
- iconv_t cd = iconv_open("UCS-2LE", cp);
- if (cd == (iconv_t) -1)
- return FALSE;
-
- iconv_close(cd);
-
- return TRUE;
-}
-
-#define MY_ERROR_MSG(x) {if (g_display_errors) {fprintf(g_output,"%s", x);}}
-
-char *my_convert(const char *path)
-{
- // TODO: (orip) ref. this func. to use std::string?
- char *converted_path = strdup(path);
- size_t len = strlen(path);
-
- if(!converted_path)
- {
- MY_ERROR_MSG("Error: could not allocate memory in my_convert()\n");
- return (char*) path; /* dirty */
- }
-
- /* Replace drive letter X: by /X */
- if(len >= 2)
- {
- if (path[1] == ':')
- {
- converted_path[0] = '/';
- converted_path[1] = (char) tolower((int) path[0]);
- }
- }
-
- char *p = converted_path;
-
- do
- {
- if (*p == '\\')
- {
- *p = '/';
- }
- p = CharNext(p);
- }
- while (*p);
-
- return converted_path;
-}
-
-void my_convert_free(char *converted_path)
-{
- free(converted_path);
-}
-
-int my_open(const char *pathname, int flags)
-{
- char *converted_pathname = my_convert(pathname);
-
- int result = open(converted_pathname, flags);
- my_convert_free(converted_pathname);
- return result;
-}
-
-FILE *my_fopen(const char *path, const char *mode)
-{
- char *converted_path = my_convert(path);
-
- FILE *result = fopen(converted_path, mode);
- my_convert_free(converted_path);
- return result;
-}
-#endif//!_WIN32
-
-void *operator new(size_t size) throw(bad_alloc) {
- void *p = malloc(size);
- if (!p)
- throw bad_alloc();
- return p;
-}
-
-void operator delete(void *p) throw() {
- if (p) free(p);
-}
-
-void operator delete [](void *p) throw() {
- if (p) free(p);
-}
-
-size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm) {
- return strftime(s, max, fmt, tm);
-}
-
-string get_full_path(const string &path) {
-#ifdef _WIN32
- char *throwaway;
- char real_path[1024];
- int rc = GetFullPathName(path.c_str(),1024,real_path,&throwaway);
- assert(rc <= 1024); // path size is limited by MAX_PATH (260)
- assert(rc != 0); // rc==0 in case of error
- return string(real_path);
-#else//_WIN32
-#ifdef PATH_MAX
- static char buffer[PATH_MAX];
-#else//PATH_MAX
- int path_max = pathconf(path, _PC_PATH_MAX);
- if (path_max <= 0)
- path_max = 4096;
- char *buffer = (char *) malloc(path_max);
- if (!buffer)
- return string(path);
-#endif//PATH_MAX
- if (!realpath(path.c_str(), buffer))
- strcpy(buffer, path.c_str());
- string result(buffer);
-#ifndef PATH_MAX
- free(buffer);
-#endif//!PATH_MAX
- return result;
-#endif//_WIN32
-}
-
-string get_string_prefix(const string& str, const string& separator) {
- const string::size_type last_separator_pos = str.rfind(separator);
- if (last_separator_pos == string::npos)
- return str;
- return str.substr(0, last_separator_pos);
-}
-
-string get_string_suffix(const string& str, const string& separator) {
- const string::size_type last_separator_pos = str.rfind(separator);
- if (last_separator_pos == string::npos)
- return str;
- return str.substr(last_separator_pos + separator.size(), string::npos);
-}
-
-string get_dir_name(const string& path) {
- return get_string_prefix(path, PLATFORM_PATH_SEPARATOR_STR);
-}
-
-string get_file_name(const string& path) {
- return get_string_suffix(path, PLATFORM_PATH_SEPARATOR_STR);
-}
-
-string get_executable_path(const char* argv0) {
-#ifdef _WIN32
- char temp_buf[MAX_PATH+1];
- temp_buf[0] = '\0';
- int rc = GetModuleFileName(NULL,temp_buf,MAX_PATH);
- assert(rc != 0);
- return string(temp_buf);
-#elif __APPLE__
- char temp_buf[MAXPATHLEN+1];
- unsigned int buf_len = MAXPATHLEN;
- int rc = Apple::_NSGetExecutablePath(temp_buf, &buf_len);
- assert(rc == 0);
- return string(temp_buf);
-#else /* Linux/BSD/POSIX/etc */
- const char *envpath = getenv("_");
- if( envpath != NULL ) return get_full_path( envpath );
- else {
- char* pathtmp;
- char* path = NULL;
- size_t len = 100;
- int nchars;
- while(1){
- pathtmp = (char*)realloc(path,len+1);
- if( pathtmp == NULL ){
- free(path);
- return get_full_path(argv0);
- }
- path = pathtmp;
- nchars = readlink("/proc/self/exe", path, len);
- if( nchars == -1 ){
- free(path);
- return get_full_path(argv0);
- }
- if( nchars < (int) len ){
- path[nchars] = '\0';
- string result(path);
- free(path);
- return result;
- }
- len *= 2;
- }
- }
-#endif
-}
-
-string get_executable_dir(const char *argv0) {
- return get_dir_name(get_executable_path(argv0));
-}
-
-string remove_file_extension(const string& path) {
- return get_string_prefix(path, ".");
-}
-
-string lowercase(const string &str) {
- string result = str;
- transform(str.begin(), str.end(), result.begin(), tolower);
- return result;
-}
-
-int sane_system(const char *command) {
-#ifdef _WIN32
-
- // workaround for bug #1509909
- // http://sf.net/tracker/?func=detail&atid=373085&aid=1509909&group_id=22049
- //
- // cmd.exe /C has some weird handling for quotes. it strips
- // the surrounding quotes, if they exist. if there are quotes
- // around the program path and its arguments, it will strip
- // the outer quotes. this may result in something like:
- // `program files\nsis\makensis.exe" "args`
- // which obviously fails...
- //
- // to avoid the stripping, a harmless string is prefixed
- // to the command line.
-
- string command_s = "IF 1==1 ";
- command_s += command;
- return system(command_s.c_str());
-
-#else
-
- return system(command);
-
-#endif
-}
-
-static bool GetDLLVersionUsingRE(const string& filepath, DWORD& high, DWORD & low)
-{
- bool found = false;
-
- FILE *fdll = FOPEN(filepath.c_str(), "rb");
- if (!fdll)
- return 0;
-
- fseek(fdll, 0, SEEK_END);
- unsigned int len = ftell(fdll);
- fseek(fdll, 0, SEEK_SET);
-
- LPBYTE dll = (LPBYTE) malloc(len);
-
- if (!dll)
- {
- fclose(fdll);
- return 0;
- }
-
- if (fread(dll, 1, len, fdll) != len)
- {
- fclose(fdll);
- free(dll);
- return 0;
- }
-
- try
- {
- CResourceEditor *dllre = new CResourceEditor(dll, len);
- LPBYTE ver = dllre->GetResourceA(VS_FILE_INFO, MAKEINTRESOURCE(VS_VERSION_INFO), 0);
- int versize = dllre->GetResourceSizeA(VS_FILE_INFO, MAKEINTRESOURCE(VS_VERSION_INFO), 0);
-
- if (ver)
- {
- if ((size_t) versize > sizeof(WORD) * 3)
- {
- // get VS_FIXEDFILEINFO from VS_VERSIONINFO
- WCHAR *szKey = (WCHAR *)(ver + sizeof(WORD) * 3);
- int len = (winchar_strlen(szKey) + 1) * sizeof(WCHAR) + sizeof(WORD) * 3;
- len = (len + 3) & ~3; // align on DWORD boundry
- VS_FIXEDFILEINFO *verinfo = (VS_FIXEDFILEINFO *)(ver + len);
- if (versize > len && verinfo->dwSignature == VS_FFI_SIGNATURE)
- {
- low = verinfo->dwFileVersionLS;
- high = verinfo->dwFileVersionMS;
- found = true;
- }
- }
- dllre->FreeResource(ver);
- }
-
- delete dllre;
- }
- catch (exception&)
- {
- }
-
- return found;
-}
-
-static bool GetDLLVersionUsingAPI(const string& filepath, DWORD& high, DWORD& low)
-{
- bool found = false;
-
-#ifdef _WIN32
- char path[1024];
- char *name;
- path[0] = 0;
-
- GetFullPathName(filepath.c_str(), 1024, path, &name);
-
- DWORD d;
- DWORD verSize = GetFileVersionInfoSize(path, &d);
- if (verSize)
- {
- void *buf = (void *) GlobalAlloc(GPTR, verSize);
- if (buf)
- {
- UINT uLen;
- VS_FIXEDFILEINFO *pvsf;
- if (GetFileVersionInfo(path, 0, verSize, buf) && VerQueryValue(buf, "\\", (void**) &pvsf, &uLen))
- {
- low = pvsf->dwFileVersionLS;
- high = pvsf->dwFileVersionMS;
- found = true;
- }
- GlobalFree(buf);
- }
- }
-#endif
-
- return found;
-}
-
-#ifdef _WIN32
-
-// the following structure must be byte-aligned.
-#pragma pack( push, pre_vxd_ver, 1 )
-typedef struct _VXD_VERSION_RESOURCE {
- char cType;
- WORD wID;
- char cName;
- WORD wOrdinal;
- WORD wFlags;
- DWORD dwResSize;
- BYTE bVerData;
-} VXD_VERSION_RESOURCE, *PVXD_VERSION_RESOURCE;
-#pragma pack( pop, pre_vxd_ver )
-
-static BOOL GetVxdVersion( LPCSTR szFile, LPDWORD lpdwLen, LPVOID lpData )
-{
-
- HANDLE hFile = NULL;
- HANDLE hFileMapping = NULL;
- void * pView = NULL;
- DWORD dwSize = 0;
- DWORD dwError = 0;
-
- PIMAGE_DOS_HEADER pDosExeHdr = NULL;
- PIMAGE_NT_HEADERS pNtExeHdr = NULL;
- PIMAGE_VXD_HEADER pLEHdr = NULL;
- PVXD_VERSION_RESOURCE pVerRes = NULL;
- LPVOID pRawRes = NULL;
-
- // Open the file for shared read access.
- hFile = CreateFile( szFile, GENERIC_READ, FILE_SHARE_READ,
- NULL, OPEN_EXISTING, 0, NULL );
- if ( hFile == INVALID_HANDLE_VALUE )
- {
- return FALSE;
- }
-
- // Create a read-only file mapping object for the file.
- hFileMapping = CreateFileMapping( hFile, NULL,
- PAGE_READONLY, 0, 0, NULL);
- if ( !hFileMapping )
- {
- dwError = GetLastError();
-
- if ( hFile != INVALID_HANDLE_VALUE )
- CloseHandle( hFile );
-
- SetLastError( dwError );
- return FALSE;
- }
-
- // Map a view of the the file.
- pView = MapViewOfFile( hFileMapping, FILE_MAP_READ, 0, 0, 0 );
- if ( !pView )
- {
- dwError = GetLastError();
-
- if ( hFileMapping )
- CloseHandle( hFileMapping );
-
- if ( hFile != INVALID_HANDLE_VALUE )
- CloseHandle( hFile );
-
- SetLastError( dwError );
- return FALSE;
- }
-
- // The DOS header begins at byte 0.
- pDosExeHdr = (PIMAGE_DOS_HEADER) pView;
-
- // Check to make sure the file has a DOS EXE header.
- if ( pDosExeHdr->e_magic != IMAGE_DOS_SIGNATURE )
- {
- if ( pView )
- UnmapViewOfFile( pView );
-
- if ( hFileMapping )
- CloseHandle( hFileMapping );
-
- if ( hFile != INVALID_HANDLE_VALUE )
- CloseHandle( hFile );
-
- SetLastError( ERROR_BAD_FORMAT );
- return FALSE;
- }
-
- // Find the beginning of the NT header at offset e_lfanew.
- pNtExeHdr = (PIMAGE_NT_HEADERS) ( (DWORD) pView
- + (DWORD) pDosExeHdr->e_lfanew );
-
- // Check to make sure the file is a VxD.
- if ( (DWORD) pNtExeHdr->Signature != IMAGE_VXD_SIGNATURE )
- {
- if ( pView )
- UnmapViewOfFile( pView );
-
- if ( hFileMapping )
- CloseHandle( hFileMapping );
-
- if ( hFile != INVALID_HANDLE_VALUE )
- CloseHandle( hFile );
-
- SetLastError( ERROR_BAD_FORMAT );
- return FALSE;
- }
-
- // The LE header begins at the same place as the NT header.
- pLEHdr = (PIMAGE_VXD_HEADER) pNtExeHdr;
-
- // e32_winreslen contains the size of the VxD's version resource.
- if ( pLEHdr->e32_winreslen == 0 ) {
- *lpdwLen = 0;
- if ( pView )
- UnmapViewOfFile( pView );
-
- if ( hFileMapping )
- CloseHandle( hFileMapping );
-
- if ( hFile != INVALID_HANDLE_VALUE )
- CloseHandle( hFile );
-
- SetLastError( ERROR_RESOURCE_DATA_NOT_FOUND );
- return FALSE;
- }
-
- // e32_winresoff contains the offset of the resource in the VxD.
- pVerRes = (VXD_VERSION_RESOURCE *) ( (DWORD) pView
- + (DWORD) pLEHdr->e32_winresoff );
- dwSize = pVerRes->dwResSize;
- pRawRes = &(pVerRes->bVerData);
-
- // Make sure the supplied buffer is large enough for the resource.
- if ( ( lpData == NULL ) || ( *lpdwLen < dwSize ) ) {
- *lpdwLen = dwSize;
-
- if ( pView )
- UnmapViewOfFile( pView );
-
- if ( hFileMapping )
- CloseHandle( hFileMapping );
-
- if ( hFile != INVALID_HANDLE_VALUE )
- CloseHandle( hFile );
-
- SetLastError( ERROR_INSUFFICIENT_BUFFER );
- return FALSE;
- }
-
- // Zero the passed buffer and copy the resource into it.
- ZeroMemory( lpData, *lpdwLen );
- CopyMemory( lpData, pRawRes, dwSize );
- *lpdwLen = dwSize;
-
- // Clean up resources.
- if ( pView )
- UnmapViewOfFile( pView );
-
- if ( hFileMapping )
- CloseHandle( hFileMapping );
-
- if ( hFile != INVALID_HANDLE_VALUE )
- CloseHandle( hFile );
-
- SetLastError(0);
- return TRUE;
-}
-
-static DWORD GetVxdVersionInfoSize( LPCSTR szFile )
-{
- DWORD dwResult = 0;
-
- // Call GetVxdVersion() with NULL for the pointer to the buffer.
- if ( !GetVxdVersion( szFile, &dwResult, NULL ) )
- {
- DWORD dwError = GetLastError();
-
- // GetVxdVersion() will fail with ERROR_INSUFFICIENT_BUFFER and
- // the required buffer size will be returned in dwResult.
- if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
- {
- SetLastError( 0 );
- return dwResult;
- }
- }
-
- // The following line is never executed.
- return 0;
-}
-
-static BOOL GetVxdVersionInfo( LPCSTR szFile, DWORD dwLen, LPVOID lpData )
-{
- return GetVxdVersion( szFile, &dwLen, lpData );
-}
-
-#endif //_WIN32
-
-static bool GetDLLVersionFromVXD(const string& filepath, DWORD& high, DWORD& low)
-{
- bool found = false;
-
-#ifdef _WIN32
- DWORD verSize = GetVxdVersionInfoSize(filepath.c_str());
- if (verSize)
- {
- void *buf = (void *) GlobalAlloc(GPTR, verSize);
- if (buf)
- {
- UINT uLen;
- VS_FIXEDFILEINFO *pvsf;
- if (GetVxdVersionInfo(filepath.c_str(), verSize, buf) && VerQueryValue(buf, "\\", (void**) &pvsf, &uLen))
- {
- low = pvsf->dwFileVersionLS;
- high = pvsf->dwFileVersionMS;
- found = true;
- }
- GlobalFree(buf);
- }
- }
-#endif
-
- return found;
-}
-
-bool GetDLLVersion(const string& filepath, DWORD& high, DWORD& low)
-{
- if (GetDLLVersionUsingAPI(filepath, high, low))
- return true;
-
- if (GetDLLVersionUsingRE(filepath, high, low))
- return true;
-
- if (GetDLLVersionFromVXD(filepath, high, low))
- return true;
-
- return false;
-}
+/*
+ * util.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+#include <string.h>
+#include "exehead/fileform.h"
+#include "util.h"
+#include "strlist.h"
+#include "winchar.h"
+
+#ifndef _WIN32
+# include <ctype.h>
+# include <unistd.h> // for close(2)
+# include <fcntl.h> // for open(2)
+# include <iconv.h>
+#endif
+
+#ifdef __APPLE__
+namespace Apple { // defines struct section
+# include <mach-o/dyld.h> // for _NSGetExecutablePath
+};
+# include <sys/param.h> // for MAXPATHLEN
+#endif
+
+#include <cassert> // for assert
+#include <algorithm>
+#include <stdexcept>
+
+using namespace std;
+
+int g_dopause=0;
+extern int g_display_errors;
+extern FILE *g_output;
+
+void dopause(void)
+{
+ if (g_dopause)
+ {
+ if (g_display_errors) fprintf(g_output,"MakeNSIS done - hit enter to close...");
+ fflush(stdout);
+ int a;
+ while ((a=getchar()) != '\r' && a != '\n' && a != 27/*esc*/);
+ }
+}
+
+// Returns 0 if everything is OK
+// Returns -1 if can't find the file
+// Returns -2 if the file is an invalid bitmap
+// Returns -3 if the size doesn't match
+// Returns -4 if the bpp doesn't match
+int update_bitmap(CResourceEditor* re, WORD id, const char* filename, int width/*=0*/, int height/*=0*/, int maxbpp/*=0*/) {
+ FILE *f = FOPEN(filename, "rb");
+ if (!f) return -1;
+
+ if (fgetc(f) != 'B' || fgetc(f) != 'M') {
+ fclose(f);
+ return -2;
+ }
+
+ if (width != 0) {
+ LONG biWidth;
+ fseek(f, 18, SEEK_SET); // Seek to the width member of the header
+ fread(&biWidth, sizeof(LONG), 1, f);
+ FIX_ENDIAN_INT32_INPLACE(biWidth);
+ if (width != biWidth) {
+ fclose(f);
+ return -3;
+ }
+ }
+
+ if (height != 0) {
+ LONG biHeight;
+ fseek(f, 22, SEEK_SET); // Seek to the height member of the header
+ fread(&biHeight, sizeof(LONG), 1, f);
+ FIX_ENDIAN_INT32_INPLACE(biHeight);
+ // Bitmap height can be negative too...
+ if (height != abs(biHeight)) {
+ fclose(f);
+ return -3;
+ }
+ }
+
+ if (maxbpp != 0) {
+ WORD biBitCount;
+ fseek(f, 28, SEEK_SET); // Seek to the height member of the header
+ fread(&biBitCount, sizeof(WORD), 1, f);
+ FIX_ENDIAN_INT16_INPLACE(biBitCount);
+ if (biBitCount > maxbpp) {
+ fclose(f);
+ return -4;
+ }
+ }
+
+ DWORD dwSize;
+ fseek(f, 2, SEEK_SET);
+ fread(&dwSize, sizeof(DWORD), 1, f);
+ FIX_ENDIAN_INT32_INPLACE(dwSize);
+ dwSize -= 14;
+
+ unsigned char* bitmap = (unsigned char*)malloc(dwSize);
+ if (!bitmap) throw bad_alloc();
+
+ fseek(f, 14, SEEK_SET);
+ if (fread(bitmap, 1, dwSize, f) != dwSize) {
+ fclose(f);
+ return -2;
+ }
+ fclose(f);
+
+ re->UpdateResourceA(RT_BITMAP, MAKEINTRESOURCE(id), NSIS_DEFAULT_LANG, bitmap, dwSize);
+
+ free(bitmap);
+
+ return 0;
+}
+
+#ifndef _WIN32
+char *CharPrev(const char *s, const char *p) {
+ if (!s || !p || p < s)
+ return NULL;
+ while (*s) {
+ char *n = CharNext(s);
+ if (n >= p)
+ break;
+ s = n;
+ }
+ return (char *) s;
+}
+
+char *CharNext(const char *s) {
+ int l = 0;
+ if (s && *s)
+ l = max(1, mblen(s, MB_CUR_MAX));
+ return (char *) s + l;
+}
+
+char *CharNextExA(WORD codepage, const char *s, int flags) {
+ char buf[1024];
+ snprintf(buf, 1024, "CP%d", codepage);
+ setlocale(LC_CTYPE, buf);
+
+ const char* np;
+ int len = mblen(s, strlen(s));
+ if (len > 0)
+ np = s + len;
+ else
+ np = s + 1;
+
+ setlocale(LC_CTYPE, "");
+
+ return (char *) np;
+}
+
+int wsprintf(char *s, const char *format, ...) {
+ va_list val;
+ va_start(val, format);
+ int res = vsnprintf(s, 1024, format, val);
+ va_end(val);
+ return res;
+}
+
+// iconv const inconsistency workaround by Alexandre Oliva
+template <typename T>
+inline size_t __iconv_adaptor
+ (size_t (*iconv_func)(iconv_t, T, size_t *, char**,size_t*),
+ iconv_t cd, char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ return iconv_func (cd, (T)inbuf, inbytesleft, outbuf, outbytesleft);
+}
+
+void static create_code_page_string(char *buf, size_t len, UINT code_page) {
+ if (code_page == CP_ACP)
+ code_page = 1252;
+
+ snprintf(buf, len, "CP%d", code_page);
+}
+
+int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr,
+ int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar,
+ LPBOOL lpUsedDefaultChar) {
+ static char buffer[4096];
+
+ char cp[128];
+ create_code_page_string(cp, sizeof(cp), CodePage);
+
+ iconv_t cd = iconv_open(cp, "UCS-2LE");
+ if (cd == (iconv_t) -1) {
+ return 0;
+ }
+
+ if (cchWideChar < 0) {
+ cchWideChar = (int) winchar_strlen(lpWideCharStr) + 1;
+ }
+
+ if (cbMultiByte == 0) {
+ cbMultiByte = sizeof(buffer);
+ lpMultiByteStr = buffer;
+ }
+
+ char *in = (char *) lpWideCharStr;
+ char *out = lpMultiByteStr;
+ size_t inbytes = cchWideChar * sizeof(WCHAR);
+ size_t outbytes = cbMultiByte;
+
+ if (__iconv_adaptor(iconv, cd, &in, &inbytes, &out, &outbytes) == (size_t) -1) {
+ iconv_close(cd);
+ return 0;
+ }
+
+ iconv_close(cd);
+
+ return cbMultiByte - outbytes;
+}
+
+int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
+ int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar) {
+ static WCHAR buffer[4096];
+
+ char cp[128];
+ create_code_page_string(cp, sizeof(cp), CodePage);
+
+ iconv_t cd = iconv_open("UCS-2LE", cp);
+ if (cd == (iconv_t) -1) {
+ return 0;
+ }
+
+ if (cbMultiByte < 0) {
+ cbMultiByte = strlen(lpMultiByteStr) + 1;
+ }
+
+ if (cchWideChar == 0) {
+ cchWideChar = sizeof(buffer);
+ lpWideCharStr = buffer;
+ }
+
+ char *in = (char *) lpMultiByteStr;
+ char *out = (char *) lpWideCharStr;
+ size_t inbytes = cbMultiByte;
+ size_t outbytes = cchWideChar * sizeof(WCHAR);
+
+ if (__iconv_adaptor(iconv, cd, &in, &inbytes, &out, &outbytes) == (size_t) -1) {
+ iconv_close(cd);
+ return 0;
+ }
+
+ iconv_close(cd);
+
+ return cchWideChar - (outbytes / sizeof (WCHAR));
+}
+
+BOOL IsValidCodePage(UINT CodePage)
+{
+ char cp[128];
+ create_code_page_string(cp, sizeof(cp), CodePage);
+
+ iconv_t cd = iconv_open("UCS-2LE", cp);
+ if (cd == (iconv_t) -1)
+ return FALSE;
+
+ iconv_close(cd);
+
+ return TRUE;
+}
+
+#define MY_ERROR_MSG(x) {if (g_display_errors) {fprintf(g_output,"%s", x);}}
+
+char *my_convert(const char *path)
+{
+ // TODO: (orip) ref. this func. to use std::string?
+ char *converted_path = strdup(path);
+ size_t len = strlen(path);
+
+ if(!converted_path)
+ {
+ MY_ERROR_MSG("Error: could not allocate memory in my_convert()\n");
+ return (char*) path; /* dirty */
+ }
+
+ /* Replace drive letter X: by /X */
+ if(len >= 2)
+ {
+ if (path[1] == ':')
+ {
+ converted_path[0] = '/';
+ converted_path[1] = (char) tolower((int) path[0]);
+ }
+ }
+
+ char *p = converted_path;
+
+ do
+ {
+ if (*p == '\\')
+ {
+ *p = '/';
+ }
+ p = CharNext(p);
+ }
+ while (*p);
+
+ return converted_path;
+}
+
+void my_convert_free(char *converted_path)
+{
+ free(converted_path);
+}
+
+int my_open(const char *pathname, int flags)
+{
+ char *converted_pathname = my_convert(pathname);
+
+ int result = open(converted_pathname, flags);
+ my_convert_free(converted_pathname);
+ return result;
+}
+
+FILE *my_fopen(const char *path, const char *mode)
+{
+ char *converted_path = my_convert(path);
+
+ FILE *result = fopen(converted_path, mode);
+ my_convert_free(converted_path);
+ return result;
+}
+#endif//!_WIN32
+
+void *operator new(size_t size) throw(bad_alloc) {
+ void *p = malloc(size);
+ if (!p)
+ throw bad_alloc();
+ return p;
+}
+
+void operator delete(void *p) throw() {
+ if (p) free(p);
+}
+
+void operator delete [](void *p) throw() {
+ if (p) free(p);
+}
+
+size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm) {
+ return strftime(s, max, fmt, tm);
+}
+
+string get_full_path(const string &path) {
+#ifdef _WIN32
+ char *throwaway;
+ char real_path[1024];
+ int rc = GetFullPathName(path.c_str(),1024,real_path,&throwaway);
+ assert(rc <= 1024); // path size is limited by MAX_PATH (260)
+ assert(rc != 0); // rc==0 in case of error
+ return string(real_path);
+#else//_WIN32
+#ifdef PATH_MAX
+ static char buffer[PATH_MAX];
+#else//PATH_MAX
+ int path_max = pathconf(path, _PC_PATH_MAX);
+ if (path_max <= 0)
+ path_max = 4096;
+ char *buffer = (char *) malloc(path_max);
+ if (!buffer)
+ return string(path);
+#endif//PATH_MAX
+ if (!realpath(path.c_str(), buffer))
+ strcpy(buffer, path.c_str());
+ string result(buffer);
+#ifndef PATH_MAX
+ free(buffer);
+#endif//!PATH_MAX
+ return result;
+#endif//_WIN32
+}
+
+string get_string_prefix(const string& str, const string& separator) {
+ const string::size_type last_separator_pos = str.rfind(separator);
+ if (last_separator_pos == string::npos)
+ return str;
+ return str.substr(0, last_separator_pos);
+}
+
+string get_string_suffix(const string& str, const string& separator) {
+ const string::size_type last_separator_pos = str.rfind(separator);
+ if (last_separator_pos == string::npos)
+ return str;
+ return str.substr(last_separator_pos + separator.size(), string::npos);
+}
+
+string get_dir_name(const string& path) {
+ return get_string_prefix(path, PLATFORM_PATH_SEPARATOR_STR);
+}
+
+string get_file_name(const string& path) {
+ return get_string_suffix(path, PLATFORM_PATH_SEPARATOR_STR);
+}
+
+string get_executable_path(const char* argv0) {
+#ifdef _WIN32
+ char temp_buf[MAX_PATH+1];
+ temp_buf[0] = '\0';
+ int rc = GetModuleFileName(NULL,temp_buf,MAX_PATH);
+ assert(rc != 0);
+ return string(temp_buf);
+#elif __APPLE__
+ char temp_buf[MAXPATHLEN+1];
+ unsigned int buf_len = MAXPATHLEN;
+ int rc = Apple::_NSGetExecutablePath(temp_buf, &buf_len);
+ assert(rc == 0);
+ return string(temp_buf);
+#else /* Linux/BSD/POSIX/etc */
+ const char *envpath = getenv("_");
+ if( envpath != NULL ) return get_full_path( envpath );
+ else {
+ char* pathtmp;
+ char* path = NULL;
+ size_t len = 100;
+ int nchars;
+ while(1){
+ pathtmp = (char*)realloc(path,len+1);
+ if( pathtmp == NULL ){
+ free(path);
+ return get_full_path(argv0);
+ }
+ path = pathtmp;
+ nchars = readlink("/proc/self/exe", path, len);
+ if( nchars == -1 ){
+ free(path);
+ return get_full_path(argv0);
+ }
+ if( nchars < (int) len ){
+ path[nchars] = '\0';
+ string result(path);
+ free(path);
+ return result;
+ }
+ len *= 2;
+ }
+ }
+#endif
+}
+
+string get_executable_dir(const char *argv0) {
+ return get_dir_name(get_executable_path(argv0));
+}
+
+string remove_file_extension(const string& path) {
+ return get_string_prefix(path, ".");
+}
+
+string lowercase(const string &str) {
+ string result = str;
+ transform(str.begin(), str.end(), result.begin(), tolower);
+ return result;
+}
+
+int sane_system(const char *command) {
+#ifdef _WIN32
+
+ // workaround for bug #1509909
+ // http://sf.net/tracker/?func=detail&atid=373085&aid=1509909&group_id=22049
+ //
+ // cmd.exe /C has some weird handling for quotes. it strips
+ // the surrounding quotes, if they exist. if there are quotes
+ // around the program path and its arguments, it will strip
+ // the outer quotes. this may result in something like:
+ // `program files\nsis\makensis.exe" "args`
+ // which obviously fails...
+ //
+ // to avoid the stripping, a harmless string is prefixed
+ // to the command line.
+
+ string command_s = "IF 1==1 ";
+ command_s += command;
+ return system(command_s.c_str());
+
+#else
+
+ return system(command);
+
+#endif
+}
+
+static bool GetDLLVersionUsingRE(const string& filepath, DWORD& high, DWORD & low)
+{
+ bool found = false;
+
+ FILE *fdll = FOPEN(filepath.c_str(), "rb");
+ if (!fdll)
+ return 0;
+
+ fseek(fdll, 0, SEEK_END);
+ unsigned int len = ftell(fdll);
+ fseek(fdll, 0, SEEK_SET);
+
+ LPBYTE dll = (LPBYTE) malloc(len);
+
+ if (!dll)
+ {
+ fclose(fdll);
+ return 0;
+ }
+
+ if (fread(dll, 1, len, fdll) != len)
+ {
+ fclose(fdll);
+ free(dll);
+ return 0;
+ }
+
+ try
+ {
+ CResourceEditor *dllre = new CResourceEditor(dll, len);
+ LPBYTE ver = dllre->GetResourceA(VS_FILE_INFO, MAKEINTRESOURCE(VS_VERSION_INFO), 0);
+ int versize = dllre->GetResourceSizeA(VS_FILE_INFO, MAKEINTRESOURCE(VS_VERSION_INFO), 0);
+
+ if (ver)
+ {
+ if ((size_t) versize > sizeof(WORD) * 3)
+ {
+ // get VS_FIXEDFILEINFO from VS_VERSIONINFO
+ WCHAR *szKey = (WCHAR *)(ver + sizeof(WORD) * 3);
+ int len = (winchar_strlen(szKey) + 1) * sizeof(WCHAR) + sizeof(WORD) * 3;
+ len = (len + 3) & ~3; // align on DWORD boundry
+ VS_FIXEDFILEINFO *verinfo = (VS_FIXEDFILEINFO *)(ver + len);
+ if (versize > len && verinfo->dwSignature == VS_FFI_SIGNATURE)
+ {
+ low = verinfo->dwFileVersionLS;
+ high = verinfo->dwFileVersionMS;
+ found = true;
+ }
+ }
+ dllre->FreeResource(ver);
+ }
+
+ delete dllre;
+ }
+ catch (exception&)
+ {
+ }
+
+ return found;
+}
+
+static bool GetDLLVersionUsingAPI(const string& filepath, DWORD& high, DWORD& low)
+{
+ bool found = false;
+
+#ifdef _WIN32
+ char path[1024];
+ char *name;
+ path[0] = 0;
+
+ GetFullPathName(filepath.c_str(), 1024, path, &name);
+
+ DWORD d;
+ DWORD verSize = GetFileVersionInfoSize(path, &d);
+ if (verSize)
+ {
+ void *buf = (void *) GlobalAlloc(GPTR, verSize);
+ if (buf)
+ {
+ UINT uLen;
+ VS_FIXEDFILEINFO *pvsf;
+ if (GetFileVersionInfo(path, 0, verSize, buf) && VerQueryValue(buf, "\\", (void**) &pvsf, &uLen))
+ {
+ low = pvsf->dwFileVersionLS;
+ high = pvsf->dwFileVersionMS;
+ found = true;
+ }
+ GlobalFree(buf);
+ }
+ }
+#endif
+
+ return found;
+}
+
+#ifdef _WIN32
+
+// the following structure must be byte-aligned.
+#pragma pack( push, pre_vxd_ver, 1 )
+typedef struct _VXD_VERSION_RESOURCE {
+ char cType;
+ WORD wID;
+ char cName;
+ WORD wOrdinal;
+ WORD wFlags;
+ DWORD dwResSize;
+ BYTE bVerData;
+} VXD_VERSION_RESOURCE, *PVXD_VERSION_RESOURCE;
+#pragma pack( pop, pre_vxd_ver )
+
+static BOOL GetVxdVersion( LPCSTR szFile, LPDWORD lpdwLen, LPVOID lpData )
+{
+
+ HANDLE hFile = NULL;
+ HANDLE hFileMapping = NULL;
+ void * pView = NULL;
+ DWORD dwSize = 0;
+ DWORD dwError = 0;
+
+ PIMAGE_DOS_HEADER pDosExeHdr = NULL;
+ PIMAGE_NT_HEADERS pNtExeHdr = NULL;
+ PIMAGE_VXD_HEADER pLEHdr = NULL;
+ PVXD_VERSION_RESOURCE pVerRes = NULL;
+ LPVOID pRawRes = NULL;
+
+ // Open the file for shared read access.
+ hFile = CreateFile( szFile, GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, 0, NULL );
+ if ( hFile == INVALID_HANDLE_VALUE )
+ {
+ return FALSE;
+ }
+
+ // Create a read-only file mapping object for the file.
+ hFileMapping = CreateFileMapping( hFile, NULL,
+ PAGE_READONLY, 0, 0, NULL);
+ if ( !hFileMapping )
+ {
+ dwError = GetLastError();
+
+ if ( hFile != INVALID_HANDLE_VALUE )
+ CloseHandle( hFile );
+
+ SetLastError( dwError );
+ return FALSE;
+ }
+
+ // Map a view of the the file.
+ pView = MapViewOfFile( hFileMapping, FILE_MAP_READ, 0, 0, 0 );
+ if ( !pView )
+ {
+ dwError = GetLastError();
+
+ if ( hFileMapping )
+ CloseHandle( hFileMapping );
+
+ if ( hFile != INVALID_HANDLE_VALUE )
+ CloseHandle( hFile );
+
+ SetLastError( dwError );
+ return FALSE;
+ }
+
+ // The DOS header begins at byte 0.
+ pDosExeHdr = (PIMAGE_DOS_HEADER) pView;
+
+ // Check to make sure the file has a DOS EXE header.
+ if ( pDosExeHdr->e_magic != IMAGE_DOS_SIGNATURE )
+ {
+ if ( pView )
+ UnmapViewOfFile( pView );
+
+ if ( hFileMapping )
+ CloseHandle( hFileMapping );
+
+ if ( hFile != INVALID_HANDLE_VALUE )
+ CloseHandle( hFile );
+
+ SetLastError( ERROR_BAD_FORMAT );
+ return FALSE;
+ }
+
+ // Find the beginning of the NT header at offset e_lfanew.
+ pNtExeHdr = (PIMAGE_NT_HEADERS) ( (DWORD) pView
+ + (DWORD) pDosExeHdr->e_lfanew );
+
+ // Check to make sure the file is a VxD.
+ if ( (DWORD) pNtExeHdr->Signature != IMAGE_VXD_SIGNATURE )
+ {
+ if ( pView )
+ UnmapViewOfFile( pView );
+
+ if ( hFileMapping )
+ CloseHandle( hFileMapping );
+
+ if ( hFile != INVALID_HANDLE_VALUE )
+ CloseHandle( hFile );
+
+ SetLastError( ERROR_BAD_FORMAT );
+ return FALSE;
+ }
+
+ // The LE header begins at the same place as the NT header.
+ pLEHdr = (PIMAGE_VXD_HEADER) pNtExeHdr;
+
+ // e32_winreslen contains the size of the VxD's version resource.
+ if ( pLEHdr->e32_winreslen == 0 ) {
+ *lpdwLen = 0;
+ if ( pView )
+ UnmapViewOfFile( pView );
+
+ if ( hFileMapping )
+ CloseHandle( hFileMapping );
+
+ if ( hFile != INVALID_HANDLE_VALUE )
+ CloseHandle( hFile );
+
+ SetLastError( ERROR_RESOURCE_DATA_NOT_FOUND );
+ return FALSE;
+ }
+
+ // e32_winresoff contains the offset of the resource in the VxD.
+ pVerRes = (VXD_VERSION_RESOURCE *) ( (DWORD) pView
+ + (DWORD) pLEHdr->e32_winresoff );
+ dwSize = pVerRes->dwResSize;
+ pRawRes = &(pVerRes->bVerData);
+
+ // Make sure the supplied buffer is large enough for the resource.
+ if ( ( lpData == NULL ) || ( *lpdwLen < dwSize ) ) {
+ *lpdwLen = dwSize;
+
+ if ( pView )
+ UnmapViewOfFile( pView );
+
+ if ( hFileMapping )
+ CloseHandle( hFileMapping );
+
+ if ( hFile != INVALID_HANDLE_VALUE )
+ CloseHandle( hFile );
+
+ SetLastError( ERROR_INSUFFICIENT_BUFFER );
+ return FALSE;
+ }
+
+ // Zero the passed buffer and copy the resource into it.
+ ZeroMemory( lpData, *lpdwLen );
+ CopyMemory( lpData, pRawRes, dwSize );
+ *lpdwLen = dwSize;
+
+ // Clean up resources.
+ if ( pView )
+ UnmapViewOfFile( pView );
+
+ if ( hFileMapping )
+ CloseHandle( hFileMapping );
+
+ if ( hFile != INVALID_HANDLE_VALUE )
+ CloseHandle( hFile );
+
+ SetLastError(0);
+ return TRUE;
+}
+
+static DWORD GetVxdVersionInfoSize( LPCSTR szFile )
+{
+ DWORD dwResult = 0;
+
+ // Call GetVxdVersion() with NULL for the pointer to the buffer.
+ if ( !GetVxdVersion( szFile, &dwResult, NULL ) )
+ {
+ DWORD dwError = GetLastError();
+
+ // GetVxdVersion() will fail with ERROR_INSUFFICIENT_BUFFER and
+ // the required buffer size will be returned in dwResult.
+ if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
+ {
+ SetLastError( 0 );
+ return dwResult;
+ }
+ }
+
+ // The following line is never executed.
+ return 0;
+}
+
+static BOOL GetVxdVersionInfo( LPCSTR szFile, DWORD dwLen, LPVOID lpData )
+{
+ return GetVxdVersion( szFile, &dwLen, lpData );
+}
+
+#endif //_WIN32
+
+static bool GetDLLVersionFromVXD(const string& filepath, DWORD& high, DWORD& low)
+{
+ bool found = false;
+
+#ifdef _WIN32
+ DWORD verSize = GetVxdVersionInfoSize(filepath.c_str());
+ if (verSize)
+ {
+ void *buf = (void *) GlobalAlloc(GPTR, verSize);
+ if (buf)
+ {
+ UINT uLen;
+ VS_FIXEDFILEINFO *pvsf;
+ if (GetVxdVersionInfo(filepath.c_str(), verSize, buf) && VerQueryValue(buf, "\\", (void**) &pvsf, &uLen))
+ {
+ low = pvsf->dwFileVersionLS;
+ high = pvsf->dwFileVersionMS;
+ found = true;
+ }
+ GlobalFree(buf);
+ }
+ }
+#endif
+
+ return found;
+}
+
+bool GetDLLVersion(const string& filepath, DWORD& high, DWORD& low)
+{
+ if (GetDLLVersionUsingAPI(filepath, high, low))
+ return true;
+
+ if (GetDLLVersionUsingRE(filepath, high, low))
+ return true;
+
+ if (GetDLLVersionFromVXD(filepath, high, low))
+ return true;
+
+ return false;
+}
diff --git a/Source/util.h b/Source/util.h
index b29c4a8..9f1a480 100755
--- a/Source/util.h
+++ b/Source/util.h
@@ -1,156 +1,146 @@
-/*
- * util.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef _UTIL_H_
-#define _UTIL_H_
-
-#include <string> // for std::string
-
-#include "boost/scoped_ptr.hpp" // for boost::scoped_ptr
-#include "ResourceEditor.h"
-
-#ifndef _WIN32
-# include <iconv.h>
-# include <stdio.h>
-#endif
-
-
-// these are the standard pause-before-quit shit.
-extern int g_dopause;
-extern void dopause(void);
-
-// Adds the bitmap in filename using resource editor re as id id.
-// If width or height are specified it will also make sure the bitmap is in that size
-int update_bitmap(CResourceEditor* re, WORD id, const char* filename, int width=0, int height=0, int maxbpp=0);
-
-// reads icon file filename and places its icons in the resource wIconId using resource editor re
-void replace_icon(CResourceEditor* re, WORD wIconId, const char* filename);
-
-#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
-// returns the data of the uninstaller icon (inside filename) that should replace the installer icon data
-unsigned char* generate_uninstall_icon_data(const char* filename, size_t &size);
-// Fill the array of icons for uninstall with their offsets
-int generate_unicons_offsets(unsigned char* exeHeader, size_t exeHeaderSize, unsigned char* uninstIconData);
-#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
-
-size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm);
-
-bool GetDLLVersion(const std::string& filepath, DWORD& high, DWORD& low);
-
-std::string get_full_path(const std::string& path);
-std::string get_dir_name(const std::string& path);
-std::string get_file_name(const std::string& path);
-std::string get_executable_dir(const char *argv0);
-std::string remove_file_extension(const std::string& path);
-std::string lowercase(const std::string&);
-
-std::string get_string_prefix(const std::string& str, const std::string& separator);
-std::string get_string_suffix(const std::string& str, const std::string& separator);
-
-int sane_system(const char *command);
-
-#ifndef _WIN32
-char *CharPrev(const char *s, const char *p);
-char *CharNext(const char *s);
-char *CharNextExA(WORD codepage, const char *s, int flags);
-int wsprintf(char *s, const char *format, ...);
-int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr,
- int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar,
- LPBOOL lpUsedDefaultChar);
-int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
- int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-BOOL IsValidCodePage(UINT CodePage);
-
-char *my_convert(const char *path);
-void my_convert_free(char *converted_path);
-int my_open(const char *pathname, int flags);
-FILE *my_fopen(const char *path, const char *mode);
-
-#define FOPEN(a, b) my_fopen(a, b)
-#define OPEN(a, b) my_open(a, b)
-
-#else
-
-#define FOPEN(a, b) fopen(a, b)
-#define OPEN(a, b) open(a, b)
-#endif
-
-// round a value up to be a multiple of 512
-// assumption: T is an int type
-template <class T>
-inline T align_to_512(const T x) {
- return (x+511) & ~511;
-}
-
-// ================
-// ResourceManagers
-// ================
-
-// When a ResourceManager instance goes out of scope, it will run
-// _FREE_RESOURCE on the resource.
-// Example use:
-// int fd = open(..);
-// assert(fd != -1);
-// MANAGE_WITH(fd, close);
-
-class BaseResourceManager {
-protected:
- BaseResourceManager() {}
-public:
- virtual ~BaseResourceManager() {}
-};
-
-template <typename _RESOURCE, typename _FREE_RESOURCE>
-class ResourceManager : public BaseResourceManager {
-public:
- ResourceManager(_RESOURCE& resource) : m_resource(resource) {}
- virtual ~ResourceManager() { m_free_resource(m_resource); };
-private: // members
- _RESOURCE& m_resource;
- _FREE_RESOURCE m_free_resource;
-private: // don't copy instances
- ResourceManager(const ResourceManager&);
- void operator=(const ResourceManager&);
-};
-
-#define RM_MANGLE_FREEFUNC(freefunc) \
- __free_with_##freefunc
-
-#define RM_DEFINE_FREEFUNC(freefunc) \
-struct RM_MANGLE_FREEFUNC(freefunc) { \
- template <typename T> void operator()(T& x) { freefunc(x); } \
-}
-
-typedef boost::scoped_ptr<BaseResourceManager> ResourceManagerPtr;
-
-template<typename _FREE_RESOURCE, typename _RESOURCE>
-void createResourceManager(_RESOURCE& resource, ResourceManagerPtr& ptr) {
- ptr.reset(new ResourceManager<_RESOURCE, _FREE_RESOURCE>(resource));
-}
-
-#define RM_MANGLE_RESOURCE(resource) resource##_autoManager
-#define MANAGE_WITH(resource, freefunc) \
- ResourceManagerPtr RM_MANGLE_RESOURCE(resource); \
- createResourceManager<RM_MANGLE_FREEFUNC(freefunc)>( \
- resource, RM_MANGLE_RESOURCE(resource))
-
-// Add more resource-freeing functions here when you need them
-RM_DEFINE_FREEFUNC(close);
-RM_DEFINE_FREEFUNC(CloseHandle);
-RM_DEFINE_FREEFUNC(fclose);
-RM_DEFINE_FREEFUNC(free);
-
-#endif //_UTIL_H_
+/*
+ * util.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef _UTIL_H_
+#define _UTIL_H_
+
+#include <string> // for std::string
+
+#include "boost/scoped_ptr.hpp" // for boost::scoped_ptr
+#include "ResourceEditor.h"
+
+#ifndef _WIN32
+# include <iconv.h>
+# include <stdio.h>
+#endif
+
+
+// these are the standard pause-before-quit shit.
+extern int g_dopause;
+extern void dopause(void);
+
+// Adds the bitmap in filename using resource editor re as id id.
+// If width or height are specified it will also make sure the bitmap is in that size
+int update_bitmap(CResourceEditor* re, WORD id, const char* filename, int width=0, int height=0, int maxbpp=0);
+
+size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm);
+
+bool GetDLLVersion(const std::string& filepath, DWORD& high, DWORD& low);
+
+std::string get_full_path(const std::string& path);
+std::string get_dir_name(const std::string& path);
+std::string get_file_name(const std::string& path);
+std::string get_executable_dir(const char *argv0);
+std::string remove_file_extension(const std::string& path);
+std::string lowercase(const std::string&);
+
+std::string get_string_prefix(const std::string& str, const std::string& separator);
+std::string get_string_suffix(const std::string& str, const std::string& separator);
+
+int sane_system(const char *command);
+
+#ifndef _WIN32
+char *CharPrev(const char *s, const char *p);
+char *CharNext(const char *s);
+char *CharNextExA(WORD codepage, const char *s, int flags);
+int wsprintf(char *s, const char *format, ...);
+int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr,
+ int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar,
+ LPBOOL lpUsedDefaultChar);
+int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
+ int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+BOOL IsValidCodePage(UINT CodePage);
+
+char *my_convert(const char *path);
+void my_convert_free(char *converted_path);
+int my_open(const char *pathname, int flags);
+FILE *my_fopen(const char *path, const char *mode);
+
+#define FOPEN(a, b) my_fopen(a, b)
+#define OPEN(a, b) my_open(a, b)
+
+#else
+
+#define FOPEN(a, b) fopen(a, b)
+#define OPEN(a, b) open(a, b)
+#endif
+
+// round a value up to be a multiple of 512
+// assumption: T is an int type
+template <class T>
+inline T align_to_512(const T x) {
+ return (x+511) & ~511;
+}
+
+// ================
+// ResourceManagers
+// ================
+
+// When a ResourceManager instance goes out of scope, it will run
+// _FREE_RESOURCE on the resource.
+// Example use:
+// int fd = open(..);
+// assert(fd != -1);
+// MANAGE_WITH(fd, close);
+
+class BaseResourceManager {
+protected:
+ BaseResourceManager() {}
+public:
+ virtual ~BaseResourceManager() {}
+};
+
+template <typename _RESOURCE, typename _FREE_RESOURCE>
+class ResourceManager : public BaseResourceManager {
+public:
+ ResourceManager(_RESOURCE& resource) : m_resource(resource) {}
+ virtual ~ResourceManager() { m_free_resource(m_resource); };
+private: // members
+ _RESOURCE& m_resource;
+ _FREE_RESOURCE m_free_resource;
+private: // don't copy instances
+ ResourceManager(const ResourceManager&);
+ void operator=(const ResourceManager&);
+};
+
+#define RM_MANGLE_FREEFUNC(freefunc) \
+ __free_with_##freefunc
+
+#define RM_DEFINE_FREEFUNC(freefunc) \
+struct RM_MANGLE_FREEFUNC(freefunc) { \
+ template <typename T> void operator()(T& x) { freefunc(x); } \
+}
+
+typedef boost::scoped_ptr<BaseResourceManager> ResourceManagerPtr;
+
+template<typename _FREE_RESOURCE, typename _RESOURCE>
+void createResourceManager(_RESOURCE& resource, ResourceManagerPtr& ptr) {
+ ptr.reset(new ResourceManager<_RESOURCE, _FREE_RESOURCE>(resource));
+}
+
+#define RM_MANGLE_RESOURCE(resource) resource##_autoManager
+#define MANAGE_WITH(resource, freefunc) \
+ ResourceManagerPtr RM_MANGLE_RESOURCE(resource); \
+ createResourceManager<RM_MANGLE_FREEFUNC(freefunc)>( \
+ resource, RM_MANGLE_RESOURCE(resource))
+
+// Add more resource-freeing functions here when you need them
+RM_DEFINE_FREEFUNC(close);
+RM_DEFINE_FREEFUNC(CloseHandle);
+RM_DEFINE_FREEFUNC(fclose);
+RM_DEFINE_FREEFUNC(free);
+
+#endif //_UTIL_H_
diff --git a/Source/winchar.cpp b/Source/winchar.cpp
index 8657867..87d446b 100755
--- a/Source/winchar.cpp
+++ b/Source/winchar.cpp
@@ -1,126 +1,126 @@
-/*
- * winchar.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-#include "winchar.h"
-#include "util.h"
-
-#include <stdexcept>
-
-using std::runtime_error;
-
-WCHAR *winchar_fromansi(const char* s, unsigned int codepage/*=CP_ACP*/)
-{
- int l = MultiByteToWideChar(codepage, 0, s, -1, 0, 0);
- if (l == 0)
- throw runtime_error("Unicode conversion failed");
-
- WCHAR *ws = new WCHAR[l + 1];
-
- if (MultiByteToWideChar(codepage, 0, s, -1, ws, l + 1) == 0)
- throw runtime_error("Unicode conversion failed");
-
- return ws;
-}
-
-char *winchar_toansi(const WCHAR* ws, unsigned int codepage/*=CP_ACP*/)
-{
- int l = WideCharToMultiByte(codepage, 0, ws, -1, 0, 0, 0, 0);
- if (l == 0)
- throw runtime_error("Unicode conversion failed");
-
- char *s = new char[l + 1];
-
- if (WideCharToMultiByte(codepage, 0, ws, -1, s, l + 1, 0, 0) == 0)
- throw runtime_error("Unicode conversion failed");
-
- return s;
-}
-
-WCHAR *winchar_strcpy(WCHAR *ws1, const WCHAR *ws2)
-{
- WCHAR *ret = ws1;
-
- while (*ws2)
- {
- *ws1++ = *ws2++;
- }
-
- *ws1 = 0;
-
- return ret;
-}
-
-WCHAR *winchar_strncpy(WCHAR *ws1, const WCHAR *ws2, size_t n)
-{
- WCHAR *ret = ws1;
-
- while (n && *ws2)
- {
- *ws1++ = *ws2++;
- n--;
- }
-
- while (n--)
- {
- *ws1++ = 0;
- }
-
- return ret;
-}
-
-size_t winchar_strlen(const WCHAR *ws)
-{
- size_t len = 0;
-
- while (*ws++)
- {
- len++;
- }
-
- return len;
-}
-
-WCHAR *winchar_strdup(const WCHAR *ws)
-{
- WCHAR *dup = new WCHAR[winchar_strlen(ws) + 1];
- winchar_strcpy(dup, ws);
- return dup;
-}
-
-int winchar_strcmp(const WCHAR *ws1, const WCHAR *ws2)
-{
- int diff = 0;
-
- do
- {
- diff = static_cast<int>(*ws1) - static_cast<int>(*ws2);
- }
- while (*ws1++ && *ws2++ && !diff);
-
- return diff;
-}
-
-int winchar_stoi(const WCHAR *ws)
-{
- char *s = winchar_toansi(ws);
-
- int ret = atoi(s);
-
- delete [] s;
-
- return ret;
-}
+/*
+ * winchar.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+#include "winchar.h"
+#include "util.h"
+
+#include <stdexcept>
+
+using std::runtime_error;
+
+WCHAR *winchar_fromansi(const char* s, unsigned int codepage/*=CP_ACP*/)
+{
+ int l = MultiByteToWideChar(codepage, 0, s, -1, 0, 0);
+ if (l == 0)
+ throw runtime_error("Unicode conversion failed");
+
+ WCHAR *ws = new WCHAR[l + 1];
+
+ if (MultiByteToWideChar(codepage, 0, s, -1, ws, l + 1) == 0)
+ throw runtime_error("Unicode conversion failed");
+
+ return ws;
+}
+
+char *winchar_toansi(const WCHAR* ws, unsigned int codepage/*=CP_ACP*/)
+{
+ int l = WideCharToMultiByte(codepage, 0, ws, -1, 0, 0, 0, 0);
+ if (l == 0)
+ throw runtime_error("Unicode conversion failed");
+
+ char *s = new char[l + 1];
+
+ if (WideCharToMultiByte(codepage, 0, ws, -1, s, l + 1, 0, 0) == 0)
+ throw runtime_error("Unicode conversion failed");
+
+ return s;
+}
+
+WCHAR *winchar_strcpy(WCHAR *ws1, const WCHAR *ws2)
+{
+ WCHAR *ret = ws1;
+
+ while (*ws2)
+ {
+ *ws1++ = *ws2++;
+ }
+
+ *ws1 = 0;
+
+ return ret;
+}
+
+WCHAR *winchar_strncpy(WCHAR *ws1, const WCHAR *ws2, size_t n)
+{
+ WCHAR *ret = ws1;
+
+ while (n && *ws2)
+ {
+ *ws1++ = *ws2++;
+ n--;
+ }
+
+ while (n--)
+ {
+ *ws1++ = 0;
+ }
+
+ return ret;
+}
+
+size_t winchar_strlen(const WCHAR *ws)
+{
+ size_t len = 0;
+
+ while (*ws++)
+ {
+ len++;
+ }
+
+ return len;
+}
+
+WCHAR *winchar_strdup(const WCHAR *ws)
+{
+ WCHAR *dup = new WCHAR[winchar_strlen(ws) + 1];
+ winchar_strcpy(dup, ws);
+ return dup;
+}
+
+int winchar_strcmp(const WCHAR *ws1, const WCHAR *ws2)
+{
+ int diff = 0;
+
+ do
+ {
+ diff = static_cast<int>(*ws1) - static_cast<int>(*ws2);
+ }
+ while (*ws1++ && *ws2++ && !diff);
+
+ return diff;
+}
+
+int winchar_stoi(const WCHAR *ws)
+{
+ char *s = winchar_toansi(ws);
+
+ int ret = atoi(s);
+
+ delete [] s;
+
+ return ret;
+}
diff --git a/Source/winchar.h b/Source/winchar.h
index b0be250..07ac7e7 100755
--- a/Source/winchar.h
+++ b/Source/winchar.h
@@ -1,26 +1,26 @@
-/*
- * winchar.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "Platform.h"
-
-WCHAR *winchar_fromansi(const char* s, unsigned int codepage = CP_ACP);
-char *winchar_toansi(const WCHAR* ws, unsigned int codepage = CP_ACP);
-WCHAR *winchar_strcpy(WCHAR *ws1, const WCHAR *ws2);
-WCHAR *winchar_strncpy(WCHAR *ws1, const WCHAR *ws2, size_t n);
-size_t winchar_strlen(const WCHAR *ws);
-WCHAR *winchar_strdup(const WCHAR *ws);
-int winchar_strcmp(const WCHAR *ws1, const WCHAR *ws2);
-int winchar_stoi(const WCHAR *ws);
+/*
+ * winchar.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "Platform.h"
+
+WCHAR *winchar_fromansi(const char* s, unsigned int codepage = CP_ACP);
+char *winchar_toansi(const WCHAR* ws, unsigned int codepage = CP_ACP);
+WCHAR *winchar_strcpy(WCHAR *ws1, const WCHAR *ws2);
+WCHAR *winchar_strncpy(WCHAR *ws1, const WCHAR *ws2, size_t n);
+size_t winchar_strlen(const WCHAR *ws);
+WCHAR *winchar_strdup(const WCHAR *ws);
+int winchar_strcmp(const WCHAR *ws1, const WCHAR *ws2);
+int winchar_stoi(const WCHAR *ws);
diff --git a/Source/writer.cpp b/Source/writer.cpp
index 20207fd..f41975f 100755
--- a/Source/writer.cpp
+++ b/Source/writer.cpp
@@ -1,89 +1,89 @@
-/*
- * writer.cpp
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "exehead/config.h"
-#include "writer.h"
-#include "growbuf.h"
-#include "util.h"
-#include <string.h>
-#include <stdlib.h>
-#include <stdexcept>
-
-void writer_sink::write_byte(const unsigned char b)
-{
- write_data(&b, 1);
-}
-
-void writer_sink::write_short(const short s)
-{
- short fs = FIX_ENDIAN_INT16(s);
- write_data(&fs, sizeof(short));
-}
-
-void writer_sink::write_int(const int i)
-{
- int fi = FIX_ENDIAN_INT32(i);
- write_data(&fi, sizeof(int));
-}
-
-void writer_sink::write_int_array(const int i[], const size_t len)
-{
- for (size_t l = 0; l < len; l++)
- {
- write_int(i[l]);
- }
-}
-
-void writer_sink::write_string(const char *s)
-{
- write_data(s, strlen(s) + 1);
-}
-
-void writer_sink::write_string(const char *s, const size_t size)
-{
- char *wb = new char[size];
- memset(wb, 0, size);
- strncpy(wb, s, size);
- write_data(wb, size);
- delete [] wb;
-}
-
-void writer_sink::write_growbuf(const IGrowBuf *b)
-{
- write_data(b->get(), b->getlen());
-}
-
-void growbuf_writer_sink::write_data(const void *data, const size_t size)
-{
- m_buf->add(data, size);
-}
-
-void file_writer_sink::write_data(const void *data, const size_t size)
-{
- if (fwrite(data, 1, size, m_fp) != size)
- {
- throw std::runtime_error("error writing");
- }
-}
-
-#ifdef NSIS_CONFIG_CRC_SUPPORT
-#include "crc32.h"
-
-void crc_writer_sink::write_data(const void *data, const size_t size)
-{
- *m_crc = CRC32(*m_crc, (const unsigned char *) data, size);
-}
-#endif
+/*
+ * writer.cpp
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "exehead/config.h"
+#include "writer.h"
+#include "growbuf.h"
+#include "util.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdexcept>
+
+void writer_sink::write_byte(const unsigned char b)
+{
+ write_data(&b, 1);
+}
+
+void writer_sink::write_short(const short s)
+{
+ short fs = FIX_ENDIAN_INT16(s);
+ write_data(&fs, sizeof(short));
+}
+
+void writer_sink::write_int(const int i)
+{
+ int fi = FIX_ENDIAN_INT32(i);
+ write_data(&fi, sizeof(int));
+}
+
+void writer_sink::write_int_array(const int i[], const size_t len)
+{
+ for (size_t l = 0; l < len; l++)
+ {
+ write_int(i[l]);
+ }
+}
+
+void writer_sink::write_string(const char *s)
+{
+ write_data(s, strlen(s) + 1);
+}
+
+void writer_sink::write_string(const char *s, const size_t size)
+{
+ char *wb = new char[size];
+ memset(wb, 0, size);
+ strncpy(wb, s, size);
+ write_data(wb, size);
+ delete [] wb;
+}
+
+void writer_sink::write_growbuf(const IGrowBuf *b)
+{
+ write_data(b->get(), b->getlen());
+}
+
+void growbuf_writer_sink::write_data(const void *data, const size_t size)
+{
+ m_buf->add(data, size);
+}
+
+void file_writer_sink::write_data(const void *data, const size_t size)
+{
+ if (fwrite(data, 1, size, m_fp) != size)
+ {
+ throw std::runtime_error("error writing");
+ }
+}
+
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+#include "crc32.h"
+
+void crc_writer_sink::write_data(const void *data, const size_t size)
+{
+ *m_crc = CRC32(*m_crc, (const unsigned char *) data, size);
+}
+#endif
diff --git a/Source/writer.h b/Source/writer.h
index 7f672bb..1a26581 100755
--- a/Source/writer.h
+++ b/Source/writer.h
@@ -1,87 +1,87 @@
-/*
- * writer.h
- *
- * This file is a part of NSIS.
- *
- * Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * Licensed under the zlib/libpng license (the "License");
- * you may not use this file except in compliance with the License.
- *
- * Licence details can be found in the file COPYING.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#ifndef ___WRITER__H___
-#define ___WRITER__H___
-
-#include "exehead/config.h"
-#include "growbuf.h"
-#include "crc32.h"
-#include <stdio.h>
-
-class writer_sink {
-public:
- writer_sink() {}
- virtual ~writer_sink() {}
-
- virtual void write_byte(const unsigned char b);
- virtual void write_short(const short s);
- virtual void write_int(const int i);
- virtual void write_int_array(const int i[], const size_t len);
- virtual void write_string(const char *s);
- virtual void write_string(const char *s, const size_t size);
- virtual void write_growbuf(const IGrowBuf *b);
-
- virtual void write_data(const void *data, const size_t size) = 0;
-
-};
-
-class writer {
-public:
- writer(writer_sink *sink) : m_sink(sink) {}
- virtual ~writer() {}
-
-protected:
- writer_sink *m_sink;
-
-};
-
-class growbuf_writer_sink : public writer_sink {
-public:
- growbuf_writer_sink(IGrowBuf *buf) : m_buf(buf) {}
-
- virtual void write_data(const void *data, const size_t size);
-
-private:
- IGrowBuf *m_buf;
-
-};
-
-class file_writer_sink : public writer_sink {
-public:
- file_writer_sink(FILE *fp) : m_fp(fp) {}
-
- virtual void write_data(const void *data, const size_t size);
-
-private:
- FILE *m_fp;
-
-};
-
-#ifdef NSIS_CONFIG_CRC_SUPPORT
-class crc_writer_sink : public writer_sink {
-public:
- crc_writer_sink(crc32_t *crc) : m_crc(crc) {}
-
- virtual void write_data(const void *data, const size_t size);
-
-private:
- crc32_t *m_crc;
-
-};
-#endif
-
-#endif//!___WRITER__H___
+/*
+ * writer.h
+ *
+ * This file is a part of NSIS.
+ *
+ * Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * Licensed under the zlib/libpng license (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ * Licence details can be found in the file COPYING.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#ifndef ___WRITER__H___
+#define ___WRITER__H___
+
+#include "exehead/config.h"
+#include "growbuf.h"
+#include "crc32.h"
+#include <stdio.h>
+
+class writer_sink {
+public:
+ writer_sink() {}
+ virtual ~writer_sink() {}
+
+ virtual void write_byte(const unsigned char b);
+ virtual void write_short(const short s);
+ virtual void write_int(const int i);
+ virtual void write_int_array(const int i[], const size_t len);
+ virtual void write_string(const char *s);
+ virtual void write_string(const char *s, const size_t size);
+ virtual void write_growbuf(const IGrowBuf *b);
+
+ virtual void write_data(const void *data, const size_t size) = 0;
+
+};
+
+class writer {
+public:
+ writer(writer_sink *sink) : m_sink(sink) {}
+ virtual ~writer() {}
+
+protected:
+ writer_sink *m_sink;
+
+};
+
+class growbuf_writer_sink : public writer_sink {
+public:
+ growbuf_writer_sink(IGrowBuf *buf) : m_buf(buf) {}
+
+ virtual void write_data(const void *data, const size_t size);
+
+private:
+ IGrowBuf *m_buf;
+
+};
+
+class file_writer_sink : public writer_sink {
+public:
+ file_writer_sink(FILE *fp) : m_fp(fp) {}
+
+ virtual void write_data(const void *data, const size_t size);
+
+private:
+ FILE *m_fp;
+
+};
+
+#ifdef NSIS_CONFIG_CRC_SUPPORT
+class crc_writer_sink : public writer_sink {
+public:
+ crc_writer_sink(crc32_t *crc) : m_crc(crc) {}
+
+ virtual void write_data(const void *data, const size_t size);
+
+private:
+ crc32_t *m_crc;
+
+};
+#endif
+
+#endif//!___WRITER__H___
diff --git a/Source/zlib/DEFLATE.H b/Source/zlib/DEFLATE.H
index 0af4034..7dc521b 100755
--- a/Source/zlib/DEFLATE.H
+++ b/Source/zlib/DEFLATE.H
@@ -1,251 +1,251 @@
-/*
- * This file is a part of the zlib compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.zlib.net/
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-1998 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-
-#ifndef _DEFLATE_H
-#define _DEFLATE_H
-
-#include "ZUTIL.H"
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS 256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES 30
-/* number of distance codes */
-
-#define BL_CODES 19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE 42
-#define BUSY_STATE 113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
- union {
- ush freq; /* frequency count */
- ush code; /* bit string */
- } fc;
- union {
- ush dad; /* father node in Huffman tree */
- ush len; /* length of bit string */
- } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad dl.dad
-#define Len dl.len
-
-typedef struct static_tree_desc_s static_tree_desc;
-
-typedef struct tree_desc_s {
- ct_data *dyn_tree; /* the dynamic tree */
- int max_code; /* largest code with non zero frequency */
- static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct internal_state {
- z_streamp strm; /* pointer back to this zlib stream */
- int status; /* as the name implies */
- Bytef *pending_buf; /* output still pending */
- ulg pending_buf_size; /* size of pending_buf */
- Bytef *pending_out; /* next pending byte to output to the stream */
- int pending; /* nb of bytes in the pending buffer */
- int noheader; /* suppress zlib header and adler32 */
- Byte method; /* STORED (for zip only) or DEFLATED */
- int last_flush; /* value of flush param for previous deflate call */
-
- /* used by deflate.c: */
-
- uInt w_size; /* LZ77 window size (32K by default) */
- uInt w_bits; /* log2(w_size) (8..16) */
- uInt w_mask; /* w_size - 1 */
-
- Bytef *window;
-
- ulg window_size;
-
- Posf *prev;
-
- Posf *head; /* Heads of the hash chains or NIL. */
-
- uInt ins_h; /* hash index of string to be inserted */
- uInt hash_size; /* number of elements in hash table */
- uInt hash_bits; /* log2(hash_size) */
- uInt hash_mask; /* hash_size-1 */
-
- uInt hash_shift;
- long block_start;
-
- uInt match_length; /* length of best match */
- IPos prev_match; /* previous match */
- int match_available; /* set if previous match exists */
- uInt strstart; /* start of string to insert */
- uInt match_start; /* start of matching string */
- uInt lookahead; /* number of valid bytes ahead in window */
-
- uInt prev_length;
-
- uInt max_chain_length;
-
- uInt max_lazy_match;
-# define max_insert_length max_lazy_match
-
- int level; /* compression level (1..9) */
- int strategy; /* favor or force Huffman coding*/
-
- uInt good_match;
-
- int nice_match; /* Stop searching when current match exceeds this */
-
- struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
- struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
- struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-
- struct tree_desc_s l_desc; /* desc. for literal tree */
- struct tree_desc_s d_desc; /* desc. for distance tree */
- struct tree_desc_s bl_desc; /* desc. for bit length tree */
-
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
- int heap_len; /* number of elements in the heap */
- int heap_max; /* element of largest frequency */
-
- uch depth[2*L_CODES+1];
- /* Depth of each subtree used as tie breaker for trees of equal frequency
- */
-
- uchf *l_buf; /* buffer for literals or lengths */
-
- uInt lit_bufsize;
-
- uInt last_lit; /* running index in l_buf */
-
- ushf *d_buf;
-
- ulg opt_len; /* bit length of current block with optimal trees */
- ulg static_len; /* bit length of current block with static trees */
- uInt matches; /* number of string matches in current block */
- int last_eob_len; /* bit length of EOB code for last block */
-
-#ifdef DEBUG
- ulg compressed_len; /* total bit length of compressed file mod 2^32 */
- ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-#endif
-
- ush bi_buf;
- int bi_valid;
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
- /* in trees.c */
-void _tr_init OF((deflate_state *s));
-int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-void _tr_align OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
- int eof));
-
-#define d_code(dist) \
- ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. _dist_code[256] and _dist_code[257] are never
- * used.
- */
-
-#ifndef DEBUG
-/* Inline versions of _tr_tally for speed: */
-
-#if defined(GEN_TREES_H) || !defined(STDC)
- extern uch _length_code[];
- extern uch _dist_code[];
-#else
- extern const uch _length_code[];
- extern const uch _dist_code[];
-#endif
-
-# define _tr_tally_lit(s, c, flush) \
- { uch cc = (c); \
- s->d_buf[s->last_lit] = 0; \
- s->l_buf[s->last_lit++] = cc; \
- s->dyn_ltree[cc].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-# define _tr_tally_dist(s, distance, length, flush) \
- { uch len = (length); \
- ush dist = (distance); \
- s->d_buf[s->last_lit] = dist; \
- s->l_buf[s->last_lit++] = len; \
- dist--; \
- s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
- s->dyn_dtree[d_code(dist)].Freq++; \
- flush = (s->last_lit == s->lit_bufsize-1); \
- }
-#else
-# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-# define _tr_tally_dist(s, distance, length, flush) \
- flush = _tr_tally(s, distance, length)
-#endif
-
-#endif
+/*
+ * This file is a part of the zlib compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.zlib.net/
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-1998 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+
+#ifndef _DEFLATE_H
+#define _DEFLATE_H
+
+#include "ZUTIL.H"
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS 256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES 30
+/* number of distance codes */
+
+#define BL_CODES 19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE 42
+#define BUSY_STATE 113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+ union {
+ ush freq; /* frequency count */
+ ush code; /* bit string */
+ } fc;
+ union {
+ ush dad; /* father node in Huffman tree */
+ ush len; /* length of bit string */
+ } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad dl.dad
+#define Len dl.len
+
+typedef struct static_tree_desc_s static_tree_desc;
+
+typedef struct tree_desc_s {
+ ct_data *dyn_tree; /* the dynamic tree */
+ int max_code; /* largest code with non zero frequency */
+ static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ int status; /* as the name implies */
+ Bytef *pending_buf; /* output still pending */
+ ulg pending_buf_size; /* size of pending_buf */
+ Bytef *pending_out; /* next pending byte to output to the stream */
+ int pending; /* nb of bytes in the pending buffer */
+ int noheader; /* suppress zlib header and adler32 */
+ Byte method; /* STORED (for zip only) or DEFLATED */
+ int last_flush; /* value of flush param for previous deflate call */
+
+ /* used by deflate.c: */
+
+ uInt w_size; /* LZ77 window size (32K by default) */
+ uInt w_bits; /* log2(w_size) (8..16) */
+ uInt w_mask; /* w_size - 1 */
+
+ Bytef *window;
+
+ ulg window_size;
+
+ Posf *prev;
+
+ Posf *head; /* Heads of the hash chains or NIL. */
+
+ uInt ins_h; /* hash index of string to be inserted */
+ uInt hash_size; /* number of elements in hash table */
+ uInt hash_bits; /* log2(hash_size) */
+ uInt hash_mask; /* hash_size-1 */
+
+ uInt hash_shift;
+ long block_start;
+
+ uInt match_length; /* length of best match */
+ IPos prev_match; /* previous match */
+ int match_available; /* set if previous match exists */
+ uInt strstart; /* start of string to insert */
+ uInt match_start; /* start of matching string */
+ uInt lookahead; /* number of valid bytes ahead in window */
+
+ uInt prev_length;
+
+ uInt max_chain_length;
+
+ uInt max_lazy_match;
+# define max_insert_length max_lazy_match
+
+ int level; /* compression level (1..9) */
+ int strategy; /* favor or force Huffman coding*/
+
+ uInt good_match;
+
+ int nice_match; /* Stop searching when current match exceeds this */
+
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
+
+ struct tree_desc_s l_desc; /* desc. for literal tree */
+ struct tree_desc_s d_desc; /* desc. for distance tree */
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
+
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+ int heap_len; /* number of elements in the heap */
+ int heap_max; /* element of largest frequency */
+
+ uch depth[2*L_CODES+1];
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
+ */
+
+ uchf *l_buf; /* buffer for literals or lengths */
+
+ uInt lit_bufsize;
+
+ uInt last_lit; /* running index in l_buf */
+
+ ushf *d_buf;
+
+ ulg opt_len; /* bit length of current block with optimal trees */
+ ulg static_len; /* bit length of current block with static trees */
+ uInt matches; /* number of string matches in current block */
+ int last_eob_len; /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
+#endif
+
+ ush bi_buf;
+ int bi_valid;
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+ /* in trees.c */
+void _tr_init OF((deflate_state *s));
+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+void _tr_align OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+
+#define d_code(dist) \
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+ extern uch _length_code[];
+ extern uch _dist_code[];
+#else
+ extern const uch _length_code[];
+ extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+ { uch cc = (c); \
+ s->d_buf[s->last_lit] = 0; \
+ s->l_buf[s->last_lit++] = cc; \
+ s->dyn_ltree[cc].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (length); \
+ ush dist = (distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+ flush = _tr_tally(s, distance, length)
+#endif
+
+#endif
diff --git a/Source/zlib/INFBLOCK.C b/Source/zlib/INFBLOCK.C
index 8e937fb..73aef2d 100755
--- a/Source/zlib/INFBLOCK.C
+++ b/Source/zlib/INFBLOCK.C
@@ -1,710 +1,710 @@
-/*
- * This file is a part of the zlib compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.zlib.net/
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-#include "../Platform.h"
-#include "../exehead/config.h"
-
-#include "ZUTIL.H"
-
-#ifndef min
-# define min(x,y) ((x<y)?x:y)
-#endif
-
-/* defines for inflate input/output */
-/* update pointers and return */
-#define UPDBITS {s->bitb=b;s->bitk=k;}
-#define UPDIN {z->avail_in=n;z->next_in=p;}
-#define UPDOUT {s->write=q;}
-#define UPDATE {UPDBITS UPDIN UPDOUT}
-#define LEAVE(r) {UPDATE inflate_flush(z); return r;}
-
-/* get bytes and bits */
-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-
-
-#define NEEDBYTE {if(!n)LEAVE(Z_OK)}
-#define NEXTBYTE (n--,*p++)
-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-
-#define DUMPBITS(j) {b>>=(j);k-=(j);}
-/* output bytes */
-#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
-#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
-#define FLUSH {UPDOUT inflate_flush(z); LOADOUT}
-#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE(Z_OK)}}}
-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-/* load local pointers */
-#define LOAD {LOADIN LOADOUT}
-
-#define LAST (s->last == DRY)
-
-#define FIXEDH 544 /* number of hufts used by fixed tables */
-
-
-
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* And'ing with mask[n] masks the lower n bits */
-local unsigned short inflate_mask[17] = {
- 0x0000,
- 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-}; // use to reduce .data #define INFLATE_MASK(x, n) (x & (~((unsigned short) 0xFFFF << n)))
-local const char border[] = { /* Order of the bit length code lengths */
- 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-local const unsigned short cplens[31] = { /* Copy lengths for literal codes 257..285 */
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
- 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
- /* see note #13 above about 258 */
-local const unsigned short cplext[31] = { /* Extra bits for literal codes 257..285 */
- 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
- 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
-local const unsigned short cpdist[30] = { /* Copy offsets for distance codes 0..29 */
- 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
- 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
- 8193, 12289, 16385, 24577};
-local const unsigned short cpdext[30] = { /* Extra bits for distance codes */
- 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
- 12, 12, 13, 13};
-
-/* build fixed tables only once--keep them here */
-local char fixed_built = 0;
-local inflate_huft fixed_mem[FIXEDH];
-local uInt fixed_bl=9;
-local uInt fixed_bd=5;
-local inflate_huft *fixed_tl;
-local inflate_huft *fixed_td;
-
-/* copy as much as possible from the sliding window to the output area */
-local void ZEXPORT inflate_flush(z)
-z_streamp z;
-{
- inflate_blocks_statef *s = &z->blocks;
- uInt n;
- Bytef *q;
-
- /* local copies of source and destination pointers */
- q = s->read;
-
-again:
- /* compute number of bytes to copy as far as end of window */
- n = (uInt)((q <= s->write ? s->write : s->end) - q);
- n = min(n, z->avail_out);
-
- /* update counters */
- z->avail_out -= n;
- //z->total_out += n;
-
- /* copy as far as end of window */
- zmemcpy(z->next_out, q, n);
- z->next_out += n;
- q += n;
-
- /* see if more to copy at beginning of window */
- if (q == s->end)
- {
- /* wrap pointers */
- q = s->window;
- if (s->write == s->end)
- s->write = s->window;
-
- /* do the same for the beginning of the window */
- goto again;
- }
-
- /* update pointers */
- s->read = q;
-}
-
-#define BMAX 15 /* maximum bit length of any code */
-
-local int ZEXPORT huft_build(
-uIntf *b, /* code lengths in bits (all assumed <= BMAX) */
-uInt n, /* number of codes (assumed <= 288) */
-uInt s, /* number of simple-valued codes (0..s-1) */
-const unsigned short *d, /* list of base values for non-simple codes */
-const unsigned short *e, /* list of extra bits for non-simple codes */
-inflate_huft * FAR *t, /* result: starting table */
-uIntf *m, /* maximum lookup bits, returns actual */
-inflate_huft *hp, /* space for trees */
-uInt *hn) /* working area: values in order of bit length */
-{
- static uIntf v[288]; /* work area for huft_build */
- uInt a; /* counter for codes of length k */
- uInt c[BMAX+1]; /* bit length count table */
- uInt f; /* i repeats in table every f entries */
- int g; /* maximum code length */
- int h; /* table level */
- uInt i; /* counter, current code */
- uInt j; /* counter */
- int k; /* number of bits in current code */
- int l; /* bits per table (returned in m) */
- uIntf *p; /* pointer into c[], b[], or v[] */
- inflate_huft *q; /* points to current table */
- struct inflate_huft_s r; /* table entry for structure assignment */
- inflate_huft *u[BMAX]; /* table stack */
- int w; /* bits before this table == (l * h) */
- uInt x[BMAX+1]; /* bit offsets, then code stack */
- uIntf *xp; /* pointer into x */
- int y; /* number of dummy codes added */
- uInt z; /* number of entries in current table */
-
-
- /* Generate counts for each bit length */
- p=c;
- y=16; while (y--) *p++ = 0;
- p = b;
- i = n;
- do {
- c[*p++]++; /* assume all entries <= BMAX */
- } while (--i);
- if (c[0] == n) /* null input--all zero length codes */
- {
- *t = (inflate_huft *)Z_NULL;
- *m = 0;
- return Z_OK;
- }
-
-
- /* Find minimum and maximum length, bound *m by those */
- l = *m;
- for (j = 1; j <= BMAX; j++)
- if (c[j])
- break;
- k = j; /* minimum code length */
- if ((uInt)l < j)
- l = j;
- for (i = BMAX; i; i--)
- if (c[i])
- break;
- g = i; /* maximum code length */
- if ((uInt)l > i)
- l = i;
- *m = l;
-
-
- /* Adjust last length count to fill out codes, if needed */
- for (y = 1 << j; j < i; j++, y <<= 1)
- if ((y -= c[j]) < 0)
- return Z_DATA_ERROR;
- if ((y -= c[i]) < 0)
- return Z_DATA_ERROR;
- c[i] += y;
-
-
- /* Generate starting offsets into the value table for each length */
- x[1] = j = 0;
- p = c + 1; xp = x + 2;
- while (--i) { /* note that i == g from above */
- *xp++ = (j += *p++);
- }
-
-
- /* Make a table of values in order of bit lengths */
- p = b; i = 0;
- do {
- if ((j = *p++) != 0)
- v[x[j]++] = i;
- } while (++i < n);
- n = x[g]; /* set n to length of v */
-
-
- /* Generate the Huffman codes and for each, make the table entries */
- x[0] = i = 0; /* first Huffman code is zero */
- p = v; /* grab values in bit order */
- h = -1; /* no tables yet--level -1 */
- w = -l; /* bits decoded == (l * h) */
- u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
- q = (inflate_huft *)Z_NULL; /* ditto */
- z = 0; /* ditto */
-
- /* go through the bit lengths (k already is bits in shortest code) */
- for (; k <= g; k++)
- {
- a = c[k];
- while (a--)
- {
- int nextw=w;
- /* here i is the Huffman code of length k bits for value *p */
- /* make tables up to required level */
- while (k > (nextw=w + l))
- {
- h++;
-
- /* compute minimum size table less than or equal to l bits */
- z = g - nextw;
- z = z > (uInt)l ? l : z; /* table size upper limit */
- if ((f = 1 << (j = k - nextw)) > a + 1) /* try a k-w bit table */
- { /* too few codes for k-w bit table */
- f -= a + 1; /* deduct codes from patterns left */
- xp = c + k;
- if (j < z)
- while (++j < z && (f <<= 1) > *++xp) /* try smaller tables up to z bits */
- {
- f -= *xp; /* else deduct codes from patterns */
- }
- }
- z = 1 << j; /* table entries for j-bit table */
-
- /* allocate new table */
- if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
- return Z_MEM_ERROR; /* not enough memory */
- u[h] = q = hp + *hn;
- *hn += z;
-
- /* connect to last table, if there is one */
- if (h)
- {
- x[h] = i; /* save pattern for backing up */
- r.bits = (Byte)l; /* bits to dump before this table */
- r.exop = (Byte)j; /* bits in this table */
- j = i >> w;
- r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
- u[h-1][j] = r; /* connect to last table */
- }
- else
- *t = q; /* first table is returned result */
- w=nextw; /* previous table always l bits */
- }
-
- /* set up table entry in r */
- r.bits = (Byte)(k - w);
- if (p >= v + n)
- r.exop = 128 + 64; /* out of values--invalid code */
- else if (*p < s)
- {
- r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
- r.base = *p++; /* simple code is just the value */
- }
- else
- {
- r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
- r.base = d[*p++ - s];
- }
-
- /* fill code-like entries with r */
- f = 1 << (k - w);
- for (j = i >> w; j < z; j += f)
- q[j] = r;
-
- /* backwards increment the k-bit code i */
- for (j = 1 << (k - 1); i & j; j >>= 1)
- i ^= j;
- i ^= j;
-
- /* backup over finished tables */
- while ((i & ((1 << w) - 1)) != x[h])
- {
- h--; /* don't need to update q */
- w -= l;
- }
- }
- }
-
-
- /* Return Z_BUF_ERROR if we were given an incomplete table */
- return (y != 0 && g != 1) ? Z_BUF_ERROR : Z_OK;
-}
-
-int ZEXPORT inflate(z_streamp z)
-{
- inflate_blocks_statef *s = &z->blocks;
- inflate_codes_statef *c = &s->sub.decode.t_codes; /* codes state */
-
- // lousy two bytes saved by doing this
- struct
- {
- uInt t; /* temporary storage */
- uLong b; /* bit buffer */
- uInt k; /* bits in bit buffer */
- Bytef *p; /* input data pointer */
- uInt n; /* bytes available there */
- Bytef *q; /* output window write pointer */
- uInt m; /* bytes to end of window or read pointer */
-
- /* CODES variables */
-
- inflate_huft *j; /* temporary pointer */
- uInt e; /* extra bits or operation */
- Bytef *f; /* pointer to copy strings from */
- } _state;
-
-#define t _state.t
-#define b _state.b
-#define k _state.k
-#define p _state.p
-#define n _state.n
-#define q _state.q
-#define m _state.m
-
- /* copy input/output information to locals (UPDATE macro restores) */
- LOAD
-
- /* process input based on current state */
- for (;;) switch (s->mode)
- {
- case TYPE:
- NEEDBITS(3)
- t = (uInt)b & 7;
- DUMPBITS(3)
- s->last = (t & 1) ? DRY : TYPE;
- switch (t >> 1)
- {
- case 0: /* stored */
- Tracev((stderr, "inflate: stored block%s\n",
- LAST ? " (last)" : ""));
- DUMPBITS(k&7)
- s->mode = LENS; /* get length of stored block */
- break;
- case 1: /* fixed */
- Tracev((stderr, "inflate: fixed codes block%s\n",
- LAST ? " (last)" : ""));
- {
- if (!fixed_built)
- {
- int _k; /* temporary variable */
- uInt f = 0; /* number of hufts used in fixed_mem */
- static uIntf c[288]; /* length list for huft_build */
-
- /* literal table */
- for (_k = 0; _k < 288; _k++)
- {
- char v=8;
- if (_k > 143)
- {
- if (_k < 256) v++;
- else if (_k < 280) v--;
- }
- c[_k] = v;
- }
-
- huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, fixed_mem, &f);
-
- /* distance table */
- for (_k = 0; _k < 30; _k++) c[_k] = 5;
-
- huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, fixed_mem, &f);
-
- /* done */
- fixed_built++;
- }
-
- //s->sub.decode.t_codes.mode = CODES_START;
- s->sub.decode.t_codes.lbits = (Byte)fixed_bl;
- s->sub.decode.t_codes.dbits = (Byte)fixed_bd;
- s->sub.decode.t_codes.ltree = fixed_tl;
- s->sub.decode.t_codes.dtree = fixed_td;
- }
- s->mode = CODES_START;
- break;
- case 2: /* dynamic */
- Tracev((stderr, "inflate: dynamic codes block%s\n",
- LAST ? " (last)" : ""));
- s->mode = TABLE;
- break;
- case 3: /* illegal */
- /* the only illegal value possible is 3 because we check only 2 bits */
- goto bad;
- }
- break;
- case LENS:
- NEEDBITS(16)
- s->sub.left = (uInt)b & 0xffff;
- b = k = 0; /* dump bits */
- Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
- s->mode = s->sub.left ? STORED : s->last;
- break;
- case STORED:
- {
- uInt mn;
-
- if (n == 0)
- LEAVE(Z_OK)
- NEEDOUT
- mn = min(m, n);
- t = min(s->sub.left, mn);
- zmemcpy(q, p, t);
- p += t; n -= t;
- q += t; m -= t;
- if (!(s->sub.left -= t))
- s->mode = s->last;
- break;
- }
- case TABLE:
- NEEDBITS(14)
- s->sub.trees.table = t = (uInt)b & 0x3fff;
- if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
- {
- s->mode = BAD;
- LEAVE(Z_DATA_ERROR);
- }
- //t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
- DUMPBITS(14)
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: table sizes ok\n"));
- s->mode = BTREE;
- case BTREE:
- while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
- {
- NEEDBITS(3)
- s->sub.trees.t_blens[(int)border[s->sub.trees.index++]] = (uInt)b & 7;
- DUMPBITS(3)
- }
- while (s->sub.trees.index < 19)
- s->sub.trees.t_blens[(int)border[s->sub.trees.index++]] = 0;
- s->sub.trees.bb = 7;
-
- {
- uInt hn = 0; /* hufts used in space */
-
- t = huft_build(s->sub.trees.t_blens, 19, 19, (short *)Z_NULL, (short*)Z_NULL,
- &s->sub.trees.tb, &s->sub.trees.bb, s->hufts, &hn);
- if (t != Z_OK || !s->sub.trees.bb)
- {
- s->mode = BAD;
- break;
- }
- }
-
- s->sub.trees.index = 0;
- Tracev((stderr, "inflate: bits tree ok\n"));
- s->mode = DTREE;
- case DTREE:
- while (t = s->sub.trees.table,
- s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
- {
- inflate_huft *h;
- uInt i, j, c;
-
- t = s->sub.trees.bb;
- NEEDBITS(t)
- h = s->sub.trees.tb + ((uInt)b & (uInt)inflate_mask[t]);
- t = h->bits;
- c = h->base;
- if (c < 16)
- {
- DUMPBITS(t)
- s->sub.trees.t_blens[s->sub.trees.index++] = c;
- }
- else /* c == 16..18 */
- {
- if (c == 18)
- {
- i=7;
- j=11;
- }
- else
- {
- i=c-14;
- j=3;
- }
- NEEDBITS(t+i)
- DUMPBITS(t)
- j += (uInt)b & (uInt)inflate_mask[i];
- DUMPBITS(i)
- i = s->sub.trees.index;
- t = s->sub.trees.table;
- if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
- (c == 16 && i < 1))
- {
- s->mode = BAD;
- LEAVE(Z_DATA_ERROR);
- }
- c = c == 16 ? s->sub.trees.t_blens[i - 1] : 0;
- do {
- s->sub.trees.t_blens[i++] = c;
- } while (--j);
- s->sub.trees.index = i;
- }
- }
- s->sub.trees.tb = Z_NULL;
- {
- uInt hn = 0; /* hufts used in space */
- uInt bl, bd;
- inflate_huft *tl, *td;
- int nl,nd;
- t = s->sub.trees.table;
-
- nl = 257 + (t & 0x1f);
- nd = 1 + ((t >> 5) & 0x1f);
- bl = 9; /* must be <= 9 for lookahead assumptions */
- bd = 6; /* must be <= 9 for lookahead assumptions */
-
- t = huft_build(s->sub.trees.t_blens, nl, 257, cplens, cplext, &tl, &bl, s->hufts, &hn);
- if (bl == 0) t = Z_DATA_ERROR;
- if (t == Z_OK)
- {
- /* build distance tree */
- t = huft_build(s->sub.trees.t_blens + nl, nd, 0, cpdist, cpdext, &td, &bd, s->hufts, &hn);
- }
- if (t != Z_OK || (bd == 0 && nl > 257))
- {
- s->mode = BAD;
- LEAVE(Z_DATA_ERROR);
- }
- Tracev((stderr, "inflate: trees ok\n"));
-
- //s->sub.decode.t_codes.mode = CODES_START;
- s->sub.decode.t_codes.lbits = (Byte)bl;
- s->sub.decode.t_codes.dbits = (Byte)bd;
- s->sub.decode.t_codes.ltree = tl;
- s->sub.decode.t_codes.dtree = td;
- }
- s->mode = CODES_START;
-
-#define j (_state.j)
-#define e (_state.e)
-#define f (_state.f)
-
- /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-
- case CODES_START: /* x: set up for LEN */
- c->sub.code.need = c->lbits;
- c->sub.code.tree = c->ltree;
- s->mode = CODES_LEN;
- case CODES_LEN: /* i: get length/literal/eob next */
- t = c->sub.code.need;
- NEEDBITS(t)
- j = c->sub.code.tree + ((uInt)b & (uInt)inflate_mask[t]);
- DUMPBITS(j->bits)
- e = (uInt)(j->exop);
- if (e == 0) /* literal */
- {
- c->sub.lit = j->base;
- s->mode = CODES_LIT;
- break;
- }
- if (e & 16) /* length */
- {
- c->sub.copy.get = e & 15;
- c->len = j->base;
- s->mode = CODES_LENEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = j + j->base;
- break;
- }
- if (e & 32) /* end of block */
- {
- s->mode = CODES_WASH;
- break;
- }
- goto bad;
- case CODES_LENEXT: /* i: getting length extra (have base) */
- t = c->sub.copy.get;
- NEEDBITS(t)
- c->len += (uInt)b & (uInt)inflate_mask[t];
- DUMPBITS(t)
- c->sub.code.need = c->dbits;
- c->sub.code.tree = c->dtree;
- s->mode = CODES_DIST;
- case CODES_DIST: /* i: get distance next */
- t = c->sub.code.need;
- NEEDBITS(t)
- j = c->sub.code.tree + ((uInt)b & (uInt)inflate_mask[t]);
- DUMPBITS(j->bits)
- e = (uInt)(j->exop);
- if (e & 16) /* distance */
- {
- c->sub.copy.get = e & 15;
- c->sub.copy.dist = j->base;
- s->mode = CODES_DISTEXT;
- break;
- }
- if ((e & 64) == 0) /* next table */
- {
- c->sub.code.need = e;
- c->sub.code.tree = j + j->base;
- break;
- }
- goto bad; /* invalid code */
- case CODES_DISTEXT: /* i: getting distance extra */
- t = c->sub.copy.get;
- NEEDBITS(t)
- c->sub.copy.dist += (uInt)b & (uInt)inflate_mask[t];
- DUMPBITS(t)
- s->mode = CODES_COPY;
- case CODES_COPY: /* o: copying bytes in window, waiting for space */
- f = (uInt)(q - s->window) < c->sub.copy.dist ?
- s->end - (c->sub.copy.dist - (q - s->window)) :
- q - c->sub.copy.dist;
-
- while (c->len)
- {
- NEEDOUT
- OUTBYTE(*f++)
- if (f == s->end)
- f = s->window;
- c->len--;
- }
- s->mode = CODES_START;
- break;
- case CODES_LIT: /* o: got literal, waiting for output space */
- NEEDOUT
- OUTBYTE(c->sub.lit)
- s->mode = CODES_START;
- break;
- case CODES_WASH: /* o: got eob, possibly more output */
- if (k > 7) /* return unused byte, if any */
- {
- k -= 8;
- n++;
- p--; /* can always return one */
- }
- /* flushing will be done in DRY */
-
-#undef j
-#undef e
-#undef f
-
- case DRY:
- FLUSH
- if (s->write != s->read)
- LEAVE(Z_OK)
- if (s->mode == CODES_WASH)
- {
- Tracev((stderr, "inflate: codes end, %lu total out\n",
- z->total_out + (q >= s->read ? q - s->read :
- (s->end - s->read) + (q - s->window))));
- }
- /* DRY if last, TYPE if not */
- s->mode = s->last;
- if (s->mode == TYPE)
- break;
- LEAVE(Z_STREAM_END)
- //case BAD:
- //r = Z_DATA_ERROR;
- //LEAVE
- default: // we'll call Z_STREAM_ERROR if BAD anyway
- bad:
- s->mode = BAD;
- LEAVE(Z_STREAM_ERROR)
- }
-}
-
-#undef t
-#undef b
-#undef k
-#undef p
-#undef n
-#undef q
-#undef m
+/*
+ * This file is a part of the zlib compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.zlib.net/
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+#include "../Platform.h"
+#include "../exehead/config.h"
+
+#include "ZUTIL.H"
+
+#ifndef min
+# define min(x,y) ((x<y)?x:y)
+#endif
+
+/* defines for inflate input/output */
+/* update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE(r) {UPDATE inflate_flush(z); return r;}
+
+/* get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+
+
+#define NEEDBYTE {if(!n)LEAVE(Z_OK)}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
+/* output bytes */
+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
+#define FLUSH {UPDOUT inflate_flush(z); LOADOUT}
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE(Z_OK)}}}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/* load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+#define LAST (s->last == DRY)
+
+#define FIXEDH 544 /* number of hufts used by fixed tables */
+
+
+
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* And'ing with mask[n] masks the lower n bits */
+local unsigned short inflate_mask[17] = {
+ 0x0000,
+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+}; // use to reduce .data #define INFLATE_MASK(x, n) (x & (~((unsigned short) 0xFFFF << n)))
+local const char border[] = { /* Order of the bit length code lengths */
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local const unsigned short cplens[31] = { /* Copy lengths for literal codes 257..285 */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ /* see note #13 above about 258 */
+local const unsigned short cplext[31] = { /* Extra bits for literal codes 257..285 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
+local const unsigned short cpdist[30] = { /* Copy offsets for distance codes 0..29 */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577};
+local const unsigned short cpdext[30] = { /* Extra bits for distance codes */
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+ 12, 12, 13, 13};
+
+/* build fixed tables only once--keep them here */
+local char fixed_built = 0;
+local inflate_huft fixed_mem[FIXEDH];
+local uInt fixed_bl=9;
+local uInt fixed_bd=5;
+local inflate_huft *fixed_tl;
+local inflate_huft *fixed_td;
+
+/* copy as much as possible from the sliding window to the output area */
+local void ZEXPORT inflate_flush(z)
+z_streamp z;
+{
+ inflate_blocks_statef *s = &z->blocks;
+ uInt n;
+ Bytef *q;
+
+ /* local copies of source and destination pointers */
+ q = s->read;
+
+again:
+ /* compute number of bytes to copy as far as end of window */
+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
+ n = min(n, z->avail_out);
+
+ /* update counters */
+ z->avail_out -= n;
+ //z->total_out += n;
+
+ /* copy as far as end of window */
+ zmemcpy(z->next_out, q, n);
+ z->next_out += n;
+ q += n;
+
+ /* see if more to copy at beginning of window */
+ if (q == s->end)
+ {
+ /* wrap pointers */
+ q = s->window;
+ if (s->write == s->end)
+ s->write = s->window;
+
+ /* do the same for the beginning of the window */
+ goto again;
+ }
+
+ /* update pointers */
+ s->read = q;
+}
+
+#define BMAX 15 /* maximum bit length of any code */
+
+local int ZEXPORT huft_build(
+uIntf *b, /* code lengths in bits (all assumed <= BMAX) */
+uInt n, /* number of codes (assumed <= 288) */
+uInt s, /* number of simple-valued codes (0..s-1) */
+const unsigned short *d, /* list of base values for non-simple codes */
+const unsigned short *e, /* list of extra bits for non-simple codes */
+inflate_huft * FAR *t, /* result: starting table */
+uIntf *m, /* maximum lookup bits, returns actual */
+inflate_huft *hp, /* space for trees */
+uInt *hn) /* working area: values in order of bit length */
+{
+ static uIntf v[288]; /* work area for huft_build */
+ uInt a; /* counter for codes of length k */
+ uInt c[BMAX+1]; /* bit length count table */
+ uInt f; /* i repeats in table every f entries */
+ int g; /* maximum code length */
+ int h; /* table level */
+ uInt i; /* counter, current code */
+ uInt j; /* counter */
+ int k; /* number of bits in current code */
+ int l; /* bits per table (returned in m) */
+ uIntf *p; /* pointer into c[], b[], or v[] */
+ inflate_huft *q; /* points to current table */
+ struct inflate_huft_s r; /* table entry for structure assignment */
+ inflate_huft *u[BMAX]; /* table stack */
+ int w; /* bits before this table == (l * h) */
+ uInt x[BMAX+1]; /* bit offsets, then code stack */
+ uIntf *xp; /* pointer into x */
+ int y; /* number of dummy codes added */
+ uInt z; /* number of entries in current table */
+
+
+ /* Generate counts for each bit length */
+ p=c;
+ y=16; while (y--) *p++ = 0;
+ p = b;
+ i = n;
+ do {
+ c[*p++]++; /* assume all entries <= BMAX */
+ } while (--i);
+ if (c[0] == n) /* null input--all zero length codes */
+ {
+ *t = (inflate_huft *)Z_NULL;
+ *m = 0;
+ return Z_OK;
+ }
+
+
+ /* Find minimum and maximum length, bound *m by those */
+ l = *m;
+ for (j = 1; j <= BMAX; j++)
+ if (c[j])
+ break;
+ k = j; /* minimum code length */
+ if ((uInt)l < j)
+ l = j;
+ for (i = BMAX; i; i--)
+ if (c[i])
+ break;
+ g = i; /* maximum code length */
+ if ((uInt)l > i)
+ l = i;
+ *m = l;
+
+
+ /* Adjust last length count to fill out codes, if needed */
+ for (y = 1 << j; j < i; j++, y <<= 1)
+ if ((y -= c[j]) < 0)
+ return Z_DATA_ERROR;
+ if ((y -= c[i]) < 0)
+ return Z_DATA_ERROR;
+ c[i] += y;
+
+
+ /* Generate starting offsets into the value table for each length */
+ x[1] = j = 0;
+ p = c + 1; xp = x + 2;
+ while (--i) { /* note that i == g from above */
+ *xp++ = (j += *p++);
+ }
+
+
+ /* Make a table of values in order of bit lengths */
+ p = b; i = 0;
+ do {
+ if ((j = *p++) != 0)
+ v[x[j]++] = i;
+ } while (++i < n);
+ n = x[g]; /* set n to length of v */
+
+
+ /* Generate the Huffman codes and for each, make the table entries */
+ x[0] = i = 0; /* first Huffman code is zero */
+ p = v; /* grab values in bit order */
+ h = -1; /* no tables yet--level -1 */
+ w = -l; /* bits decoded == (l * h) */
+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
+ q = (inflate_huft *)Z_NULL; /* ditto */
+ z = 0; /* ditto */
+
+ /* go through the bit lengths (k already is bits in shortest code) */
+ for (; k <= g; k++)
+ {
+ a = c[k];
+ while (a--)
+ {
+ int nextw=w;
+ /* here i is the Huffman code of length k bits for value *p */
+ /* make tables up to required level */
+ while (k > (nextw=w + l))
+ {
+ h++;
+
+ /* compute minimum size table less than or equal to l bits */
+ z = g - nextw;
+ z = z > (uInt)l ? l : z; /* table size upper limit */
+ if ((f = 1 << (j = k - nextw)) > a + 1) /* try a k-w bit table */
+ { /* too few codes for k-w bit table */
+ f -= a + 1; /* deduct codes from patterns left */
+ xp = c + k;
+ if (j < z)
+ while (++j < z && (f <<= 1) > *++xp) /* try smaller tables up to z bits */
+ {
+ f -= *xp; /* else deduct codes from patterns */
+ }
+ }
+ z = 1 << j; /* table entries for j-bit table */
+
+ /* allocate new table */
+ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
+ return Z_MEM_ERROR; /* not enough memory */
+ u[h] = q = hp + *hn;
+ *hn += z;
+
+ /* connect to last table, if there is one */
+ if (h)
+ {
+ x[h] = i; /* save pattern for backing up */
+ r.bits = (Byte)l; /* bits to dump before this table */
+ r.exop = (Byte)j; /* bits in this table */
+ j = i >> w;
+ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
+ u[h-1][j] = r; /* connect to last table */
+ }
+ else
+ *t = q; /* first table is returned result */
+ w=nextw; /* previous table always l bits */
+ }
+
+ /* set up table entry in r */
+ r.bits = (Byte)(k - w);
+ if (p >= v + n)
+ r.exop = 128 + 64; /* out of values--invalid code */
+ else if (*p < s)
+ {
+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
+ r.base = *p++; /* simple code is just the value */
+ }
+ else
+ {
+ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
+ r.base = d[*p++ - s];
+ }
+
+ /* fill code-like entries with r */
+ f = 1 << (k - w);
+ for (j = i >> w; j < z; j += f)
+ q[j] = r;
+
+ /* backwards increment the k-bit code i */
+ for (j = 1 << (k - 1); i & j; j >>= 1)
+ i ^= j;
+ i ^= j;
+
+ /* backup over finished tables */
+ while ((i & ((1 << w) - 1)) != x[h])
+ {
+ h--; /* don't need to update q */
+ w -= l;
+ }
+ }
+ }
+
+
+ /* Return Z_BUF_ERROR if we were given an incomplete table */
+ return (y != 0 && g != 1) ? Z_BUF_ERROR : Z_OK;
+}
+
+int ZEXPORT inflate(z_streamp z)
+{
+ inflate_blocks_statef *s = &z->blocks;
+ inflate_codes_statef *c = &s->sub.decode.t_codes; /* codes state */
+
+ // lousy two bytes saved by doing this
+ struct
+ {
+ uInt t; /* temporary storage */
+ uLong b; /* bit buffer */
+ uInt k; /* bits in bit buffer */
+ Bytef *p; /* input data pointer */
+ uInt n; /* bytes available there */
+ Bytef *q; /* output window write pointer */
+ uInt m; /* bytes to end of window or read pointer */
+
+ /* CODES variables */
+
+ inflate_huft *j; /* temporary pointer */
+ uInt e; /* extra bits or operation */
+ Bytef *f; /* pointer to copy strings from */
+ } _state;
+
+#define t _state.t
+#define b _state.b
+#define k _state.k
+#define p _state.p
+#define n _state.n
+#define q _state.q
+#define m _state.m
+
+ /* copy input/output information to locals (UPDATE macro restores) */
+ LOAD
+
+ /* process input based on current state */
+ for (;;) switch (s->mode)
+ {
+ case TYPE:
+ NEEDBITS(3)
+ t = (uInt)b & 7;
+ DUMPBITS(3)
+ s->last = (t & 1) ? DRY : TYPE;
+ switch (t >> 1)
+ {
+ case 0: /* stored */
+ Tracev((stderr, "inflate: stored block%s\n",
+ LAST ? " (last)" : ""));
+ DUMPBITS(k&7)
+ s->mode = LENS; /* get length of stored block */
+ break;
+ case 1: /* fixed */
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ LAST ? " (last)" : ""));
+ {
+ if (!fixed_built)
+ {
+ int _k; /* temporary variable */
+ uInt f = 0; /* number of hufts used in fixed_mem */
+ static uIntf c[288]; /* length list for huft_build */
+
+ /* literal table */
+ for (_k = 0; _k < 288; _k++)
+ {
+ char v=8;
+ if (_k > 143)
+ {
+ if (_k < 256) v++;
+ else if (_k < 280) v--;
+ }
+ c[_k] = v;
+ }
+
+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, fixed_mem, &f);
+
+ /* distance table */
+ for (_k = 0; _k < 30; _k++) c[_k] = 5;
+
+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, fixed_mem, &f);
+
+ /* done */
+ fixed_built++;
+ }
+
+ //s->sub.decode.t_codes.mode = CODES_START;
+ s->sub.decode.t_codes.lbits = (Byte)fixed_bl;
+ s->sub.decode.t_codes.dbits = (Byte)fixed_bd;
+ s->sub.decode.t_codes.ltree = fixed_tl;
+ s->sub.decode.t_codes.dtree = fixed_td;
+ }
+ s->mode = CODES_START;
+ break;
+ case 2: /* dynamic */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ LAST ? " (last)" : ""));
+ s->mode = TABLE;
+ break;
+ case 3: /* illegal */
+ /* the only illegal value possible is 3 because we check only 2 bits */
+ goto bad;
+ }
+ break;
+ case LENS:
+ NEEDBITS(16)
+ s->sub.left = (uInt)b & 0xffff;
+ b = k = 0; /* dump bits */
+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
+ s->mode = s->sub.left ? STORED : s->last;
+ break;
+ case STORED:
+ {
+ uInt mn;
+
+ if (n == 0)
+ LEAVE(Z_OK)
+ NEEDOUT
+ mn = min(m, n);
+ t = min(s->sub.left, mn);
+ zmemcpy(q, p, t);
+ p += t; n -= t;
+ q += t; m -= t;
+ if (!(s->sub.left -= t))
+ s->mode = s->last;
+ break;
+ }
+ case TABLE:
+ NEEDBITS(14)
+ s->sub.trees.table = t = (uInt)b & 0x3fff;
+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+ {
+ s->mode = BAD;
+ LEAVE(Z_DATA_ERROR);
+ }
+ //t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+ DUMPBITS(14)
+ s->sub.trees.index = 0;
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ s->mode = BTREE;
+ case BTREE:
+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+ {
+ NEEDBITS(3)
+ s->sub.trees.t_blens[(int)border[s->sub.trees.index++]] = (uInt)b & 7;
+ DUMPBITS(3)
+ }
+ while (s->sub.trees.index < 19)
+ s->sub.trees.t_blens[(int)border[s->sub.trees.index++]] = 0;
+ s->sub.trees.bb = 7;
+
+ {
+ uInt hn = 0; /* hufts used in space */
+
+ t = huft_build(s->sub.trees.t_blens, 19, 19, (short *)Z_NULL, (short*)Z_NULL,
+ &s->sub.trees.tb, &s->sub.trees.bb, s->hufts, &hn);
+ if (t != Z_OK || !s->sub.trees.bb)
+ {
+ s->mode = BAD;
+ break;
+ }
+ }
+
+ s->sub.trees.index = 0;
+ Tracev((stderr, "inflate: bits tree ok\n"));
+ s->mode = DTREE;
+ case DTREE:
+ while (t = s->sub.trees.table,
+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+ {
+ inflate_huft *h;
+ uInt i, j, c;
+
+ t = s->sub.trees.bb;
+ NEEDBITS(t)
+ h = s->sub.trees.tb + ((uInt)b & (uInt)inflate_mask[t]);
+ t = h->bits;
+ c = h->base;
+ if (c < 16)
+ {
+ DUMPBITS(t)
+ s->sub.trees.t_blens[s->sub.trees.index++] = c;
+ }
+ else /* c == 16..18 */
+ {
+ if (c == 18)
+ {
+ i=7;
+ j=11;
+ }
+ else
+ {
+ i=c-14;
+ j=3;
+ }
+ NEEDBITS(t+i)
+ DUMPBITS(t)
+ j += (uInt)b & (uInt)inflate_mask[i];
+ DUMPBITS(i)
+ i = s->sub.trees.index;
+ t = s->sub.trees.table;
+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+ (c == 16 && i < 1))
+ {
+ s->mode = BAD;
+ LEAVE(Z_DATA_ERROR);
+ }
+ c = c == 16 ? s->sub.trees.t_blens[i - 1] : 0;
+ do {
+ s->sub.trees.t_blens[i++] = c;
+ } while (--j);
+ s->sub.trees.index = i;
+ }
+ }
+ s->sub.trees.tb = Z_NULL;
+ {
+ uInt hn = 0; /* hufts used in space */
+ uInt bl, bd;
+ inflate_huft *tl, *td;
+ int nl,nd;
+ t = s->sub.trees.table;
+
+ nl = 257 + (t & 0x1f);
+ nd = 1 + ((t >> 5) & 0x1f);
+ bl = 9; /* must be <= 9 for lookahead assumptions */
+ bd = 6; /* must be <= 9 for lookahead assumptions */
+
+ t = huft_build(s->sub.trees.t_blens, nl, 257, cplens, cplext, &tl, &bl, s->hufts, &hn);
+ if (bl == 0) t = Z_DATA_ERROR;
+ if (t == Z_OK)
+ {
+ /* build distance tree */
+ t = huft_build(s->sub.trees.t_blens + nl, nd, 0, cpdist, cpdext, &td, &bd, s->hufts, &hn);
+ }
+ if (t != Z_OK || (bd == 0 && nl > 257))
+ {
+ s->mode = BAD;
+ LEAVE(Z_DATA_ERROR);
+ }
+ Tracev((stderr, "inflate: trees ok\n"));
+
+ //s->sub.decode.t_codes.mode = CODES_START;
+ s->sub.decode.t_codes.lbits = (Byte)bl;
+ s->sub.decode.t_codes.dbits = (Byte)bd;
+ s->sub.decode.t_codes.ltree = tl;
+ s->sub.decode.t_codes.dtree = td;
+ }
+ s->mode = CODES_START;
+
+#define j (_state.j)
+#define e (_state.e)
+#define f (_state.f)
+
+ /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+
+ case CODES_START: /* x: set up for LEN */
+ c->sub.code.need = c->lbits;
+ c->sub.code.tree = c->ltree;
+ s->mode = CODES_LEN;
+ case CODES_LEN: /* i: get length/literal/eob next */
+ t = c->sub.code.need;
+ NEEDBITS(t)
+ j = c->sub.code.tree + ((uInt)b & (uInt)inflate_mask[t]);
+ DUMPBITS(j->bits)
+ e = (uInt)(j->exop);
+ if (e == 0) /* literal */
+ {
+ c->sub.lit = j->base;
+ s->mode = CODES_LIT;
+ break;
+ }
+ if (e & 16) /* length */
+ {
+ c->sub.copy.get = e & 15;
+ c->len = j->base;
+ s->mode = CODES_LENEXT;
+ break;
+ }
+ if ((e & 64) == 0) /* next table */
+ {
+ c->sub.code.need = e;
+ c->sub.code.tree = j + j->base;
+ break;
+ }
+ if (e & 32) /* end of block */
+ {
+ s->mode = CODES_WASH;
+ break;
+ }
+ goto bad;
+ case CODES_LENEXT: /* i: getting length extra (have base) */
+ t = c->sub.copy.get;
+ NEEDBITS(t)
+ c->len += (uInt)b & (uInt)inflate_mask[t];
+ DUMPBITS(t)
+ c->sub.code.need = c->dbits;
+ c->sub.code.tree = c->dtree;
+ s->mode = CODES_DIST;
+ case CODES_DIST: /* i: get distance next */
+ t = c->sub.code.need;
+ NEEDBITS(t)
+ j = c->sub.code.tree + ((uInt)b & (uInt)inflate_mask[t]);
+ DUMPBITS(j->bits)
+ e = (uInt)(j->exop);
+ if (e & 16) /* distance */
+ {
+ c->sub.copy.get = e & 15;
+ c->sub.copy.dist = j->base;
+ s->mode = CODES_DISTEXT;
+ break;
+ }
+ if ((e & 64) == 0) /* next table */
+ {
+ c->sub.code.need = e;
+ c->sub.code.tree = j + j->base;
+ break;
+ }
+ goto bad; /* invalid code */
+ case CODES_DISTEXT: /* i: getting distance extra */
+ t = c->sub.copy.get;
+ NEEDBITS(t)
+ c->sub.copy.dist += (uInt)b & (uInt)inflate_mask[t];
+ DUMPBITS(t)
+ s->mode = CODES_COPY;
+ case CODES_COPY: /* o: copying bytes in window, waiting for space */
+ f = (uInt)(q - s->window) < c->sub.copy.dist ?
+ s->end - (c->sub.copy.dist - (q - s->window)) :
+ q - c->sub.copy.dist;
+
+ while (c->len)
+ {
+ NEEDOUT
+ OUTBYTE(*f++)
+ if (f == s->end)
+ f = s->window;
+ c->len--;
+ }
+ s->mode = CODES_START;
+ break;
+ case CODES_LIT: /* o: got literal, waiting for output space */
+ NEEDOUT
+ OUTBYTE(c->sub.lit)
+ s->mode = CODES_START;
+ break;
+ case CODES_WASH: /* o: got eob, possibly more output */
+ if (k > 7) /* return unused byte, if any */
+ {
+ k -= 8;
+ n++;
+ p--; /* can always return one */
+ }
+ /* flushing will be done in DRY */
+
+#undef j
+#undef e
+#undef f
+
+ case DRY:
+ FLUSH
+ if (s->write != s->read)
+ LEAVE(Z_OK)
+ if (s->mode == CODES_WASH)
+ {
+ Tracev((stderr, "inflate: codes end, %lu total out\n",
+ z->total_out + (q >= s->read ? q - s->read :
+ (s->end - s->read) + (q - s->window))));
+ }
+ /* DRY if last, TYPE if not */
+ s->mode = s->last;
+ if (s->mode == TYPE)
+ break;
+ LEAVE(Z_STREAM_END)
+ //case BAD:
+ //r = Z_DATA_ERROR;
+ //LEAVE
+ default: // we'll call Z_STREAM_ERROR if BAD anyway
+ bad:
+ s->mode = BAD;
+ LEAVE(Z_STREAM_ERROR)
+ }
+}
+
+#undef t
+#undef b
+#undef k
+#undef p
+#undef n
+#undef q
+#undef m
diff --git a/Source/zlib/ZCONF.H b/Source/zlib/ZCONF.H
index 6ca8fb5..d465607 100755
--- a/Source/zlib/ZCONF.H
+++ b/Source/zlib/ZCONF.H
@@ -1,71 +1,71 @@
-/*
- * This file is a part of the zlib compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.zlib.net/
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-1998 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id: ZCONF.H,v 1.3 2007/01/13 17:28:23 kichik Exp $ */
-
-#ifndef _ZCONF_H
-#define _ZCONF_H
-
-
-#define MAX_MEM_LEVEL 9
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-#define OF(args) args
-
-
-#ifndef ZEXPORT
-# define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-# define ZEXPORTVA
-#endif
-#ifndef ZEXTERN
-# define ZEXTERN extern
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-typedef unsigned char Byte; /* 8 bits */
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-typedef Byte FAR Bytef;
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-typedef void FAR *voidpf;
-typedef void *voidp;
-
-#ifndef z_off_t
-# define z_off_t long
-#endif
-
-
-#endif /* _ZCONF_H */
+/*
+ * This file is a part of the zlib compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.zlib.net/
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: ZCONF.H,v 1.2 2006/10/28 19:45:02 joostverburg Exp $ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+
+#define MAX_MEM_LEVEL 9
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+#define OF(args) args
+
+
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+typedef unsigned char Byte; /* 8 bits */
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+typedef Byte FAR Bytef;
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+typedef void FAR *voidpf;
+typedef void *voidp;
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+
+#endif /* _ZCONF_H */
diff --git a/Source/zlib/ZLIB.H b/Source/zlib/ZLIB.H
index e1ee3a4..1c983d8 100755
--- a/Source/zlib/ZLIB.H
+++ b/Source/zlib/ZLIB.H
@@ -1,297 +1,297 @@
-/*
- * This file is a part of the zlib compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.zlib.net/
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 1.1.3, July 9th, 1998
-
- Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- jloup@gzip.org madler@alumni.caltech.edu
-
-
-*/
-
-#ifndef _ZLIB_H
-#define _ZLIB_H
-
-#include "ZCONF.H"
-#include "ZUTIL.H"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifdef EXEHEAD
-
-typedef struct inflate_huft_s FAR inflate_huft;
-
-
-
-typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
- CODES_START, /* x: set up for LEN */
- CODES_LEN, /* i: get length/literal/eob next */
- CODES_LENEXT, /* i: getting length extra (have base) */
- CODES_DIST, /* i: get distance next */
- CODES_DISTEXT, /* i: getting distance extra */
- CODES_COPY, /* o: copying bytes in window, waiting for space */
- CODES_LIT, /* o: got literal, waiting for output space */
- CODES_WASH, /* o: got eob, possibly still output waiting */
- //CODES_END, /* x: got eob and all data flushed */
- //CODES_BADCODE, /* x: got error */
-
- TYPE, /* get type bits (3, including end bit) */
- LENS, /* get lengths for stored */
- STORED, /* processing stored block */
- TABLE, /* get table lengths */
- BTREE, /* get bit lengths tree for a dynamic block */
- DTREE, /* get length, distance trees for a dynamic block */
- CODES, /* processing fixed or dynamic block */
- DRY, /* output remaining window bytes */
- DONE, /* finished last block, done */
- BAD /* got a data error--stuck here */
-} inflate_mode;
-
-/* inflate codes private state */
-struct inflate_codes_state {
-
- /* mode */
- //inflate_mode mode; /* current inflate_codes mode */
-
- /* mode dependent information */
- uInt len;
- union {
- struct {
- inflate_huft *tree; /* pointer into tree */
- uInt need; /* bits needed */
- } code; /* if LEN or DIST, where in tree */
- uInt lit; /* if LIT, literal */
- struct {
- uInt get; /* bits to get for extra */
- uInt dist; /* distance back to copy from */
- } copy; /* if EXT or COPY, where and how much */
- } sub; /* submode */
-
- /* mode independent information */
- Byte lbits; /* ltree bits decoded per branch */
- Byte dbits; /* dtree bits decoder per branch */
- inflate_huft *ltree; /* literal/length/eob tree */
- inflate_huft *dtree; /* distance tree */
-
-};
-
-struct inflate_huft_s {
- union {
- struct {
- Byte Exop; /* number of extra bits or operation */
- Byte Bits; /* number of bits in this code or subcode */
- } what;
- } word;
- unsigned short base; /* literal, length base, distance base,
- or table offset */
-};
-
-#define MANY 1440
-
-typedef struct inflate_codes_state inflate_codes_statef;
-
-struct inflate_blocks_state {
-
- /* mode */
- inflate_mode mode; /* current inflate_block mode */
-
- /* mode dependent information */
- union {
- uInt left; /* if STORED, bytes left to copy */
- struct {
- uInt table; /* table lengths (14 bits) */
- uInt index; /* index into blens (or border) */
- uIntf t_blens[258+31+31]; /* bit lengths of codes */
- uInt bb; /* bit length tree depth */
- inflate_huft *tb; /* bit length decoding tree */
- } trees; /* if DTREE, decoding info for trees */
- struct {
- inflate_codes_statef t_codes;
- } decode; /* if CODES, current state */
- } sub; /* submode */
-
- uInt last; /* DRY if this block is the last block, TYPE otherwise */
-
- /* mode independent information */
- uInt bitk; /* bits in bit buffer */
- uLong bitb; /* bit buffer */
- inflate_huft hufts[MANY]; /* single malloc for tree space */
- Bytef window[1 << MAX_WBITS]; /* sliding window */
- Bytef *end; /* one byte after sliding window */
- Bytef *read; /* window read pointer */
- Bytef *write; /* window write pointer */
- uLong check; /* check on output */
-
-};
-
-
-
-#else
-struct internal_state;
-#endif
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
-#ifndef EXEHEAD
- uLong total_in; /* total nb of input bytes read so far */
-#endif
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
-#ifndef EXEHEAD
- uLong total_out; /* total nb of bytes output so far */
-#endif
-
-// char *msg; /* last error message, NULL if no error */
- //struct internal_state FAR *state; /* not visible by applications */
-#ifdef EXEHEAD
- struct inflate_blocks_state blocks; /* current inflate_blocks state */
-#else
- struct internal_state *state;
-#endif
-
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-#define Z_SYNC_FLUSH 2
-#define Z_FULL_FLUSH 3
-#define Z_FINISH 4
-/* Allowed flush values; see deflate() below for details */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_NEED_DICT 2
-#define Z_ERRNO (-1)
-
-#ifndef EXEHEAD
-
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-#define Z_VERSION_ERROR (-6)
-
-#else
-// EXEHEAD doesn't need a specific return code, just < 0
-
-#define Z_STREAM_ERROR Z_ERRNO
-#define Z_DATA_ERROR Z_ERRNO
-#define Z_MEM_ERROR Z_ERRNO
-#define Z_BUF_ERROR Z_ERRNO
-#define Z_VERSION_ERROR Z_ERRNO
-
-#endif
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION 0
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_DEFAULT_STRATEGY 0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY 0
-#define Z_ASCII 1
-#define Z_UNKNOWN 2
-/* Possible values of the data_type field */
-
-#define Z_DEFLATED 8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-
-ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
-
-ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
-
-
-#define inflateInit(x) inflateReset(x)
-int ZEXPORT inflate(z_streamp z);
-ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
-ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
- int level,
- int method,
- int windowBits,
- int memLevel,
- int strategy));
-
-
-ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
-
-//void ZEXPORT inflateReset OF((
- // z_streamp));
-#define inflateReset(z) \
-{ \
- (z)->blocks.mode = TYPE; \
- (z)->blocks.bitk = (z)->blocks.bitb = 0; \
- (z)->blocks.read = (z)->blocks.write = (z)->blocks.window; \
- (z)->blocks.end = (z)->blocks.window + (1 << DEF_WBITS); \
-}
-
- /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
- const char *version, int stream_size));
-//ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
- // const char *version, int stream_size));
-ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
- int windowBits, int memLevel,
- int strategy, const char *version,
- int stream_size));
-
-#define deflateInit(strm, level) \
- deflateInit_((strm), (level), "", sizeof(z_stream))
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ZLIB_H */
+/*
+ * This file is a part of the zlib compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.zlib.net/
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.1.3, July 9th, 1998
+
+ Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+*/
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#include "ZCONF.H"
+#include "ZUTIL.H"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef EXEHEAD
+
+typedef struct inflate_huft_s FAR inflate_huft;
+
+
+
+typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+ CODES_START, /* x: set up for LEN */
+ CODES_LEN, /* i: get length/literal/eob next */
+ CODES_LENEXT, /* i: getting length extra (have base) */
+ CODES_DIST, /* i: get distance next */
+ CODES_DISTEXT, /* i: getting distance extra */
+ CODES_COPY, /* o: copying bytes in window, waiting for space */
+ CODES_LIT, /* o: got literal, waiting for output space */
+ CODES_WASH, /* o: got eob, possibly still output waiting */
+ //CODES_END, /* x: got eob and all data flushed */
+ //CODES_BADCODE, /* x: got error */
+
+ TYPE, /* get type bits (3, including end bit) */
+ LENS, /* get lengths for stored */
+ STORED, /* processing stored block */
+ TABLE, /* get table lengths */
+ BTREE, /* get bit lengths tree for a dynamic block */
+ DTREE, /* get length, distance trees for a dynamic block */
+ CODES, /* processing fixed or dynamic block */
+ DRY, /* output remaining window bytes */
+ DONE, /* finished last block, done */
+ BAD /* got a data error--stuck here */
+} inflate_mode;
+
+/* inflate codes private state */
+struct inflate_codes_state {
+
+ /* mode */
+ //inflate_mode mode; /* current inflate_codes mode */
+
+ /* mode dependent information */
+ uInt len;
+ union {
+ struct {
+ inflate_huft *tree; /* pointer into tree */
+ uInt need; /* bits needed */
+ } code; /* if LEN or DIST, where in tree */
+ uInt lit; /* if LIT, literal */
+ struct {
+ uInt get; /* bits to get for extra */
+ uInt dist; /* distance back to copy from */
+ } copy; /* if EXT or COPY, where and how much */
+ } sub; /* submode */
+
+ /* mode independent information */
+ Byte lbits; /* ltree bits decoded per branch */
+ Byte dbits; /* dtree bits decoder per branch */
+ inflate_huft *ltree; /* literal/length/eob tree */
+ inflate_huft *dtree; /* distance tree */
+
+};
+
+struct inflate_huft_s {
+ union {
+ struct {
+ Byte Exop; /* number of extra bits or operation */
+ Byte Bits; /* number of bits in this code or subcode */
+ } what;
+ } word;
+ unsigned short base; /* literal, length base, distance base,
+ or table offset */
+};
+
+#define MANY 1440
+
+typedef struct inflate_codes_state inflate_codes_statef;
+
+struct inflate_blocks_state {
+
+ /* mode */
+ inflate_mode mode; /* current inflate_block mode */
+
+ /* mode dependent information */
+ union {
+ uInt left; /* if STORED, bytes left to copy */
+ struct {
+ uInt table; /* table lengths (14 bits) */
+ uInt index; /* index into blens (or border) */
+ uIntf t_blens[258+31+31]; /* bit lengths of codes */
+ uInt bb; /* bit length tree depth */
+ inflate_huft *tb; /* bit length decoding tree */
+ } trees; /* if DTREE, decoding info for trees */
+ struct {
+ inflate_codes_statef t_codes;
+ } decode; /* if CODES, current state */
+ } sub; /* submode */
+
+ uInt last; /* DRY if this block is the last block, TYPE otherwise */
+
+ /* mode independent information */
+ uInt bitk; /* bits in bit buffer */
+ uLong bitb; /* bit buffer */
+ inflate_huft hufts[MANY]; /* single malloc for tree space */
+ Bytef window[1 << MAX_WBITS]; /* sliding window */
+ Bytef *end; /* one byte after sliding window */
+ Bytef *read; /* window read pointer */
+ Bytef *write; /* window write pointer */
+ uLong check; /* check on output */
+
+};
+
+
+
+#else
+struct internal_state;
+#endif
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+#ifndef EXEHEAD
+ uLong total_in; /* total nb of input bytes read so far */
+#endif
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+#ifndef EXEHEAD
+ uLong total_out; /* total nb of bytes output so far */
+#endif
+
+// char *msg; /* last error message, NULL if no error */
+ //struct internal_state FAR *state; /* not visible by applications */
+#ifdef EXEHEAD
+ struct inflate_blocks_state blocks; /* current inflate_blocks state */
+#else
+ struct internal_state *state;
+#endif
+
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+/* Allowed flush values; see deflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+
+#ifndef EXEHEAD
+
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+
+#else
+// EXEHEAD doesn't need a specific return code, just < 0
+
+#define Z_STREAM_ERROR Z_ERRNO
+#define Z_DATA_ERROR Z_ERRNO
+#define Z_MEM_ERROR Z_ERRNO
+#define Z_BUF_ERROR Z_ERRNO
+#define Z_VERSION_ERROR Z_ERRNO
+
+#endif
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_ASCII 1
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+
+
+#define inflateInit(x) inflateReset(x)
+int ZEXPORT inflate(z_streamp z);
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+
+//void ZEXPORT inflateReset OF((
+ // z_streamp));
+#define inflateReset(z) \
+{ \
+ (z)->blocks.mode = TYPE; \
+ (z)->blocks.bitk = (z)->blocks.bitb = 0; \
+ (z)->blocks.read = (z)->blocks.write = (z)->blocks.window; \
+ (z)->blocks.end = (z)->blocks.window + (1 << DEF_WBITS); \
+}
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+//ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ // const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), "", sizeof(z_stream))
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZLIB_H */
diff --git a/Source/zlib/ZUTIL.H b/Source/zlib/ZUTIL.H
index 67defc5..cf27a2c 100755
--- a/Source/zlib/ZUTIL.H
+++ b/Source/zlib/ZUTIL.H
@@ -1,85 +1,85 @@
-/*
- * This file is a part of the zlib compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.zlib.net/
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-1998 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
- part of the implementation of the compression library and is
- subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id: ZUTIL.H,v 1.6 2007/01/25 18:07:40 kichik Exp $ */
-
-#ifndef _Z_UTIL_H
-#define _Z_UTIL_H
-
-#include "../Platform.h"
-#include "ZLIB.H"
-
-#ifndef local
-# define local static
-#endif
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-#ifndef DEF_WBITS
-# define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#define DEF_MEM_LEVEL MAX_MEM_LEVEL
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES 2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
-
-#ifdef EXEHEAD
-# ifdef _WIN32
-# include "../exehead/util.h"
-# define zmemcpy mini_memcpy
-# else
-# define zmemcpy memcpy
-# endif
-#else
-# define zmemcpy memcpy
-# define zmemzero(a,b) memset(a,0,b)
-#endif
-
-#define Assert(cond,msg)
-#define Trace(x)
-#define Tracev(x)
-#define Tracevv(x)
-#define Tracec(c,x)
-#define Tracecv(c,x)
-
-#define ZALLOC(strm, items, size) malloc((items)*(size))
-#define ZFREE(strm, addr) { if (addr) free(addr); }
-#define TRY_FREE(s, p) { ZFREE(s, p); }
-#define ERR_RETURN(strm,err) return (err)
-
-#endif /* _Z_UTIL_H */
+/*
+ * This file is a part of the zlib compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.zlib.net/
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id: ZUTIL.H,v 1.5 2007/01/13 17:28:23 kichik Exp $ */
+
+#ifndef _Z_UTIL_H
+#define _Z_UTIL_H
+
+#include "../Platform.h"
+#include "ZLIB.H"
+
+#ifndef local
+# define local static
+#endif
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#define DEF_MEM_LEVEL MAX_MEM_LEVEL
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+
+#ifdef EXEHEAD
+# ifdef _WIN32
+# include "../exehead/util.h"
+# define zmemcpy mini_memcpy
+# else
+# define zmemcpy memcpy
+# endif
+#else
+# define zmemcpy memcpy
+# define zmemzero(a,b) memset(a,0,b)
+#endif
+
+#define Assert(cond,msg)
+#define Trace(x)
+#define Tracev(x)
+#define Tracevv(x)
+#define Tracec(c,x)
+#define Tracecv(c,x)
+
+#define ZALLOC(strm, items, size) malloc((items)*(size))
+#define ZFREE(strm, addr) { if (addr) free(addr); }
+#define TRY_FREE(s, p) { ZFREE(s, p); }
+#define ERR_RETURN(strm,err) return (err)
+
+#endif /* _Z_UTIL_H */
diff --git a/Source/zlib/deflate.c b/Source/zlib/deflate.c
index 1b74143..6cd5bc2 100755
--- a/Source/zlib/deflate.c
+++ b/Source/zlib/deflate.c
@@ -1,857 +1,857 @@
-/*
- * This file is a part of the zlib compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.zlib.net/
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-1998 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-
-#include "DEFLATE.H"
-
-const char deflate_copyright[] =
- " deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly ";
-/*
- If you use the zlib library in a product, an acknowledgment is welcome
- in the documentation of your product. If for some reason you cannot
- include such an acknowledgment, I would appreciate that you keep this
- copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- * Function prototypes.
- */
-typedef enum {
- need_more, /* block not completed, need more input or more output */
- block_done, /* block flush performed */
- finish_started, /* finish started, need only more output at next deflate */
- finish_done /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window OF((deflate_state *s));
-local block_state deflate_slow OF((deflate_state *s, int flush));
-local void lm_init OF((deflate_state *s));
-local void putShortMSB OF((deflate_state *s, uInt b));
-local void flush_pending OF((z_streamp strm));
-local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-#ifdef ASMV
- void match_init OF((void)); /* asm code initialization */
- uInt longest_match OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match OF((deflate_state *s, IPos cur_match));
-#endif
-
-#ifdef DEBUG
-local void check_match OF((deflate_state *s, IPos start, IPos match,
- int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-# define TOO_FAR 32767 //stock is 4096, but 32767 enables slightly better compression
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-
-typedef struct config_s {
- ush good_length; /* reduce lazy search above this match length */
- ush max_lazy; /* do not perform lazy search above this match length */
- ush nice_length; /* quit search above this match length */
- ush max_chain;
- compress_func func;
-} config;
-
-local const config configuration_table =
-/* 9 */ {32, 258, 258, 16384, deflate_slow}; /* maximum compression */
-
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-#ifdef FASTEST
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#else
-#define INSERT_STRING(s, str, match_head) \
- (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
- s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
- s->head[s->ins_h] = (Pos)(str))
-#endif
-
-#define CLEAR_HASH(s) \
- s->head[s->hash_size-1] = NIL; \
- zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
- z_streamp strm;
- int level;
- const char *version;
- int stream_size;
-{
- return deflateInit2_(strm, level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
- /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- version, stream_size)
- z_streamp strm;
- int level;
- int method;
- int windowBits;
- int memLevel;
- int strategy;
- const char *version;
- int stream_size;
-{
- deflate_state *s;
- int noheader = 0;
-
- ushf *overlay;
- /* We overlay pending_buf and d_buf+l_buf. This works since the average
- * output size for (length,distance) codes is <= 24 bits.
- */
-
- if (stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
- if (strm == Z_NULL) return Z_STREAM_ERROR;
-
-
- if (windowBits < 0) { /* undocumented feature: suppress zlib header */
- noheader = 1;
- windowBits = -windowBits;
- }
- if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
- windowBits < 8 || windowBits > MAX_WBITS || level < 0 || level > 9 ||
- strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
-
- return Z_STREAM_ERROR;
- }
-
- s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
- if (s == Z_NULL) return Z_MEM_ERROR;
- strm->state = (struct internal_state FAR *)s;
- s->strm = strm;
-
- s->noheader = noheader;
- s->w_bits = windowBits;
- s->w_size = 1 << s->w_bits;
- s->w_mask = s->w_size - 1;
-
- s->hash_bits = memLevel + 7;
- s->hash_size = 1 << s->hash_bits;
- s->hash_mask = s->hash_size - 1;
- s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
- s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
- s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
- s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-
- s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
- overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
- s->pending_buf = (uchf *) overlay;
- s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
- if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
- s->pending_buf == Z_NULL) {
-// strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
- deflateEnd (strm);
- return Z_MEM_ERROR;
- }
- s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
- s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
- s->level = level;
- s->strategy = strategy;
- s->method = (Byte)method;
-
- return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
- z_streamp strm;
- const Bytef *dictionary;
- uInt dictLength;
-{
- deflate_state *s;
- uInt length = dictLength;
- uInt n;
- IPos hash_head = 0;
-
- if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
- strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
-
- s = strm->state;
-
- if (length < MIN_MATCH) return Z_OK;
- if (length > MAX_DIST(s)) {
- length = MAX_DIST(s);
-#ifndef USE_DICT_HEAD
- dictionary += dictLength - length; /* use the tail of the dictionary */
-#endif
- }
- zmemcpy(s->window, dictionary, length);
- s->strstart = length;
- s->block_start = (long)length;
-
- s->ins_h = s->window[0];
- UPDATE_HASH(s, s->ins_h, s->window[1]);
- for (n = 0; n <= length - MIN_MATCH; n++) {
- INSERT_STRING(s, n, hash_head);
- }
- if (hash_head) hash_head = 0; /* to make compiler happy */
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateReset (strm)
- z_streamp strm;
-{
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- strm->total_in = strm->total_out = 0;
-// strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
-
- s = (deflate_state *)strm->state;
- s->pending = 0;
- s->pending_out = s->pending_buf;
-
- if (s->noheader < 0) {
- s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
- }
- s->status = s->noheader ? BUSY_STATE : INIT_STATE;
- s->last_flush = Z_NO_FLUSH;
-
- _tr_init(s);
- lm_init(s);
-
- return Z_OK;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateParams(strm, level, strategy)
- z_streamp strm;
- int level;
- int strategy;
-{
- deflate_state *s;
- compress_func func;
- int err = Z_OK;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
- s = strm->state;
-
- if (level == Z_DEFAULT_COMPRESSION) {
- level = 6;
- }
- if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
- return Z_STREAM_ERROR;
- }
- func = configuration_table.func;
-
- s->level = level;
- s->max_lazy_match = configuration_table.max_lazy;
- s->good_match = configuration_table.good_length;
- s->nice_match = configuration_table.nice_length;
- s->max_chain_length = configuration_table.max_chain;
- s->strategy = strategy;
- return err;
-}
-
-local void putShortMSB (s, b)
- deflate_state *s;
- uInt b;
-{
- put_byte(s, (Byte)(b >> 8));
- put_byte(s, (Byte)(b & 0xff));
-}
-
-local void flush_pending(strm)
- z_streamp strm;
-{
- unsigned len = strm->state->pending;
-
- if (len > strm->avail_out) len = strm->avail_out;
- if (len == 0) return;
-
- zmemcpy(strm->next_out, strm->state->pending_out, len);
- strm->next_out += len;
- strm->state->pending_out += len;
- strm->total_out += len;
- strm->avail_out -= len;
- strm->state->pending -= len;
- if (strm->state->pending == 0) {
- strm->state->pending_out = strm->state->pending_buf;
- }
-}
-
-/* ========================================================================= */
-int ZEXPORT deflate (strm, flush)
- z_streamp strm;
- int flush;
-{
- int old_flush; /* value of flush param for previous deflate call */
- deflate_state *s;
-
- if (strm == Z_NULL || strm->state == Z_NULL ||
- flush > Z_FINISH || flush < 0) {
- return Z_STREAM_ERROR;
- }
- s = strm->state;
-
- if (strm->next_out == Z_NULL ||
- (strm->next_in == Z_NULL && strm->avail_in != 0) ||
- (s->status == FINISH_STATE && flush != Z_FINISH)) {
- ERR_RETURN(strm, Z_STREAM_ERROR);
- }
- if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
- s->strm = strm; /* just in case */
- old_flush = s->last_flush;
- s->last_flush = flush;
-
- /* Write the zlib header */
- if (s->status == INIT_STATE) {
-
- uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
- uInt level_flags = (s->level-1) >> 1;
-
- if (level_flags > 3) level_flags = 3;
- header |= (level_flags << 6);
- if (s->strstart != 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
-
- s->status = BUSY_STATE;
- putShortMSB(s, header);
-
- /* Save the adler32 of the preset dictionary: */
- if (s->strstart != 0) {
- //putShortMSB(s, (uInt)(strm->adler >> 16));
- //putShortMSB(s, (uInt)(strm->adler & 0xffff));
- }
- //strm->adler = 1L;
- }
-
- /* Flush as much pending output as possible */
- if (s->pending != 0) {
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1;
- return Z_OK;
- }
-
- } else if (strm->avail_in == 0 && flush <= old_flush &&
- flush != Z_FINISH) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* User must not provide more input after the first FINISH: */
- if (s->status == FINISH_STATE && strm->avail_in != 0) {
- ERR_RETURN(strm, Z_BUF_ERROR);
- }
-
- /* Start a new block or continue the current one.
- */
- if (strm->avail_in != 0 || s->lookahead != 0 ||
- (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
- block_state bstate;
-
- bstate = (*(configuration_table.func))(s, flush);
-
- if (bstate == finish_started || bstate == finish_done) {
- s->status = FINISH_STATE;
- }
- if (bstate == need_more || bstate == finish_started) {
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
- }
- return Z_OK;
- }
- if (bstate == block_done) {
- if (flush == Z_PARTIAL_FLUSH) {
- _tr_align(s);
- } else { /* FULL_FLUSH or SYNC_FLUSH */
- _tr_stored_block(s, (char*)0, 0L, 0);
- /* For a full flush, this empty block will be recognized
- * as a special marker by inflate_sync().
- */
- if (flush == Z_FULL_FLUSH) {
- CLEAR_HASH(s); /* forget history */
- }
- }
- flush_pending(strm);
- if (strm->avail_out == 0) {
- s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
- return Z_OK;
- }
- }
- }
- Assert(strm->avail_out > 0, "bug2");
-
- if (flush != Z_FINISH) return Z_OK;
- if (s->noheader) return Z_STREAM_END;
-
- flush_pending(strm);
- s->noheader = -1; /* write the trailer only once! */
- return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int ZEXPORT deflateEnd (strm)
- z_streamp strm;
-{
- int status;
-
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-
- status = strm->state->status;
- if (status != INIT_STATE && status != BUSY_STATE &&
- status != FINISH_STATE) {
- return Z_STREAM_ERROR;
- }
-
- /* Deallocate in reverse order of allocations: */
- TRY_FREE(strm, strm->state->pending_buf);
- TRY_FREE(strm, strm->state->head);
- TRY_FREE(strm, strm->state->prev);
- TRY_FREE(strm, strm->state->window);
-
- ZFREE(strm, strm->state);
- strm->state = Z_NULL;
-
- return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-
-local int read_buf(strm, buf, size)
- z_streamp strm;
- Bytef *buf;
- unsigned size;
-{
- unsigned len = strm->avail_in;
-
- if (len > size) len = size;
- if (len == 0) return 0;
-
- strm->avail_in -= len;
-
- //if (!strm->state->noheader) {
-// strm->adler = adler32(strm->adler, strm->next_in, len);
- // }
- zmemcpy(buf, strm->next_in, len);
- strm->next_in += len;
- strm->total_in += len;
-
- return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
- deflate_state *s;
-{
- s->window_size = (ulg)2L*s->w_size;
-
- CLEAR_HASH(s);
-
- /* Set the default configuration parameters:
- */
- s->max_lazy_match = configuration_table.max_lazy;
- s->good_match = configuration_table.good_length;
- s->nice_match = configuration_table.nice_length;
- s->max_chain_length = configuration_table.max_chain;
-
- s->strstart = 0;
- s->block_start = 0L;
- s->lookahead = 0;
- s->match_length = s->prev_length = MIN_MATCH-1;
- s->match_available = 0;
- s->ins_h = 0;
-#ifdef ASMV
- match_init(); /* initialize the asm code */
-#endif
-}
-
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-#ifndef FASTEST
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- unsigned chain_length = s->max_chain_length;/* max hash chain length */
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- int best_len = s->prev_length; /* best match length so far */
- int nice_match = s->nice_match; /* stop if match long enough */
- IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
- s->strstart - (IPos)MAX_DIST(s) : NIL;
- /* Stop when cur_match becomes <= limit. To simplify the code,
- * we prevent matches with the string of window index 0.
- */
- Posf *prev = s->prev;
- uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
- /* Compare two bytes at a time. Note: this is not always beneficial.
- * Try with and without -DUNALIGNED_OK to check.
- */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
- register ush scan_start = *(ushf*)scan;
- register ush scan_end = *(ushf*)(scan+best_len-1);
-#else
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
- register Byte scan_end1 = scan[best_len-1];
- register Byte scan_end = scan[best_len];
-#endif
-
- /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
- * It is easy to get rid of this optimization if necessary.
- */
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- /* Do not waste too much time if we already have a good match: */
- if (s->prev_length >= s->good_match) {
- chain_length >>= 2;
- }
- /* Do not look for matches beyond the end of the input. This is necessary
- * to make deflate deterministic.
- */
- if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- do {
- Assert(cur_match < s->strstart, "no future");
- match = s->window + cur_match;
-
- /* Skip to next match if the match length cannot increase
- * or if the match length is less than 2:
- */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
- /* This code assumes sizeof(unsigned short) == 2. Do not use
- * UNALIGNED_OK if your compiler uses a different size.
- */
- if (*(ushf*)(match+best_len-1) != scan_end ||
- *(ushf*)match != scan_start) continue;
-
- Assert(scan[2] == match[2], "scan[2]?");
- scan++, match++;
- do {
- } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
- scan < strend);
- /* The funny "do {}" generates better code on most compilers */
-
- /* Here, scan <= window+strstart+257 */
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
- if (*scan == *match) scan++;
-
- len = (MAX_MATCH - 1) - (int)(strend-scan);
- scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
- if (match[best_len] != scan_end ||
- match[best_len-1] != scan_end1 ||
- *match != *scan ||
- *++match != scan[1]) continue;
-
- scan += 2, match++;
- Assert(*scan == *match, "match[2]?");
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
- scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
- if (len > best_len) {
- s->match_start = cur_match;
- best_len = len;
- if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
- scan_end = *(ushf*)(scan+best_len-1);
-#else
- scan_end1 = scan[best_len-1];
- scan_end = scan[best_len];
-#endif
- }
- } while ((cur_match = prev[cur_match & wmask]) > limit
- && --chain_length != 0);
-
- if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
- return s->lookahead;
-}
-
-#else /* FASTEST */
-/* ---------------------------------------------------------------------------
- * Optimized version for level == 1 only
- */
-local uInt longest_match(s, cur_match)
- deflate_state *s;
- IPos cur_match; /* current match */
-{
- register Bytef *scan = s->window + s->strstart; /* current string */
- register Bytef *match; /* matched string */
- register int len; /* length of current match */
- register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-
- Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
- Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
- Assert(cur_match < s->strstart, "no future");
-
- match = s->window + cur_match;
-
- /* Return failure if the match length is less than 2:
- */
- if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
- scan += 2, match += 2;
- Assert(*scan == *match, "match[2]?");
-
- do {
- } while (*++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- *++scan == *++match && *++scan == *++match &&
- scan < strend);
-
- Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
- len = MAX_MATCH - (int)(strend - scan);
-
- if (len < MIN_MATCH) return MIN_MATCH - 1;
-
- s->match_start = cur_match;
- return len <= s->lookahead ? len : s->lookahead;
-}
-#endif /* FASTEST */
-#endif /* ASMV */
-
-# define check_match(s, start, match, length)
-
-local void fill_window(s)
- deflate_state *s;
-{
- register unsigned n, m;
- register Posf *p;
- unsigned more; /* Amount of free space at the end of the window. */
- uInt wsize = s->w_size;
-
- do {
- more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
- /* Deal with !@#$% 64K limit: */
- if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
- more = wsize;
-
- } else if (more == (unsigned)(-1)) {
- /* Very unlikely, but possible on 16 bit machine if strstart == 0
- * and lookahead == 1 (input done one byte at time)
- */
- more--;
-
- /* If the window is almost full and there is insufficient lookahead,
- * move the upper half to the lower one to make room in the upper half.
- */
- } else if (s->strstart >= wsize+MAX_DIST(s)) {
-
- zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
- s->match_start -= wsize;
- s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
- s->block_start -= (long) wsize;
-
- n = s->hash_size;
- p = &s->head[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- } while (--n);
-
- n = wsize;
-#ifndef FASTEST
- p = &s->prev[n];
- do {
- m = *--p;
- *p = (Pos)(m >= wsize ? m-wsize : NIL);
- /* If n is not on any hash chain, prev[n] is garbage but
- * its value will never be used.
- */
- } while (--n);
-#endif
- more += wsize;
- }
- if (s->strm->avail_in == 0) return;
- Assert(more >= 2, "more < 2");
-
- n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
- s->lookahead += n;
-
- /* Initialize the hash value now that we have some input: */
- if (s->lookahead >= MIN_MATCH) {
- s->ins_h = s->window[s->strstart];
- UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
-# error Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
- }
-
- } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-}
-
-#define FLUSH_BLOCK_ONLY(s, eof) { \
- _tr_flush_block(s, (s->block_start >= 0L ? \
- (charf *)&s->window[(unsigned)s->block_start] : \
- (charf *)Z_NULL), \
- (ulg)((long)s->strstart - s->block_start), \
- (eof)); \
- s->block_start = s->strstart; \
- flush_pending(s->strm); \
- Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
- FLUSH_BLOCK_ONLY(s, eof); \
- if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-}
-
-
-
-local block_state deflate_slow(s, flush)
- deflate_state *s;
- int flush;
-{
- IPos hash_head = NIL; /* head of hash chain */
- int bflush; /* set if current block must be flushed */
-
- /* Process the input block. */
- for (;;) {
- if (s->lookahead < MIN_LOOKAHEAD) {
- fill_window(s);
- if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
- return need_more;
- }
- if (s->lookahead == 0) break; /* flush the current block */
- }
- if (s->lookahead >= MIN_MATCH) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
-
- /* Find the longest match, discarding those <= prev_length.
- */
- s->prev_length = s->match_length, s->prev_match = s->match_start;
- s->match_length = MIN_MATCH-1;
-
- if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
- s->strstart - hash_head <= MAX_DIST(s)) {
- if (s->strategy != Z_HUFFMAN_ONLY) {
- s->match_length = longest_match (s, hash_head);
- }
- /* longest_match() sets match_start */
-
- if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
- (s->match_length == MIN_MATCH &&
- s->strstart - s->match_start > TOO_FAR))) {
-
- s->match_length = MIN_MATCH-1;
- }
- }
- if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
- uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
- /* Do not insert strings in hash table beyond this. */
-
- check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
- _tr_tally_dist(s, s->strstart -1 - s->prev_match,
- s->prev_length - MIN_MATCH, bflush);
-
- s->lookahead -= s->prev_length-1;
- s->prev_length -= 2;
- do {
- if (++s->strstart <= max_insert) {
- INSERT_STRING(s, s->strstart, hash_head);
- }
- } while (--s->prev_length != 0);
- s->match_available = 0;
- s->match_length = MIN_MATCH-1;
- s->strstart++;
-
- if (bflush) FLUSH_BLOCK(s, 0);
-
- } else if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- if (bflush) {
- FLUSH_BLOCK_ONLY(s, 0);
- }
- s->strstart++;
- s->lookahead--;
- if (s->strm->avail_out == 0) return need_more;
- } else {
- /* There is no previous match to compare with, wait for
- * the next step to decide.
- */
- s->match_available = 1;
- s->strstart++;
- s->lookahead--;
- }
- }
- Assert (flush != Z_NO_FLUSH, "no flush?");
- if (s->match_available) {
- Tracevv((stderr,"%c", s->window[s->strstart-1]));
- _tr_tally_lit(s, s->window[s->strstart-1], bflush);
- s->match_available = 0;
- }
- FLUSH_BLOCK(s, flush == Z_FINISH);
- return flush == Z_FINISH ? finish_done : block_done;
-}
+/*
+ * This file is a part of the zlib compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.zlib.net/
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+
+#include "DEFLATE.H"
+
+const char deflate_copyright[] =
+ " deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ * Function prototypes.
+ */
+typedef enum {
+ need_more, /* block not completed, need more input or more output */
+ block_done, /* block flush performed */
+ finish_started, /* finish started, need only more output at next deflate */
+ finish_done /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window OF((deflate_state *s));
+local block_state deflate_slow OF((deflate_state *s, int flush));
+local void lm_init OF((deflate_state *s));
+local void putShortMSB OF((deflate_state *s, uInt b));
+local void flush_pending OF((z_streamp strm));
+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+ void match_init OF((void)); /* asm code initialization */
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG
+local void check_match OF((deflate_state *s, IPos start, IPos match,
+ int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+# define TOO_FAR 32767 //stock is 4096, but 32767 enables slightly better compression
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+
+typedef struct config_s {
+ ush good_length; /* reduce lazy search above this match length */
+ ush max_lazy; /* do not perform lazy search above this match length */
+ ush nice_length; /* quit search above this match length */
+ ush max_chain;
+ compress_func func;
+} config;
+
+local const config configuration_table =
+/* 9 */ {32, 258, 258, 16384, deflate_slow}; /* maximum compression */
+
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#endif
+
+#define CLEAR_HASH(s) \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+ z_streamp strm;
+ int level;
+ const char *version;
+ int stream_size;
+{
+ return deflateInit2_(strm, level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY, version, stream_size);
+ /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+ version, stream_size)
+ z_streamp strm;
+ int level;
+ int method;
+ int windowBits;
+ int memLevel;
+ int strategy;
+ const char *version;
+ int stream_size;
+{
+ deflate_state *s;
+ int noheader = 0;
+
+ ushf *overlay;
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
+ * output size for (length,distance) codes is <= 24 bits.
+ */
+
+ if (stream_size != sizeof(z_stream)) {
+ return Z_VERSION_ERROR;
+ }
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+
+ if (windowBits < 0) { /* undocumented feature: suppress zlib header */
+ noheader = 1;
+ windowBits = -windowBits;
+ }
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+ windowBits < 8 || windowBits > MAX_WBITS || level < 0 || level > 9 ||
+ strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+
+ return Z_STREAM_ERROR;
+ }
+
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+ if (s == Z_NULL) return Z_MEM_ERROR;
+ strm->state = (struct internal_state FAR *)s;
+ s->strm = strm;
+
+ s->noheader = noheader;
+ s->w_bits = windowBits;
+ s->w_size = 1 << s->w_bits;
+ s->w_mask = s->w_size - 1;
+
+ s->hash_bits = memLevel + 7;
+ s->hash_size = 1 << s->hash_bits;
+ s->hash_mask = s->hash_size - 1;
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+ s->pending_buf = (uchf *) overlay;
+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+ s->pending_buf == Z_NULL) {
+// strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+ deflateEnd (strm);
+ return Z_MEM_ERROR;
+ }
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+ s->level = level;
+ s->strategy = strategy;
+ s->method = (Byte)method;
+
+ return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ const Bytef *dictionary;
+ uInt dictLength;
+{
+ deflate_state *s;
+ uInt length = dictLength;
+ uInt n;
+ IPos hash_head = 0;
+
+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+ strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
+
+ s = strm->state;
+
+ if (length < MIN_MATCH) return Z_OK;
+ if (length > MAX_DIST(s)) {
+ length = MAX_DIST(s);
+#ifndef USE_DICT_HEAD
+ dictionary += dictLength - length; /* use the tail of the dictionary */
+#endif
+ }
+ zmemcpy(s->window, dictionary, length);
+ s->strstart = length;
+ s->block_start = (long)length;
+
+ s->ins_h = s->window[0];
+ UPDATE_HASH(s, s->ins_h, s->window[1]);
+ for (n = 0; n <= length - MIN_MATCH; n++) {
+ INSERT_STRING(s, n, hash_head);
+ }
+ if (hash_head) hash_head = 0; /* to make compiler happy */
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->total_in = strm->total_out = 0;
+// strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+
+ s = (deflate_state *)strm->state;
+ s->pending = 0;
+ s->pending_out = s->pending_buf;
+
+ if (s->noheader < 0) {
+ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
+ }
+ s->status = s->noheader ? BUSY_STATE : INIT_STATE;
+ s->last_flush = Z_NO_FLUSH;
+
+ _tr_init(s);
+ lm_init(s);
+
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+ z_streamp strm;
+ int level;
+ int strategy;
+{
+ deflate_state *s;
+ compress_func func;
+ int err = Z_OK;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+
+ if (level == Z_DEFAULT_COMPRESSION) {
+ level = 6;
+ }
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+ return Z_STREAM_ERROR;
+ }
+ func = configuration_table.func;
+
+ s->level = level;
+ s->max_lazy_match = configuration_table.max_lazy;
+ s->good_match = configuration_table.good_length;
+ s->nice_match = configuration_table.nice_length;
+ s->max_chain_length = configuration_table.max_chain;
+ s->strategy = strategy;
+ return err;
+}
+
+local void putShortMSB (s, b)
+ deflate_state *s;
+ uInt b;
+{
+ put_byte(s, (Byte)(b >> 8));
+ put_byte(s, (Byte)(b & 0xff));
+}
+
+local void flush_pending(strm)
+ z_streamp strm;
+{
+ unsigned len = strm->state->pending;
+
+ if (len > strm->avail_out) len = strm->avail_out;
+ if (len == 0) return;
+
+ zmemcpy(strm->next_out, strm->state->pending_out, len);
+ strm->next_out += len;
+ strm->state->pending_out += len;
+ strm->total_out += len;
+ strm->avail_out -= len;
+ strm->state->pending -= len;
+ if (strm->state->pending == 0) {
+ strm->state->pending_out = strm->state->pending_buf;
+ }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+ z_streamp strm;
+ int flush;
+{
+ int old_flush; /* value of flush param for previous deflate call */
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ flush > Z_FINISH || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
+ s = strm->state;
+
+ if (strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
+ ERR_RETURN(strm, Z_STREAM_ERROR);
+ }
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+ s->strm = strm; /* just in case */
+ old_flush = s->last_flush;
+ s->last_flush = flush;
+
+ /* Write the zlib header */
+ if (s->status == INIT_STATE) {
+
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags = (s->level-1) >> 1;
+
+ if (level_flags > 3) level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ s->status = BUSY_STATE;
+ putShortMSB(s, header);
+
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ //putShortMSB(s, (uInt)(strm->adler >> 16));
+ //putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ //strm->adler = 1L;
+ }
+
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ } else if (strm->avail_in == 0 && flush <= old_flush &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* Start a new block or continue the current one.
+ */
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+ block_state bstate;
+
+ bstate = (*(configuration_table.func))(s, flush);
+
+ if (bstate == finish_started || bstate == finish_done) {
+ s->status = FINISH_STATE;
+ }
+ if (bstate == need_more || bstate == finish_started) {
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+ }
+ return Z_OK;
+ }
+ if (bstate == block_done) {
+ if (flush == Z_PARTIAL_FLUSH) {
+ _tr_align(s);
+ } else { /* FULL_FLUSH or SYNC_FLUSH */
+ _tr_stored_block(s, (char*)0, 0L, 0);
+ /* For a full flush, this empty block will be recognized
+ * as a special marker by inflate_sync().
+ */
+ if (flush == Z_FULL_FLUSH) {
+ CLEAR_HASH(s); /* forget history */
+ }
+ }
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+ return Z_OK;
+ }
+ }
+ }
+ Assert(strm->avail_out > 0, "bug2");
+
+ if (flush != Z_FINISH) return Z_OK;
+ if (s->noheader) return Z_STREAM_END;
+
+ flush_pending(strm);
+ s->noheader = -1; /* write the trailer only once! */
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+ z_streamp strm;
+{
+ int status;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+ status = strm->state->status;
+ if (status != INIT_STATE && status != BUSY_STATE &&
+ status != FINISH_STATE) {
+ return Z_STREAM_ERROR;
+ }
+
+ /* Deallocate in reverse order of allocations: */
+ TRY_FREE(strm, strm->state->pending_buf);
+ TRY_FREE(strm, strm->state->head);
+ TRY_FREE(strm, strm->state->prev);
+ TRY_FREE(strm, strm->state->window);
+
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+
+local int read_buf(strm, buf, size)
+ z_streamp strm;
+ Bytef *buf;
+ unsigned size;
+{
+ unsigned len = strm->avail_in;
+
+ if (len > size) len = size;
+ if (len == 0) return 0;
+
+ strm->avail_in -= len;
+
+ //if (!strm->state->noheader) {
+// strm->adler = adler32(strm->adler, strm->next_in, len);
+ // }
+ zmemcpy(buf, strm->next_in, len);
+ strm->next_in += len;
+ strm->total_in += len;
+
+ return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+ deflate_state *s;
+{
+ s->window_size = (ulg)2L*s->w_size;
+
+ CLEAR_HASH(s);
+
+ /* Set the default configuration parameters:
+ */
+ s->max_lazy_match = configuration_table.max_lazy;
+ s->good_match = configuration_table.good_length;
+ s->nice_match = configuration_table.nice_length;
+ s->max_chain_length = configuration_table.max_chain;
+
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ s->ins_h = 0;
+#ifdef ASMV
+ match_init(); /* initialize the asm code */
+#endif
+}
+
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+#ifndef FASTEST
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = s->prev_length; /* best match length so far */
+ int nice_match = s->nice_match; /* stop if match long enough */
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
+ /* Stop when cur_match becomes <= limit. To simplify the code,
+ * we prevent matches with the string of window index 0.
+ */
+ Posf *prev = s->prev;
+ uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+ /* Compare two bytes at a time. Note: this is not always beneficial.
+ * Try with and without -DUNALIGNED_OK to check.
+ */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
+#else
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
+#endif
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ /* Do not waste too much time if we already have a good match: */
+ if (s->prev_length >= s->good_match) {
+ chain_length >>= 2;
+ }
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ do {
+ Assert(cur_match < s->strstart, "no future");
+ match = s->window + cur_match;
+
+ /* Skip to next match if the match length cannot increase
+ * or if the match length is less than 2:
+ */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
+ * UNALIGNED_OK if your compiler uses a different size.
+ */
+ if (*(ushf*)(match+best_len-1) != scan_end ||
+ *(ushf*)match != scan_start) continue;
+
+ Assert(scan[2] == match[2], "scan[2]?");
+ scan++, match++;
+ do {
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ scan < strend);
+ /* The funny "do {}" generates better code on most compilers */
+
+ /* Here, scan <= window+strstart+257 */
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+ if (*scan == *match) scan++;
+
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
+ scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+ if (match[best_len] != scan_end ||
+ match[best_len-1] != scan_end1 ||
+ *match != *scan ||
+ *++match != scan[1]) continue;
+
+ scan += 2, match++;
+ Assert(*scan == *match, "match[2]?");
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+ scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+ if (len > best_len) {
+ s->match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+ scan_end = *(ushf*)(scan+best_len-1);
+#else
+ scan_end1 = scan[best_len-1];
+ scan_end = scan[best_len];
+#endif
+ }
+ } while ((cur_match = prev[cur_match & wmask]) > limit
+ && --chain_length != 0);
+
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+ return s->lookahead;
+}
+
+#else /* FASTEST */
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 only
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ Assert(cur_match < s->strstart, "no future");
+
+ match = s->window + cur_match;
+
+ /* Return failure if the match length is less than 2:
+ */
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+ scan += 2, match += 2;
+ Assert(*scan == *match, "match[2]?");
+
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+ s->match_start = cur_match;
+ return len <= s->lookahead ? len : s->lookahead;
+}
+#endif /* FASTEST */
+#endif /* ASMV */
+
+# define check_match(s, start, match, length)
+
+local void fill_window(s)
+ deflate_state *s;
+{
+ register unsigned n, m;
+ register Posf *p;
+ unsigned more; /* Amount of free space at the end of the window. */
+ uInt wsize = s->w_size;
+
+ do {
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+ /* Deal with !@#$% 64K limit: */
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+ more = wsize;
+
+ } else if (more == (unsigned)(-1)) {
+ /* Very unlikely, but possible on 16 bit machine if strstart == 0
+ * and lookahead == 1 (input done one byte at time)
+ */
+ more--;
+
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ } else if (s->strstart >= wsize+MAX_DIST(s)) {
+
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+ s->match_start -= wsize;
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
+ s->block_start -= (long) wsize;
+
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ } while (--n);
+
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+ more += wsize;
+ }
+ if (s->strm->avail_in == 0) return;
+ Assert(more >= 2, "more < 2");
+
+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+ s->lookahead += n;
+
+ /* Initialize the hash value now that we have some input: */
+ if (s->lookahead >= MIN_MATCH) {
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+# error Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ }
+
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+ _tr_flush_block(s, (s->block_start >= 0L ? \
+ (charf *)&s->window[(unsigned)s->block_start] : \
+ (charf *)Z_NULL), \
+ (ulg)((long)s->strstart - s->block_start), \
+ (eof)); \
+ s->block_start = s->strstart; \
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+ FLUSH_BLOCK_ONLY(s, eof); \
+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+
+
+local block_state deflate_slow(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ /* Process the input block. */
+ for (;;) {
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ */
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
+ s->match_length = MIN_MATCH-1;
+
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
+ if (s->strategy != Z_HUFFMAN_ONLY) {
+ s->match_length = longest_match (s, hash_head);
+ }
+ /* longest_match() sets match_start */
+
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
+ (s->match_length == MIN_MATCH &&
+ s->strstart - s->match_start > TOO_FAR))) {
+
+ s->match_length = MIN_MATCH-1;
+ }
+ }
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+ /* Do not insert strings in hash table beyond this. */
+
+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+ s->prev_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->prev_length-1;
+ s->prev_length -= 2;
+ do {
+ if (++s->strstart <= max_insert) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+ } while (--s->prev_length != 0);
+ s->match_available = 0;
+ s->match_length = MIN_MATCH-1;
+ s->strstart++;
+
+ if (bflush) FLUSH_BLOCK(s, 0);
+
+ } else if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ if (bflush) {
+ FLUSH_BLOCK_ONLY(s, 0);
+ }
+ s->strstart++;
+ s->lookahead--;
+ if (s->strm->avail_out == 0) return need_more;
+ } else {
+ /* There is no previous match to compare with, wait for
+ * the next step to decide.
+ */
+ s->match_available = 1;
+ s->strstart++;
+ s->lookahead--;
+ }
+ }
+ Assert (flush != Z_NO_FLUSH, "no flush?");
+ if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ s->match_available = 0;
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
diff --git a/Source/zlib/trees.c b/Source/zlib/trees.c
index eb1a5af..43377e5 100755
--- a/Source/zlib/trees.c
+++ b/Source/zlib/trees.c
@@ -1,894 +1,894 @@
-/*
- * This file is a part of the zlib compression module for NSIS.
- *
- * Copyright and license information can be found below.
- * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
- *
- * The original zlib source code is available at
- * http://www.zlib.net/
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.
- */
-
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-1998 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-
-#include "DEFLATE.H"
-
-#ifdef DEBUG
-# include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6 16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10 17
-/* repeat a zero length 3-10 times (3 bits of repeat count) */
-
-#define REPZ_11_138 18
-/* repeat a zero length 11-138 times (7 bits of repeat count) */
-
-local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
- = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local const int extra_dbits[D_CODES] /* extra bits for each distance code */
- = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
- = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local const uch bl_order[BL_CODES]
- = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-#define Buf_size (8 * 2*sizeof(char))
-
-#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-
-local ct_data static_ltree[L_CODES+2];
-
-local ct_data static_dtree[D_CODES];
-
-uch _dist_code[DIST_CODE_LEN];
-
-uch _length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-struct static_tree_desc_s {
- const ct_data *static_tree; /* static tree or NULL */
- const intf *extra_bits; /* extra bits for each code or NULL */
- int extra_base; /* base index for extra_bits */
- int elems; /* max number of elements in the tree */
- int max_length; /* max bit length for the codes */
-};
-
-local static_tree_desc static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc static_d_desc =
-{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-
-local static_tree_desc static_bl_desc =
-{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block OF((deflate_state *s));
-local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
-local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree OF((deflate_state *s, tree_desc *desc));
-local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
-local int build_bl_tree OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
- int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
- ct_data *dtree));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup OF((deflate_state *s));
-local void bi_flush OF((deflate_state *s));
-local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
- int header));
-
-#ifdef GEN_TREES_H
-local void gen_trees_header OF((void));
-#endif
-
-#ifndef DEBUG
-# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
- /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG */
-# define send_code(s, c, tree) \
- { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
- send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
- put_byte(s, (uch)((w) & 0xff)); \
- put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG
-local void send_bits OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
- deflate_state *s;
- int value; /* value to send */
- int length; /* number of bits */
-{
- Tracevv((stderr," l %2d v %4x ", length, value));
- Assert(length > 0 && length <= 15, "invalid length");
- s->bits_sent += (ulg)length;
-
- if (s->bi_valid > (int)Buf_size - length) {
- s->bi_buf |= (value << s->bi_valid);
- put_short(s, s->bi_buf);
- s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
- s->bi_valid += length - Buf_size;
- } else {
- s->bi_buf |= value << s->bi_valid;
- s->bi_valid += length;
- }
-}
-#else /* !DEBUG */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
- if (s->bi_valid > (int)Buf_size - len) {\
- int val = value;\
- s->bi_buf |= (val << s->bi_valid);\
- put_short(s, s->bi_buf);\
- s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
- s->bi_valid += len - Buf_size;\
- } else {\
- s->bi_buf |= (value) << s->bi_valid;\
- s->bi_valid += len;\
- }\
-}
-#endif /* DEBUG */
-
-
-#define MAX(a,b) (a >= b ? a : b)
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables.
- */
-local void tr_static_init()
-{
- static int static_init_done = 0;
- int n; /* iterates over tree elements */
- int bits; /* bit counter */
- int length; /* length value */
- int code; /* code value */
- int dist; /* distance index */
- ush bl_count[MAX_BITS+1];
- /* number of codes at each bit length for an optimal tree */
-
- if (static_init_done) return;
-
- /* For some embedded targets, global variables are not initialized: */
- static_l_desc.static_tree = static_ltree;
- static_l_desc.extra_bits = extra_lbits;
- static_d_desc.static_tree = static_dtree;
- static_d_desc.extra_bits = extra_dbits;
- static_bl_desc.extra_bits = extra_blbits;
-
- /* Initialize the mapping length (0..255) -> length code (0..28) */
- length = 0;
- for (code = 0; code < LENGTH_CODES-1; code++) {
- base_length[code] = length;
- for (n = 0; n < (1<<extra_lbits[code]); n++) {
- _length_code[length++] = (uch)code;
- }
- }
- Assert (length == 256, "tr_static_init: length != 256");
- _length_code[length-1] = (uch)code;
-
- /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
- dist = 0;
- for (code = 0 ; code < 16; code++) {
- base_dist[code] = dist;
- for (n = 0; n < (1<<extra_dbits[code]); n++) {
- _dist_code[dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: dist != 256");
- dist >>= 7; /* from now on, all distances are divided by 128 */
- for ( ; code < D_CODES; code++) {
- base_dist[code] = dist << 7;
- for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
- _dist_code[256 + dist++] = (uch)code;
- }
- }
- Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
- /* Construct the codes of the static literal tree */
- for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
- n = 0;
- while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
- while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
- while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
- while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
- gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
- /* The static distance tree is trivial: */
- for (n = 0; n < D_CODES; n++) {
- static_dtree[n].Len = 5;
- static_dtree[n].Code = bi_reverse((unsigned)n, 5);
- }
- static_init_done = 1;
-
-}
-
-
-void _tr_init(s)
- deflate_state *s;
-{
- tr_static_init();
-
- s->l_desc.dyn_tree = s->dyn_ltree;
- s->l_desc.stat_desc = &static_l_desc;
-
- s->d_desc.dyn_tree = s->dyn_dtree;
- s->d_desc.stat_desc = &static_d_desc;
-
- s->bl_desc.dyn_tree = s->bl_tree;
- s->bl_desc.stat_desc = &static_bl_desc;
-
- s->bi_buf = 0;
- s->bi_valid = 0;
- s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG
- s->compressed_len = 0L;
- s->bits_sent = 0L;
-#endif
-
- /* Initialize the first block of the first file: */
- init_block(s);
-}
-
-local void init_block(s)
- deflate_state *s;
-{
- int n; /* iterates over tree elements */
-
- /* Initialize the trees. */
- for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
- for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
- for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
- s->dyn_ltree[END_BLOCK].Freq = 1;
- s->opt_len = s->static_len = 0L;
- s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-#define pqremove(s, tree, top) \
-{\
- top = s->heap[SMALLEST]; \
- s->heap[SMALLEST] = s->heap[s->heap_len--]; \
- pqdownheap(s, tree, SMALLEST); \
-}
-#define smaller(tree, n, m, depth) \
- (tree[n].Freq < tree[m].Freq || \
- (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-local void pqdownheap(s, tree, k)
- deflate_state *s;
- ct_data *tree; /* the tree to restore */
- int k; /* node to move down */
-{
- int v = s->heap[k];
- int j = k << 1; /* left son of k */
- while (j <= s->heap_len) {
- /* Set j to the smallest of the two sons: */
- if (j < s->heap_len &&
- smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
- j++;
- }
- /* Exit if v is smaller than both sons */
- if (smaller(tree, v, s->heap[j], s->depth)) break;
-
- /* Exchange v with the smallest son */
- s->heap[k] = s->heap[j]; k = j;
-
- /* And continue down the tree, setting j to the left son of k */
- j <<= 1;
- }
- s->heap[k] = v;
-}
-
-local void gen_bitlen(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- int max_code = desc->max_code;
- const ct_data *stree = desc->stat_desc->static_tree;
- const intf *extra = desc->stat_desc->extra_bits;
- int base = desc->stat_desc->extra_base;
- int max_length = desc->stat_desc->max_length;
- int h; /* heap index */
- int n, m; /* iterate over the tree elements */
- int bits; /* bit length */
- int xbits; /* extra bits */
- ush f; /* frequency */
- int overflow = 0; /* number of elements with bit length too large */
-
- for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
- tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
- for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
- n = s->heap[h];
- bits = tree[tree[n].Dad].Len + 1;
- if (bits > max_length) bits = max_length, overflow++;
- tree[n].Len = (ush)bits;
- /* We overwrite tree[n].Dad which is no longer needed */
-
- if (n > max_code) continue; /* not a leaf node */
-
- s->bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n-base];
- f = tree[n].Freq;
- s->opt_len += (ulg)f * (bits + xbits);
- if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
- }
- if (overflow == 0) return;
-
- Trace((stderr,"\nbit length overflow\n"));
- do {
- bits = max_length-1;
- while (s->bl_count[bits] == 0) bits--;
- s->bl_count[bits]--; /* move one leaf down the tree */
- s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
- s->bl_count[max_length]--;
- overflow -= 2;
- } while (overflow > 0);
-
- for (bits = max_length; bits != 0; bits--) {
- n = s->bl_count[bits];
- while (n != 0) {
- m = s->heap[--h];
- if (m > max_code) continue;
- if (tree[m].Len != (unsigned) bits) {
- Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
- s->opt_len += ((long)bits - (long)tree[m].Len)
- *(long)tree[m].Freq;
- tree[m].Len = (ush)bits;
- }
- n--;
- }
- }
-}
-
-local void gen_codes (tree, max_code, bl_count)
- ct_data *tree; /* the tree to decorate */
- int max_code; /* largest code with non zero frequency */
- ushf *bl_count; /* number of codes at each bit length */
-{
- ush next_code[MAX_BITS+1]; /* next code value for each bit length */
- ush code = 0; /* running code value */
- int bits; /* bit index */
- int n; /* code index */
-
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits-1]) << 1;
- }
- Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
- "inconsistent bit counts");
- Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
- for (n = 0; n <= max_code; n++) {
- int len = tree[n].Len;
- if (len == 0) continue;
- /* Now reverse the bits */
- tree[n].Code = bi_reverse(next_code[len]++, len);
-
- Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
- n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
- }
-}
-
-local void build_tree(s, desc)
- deflate_state *s;
- tree_desc *desc; /* the tree descriptor */
-{
- ct_data *tree = desc->dyn_tree;
- const ct_data *stree = desc->stat_desc->static_tree;
- int elems = desc->stat_desc->elems;
- int n, m; /* iterate over heap elements */
- int max_code = -1; /* largest code with non zero frequency */
- int node; /* new node being created */
-
- s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
- for (n = 0; n < elems; n++) {
- if (tree[n].Freq != 0) {
- s->heap[++(s->heap_len)] = max_code = n;
- s->depth[n] = 0;
- } else {
- tree[n].Len = 0;
- }
- }
- while (s->heap_len < 2) {
- node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
- tree[node].Freq = 1;
- s->depth[node] = 0;
- s->opt_len--; if (stree) s->static_len -= stree[node].Len;
- /* node is 0 or 1 so it does not have extra bits */
- }
- desc->max_code = max_code;
-
- for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
- node = elems; /* next internal node of the tree */
- do {
- pqremove(s, tree, n); /* n = node of least frequency */
- m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
- s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
- s->heap[--(s->heap_max)] = m;
-
- /* Create a new node father of n and m */
- tree[node].Freq = tree[n].Freq + tree[m].Freq;
- s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
- tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
- if (tree == s->bl_tree) {
- fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
- node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
- }
-#endif
- /* and insert the new node in the heap */
- s->heap[SMALLEST] = node++;
- pqdownheap(s, tree, SMALLEST);
-
- } while (s->heap_len >= 2);
-
- s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
- gen_bitlen(s, (tree_desc *)desc);
-
- /* The field len is now set, we can generate the bit codes */
- gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-local void scan_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- if (nextlen == 0) max_count = 138, min_count = 3;
- tree[max_code+1].Len = (ush)0xffff; /* guard */
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- s->bl_tree[curlen].Freq += count;
- } else if (curlen != 0) {
- if (curlen != prevlen) s->bl_tree[curlen].Freq++;
- s->bl_tree[REP_3_6].Freq++;
- } else if (count <= 10) {
- s->bl_tree[REPZ_3_10].Freq++;
- } else {
- s->bl_tree[REPZ_11_138].Freq++;
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-local void send_tree (s, tree, max_code)
- deflate_state *s;
- ct_data *tree; /* the tree to be scanned */
- int max_code; /* and its largest code of non zero frequency */
-{
- int n; /* iterates over all tree elements */
- int prevlen = -1; /* last emitted length */
- int curlen; /* length of current code */
- int nextlen = tree[0].Len; /* length of next code */
- int count = 0; /* repeat count of the current code */
- int max_count = 7; /* max repeat count */
- int min_count = 4; /* min repeat count */
-
- /* tree[max_code+1].Len = -1; */ /* guard already set */
- if (nextlen == 0) max_count = 138, min_count = 3;
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen; nextlen = tree[n+1].Len;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- send_code(s, curlen, s->bl_tree); count--;
- }
- Assert(count >= 3 && count <= 6, " 3_6?");
- send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
- } else if (count <= 10) {
- send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
- } else {
- send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
- }
- count = 0; prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138, min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6, min_count = 3;
- } else {
- max_count = 7, min_count = 4;
- }
- }
-}
-
-local int build_bl_tree(s)
- deflate_state *s;
-{
- int max_blindex; /* index of last bit length code of non zero freq */
-
- /* Determine the bit length frequencies for literal and distance trees */
- scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
- scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
- /* Build the bit length tree: */
- build_tree(s, (tree_desc *)(&(s->bl_desc)));
- for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
- if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
- }
- /* Update opt_len to include the bit length tree and counts */
- s->opt_len += 3*(max_blindex+1) + 5+5+4;
- Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
- s->opt_len, s->static_len));
-
- return max_blindex;
-}
-
-local void send_all_trees(s, lcodes, dcodes, blcodes)
- deflate_state *s;
- int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
- int rank; /* index in bl_order */
-
- Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
- Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
- "too many codes");
- Tracev((stderr, "\nbl counts: "));
- send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
- send_bits(s, dcodes-1, 5);
- send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
- for (rank = 0; rank < blcodes; rank++) {
- Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
- send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
- }
- Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
- Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
- send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
- Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-void _tr_stored_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-#ifdef DEBUG
- s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
- s->compressed_len += (stored_len + 4) << 3;
-#endif
- copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-void _tr_align(s)
- deflate_state *s;
-{
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-#endif
- bi_flush(s);
- if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
- send_bits(s, STATIC_TREES<<1, 3);
- send_code(s, END_BLOCK, static_ltree);
-#ifdef DEBUG
- s->compressed_len += 10L;
-#endif
- bi_flush(s);
- }
- s->last_eob_len = 7;
-}
-
-void _tr_flush_block(s, buf, stored_len, eof)
- deflate_state *s;
- charf *buf; /* input block, or NULL if too old */
- ulg stored_len; /* length of input block */
- int eof; /* true if this is the last block for a file */
-{
- ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
- int max_blindex = 0; /* index of last bit length code of non zero freq */
-
- /* Build the Huffman trees unless a stored block is forced */
- if (s->level > 0) {
-
- /* Construct the literal and distance trees */
- build_tree(s, (tree_desc *)(&(s->l_desc)));
- Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
-
- build_tree(s, (tree_desc *)(&(s->d_desc)));
- Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
- s->static_len));
- max_blindex = build_bl_tree(s);
-
- /* Determine the best encoding. Compute first the block length in bytes*/
- opt_lenb = (s->opt_len+3+7)>>3;
- static_lenb = (s->static_len+3+7)>>3;
-
- Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
- opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
- s->last_lit));
-
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
- } else {
- Assert(buf != (char*)0, "lost buf");
- opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
- }
-
-#ifdef FORCE_STORED
- if (buf != (char*)0) { /* force stored block */
-#else
- if (stored_len+4 <= opt_lenb && buf != (char*)0) {
- /* 4: two words for the lengths */
-#endif
- _tr_stored_block(s, buf, stored_len, eof);
-
-#ifdef FORCE_STATIC
- } else if (static_lenb >= 0) { /* force static trees */
-#else
- } else if (static_lenb == opt_lenb) {
-#endif
- send_bits(s, (STATIC_TREES<<1)+eof, 3);
- compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->static_len;
-#endif
- } else {
- send_bits(s, (DYN_TREES<<1)+eof, 3);
- send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
- max_blindex+1);
- compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-#ifdef DEBUG
- s->compressed_len += 3 + s->opt_len;
-#endif
- }
- Assert (s->compressed_len == s->bits_sent, "bad compressed size");
-
- init_block(s);
-
- if (eof) {
- bi_windup(s);
-#ifdef DEBUG
- s->compressed_len += 7; /* align on byte boundary */
-#endif
- }
- Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
- s->compressed_len-7*eof));
-}
-
-int _tr_tally (s, dist, lc)
- deflate_state *s;
- unsigned dist; /* distance of matched string */
- unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
- s->d_buf[s->last_lit] = (ush)dist;
- s->l_buf[s->last_lit++] = (uch)lc;
- if (dist == 0) {
- /* lc is the unmatched char */
- s->dyn_ltree[lc].Freq++;
- } else {
- s->matches++;
- /* Here, lc is the match length - MIN_MATCH */
- dist--; /* dist = match distance - 1 */
- Assert((ush)dist < (ush)MAX_DIST(s) &&
- (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
- (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-
- s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
- s->dyn_dtree[d_code(dist)].Freq++;
- }
-
-#ifdef TRUNCATE_BLOCK
- /* Try to guess if it is profitable to stop the current block here */
- if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
- /* Compute an upper bound for the compressed length */
- ulg out_length = (ulg)s->last_lit*8L;
- ulg in_length = (ulg)((long)s->strstart - s->block_start);
- int dcode;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += (ulg)s->dyn_dtree[dcode].Freq *
- (5L+extra_dbits[dcode]);
- }
- out_length >>= 3;
- Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
- s->last_lit, in_length, out_length,
- 100L - out_length*100L/in_length));
- if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
- }
-#endif
- return (s->last_lit == s->lit_bufsize-1);
-}
-
-local void compress_block(s, ltree, dtree)
- deflate_state *s;
- ct_data *ltree; /* literal tree */
- ct_data *dtree; /* distance tree */
-{
- unsigned dist; /* distance of matched string */
- int lc; /* match length or unmatched char (if dist == 0) */
- unsigned lx = 0; /* running index in l_buf */
- unsigned code; /* the code to send */
- int extra; /* number of extra bits to send */
-
- if (s->last_lit != 0) do {
- dist = s->d_buf[lx];
- lc = s->l_buf[lx++];
- if (dist == 0) {
- send_code(s, lc, ltree); /* send a literal byte */
- Tracecv(isgraph(lc), (stderr," '%c' ", lc));
- } else {
- /* Here, lc is the match length - MIN_MATCH */
- code = _length_code[lc];
- send_code(s, code+LITERALS+1, ltree); /* send the length code */
- extra = extra_lbits[code];
- if (extra != 0) {
- lc -= base_length[code];
- send_bits(s, lc, extra); /* send the extra length bits */
- }
- dist--; /* dist is now the match distance - 1 */
- code = d_code(dist);
- Assert (code < D_CODES, "bad d_code");
-
- send_code(s, code, dtree); /* send the distance code */
- extra = extra_dbits[code];
- if (extra != 0) {
- dist -= base_dist[code];
- send_bits(s, dist, extra); /* send the extra distance bits */
- }
- } /* literal or match pair ? */
-
- /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
- Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
-
- } while (lx < s->last_lit);
-
- send_code(s, END_BLOCK, ltree);
- s->last_eob_len = ltree[END_BLOCK].Len;
-}
-
-local unsigned bi_reverse(code, len)
- unsigned code; /* the value to invert */
- int len; /* its bit length */
-{
- register unsigned res = 0;
- do {
- res |= code & 1;
- code >>= 1, res <<= 1;
- } while (--len > 0);
- return res >> 1;
-}
-
-local void bi_flush(s)
- deflate_state *s;
-{
- if (s->bi_valid == 16) {
- put_short(s, s->bi_buf);
- s->bi_buf = 0;
- s->bi_valid = 0;
- } else if (s->bi_valid >= 8) {
- put_byte(s, (Byte)s->bi_buf);
- s->bi_buf >>= 8;
- s->bi_valid -= 8;
- }
-}
-
-local void bi_windup(s)
- deflate_state *s;
-{
- if (s->bi_valid > 8) {
- put_short(s, s->bi_buf);
- } else if (s->bi_valid > 0) {
- put_byte(s, (Byte)s->bi_buf);
- }
- s->bi_buf = 0;
- s->bi_valid = 0;
-#ifdef DEBUG
- s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-local void copy_block(s, buf, len, header)
- deflate_state *s;
- charf *buf; /* the input data */
- unsigned len; /* its length */
- int header; /* true if block header must be written */
-{
- bi_windup(s); /* align on byte boundary */
- s->last_eob_len = 8; /* enough lookahead for inflate */
-
- if (header) {
- put_short(s, (ush)len);
-#ifdef DEBUG
- s->bits_sent += 2*16;
-#endif
- }
-#ifdef DEBUG
- s->bits_sent += (ulg)len<<3;
-#endif
- while (len--) {
- put_byte(s, *buf++);
- }
-}
+/*
+ * This file is a part of the zlib compression module for NSIS.
+ *
+ * Copyright and license information can be found below.
+ * Modifications Copyright (C) 1999-2007 Nullsoft and Contributors
+ *
+ * The original zlib source code is available at
+ * http://www.zlib.net/
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.
+ */
+
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-1998 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+
+#include "DEFLATE.H"
+
+#ifdef DEBUG
+# include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6 16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10 17
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+#define REPZ_11_138 18
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
+
+local ct_data static_ltree[L_CODES+2];
+
+local ct_data static_dtree[D_CODES];
+
+uch _dist_code[DIST_CODE_LEN];
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+struct static_tree_desc_s {
+ const ct_data *static_tree; /* static tree or NULL */
+ const intf *extra_bits; /* extra bits for each code or NULL */
+ int extra_base; /* base index for extra_bits */
+ int elems; /* max number of elements in the tree */
+ int max_length; /* max bit length for the codes */
+};
+
+local static_tree_desc static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc static_d_desc =
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
+
+local static_tree_desc static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block OF((deflate_state *s));
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree OF((deflate_state *s, tree_desc *desc));
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local int build_bl_tree OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+ int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+ ct_data *dtree));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup OF((deflate_state *s));
+local void bi_flush OF((deflate_state *s));
+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
+ int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+ /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+# define send_code(s, c, tree) \
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+ send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+ put_byte(s, (uch)((w) & 0xff)); \
+ put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+ deflate_state *s;
+ int value; /* value to send */
+ int length; /* number of bits */
+{
+ Tracevv((stderr," l %2d v %4x ", length, value));
+ Assert(length > 0 && length <= 15, "invalid length");
+ s->bits_sent += (ulg)length;
+
+ if (s->bi_valid > (int)Buf_size - length) {
+ s->bi_buf |= (value << s->bi_valid);
+ put_short(s, s->bi_buf);
+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+ s->bi_valid += length - Buf_size;
+ } else {
+ s->bi_buf |= value << s->bi_valid;
+ s->bi_valid += length;
+ }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = value;\
+ s->bi_buf |= (val << s->bi_valid);\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf |= (value) << s->bi_valid;\
+ s->bi_valid += len;\
+ }\
+}
+#endif /* DEBUG */
+
+
+#define MAX(a,b) (a >= b ? a : b)
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+ static int static_init_done = 0;
+ int n; /* iterates over tree elements */
+ int bits; /* bit counter */
+ int length; /* length value */
+ int code; /* code value */
+ int dist; /* distance index */
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ if (static_init_done) return;
+
+ /* For some embedded targets, global variables are not initialized: */
+ static_l_desc.static_tree = static_ltree;
+ static_l_desc.extra_bits = extra_lbits;
+ static_d_desc.static_tree = static_dtree;
+ static_d_desc.extra_bits = extra_dbits;
+ static_bl_desc.extra_bits = extra_blbits;
+
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
+ length = 0;
+ for (code = 0; code < LENGTH_CODES-1; code++) {
+ base_length[code] = length;
+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
+ _length_code[length++] = (uch)code;
+ }
+ }
+ Assert (length == 256, "tr_static_init: length != 256");
+ _length_code[length-1] = (uch)code;
+
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
+ _dist_code[dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: dist != 256");
+ dist >>= 7; /* from now on, all distances are divided by 128 */
+ for ( ; code < D_CODES; code++) {
+ base_dist[code] = dist << 7;
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+ _dist_code[256 + dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+ /* Construct the codes of the static literal tree */
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+ n = 0;
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+ /* The static distance tree is trivial: */
+ for (n = 0; n < D_CODES; n++) {
+ static_dtree[n].Len = 5;
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+ }
+ static_init_done = 1;
+
+}
+
+
+void _tr_init(s)
+ deflate_state *s;
+{
+ tr_static_init();
+
+ s->l_desc.dyn_tree = s->dyn_ltree;
+ s->l_desc.stat_desc = &static_l_desc;
+
+ s->d_desc.dyn_tree = s->dyn_dtree;
+ s->d_desc.stat_desc = &static_d_desc;
+
+ s->bl_desc.dyn_tree = s->bl_tree;
+ s->bl_desc.stat_desc = &static_bl_desc;
+
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+ s->compressed_len = 0L;
+ s->bits_sent = 0L;
+#endif
+
+ /* Initialize the first block of the first file: */
+ init_block(s);
+}
+
+local void init_block(s)
+ deflate_state *s;
+{
+ int n; /* iterates over tree elements */
+
+ /* Initialize the trees. */
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+ s->dyn_ltree[END_BLOCK].Freq = 1;
+ s->opt_len = s->static_len = 0L;
+ s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+#define pqremove(s, tree, top) \
+{\
+ top = s->heap[SMALLEST]; \
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+ pqdownheap(s, tree, SMALLEST); \
+}
+#define smaller(tree, n, m, depth) \
+ (tree[n].Freq < tree[m].Freq || \
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+local void pqdownheap(s, tree, k)
+ deflate_state *s;
+ ct_data *tree; /* the tree to restore */
+ int k; /* node to move down */
+{
+ int v = s->heap[k];
+ int j = k << 1; /* left son of k */
+ while (j <= s->heap_len) {
+ /* Set j to the smallest of the two sons: */
+ if (j < s->heap_len &&
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+ j++;
+ }
+ /* Exit if v is smaller than both sons */
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+ /* Exchange v with the smallest son */
+ s->heap[k] = s->heap[j]; k = j;
+
+ /* And continue down the tree, setting j to the left son of k */
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+
+local void gen_bitlen(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ int max_code = desc->max_code;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ const intf *extra = desc->stat_desc->extra_bits;
+ int base = desc->stat_desc->extra_base;
+ int max_length = desc->stat_desc->max_length;
+ int h; /* heap index */
+ int n, m; /* iterate over the tree elements */
+ int bits; /* bit length */
+ int xbits; /* extra bits */
+ ush f; /* frequency */
+ int overflow = 0; /* number of elements with bit length too large */
+
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+ n = s->heap[h];
+ bits = tree[tree[n].Dad].Len + 1;
+ if (bits > max_length) bits = max_length, overflow++;
+ tree[n].Len = (ush)bits;
+ /* We overwrite tree[n].Dad which is no longer needed */
+
+ if (n > max_code) continue; /* not a leaf node */
+
+ s->bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n-base];
+ f = tree[n].Freq;
+ s->opt_len += (ulg)f * (bits + xbits);
+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+ }
+ if (overflow == 0) return;
+
+ Trace((stderr,"\nbit length overflow\n"));
+ do {
+ bits = max_length-1;
+ while (s->bl_count[bits] == 0) bits--;
+ s->bl_count[bits]--; /* move one leaf down the tree */
+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+ s->bl_count[max_length]--;
+ overflow -= 2;
+ } while (overflow > 0);
+
+ for (bits = max_length; bits != 0; bits--) {
+ n = s->bl_count[bits];
+ while (n != 0) {
+ m = s->heap[--h];
+ if (m > max_code) continue;
+ if (tree[m].Len != (unsigned) bits) {
+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += ((long)bits - (long)tree[m].Len)
+ *(long)tree[m].Freq;
+ tree[m].Len = (ush)bits;
+ }
+ n--;
+ }
+ }
+}
+
+local void gen_codes (tree, max_code, bl_count)
+ ct_data *tree; /* the tree to decorate */
+ int max_code; /* largest code with non zero frequency */
+ ushf *bl_count; /* number of codes at each bit length */
+{
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+ ush code = 0; /* running code value */
+ int bits; /* bit index */
+ int n; /* code index */
+
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+ }
+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+ "inconsistent bit counts");
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++) {
+ int len = tree[n].Len;
+ if (len == 0) continue;
+ /* Now reverse the bits */
+ tree[n].Code = bi_reverse(next_code[len]++, len);
+
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+ }
+}
+
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ int elems = desc->stat_desc->elems;
+ int n, m; /* iterate over heap elements */
+ int max_code = -1; /* largest code with non zero frequency */
+ int node; /* new node being created */
+
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n].Freq != 0) {
+ s->heap[++(s->heap_len)] = max_code = n;
+ s->depth[n] = 0;
+ } else {
+ tree[n].Len = 0;
+ }
+ }
+ while (s->heap_len < 2) {
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+ tree[node].Freq = 1;
+ s->depth[node] = 0;
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+ /* node is 0 or 1 so it does not have extra bits */
+ }
+ desc->max_code = max_code;
+
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+ node = elems; /* next internal node of the tree */
+ do {
+ pqremove(s, tree, n); /* n = node of least frequency */
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+ s->heap[--(s->heap_max)] = m;
+
+ /* Create a new node father of n and m */
+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
+ tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+ if (tree == s->bl_tree) {
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+ }
+#endif
+ /* and insert the new node in the heap */
+ s->heap[SMALLEST] = node++;
+ pqdownheap(s, tree, SMALLEST);
+
+ } while (s->heap_len >= 2);
+
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+ gen_bitlen(s, (tree_desc *)desc);
+
+ /* The field len is now set, we can generate the bit codes */
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+local void scan_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ if (nextlen == 0) max_count = 138, min_count = 3;
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ s->bl_tree[curlen].Freq += count;
+ } else if (curlen != 0) {
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+ s->bl_tree[REP_3_6].Freq++;
+ } else if (count <= 10) {
+ s->bl_tree[REPZ_3_10].Freq++;
+ } else {
+ s->bl_tree[REPZ_11_138].Freq++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+local void send_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
+ if (nextlen == 0) max_count = 138, min_count = 3;
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) {
+ send_code(s, curlen, s->bl_tree); count--;
+ }
+ Assert(count >= 3 && count <= 6, " 3_6?");
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+ } else if (count <= 10) {
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+ } else {
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+local int build_bl_tree(s)
+ deflate_state *s;
+{
+ int max_blindex; /* index of last bit length code of non zero freq */
+
+ /* Determine the bit length frequencies for literal and distance trees */
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+ /* Build the bit length tree: */
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+ }
+ /* Update opt_len to include the bit length tree and counts */
+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+ s->opt_len, s->static_len));
+
+ return max_blindex;
+}
+
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+ deflate_state *s;
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+ int rank; /* index in bl_order */
+
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+ "too many codes");
+ Tracev((stderr, "\nbl counts: "));
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+ send_bits(s, dcodes-1, 5);
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
+ for (rank = 0; rank < blcodes; rank++) {
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+ }
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+void _tr_stored_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
+#ifdef DEBUG
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+ s->compressed_len += (stored_len + 4) << 3;
+#endif
+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+void _tr_align(s)
+ deflate_state *s;
+{
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+ bi_flush(s);
+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L;
+#endif
+ bi_flush(s);
+ }
+ s->last_eob_len = 7;
+}
+
+void _tr_flush_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
+
+ /* Build the Huffman trees unless a stored block is forced */
+ if (s->level > 0) {
+
+ /* Construct the literal and distance trees */
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+ max_blindex = build_bl_tree(s);
+
+ /* Determine the best encoding. Compute first the block length in bytes*/
+ opt_lenb = (s->opt_len+3+7)>>3;
+ static_lenb = (s->static_len+3+7)>>3;
+
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+ s->last_lit));
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+ } else {
+ Assert(buf != (char*)0, "lost buf");
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+ }
+
+#ifdef FORCE_STORED
+ if (buf != (char*)0) { /* force stored block */
+#else
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+ /* 4: two words for the lengths */
+#endif
+ _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+ } else if (static_lenb >= 0) { /* force static trees */
+#else
+ } else if (static_lenb == opt_lenb) {
+#endif
+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
+ compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->static_len;
+#endif
+ } else {
+ send_bits(s, (DYN_TREES<<1)+eof, 3);
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+ max_blindex+1);
+ compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->opt_len;
+#endif
+ }
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+
+ init_block(s);
+
+ if (eof) {
+ bi_windup(s);
+#ifdef DEBUG
+ s->compressed_len += 7; /* align on byte boundary */
+#endif
+ }
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+ s->compressed_len-7*eof));
+}
+
+int _tr_tally (s, dist, lc)
+ deflate_state *s;
+ unsigned dist; /* distance of matched string */
+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+ s->d_buf[s->last_lit] = (ush)dist;
+ s->l_buf[s->last_lit++] = (uch)lc;
+ if (dist == 0) {
+ /* lc is the unmatched char */
+ s->dyn_ltree[lc].Freq++;
+ } else {
+ s->matches++;
+ /* Here, lc is the match length - MIN_MATCH */
+ dist--; /* dist = match distance - 1 */
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+ s->dyn_dtree[d_code(dist)].Freq++;
+ }
+
+#ifdef TRUNCATE_BLOCK
+ /* Try to guess if it is profitable to stop the current block here */
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+ /* Compute an upper bound for the compressed length */
+ ulg out_length = (ulg)s->last_lit*8L;
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
+ (5L+extra_dbits[dcode]);
+ }
+ out_length >>= 3;
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+ s->last_lit, in_length, out_length,
+ 100L - out_length*100L/in_length));
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+ }
+#endif
+ return (s->last_lit == s->lit_bufsize-1);
+}
+
+local void compress_block(s, ltree, dtree)
+ deflate_state *s;
+ ct_data *ltree; /* literal tree */
+ ct_data *dtree; /* distance tree */
+{
+ unsigned dist; /* distance of matched string */
+ int lc; /* match length or unmatched char (if dist == 0) */
+ unsigned lx = 0; /* running index in l_buf */
+ unsigned code; /* the code to send */
+ int extra; /* number of extra bits to send */
+
+ if (s->last_lit != 0) do {
+ dist = s->d_buf[lx];
+ lc = s->l_buf[lx++];
+ if (dist == 0) {
+ send_code(s, lc, ltree); /* send a literal byte */
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+ } else {
+ /* Here, lc is the match length - MIN_MATCH */
+ code = _length_code[lc];
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
+ extra = extra_lbits[code];
+ if (extra != 0) {
+ lc -= base_length[code];
+ send_bits(s, lc, extra); /* send the extra length bits */
+ }
+ dist--; /* dist is now the match distance - 1 */
+ code = d_code(dist);
+ Assert (code < D_CODES, "bad d_code");
+
+ send_code(s, code, dtree); /* send the distance code */
+ extra = extra_dbits[code];
+ if (extra != 0) {
+ dist -= base_dist[code];
+ send_bits(s, dist, extra); /* send the extra distance bits */
+ }
+ } /* literal or match pair ? */
+
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
+
+ } while (lx < s->last_lit);
+
+ send_code(s, END_BLOCK, ltree);
+ s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+local unsigned bi_reverse(code, len)
+ unsigned code; /* the value to invert */
+ int len; /* its bit length */
+{
+ register unsigned res = 0;
+ do {
+ res |= code & 1;
+ code >>= 1, res <<= 1;
+ } while (--len > 0);
+ return res >> 1;
+}
+
+local void bi_flush(s)
+ deflate_state *s;
+{
+ if (s->bi_valid == 16) {
+ put_short(s, s->bi_buf);
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ } else if (s->bi_valid >= 8) {
+ put_byte(s, (Byte)s->bi_buf);
+ s->bi_buf >>= 8;
+ s->bi_valid -= 8;
+ }
+}
+
+local void bi_windup(s)
+ deflate_state *s;
+{
+ if (s->bi_valid > 8) {
+ put_short(s, s->bi_buf);
+ } else if (s->bi_valid > 0) {
+ put_byte(s, (Byte)s->bi_buf);
+ }
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef DEBUG
+ s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+local void copy_block(s, buf, len, header)
+ deflate_state *s;
+ charf *buf; /* the input data */
+ unsigned len; /* its length */
+ int header; /* true if block header must be written */
+{
+ bi_windup(s); /* align on byte boundary */
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+
+ if (header) {
+ put_short(s, (ush)len);
+#ifdef DEBUG
+ s->bits_sent += 2*16;
+#endif
+ }
+#ifdef DEBUG
+ s->bits_sent += (ulg)len<<3;
+#endif
+ while (len--) {
+ put_byte(s, *buf++);
+ }
+}