This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches. git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@625 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
9b3b220a13
commit
3e9e73ec59
177 changed files with 37677 additions and 0 deletions
463
Source/DialogTemplate.cpp
Normal file
463
Source/DialogTemplate.cpp
Normal file
|
@ -0,0 +1,463 @@
|
|||
/*
|
||||
Copyright (C) 2002 Amir Szekely <kichik@netvision.net.il>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "DialogTemplate.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Utilities
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ALIGN(dwToAlign, dwAlignOn) dwToAlign = (dwToAlign%dwAlignOn == 0) ? dwToAlign : dwToAlign - (dwToAlign%dwAlignOn) + dwAlignOn
|
||||
|
||||
// returns the number of WCHARs in str including null charcter
|
||||
inline DWORD WCStrLen(WCHAR* szwStr) {
|
||||
int i;
|
||||
for (i = 0; szwStr[i]; i++);
|
||||
return i+1;
|
||||
}
|
||||
|
||||
// Reads a variany length array from seeker into readInto and advances seeker
|
||||
void ReadVarLenArr(BYTE* &seeker, char* &readInto) {
|
||||
WORD* arr = (WORD*)seeker;
|
||||
switch (arr[0]) {
|
||||
case 0x0000:
|
||||
readInto = 0;
|
||||
seeker += sizeof(WORD);
|
||||
break;
|
||||
case 0xFFFF:
|
||||
readInto = MAKEINTRESOURCE(arr[1]);
|
||||
seeker += 2*sizeof(WORD);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
DWORD dwStrLen = WCStrLen((WCHAR*)arr);
|
||||
readInto = new char[dwStrLen];
|
||||
WideCharToMultiByte(CP_ACP, 0, (WCHAR*)arr, dwStrLen, readInto, dwStrLen, 0, 0);
|
||||
seeker += (dwStrLen)*sizeof(WORD);
|
||||
}
|
||||
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 = WORD(x); \
|
||||
seeker += sizeof(WORD); \
|
||||
} \
|
||||
else { \
|
||||
MultiByteToWideChar(CP_ACP, 0, x, -1, (WCHAR*)seeker, dwSize); \
|
||||
seeker += (lstrlen(x)+1)*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) : (lstrlen(x)+1)*sizeof(WCHAR)) : sizeof(WORD)
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CDialogTemplate::CDialogTemplate(BYTE* pbData) {
|
||||
m_szClass = 0;
|
||||
m_szFont = 0;
|
||||
m_szMenu = 0;
|
||||
m_szTitle = 0;
|
||||
|
||||
WORD wItems = 0;
|
||||
|
||||
if (*(DWORD*)pbData == 0xFFFF0001) { // Extended dialog template signature
|
||||
m_bExtended = true;
|
||||
|
||||
DLGTEMPLATEEX* dTemplateEx = (DLGTEMPLATEEX*)pbData;
|
||||
|
||||
m_dwHelpId = dTemplateEx->helpID;
|
||||
m_dwStyle = dTemplateEx->style;
|
||||
m_dwExtStyle = dTemplateEx->exStyle;
|
||||
m_sX = dTemplateEx->x;
|
||||
m_sY = dTemplateEx->y;
|
||||
m_sWidth = dTemplateEx->cx;
|
||||
m_sHeight = dTemplateEx->cy;
|
||||
|
||||
wItems = dTemplateEx->cDlgItems;
|
||||
}
|
||||
else {
|
||||
m_bExtended = false;
|
||||
DLGTEMPLATE* dTemplate = (DLGTEMPLATE*)pbData;
|
||||
|
||||
m_dwStyle = dTemplate->style;
|
||||
m_dwExtStyle = dTemplate->dwExtendedStyle;
|
||||
m_sX = dTemplate->x;
|
||||
m_sY = dTemplate->y;
|
||||
m_sWidth = dTemplate->cx;
|
||||
m_sHeight = dTemplate->cy;
|
||||
|
||||
wItems = dTemplate->cdit;
|
||||
}
|
||||
|
||||
BYTE* seeker = pbData + (m_bExtended ? sizeof(DLGTEMPLATEEX) : sizeof(DLGTEMPLATE));
|
||||
|
||||
// Read menu variant length array
|
||||
ReadVarLenArr(seeker, m_szMenu);
|
||||
// Read class variant length array
|
||||
ReadVarLenArr(seeker, m_szClass);
|
||||
// Read title variant length array
|
||||
ReadVarLenArr(seeker, m_szTitle);
|
||||
// Read font size and variant length array (only if style DS_SETFONT is used!)
|
||||
if (m_dwStyle & DS_SETFONT) {
|
||||
m_sFontSize = *(short*)seeker;
|
||||
seeker += sizeof(short);
|
||||
ReadVarLenArr(seeker, m_szFont);
|
||||
}
|
||||
|
||||
// Read items
|
||||
for (int i = 0; i < wItems; i++) {
|
||||
// DLGITEMTEMPLATE[EX]s must be aligned on DWORD boundry
|
||||
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 = rawItem->helpID;
|
||||
item->dwStyle = rawItem->style;
|
||||
item->dwExtStyle = rawItem->exStyle;
|
||||
item->sX = rawItem->x;
|
||||
item->sY = rawItem->y;
|
||||
item->sWidth = rawItem->cx;
|
||||
item->sHeight = rawItem->cy;
|
||||
item->wId = rawItem->id;
|
||||
|
||||
seeker += sizeof(DLGITEMTEMPLATEEX);
|
||||
}
|
||||
else {
|
||||
DLGITEMTEMPLATE* rawItem = (DLGITEMTEMPLATE*)seeker;
|
||||
|
||||
item->dwStyle = rawItem->style;
|
||||
item->dwExtStyle = rawItem->dwExtendedStyle;
|
||||
item->sX = rawItem->x;
|
||||
item->sY = rawItem->y;
|
||||
item->sWidth = rawItem->cx;
|
||||
item->sHeight = rawItem->cy;
|
||||
item->wId = rawItem->id;
|
||||
|
||||
seeker += sizeof(DLGITEMTEMPLATE);
|
||||
}
|
||||
|
||||
// Read class variant length array
|
||||
ReadVarLenArr(seeker, item->szClass);
|
||||
// Read title variant length array
|
||||
ReadVarLenArr(seeker, item->szTitle);
|
||||
|
||||
// Read creation data variant length array
|
||||
// First read the size of the array (no null termination)
|
||||
item->wCreateDataSize = *(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_szTitle;
|
||||
|
||||
for (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 info about the item with the id wId
|
||||
DialogItemTemplate* CDialogTemplate::GetItem(WORD wId) {
|
||||
for (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
|
||||
void CDialogTemplate::RemoveItem(WORD wId) {
|
||||
for (int i = 0; i < m_vItems.size(); i++)
|
||||
if (m_vItems[i]->wId == wId)
|
||||
m_vItems.erase(m_vItems.begin() + i);
|
||||
}
|
||||
|
||||
// Sets the font of the dialog
|
||||
void CDialogTemplate::SetFont(char* szFaceName, WORD wFontSize) {
|
||||
m_dwStyle |= DS_SETFONT;
|
||||
if (m_szFont) delete [] m_szFont;
|
||||
m_szFont = new char[lstrlen(szFaceName)];
|
||||
lstrcpy(m_szFont, szFaceName);
|
||||
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 = new char[lstrlen(item.szClass)+1];
|
||||
lstrcpy(newItem->szClass, item.szClass);
|
||||
}
|
||||
if (item.szTitle && !IS_INTRESOURCE(item.szTitle)) {
|
||||
newItem->szTitle = new char[lstrlen(item.szTitle)+1];
|
||||
lstrcpy(newItem->szTitle, 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) and resizes the dialog by (x,y)
|
||||
void CDialogTemplate::MoveAllAndResize(short x, short y) {
|
||||
// Move all items
|
||||
for (int i = 0; i < m_vItems.size(); i++) {
|
||||
m_vItems[i]->sX += x;
|
||||
m_vItems[i]->sY += y;
|
||||
}
|
||||
// Resize
|
||||
m_sWidth += x;
|
||||
m_sHeight += y;
|
||||
}
|
||||
|
||||
// Converts pixels to this dialog's units
|
||||
void CDialogTemplate::PixelsToDlgUnits(short& x, short& y) {
|
||||
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!");
|
||||
RECT r = {0, 0, 1024, 1024};
|
||||
MapDialogRect(hDlg, &r);
|
||||
DestroyWindow(hDlg);
|
||||
|
||||
x = float(x) / (float(r.right)/1024);
|
||||
y = float(y) / (float(r.bottom)/1024);
|
||||
}
|
||||
|
||||
// Converts pixels to this dialog's units
|
||||
void CDialogTemplate::DlgUnitsToPixels(short& x, short& y) {
|
||||
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!");
|
||||
RECT r = {0, 0, 1024, 1024};
|
||||
MapDialogRect(hDlg, &r);
|
||||
DestroyWindow(hDlg);
|
||||
|
||||
x = float(x) * (float(r.right)/1024);
|
||||
y = float(y) * (float(r.bottom)/1024);
|
||||
}
|
||||
|
||||
// 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 = {
|
||||
0x0001,
|
||||
0xFFFF,
|
||||
m_dwHelpId,
|
||||
m_dwExtStyle,
|
||||
m_dwStyle,
|
||||
m_vItems.size(),
|
||||
m_sX,
|
||||
m_sY,
|
||||
m_sWidth,
|
||||
m_sHeight
|
||||
};
|
||||
|
||||
CopyMemory(seeker, &dh, sizeof(DLGTEMPLATEEX));
|
||||
seeker += sizeof(DLGTEMPLATEEX);
|
||||
}
|
||||
else {
|
||||
DLGTEMPLATE dh = {
|
||||
m_dwStyle,
|
||||
m_dwExtStyle,
|
||||
m_vItems.size(),
|
||||
m_sX,
|
||||
m_sY,
|
||||
m_sWidth,
|
||||
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 = m_sFontSize;
|
||||
seeker += sizeof(short);
|
||||
if (m_bExtended) {
|
||||
*(short*)seeker = m_sFontWeight;
|
||||
seeker += sizeof(short);
|
||||
*(short*)seeker = m_bItalic ? TRUE : FALSE;
|
||||
seeker += sizeof(short);
|
||||
}
|
||||
WriteStringOrId(m_szFont);
|
||||
}
|
||||
|
||||
// Write all of the items
|
||||
for (int i = 0; i < m_vItems.size(); i++) {
|
||||
// DLGITEMTEMPLATE[EX]s must be aligned on DWORD boundry
|
||||
if (DWORD(seeker - pbDlg) % sizeof(DWORD))
|
||||
seeker += sizeof(WORD);
|
||||
|
||||
if (m_bExtended) {
|
||||
DLGITEMTEMPLATEEX dih = {
|
||||
m_vItems[i]->dwHelpId,
|
||||
m_vItems[i]->dwExtStyle,
|
||||
m_vItems[i]->dwStyle,
|
||||
m_vItems[i]->sX,
|
||||
m_vItems[i]->sY,
|
||||
m_vItems[i]->sWidth,
|
||||
m_vItems[i]->sHeight,
|
||||
m_vItems[i]->wId
|
||||
};
|
||||
|
||||
CopyMemory(seeker, &dih, sizeof(DLGITEMTEMPLATEEX));
|
||||
seeker += sizeof(DLGITEMTEMPLATEEX);
|
||||
}
|
||||
else {
|
||||
DLGITEMTEMPLATE dih = {
|
||||
m_vItems[i]->dwStyle,
|
||||
m_vItems[i]->dwExtStyle,
|
||||
m_vItems[i]->sX,
|
||||
m_vItems[i]->sY,
|
||||
m_vItems[i]->sWidth,
|
||||
m_vItems[i]->sHeight,
|
||||
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
|
||||
if (m_vItems[i]->wCreateDataSize) m_vItems[i]->wCreateDataSize += sizeof(WORD);
|
||||
*(WORD*)seeker = m_vItems[i]->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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 ? 2*sizeof(short) : 0);
|
||||
AddStringOrIdSize(m_szFont);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_vItems.size(); i++) {
|
||||
// DLGITEMTEMPLATE[EX]s must be aligned on DWORD boundry
|
||||
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;
|
||||
}
|
121
Source/DialogTemplate.h
Normal file
121
Source/DialogTemplate.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
Copyright (C) 2002 Amir Szekely <kichik@netvision.net.il>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#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 <Windows.h>
|
||||
#include <Vector>
|
||||
|
||||
#include <StdExcept>
|
||||
using namespace std;
|
||||
|
||||
struct DialogItemTemplate {
|
||||
DWORD dwHelpId; // Extended only
|
||||
|
||||
short sX;
|
||||
short sY;
|
||||
short sWidth;
|
||||
short sHeight;
|
||||
DWORD dwExtStyle;
|
||||
DWORD dwStyle;
|
||||
WORD wId;
|
||||
|
||||
char *szClass;
|
||||
char *szTitle;
|
||||
char *szCreationData;
|
||||
|
||||
WORD wCreateDataSize;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
WORD dlgVer;
|
||||
WORD signature;
|
||||
DWORD helpID;
|
||||
DWORD exStyle;
|
||||
DWORD style;
|
||||
WORD cDlgItems;
|
||||
short x;
|
||||
short y;
|
||||
short cx;
|
||||
short cy;
|
||||
} DLGTEMPLATEEX;
|
||||
|
||||
typedef struct {
|
||||
DWORD helpID;
|
||||
DWORD exStyle;
|
||||
DWORD style;
|
||||
short x;
|
||||
short y;
|
||||
short cx;
|
||||
short cy;
|
||||
WORD id;
|
||||
} DLGITEMTEMPLATEEX;
|
||||
|
||||
|
||||
class CDialogTemplate {
|
||||
public:
|
||||
CDialogTemplate(BYTE* pbData);
|
||||
virtual ~CDialogTemplate();
|
||||
|
||||
DialogItemTemplate* GetItem(WORD wId);
|
||||
DialogItemTemplate* GetItemByIdx(DWORD i);
|
||||
void RemoveItem(WORD wId);
|
||||
void SetFont(char* szFaceName, WORD wFontSize);
|
||||
void AddItem(DialogItemTemplate item);
|
||||
void MoveAllAndResize(short x, short y);
|
||||
void PixelsToDlgUnits(short& x, short& y);
|
||||
void DlgUnitsToPixels(short& x, short& y);
|
||||
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;
|
||||
|
||||
char* m_szMenu;
|
||||
char* m_szClass;
|
||||
char* m_szTitle;
|
||||
|
||||
// Only if DS_FONT style is set
|
||||
short m_sFontSize;
|
||||
short m_sFontWeight; // Extended only
|
||||
bool m_bItalic; // Extended only
|
||||
char* m_szFont;
|
||||
|
||||
// Items vector
|
||||
vector<DialogItemTemplate*> m_vItems;
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_DIALOGTEMPLATE_H__C5A973AF_0F56_4BEC_814A_79318E2EB4AC__INCLUDED_)
|
74
Source/Makefile
Normal file
74
Source/Makefile
Normal file
|
@ -0,0 +1,74 @@
|
|||
#
|
||||
# This makefile for mingw32 by Nels. Thanks, Nels
|
||||
#
|
||||
#
|
||||
# -- Subdirs --
|
||||
SUBDIRS = exehead
|
||||
|
||||
# -- Objects and source files --
|
||||
SRCS = crc32.c build.cpp exedata.cpp makenssi.cpp script.cpp tokens.cpp util.cpp ResourceEditor.cpp DialogTemplate.cpp ./zlib/deflate.c ./zlib/trees.c ./bzip2/blocksort.c ./bzip2/bzlib.c ./bzip2/compress.c ./bzip2/huffman.c
|
||||
OBJS = build.o exedata.o makenssi.o script.o tokens.o util.o script1.res crc32.o ResourceEditor.o DialogTemplate.o deflate.o trees.o blocksort.o bzlib.o compress.o huffman.o
|
||||
LIBS = -lgdi32 -lversion
|
||||
|
||||
# -- Programs --
|
||||
MAKE = make
|
||||
CC = gcc
|
||||
RC = windres
|
||||
RM = del
|
||||
|
||||
# -- Compilers and linker flags --
|
||||
DEFINES = -DWIN32 -D_WINDOWS_
|
||||
CFLAGS = -O2 $(DEFINES)
|
||||
CPPFLAGS = -O2 -fvtable-thunks $(DEFINES)
|
||||
LFLAGS = -s
|
||||
RCFLAGS = --input-format rc --output-format coff
|
||||
|
||||
all : subdirs makensis
|
||||
|
||||
subdirs: $(SUBDIRS)
|
||||
|
||||
$(SUBDIRS)::
|
||||
$(MAKE) -C $@ all
|
||||
|
||||
makensis : $(OBJS)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(LFLAGS) -o makensis.exe $(OBJS) $(LIBS)
|
||||
|
||||
# -- Dependencies --
|
||||
build.o : build.cpp ./zlib/zlib.h ./exehead/config.h ./exehead/fileform.h ./exehead/resource.h exedata.h build.h util.h strlist.h lineparse.h ResourceEditor.h Makefile
|
||||
exedata.o : exedata.cpp exedata.h ./exehead/Release/bitmap1.h ./exehead/Release/bitmap2.h ./exehead/Release/icon.h ./exehead/Release/unicon.h ./exehead/Release/exehead.h Makefile
|
||||
makenssi.o : makenssi.cpp build.h util.h exedata.h strlist.h lineparse.h ./exehead/fileform.h ./exehead/config.h Makefile
|
||||
script.o : script.cpp tokens.h build.h util.h exedata.h strlist.h lineparse.h ResourceEditor.h DialogTemplate.h ./exehead/resource.h ./exehead/fileform.h ./exehead/config.h Makefile
|
||||
tokens.o : tokens.cpp build.h tokens.h Makefile
|
||||
util.o : util.cpp ./exehead/fileform.h util.h strlist.h ResourceEditor.h Makefile
|
||||
crc32.o : crc32.c ./exehead/config.h Makefile
|
||||
ResourceEditor.o : ResourceEditor.cpp
|
||||
DialogTemplate.o : DialogTemplate.cpp
|
||||
|
||||
# -- Special command line for the resource file --
|
||||
script1.res : script1.rc resource.h Makefile
|
||||
$(RC) $(RCFLAGS) -o script1.res -i script1.rc
|
||||
|
||||
# -- Special command lines for zlib --
|
||||
deflate.o : ./zlib/deflate.c ./zlib/deflate.h ./zlib/zutil.h ./zlib/zlib.h ./zlib/zconf.h Makefile ./exehead/config.h
|
||||
$(CC) $(CFLAGS) -c ./zlib/deflate.c -o deflate.o
|
||||
|
||||
trees.o : ./zlib/trees.c ./zlib/deflate.h ./zlib/zutil.h ./zlib/zlib.h ./zlib/zconf.h Makefile ./exehead/config.h
|
||||
$(CC) $(CFLAGS) -c ./zlib/trees.c -o trees.o
|
||||
|
||||
# -- Special command lines for bzip2 --
|
||||
blocksort.o : ./bzip2/blocksort.c ./bzip2/bzlib.h ./bzip2/bzlib_private.h ./exehead/config.h
|
||||
$(CC) $(CFLAGS) -c ./bzip2/blocksort.c -o blocksort.o
|
||||
bzlib.o : ./bzip2/bzlib.c ./bzip2/bzlib.h ./bzip2/bzlib_private.h ./exehead/config.h
|
||||
$(CC) $(CFLAGS) -c ./bzip2/bzlib.c -o bzlib.o
|
||||
compress.o : ./bzip2/compress.c ./bzip2/bzlib.h ./bzip2/bzlib_private.h ./exehead/config.h
|
||||
$(CC) $(CFLAGS) -c ./bzip2/compress.c -o compress.o
|
||||
huffman.o : ./bzip2/huffman.c ./bzip2/bzlib.h ./bzip2/bzlib_private.h ./exehead/config.h
|
||||
$(CC) $(CFLAGS) -c ./bzip2/huffman.c -o huffman.o
|
||||
|
||||
|
||||
# -- Clean script --
|
||||
clean ::
|
||||
$(MAKE) -C exehead clean
|
||||
$(RM) *.o
|
||||
$(RM) script1.res
|
||||
$(RM) makensis.exe
|
BIN
Source/Release/Script1.res
Normal file
BIN
Source/Release/Script1.res
Normal file
Binary file not shown.
1
Source/Release/vc60.idb
Normal file
1
Source/Release/vc60.idb
Normal file
|
@ -0,0 +1 @@
|
|||
Microsoft C/C++ program database 2.00
|
780
Source/ResourceEditor.cpp
Normal file
780
Source/ResourceEditor.cpp
Normal file
|
@ -0,0 +1,780 @@
|
|||
/*
|
||||
Copyright (C) 2002 Amir Szekely <kichik@netvision.net.il>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#define RESOURCE_EDITOR_NO_API
|
||||
#include "ResourceEditor.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// 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)
|
||||
|
||||
void *operator new(size_t size) {
|
||||
void *p = malloc(size);
|
||||
if (!p)
|
||||
throw bad_alloc();
|
||||
return p;
|
||||
}
|
||||
void operator delete(void *p) {
|
||||
if (p) free(p);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// CResourceEditor
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
CResourceEditor::CResourceEditor(BYTE* pbPE, int iSize) {
|
||||
// Copy the data
|
||||
m_iSize = iSize;
|
||||
m_pbPE = new BYTE[iSize];
|
||||
CopyMemory(m_pbPE, pbPE, iSize);
|
||||
|
||||
// Get dos header
|
||||
m_dosHeader = (PIMAGE_DOS_HEADER)m_pbPE;
|
||||
if (m_dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
throw runtime_error("PE file contains invalid DOS header");
|
||||
|
||||
// Get NT headers
|
||||
m_ntHeaders = (PIMAGE_NT_HEADERS)(m_pbPE + m_dosHeader->e_lfanew);
|
||||
if (m_ntHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
throw runtime_error("PE file missing NT signature");
|
||||
|
||||
// No check sum support yet...
|
||||
if (m_ntHeaders->OptionalHeader.CheckSum)
|
||||
throw runtime_error("CResourceEditor doesn't yet support check sum");
|
||||
|
||||
// Get resource section virtual address
|
||||
m_dwResourceSectionVA = m_ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
|
||||
// Pointer to the sections headers array
|
||||
PIMAGE_SECTION_HEADER sectionHeadersArray = IMAGE_FIRST_SECTION(m_ntHeaders);
|
||||
|
||||
// Find resource section index in the array
|
||||
for (m_dwResourceSectionIndex = 0; m_dwResourceSectionIndex < m_ntHeaders->FileHeader.NumberOfSections; m_dwResourceSectionIndex++)
|
||||
if (m_dwResourceSectionVA == sectionHeadersArray[m_dwResourceSectionIndex].VirtualAddress)
|
||||
break;
|
||||
|
||||
// No resource section...
|
||||
if (m_dwResourceSectionIndex == m_ntHeaders->FileHeader.NumberOfSections)
|
||||
throw runtime_error("PE file doesn't contain any resource section");
|
||||
|
||||
// Pointer to section data, the first resource directory
|
||||
PRESOURCE_DIRECTORY rdRoot = PRESOURCE_DIRECTORY(m_pbPE + sectionHeadersArray[m_dwResourceSectionIndex].PointerToRawData);
|
||||
|
||||
// Scan the resource directory
|
||||
m_cResDir = ScanDirectory(rdRoot, rdRoot);
|
||||
}
|
||||
|
||||
CResourceEditor::~CResourceEditor() {
|
||||
if (m_pbPE)
|
||||
delete [] m_pbPE;
|
||||
if (m_cResDir) {
|
||||
m_cResDir->Destroy();
|
||||
delete m_cResDir;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Methods
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Adds/Replaces/Removes a resource.
|
||||
// If lpData is 0 UpdateResource removes the resource.
|
||||
void CResourceEditor::UpdateResource(char* szType, char* szName, WORD wLanguage, BYTE* lpData, DWORD dwSize) {
|
||||
CResourceDirectory* nameDir = 0;
|
||||
CResourceDirectory* langDir = 0;
|
||||
CResourceDataEntry* data = 0;
|
||||
IMAGE_RESOURCE_DIRECTORY rd = {0, time(0),};
|
||||
int iTypeIdx, iNameIdx, iLangIdx;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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(MAKEINTRESOURCE(wLanguage), data));
|
||||
}
|
||||
}
|
||||
else if (data) {
|
||||
// Delete the resource
|
||||
delete data;
|
||||
delete langDir->GetEntry(iLangIdx);
|
||||
langDir->RemoveEntry(iLangIdx);
|
||||
// Delete directories holding the resource if empty
|
||||
if (!langDir->CountEntries()) {
|
||||
delete langDir;
|
||||
delete nameDir->GetEntry(iNameIdx);
|
||||
nameDir->RemoveEntry(iNameIdx);
|
||||
if (!nameDir->CountEntries()) {
|
||||
delete nameDir;
|
||||
delete m_cResDir->GetEntry(iTypeIdx);
|
||||
m_cResDir->RemoveEntry(iTypeIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CResourceEditor::UpdateResource(WORD szType, char* szName, WORD wLanguage, BYTE* lpData, DWORD dwSize) {
|
||||
UpdateResource(MAKEINTRESOURCE(szType), szName, wLanguage, lpData, dwSize);
|
||||
}
|
||||
|
||||
void CResourceEditor::UpdateResource(char* szType, WORD szName, WORD wLanguage, BYTE* lpData, DWORD dwSize) {
|
||||
UpdateResource(szType, MAKEINTRESOURCE(szName), wLanguage, lpData, dwSize);
|
||||
}
|
||||
|
||||
void CResourceEditor::UpdateResource(WORD szType, WORD szName, WORD wLanguage, BYTE* lpData, DWORD dwSize) {
|
||||
UpdateResource(MAKEINTRESOURCE(szType), MAKEINTRESOURCE(szName), wLanguage, lpData, dwSize);
|
||||
}
|
||||
|
||||
// Returns a copy of the resource requested
|
||||
// Returns 0 if resource can't be found
|
||||
BYTE* CResourceEditor::GetResource(char* szType, char* szName, WORD 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 = 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 0;
|
||||
}
|
||||
|
||||
// Saves the edited PE into a buffer and returns it.
|
||||
BYTE* CResourceEditor::Save(DWORD &dwSize) {
|
||||
int i;
|
||||
|
||||
DWORD dwRsrcSize = m_cResDir->GetSize(); // Size of new resource section
|
||||
DWORD dwRsrcSizeAligned = RALIGN(dwRsrcSize, m_ntHeaders->OptionalHeader.FileAlignment); // Align it to FileAlignment
|
||||
|
||||
// Calculate the total new PE size
|
||||
dwSize = m_iSize - IMAGE_FIRST_SECTION(m_ntHeaders)[m_dwResourceSectionIndex].SizeOfRawData + dwRsrcSizeAligned;
|
||||
|
||||
// Allocate memory for the new PE
|
||||
BYTE* pbNewPE = new BYTE[dwSize];
|
||||
// Fill it with zeros
|
||||
ZeroMemory(pbNewPE, dwSize);
|
||||
|
||||
BYTE* seeker = pbNewPE;
|
||||
BYTE* oldSeeker = m_pbPE;
|
||||
|
||||
// Copy old headers
|
||||
CopyMemory(seeker, oldSeeker, m_ntHeaders->OptionalHeader.SizeOfHeaders);
|
||||
|
||||
// Get new nt headers pointer
|
||||
PIMAGE_NT_HEADERS ntHeaders = PIMAGE_NT_HEADERS(pbNewPE + PIMAGE_DOS_HEADER(pbNewPE)->e_lfanew);
|
||||
// Get a pointer to the new section headers
|
||||
PIMAGE_SECTION_HEADER sectionHeadersArray = IMAGE_FIRST_SECTION(ntHeaders);
|
||||
|
||||
// Copy everything between the headers and the sections (Borland stuff...)
|
||||
CopyMemory(seeker, oldSeeker, sectionHeadersArray[0].PointerToRawData-ntHeaders->OptionalHeader.SizeOfHeaders);
|
||||
|
||||
// Skip some stuff between the headers and the sections (which is??? ask Borland...)
|
||||
seeker += sectionHeadersArray[0].PointerToRawData-ntHeaders->OptionalHeader.SizeOfHeaders;
|
||||
oldSeeker += sectionHeadersArray[0].PointerToRawData-ntHeaders->OptionalHeader.SizeOfHeaders;
|
||||
|
||||
// Skip the headers
|
||||
seeker += ntHeaders->OptionalHeader.SizeOfHeaders;
|
||||
oldSeeker += m_ntHeaders->OptionalHeader.SizeOfHeaders;
|
||||
|
||||
// Copy all of the section up until the resource section
|
||||
DWORD dwSectionsSize = 0;
|
||||
for (i = 0; i < m_dwResourceSectionIndex; i++)
|
||||
dwSectionsSize += sectionHeadersArray[i].SizeOfRawData;
|
||||
|
||||
CopyMemory(seeker, oldSeeker, dwSectionsSize);
|
||||
seeker += dwSectionsSize;
|
||||
oldSeeker += dwSectionsSize;
|
||||
|
||||
// Skip the resource section in the old PE seeker.
|
||||
oldSeeker += sectionHeadersArray[m_dwResourceSectionIndex].SizeOfRawData;
|
||||
|
||||
// Save the old virtual size of the resource section
|
||||
DWORD dwOldVirtualSize = sectionHeadersArray[m_dwResourceSectionIndex].Misc.VirtualSize;
|
||||
|
||||
// Set the new size of the resource section (size aligned to FileAlignment)
|
||||
sectionHeadersArray[m_dwResourceSectionIndex].SizeOfRawData = dwRsrcSizeAligned;
|
||||
// Set the virtual size as well (in memory)
|
||||
sectionHeadersArray[m_dwResourceSectionIndex].Misc.VirtualSize = RALIGN(dwRsrcSize, ntHeaders->OptionalHeader.SectionAlignment);
|
||||
ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = sectionHeadersArray[m_dwResourceSectionIndex].Misc.VirtualSize;
|
||||
|
||||
// Set the new virtual size of the image
|
||||
DWORD old = ntHeaders->OptionalHeader.SizeOfImage;
|
||||
ntHeaders->OptionalHeader.SizeOfImage = RALIGN(ntHeaders->OptionalHeader.SizeOfHeaders, ntHeaders->OptionalHeader.SectionAlignment);
|
||||
for (int j = 0; j < ntHeaders->FileHeader.NumberOfSections; j++)
|
||||
ntHeaders->OptionalHeader.SizeOfImage += RALIGN(sectionHeadersArray[j].Misc.VirtualSize, ntHeaders->OptionalHeader.SectionAlignment);
|
||||
|
||||
// Set the new AddressOfEntryPoint if needed
|
||||
if (ntHeaders->OptionalHeader.AddressOfEntryPoint > sectionHeadersArray[m_dwResourceSectionIndex].VirtualAddress)
|
||||
ntHeaders->OptionalHeader.AddressOfEntryPoint += sectionHeadersArray[m_dwResourceSectionIndex].Misc.VirtualSize - dwOldVirtualSize;
|
||||
|
||||
// Set the new BaseOfCode if needed
|
||||
if (ntHeaders->OptionalHeader.BaseOfCode > sectionHeadersArray[m_dwResourceSectionIndex].VirtualAddress)
|
||||
ntHeaders->OptionalHeader.BaseOfCode += sectionHeadersArray[m_dwResourceSectionIndex].Misc.VirtualSize - dwOldVirtualSize;
|
||||
|
||||
// Set the new BaseOfData if needed
|
||||
if (ntHeaders->OptionalHeader.BaseOfData > sectionHeadersArray[m_dwResourceSectionIndex].VirtualAddress)
|
||||
ntHeaders->OptionalHeader.BaseOfData += sectionHeadersArray[m_dwResourceSectionIndex].Misc.VirtualSize - dwOldVirtualSize;
|
||||
|
||||
// Refresh the headers of the sections that come after the resource section, and the data directory
|
||||
for (i++; i < ntHeaders->FileHeader.NumberOfSections; i++) {
|
||||
sectionHeadersArray[i].PointerToRawData -= IMAGE_FIRST_SECTION(m_ntHeaders)[m_dwResourceSectionIndex].SizeOfRawData;
|
||||
sectionHeadersArray[i].PointerToRawData += dwRsrcSizeAligned;
|
||||
int secInDataDir = 0;
|
||||
for (int j = 0; j < ntHeaders->OptionalHeader.NumberOfRvaAndSizes; j++)
|
||||
if (ntHeaders->OptionalHeader.DataDirectory[j].VirtualAddress == sectionHeadersArray[i].VirtualAddress)
|
||||
secInDataDir = j;
|
||||
sectionHeadersArray[i].VirtualAddress -= RALIGN(dwOldVirtualSize, ntHeaders->OptionalHeader.SectionAlignment);
|
||||
sectionHeadersArray[i].VirtualAddress += RALIGN(sectionHeadersArray[m_dwResourceSectionIndex].Misc.VirtualSize, ntHeaders->OptionalHeader.SectionAlignment);
|
||||
if (secInDataDir)
|
||||
ntHeaders->OptionalHeader.DataDirectory[secInDataDir].VirtualAddress = sectionHeadersArray[i].VirtualAddress;
|
||||
}
|
||||
|
||||
// Write the resource section
|
||||
WriteRsrcSec(seeker);
|
||||
// Advance the pointer
|
||||
seeker += dwRsrcSizeAligned;
|
||||
|
||||
// Write all the sections that come after the resource section
|
||||
dwSectionsSize = 0;
|
||||
for (i = m_dwResourceSectionIndex + 1; i < m_ntHeaders->FileHeader.NumberOfSections; i++)
|
||||
dwSectionsSize += sectionHeadersArray[i].SizeOfRawData;
|
||||
|
||||
CopyMemory(seeker, oldSeeker, dwSectionsSize);
|
||||
|
||||
/**********************************************************
|
||||
* To add checksum to the header use MapFileAndCheckSum
|
||||
**********************************************************/
|
||||
|
||||
return pbNewPE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// 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));
|
||||
char* szName;
|
||||
PIMAGE_RESOURCE_DATA_ENTRY rde;
|
||||
|
||||
// Go through all entries of this resource directory
|
||||
for (int i = 0; i < rdToScan->Header.NumberOfNamedEntries + rdToScan->Header.NumberOfIdEntries; i++) {
|
||||
// If this entry points to data entry get a pointer to it
|
||||
if (!rdToScan->Entries[i].DataIsDirectory)
|
||||
rde = PIMAGE_RESOURCE_DATA_ENTRY(rdToScan->Entries[i].OffsetToData + (BYTE*)rdRoot);
|
||||
|
||||
// If this entry has a name, translate it from Unicode
|
||||
if (rdToScan->Entries[i].NameIsString) {
|
||||
PIMAGE_RESOURCE_DIR_STRING_U rds = PIMAGE_RESOURCE_DIR_STRING_U(rdToScan->Entries[i].NameOffset + (char*)rdRoot);
|
||||
|
||||
szName = new char[rds->Length+1];
|
||||
WideCharToMultiByte(CP_ACP, 0, rds->NameString, rds->Length, szName, rds->Length, 0, 0);
|
||||
szName[rds->Length] = 0;
|
||||
}
|
||||
// Else, set the name to this entry's id
|
||||
else
|
||||
szName = MAKEINTRESOURCE(rdToScan->Entries[i].Id);
|
||||
|
||||
if (rdToScan->Entries[i].DataIsDirectory)
|
||||
rdc->AddEntry(
|
||||
new CResourceDirectoryEntry(
|
||||
szName,
|
||||
ScanDirectory(
|
||||
rdRoot,
|
||||
PRESOURCE_DIRECTORY(rdToScan->Entries[i].OffsetToDirectory + (BYTE*)rdRoot)
|
||||
)
|
||||
)
|
||||
);
|
||||
else
|
||||
rdc->AddEntry(
|
||||
new CResourceDirectoryEntry(
|
||||
szName,
|
||||
new CResourceDataEntry(
|
||||
(BYTE*)rdRoot + rde->OffsetToData - m_dwResourceSectionVA,
|
||||
rde->Size,
|
||||
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();
|
||||
|
||||
CopyMemory(seeker, &crd->GetInfo(), 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());
|
||||
}
|
||||
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY rDirE = {0,};
|
||||
rDirE.DataIsDirectory = crd->GetEntry(i)->IsDataDirectory();
|
||||
rDirE.Id = (crd->GetEntry(i)->HasName()) ? 0 : crd->GetEntry(i)->GetId();
|
||||
rDirE.NameIsString = (crd->GetEntry(i)->HasName()) ? 1 : 0;
|
||||
|
||||
CopyMemory(seeker, &rDirE, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
|
||||
crd->GetEntry(i)->m_dwWrittenAt = DWORD(seeker);
|
||||
seeker += sizeof(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 = cRDataE->GetCodePage();
|
||||
rDataE.Size = 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();
|
||||
|
||||
PIMAGE_RESOURCE_DIRECTORY_ENTRY(cRDirE->m_dwWrittenAt)->NameOffset = DWORD(seeker) - DWORD(pbRsrcSec);
|
||||
|
||||
char* szName = cRDirE->GetName();
|
||||
WORD iLen = lstrlen(szName);
|
||||
WCHAR* szwName = new WCHAR[iLen];
|
||||
MultiByteToWideChar(CP_ACP, 0, szName, iLen, szwName, iLen);
|
||||
CopyMemory(seeker, &iLen, sizeof(WORD));
|
||||
seeker += sizeof(WORD);
|
||||
CopyMemory(seeker, szwName, iLen*sizeof(WCHAR));
|
||||
seeker += iLen*sizeof(WCHAR);
|
||||
|
||||
// Even though the number of chars is predefined a null termination is required
|
||||
*(WORD*)seeker = 0;
|
||||
seeker += sizeof(WORD);
|
||||
|
||||
delete [] szName;
|
||||
delete [] szwName;
|
||||
|
||||
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 = 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++) {
|
||||
if (resDir->GetEntry(i)->IsDataDirectory()) {
|
||||
PIMAGE_RESOURCE_DIRECTORY_ENTRY(resDir->GetEntry(i)->m_dwWrittenAt)->DataIsDirectory = 1;
|
||||
PIMAGE_RESOURCE_DIRECTORY_ENTRY(resDir->GetEntry(i)->m_dwWrittenAt)->OffsetToDirectory = resDir->GetEntry(i)->GetSubDirectory()->m_dwWrittenAt - newResDirAt;
|
||||
SetOffsets(resDir->GetEntry(i)->GetSubDirectory(), newResDirAt);
|
||||
}
|
||||
else {
|
||||
PIMAGE_RESOURCE_DIRECTORY_ENTRY(resDir->GetEntry(i)->m_dwWrittenAt)->OffsetToData = resDir->GetEntry(i)->GetDataEntry()->m_dwWrittenAt - newResDirAt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// 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(int i) {
|
||||
if (m_vEntries.size() < i || i < 0)
|
||||
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()) {
|
||||
char* szEntName = entry->GetName();
|
||||
for (i = 0; i < m_rdDir.NumberOfIdEntries; i++) {
|
||||
char* szName = m_vEntries[i]->GetName();
|
||||
int cmp = lstrcmp(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--;
|
||||
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(char* szName) {
|
||||
if (IS_INTRESOURCE(szName))
|
||||
return Find(WORD(szName));
|
||||
else
|
||||
if (szName[0] == '#')
|
||||
return Find(atol(szName+1));
|
||||
|
||||
for (int i = 0; i < m_vEntries.size(); i++) {
|
||||
if (!m_vEntries[i]->HasName())
|
||||
continue;
|
||||
|
||||
char* szEntName = m_vEntries[i]->GetName();
|
||||
int cmp = lstrcmp(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 (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 (int i = 0; i < m_vEntries.size(); i++) {
|
||||
dwSize += sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY);
|
||||
if (m_vEntries[i]->HasName())
|
||||
dwSize += sizeof(IMAGE_RESOURCE_DIR_STRING_U) + m_vEntries[i]->GetNameLength()*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 (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(char* szName, CResourceDirectory* rdSubDir) {
|
||||
if (IS_INTRESOURCE(szName)) {
|
||||
m_bHasName = false;
|
||||
m_szName = 0;
|
||||
m_wId = WORD(szName);
|
||||
}
|
||||
else {
|
||||
m_bHasName = true;
|
||||
m_szName = new char[lstrlen(szName)];
|
||||
lstrcpy(m_szName, szName);
|
||||
}
|
||||
m_bIsDataDirectory = true;
|
||||
m_rdSubDir = rdSubDir;
|
||||
}
|
||||
|
||||
CResourceDirectoryEntry::CResourceDirectoryEntry(char* szName, CResourceDataEntry* rdeData) {
|
||||
if (IS_INTRESOURCE(szName)) {
|
||||
m_bHasName = false;
|
||||
m_szName = 0;
|
||||
m_wId = WORD(szName);
|
||||
}
|
||||
else {
|
||||
m_bHasName = true;
|
||||
m_szName = new char[lstrlen(szName)];
|
||||
lstrcpy(m_szName, 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!
|
||||
char* CResourceDirectoryEntry::GetName() {
|
||||
if (!m_bHasName)
|
||||
return 0;
|
||||
char* szName = 0;
|
||||
szName = new char[lstrlen(m_szName)];
|
||||
lstrcpy(szName, m_szName);
|
||||
return szName;
|
||||
}
|
||||
|
||||
int CResourceDirectoryEntry::GetNameLength() {
|
||||
return lstrlen(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;
|
||||
}
|
167
Source/ResourceEditor.h
Normal file
167
Source/ResourceEditor.h
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
Copyright (C) 2002 Amir Szekely <kichik@netvision.net.il>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
#ifdef RESOURCE_EDITOR_NO_API
|
||||
|
||||
#include <Windows.h>
|
||||
#include <WinNT.h>
|
||||
#include <Time.h>
|
||||
#include <Vector>
|
||||
#include <Queue>
|
||||
|
||||
#endif // #ifdef RESOURCE_EDITOR_NO_API
|
||||
|
||||
#include <StdExcept>
|
||||
using namespace std;
|
||||
|
||||
class CResourceDirectory;
|
||||
class CResourceDirectoryEntry;
|
||||
class CResourceDataEntry;
|
||||
|
||||
// Resource directory with entries
|
||||
typedef struct RESOURCE_DIRECTORY {
|
||||
IMAGE_RESOURCE_DIRECTORY Header;
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY Entries[1];
|
||||
} *PRESOURCE_DIRECTORY;
|
||||
|
||||
class CResourceEditor {
|
||||
public:
|
||||
CResourceEditor(BYTE* pbPE, int iSize);
|
||||
virtual ~CResourceEditor();
|
||||
|
||||
void UpdateResource(char* szType, char* szName, WORD wLanguage, BYTE* lpData, DWORD dwSize);
|
||||
void UpdateResource(WORD szType, char* szName, WORD wLanguage, BYTE* lpData, DWORD dwSize);
|
||||
void UpdateResource(char* szType, WORD szName, WORD wLanguage, BYTE* lpData, DWORD dwSize);
|
||||
void UpdateResource(WORD szType, WORD szName, WORD wLanguage, BYTE* lpData, DWORD dwSize);
|
||||
BYTE* GetResource(char* szType, char* szName, WORD wLanguage);
|
||||
|
||||
BYTE* Save(DWORD &dwSize);
|
||||
|
||||
private:
|
||||
BYTE* m_pbPE;
|
||||
int m_iSize;
|
||||
|
||||
PIMAGE_DOS_HEADER m_dosHeader;
|
||||
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);
|
||||
};
|
||||
|
||||
#ifdef RESOURCE_EDITOR_NO_API
|
||||
|
||||
class CResourceDirectory {
|
||||
public:
|
||||
CResourceDirectory(PIMAGE_RESOURCE_DIRECTORY prd);
|
||||
virtual ~CResourceDirectory();
|
||||
|
||||
IMAGE_RESOURCE_DIRECTORY GetInfo();
|
||||
|
||||
CResourceDirectoryEntry* GetEntry(int i);
|
||||
void AddEntry(CResourceDirectoryEntry* entry);
|
||||
void RemoveEntry(int i);
|
||||
int CountEntries();
|
||||
int Find(char* szName);
|
||||
int Find(WORD wId);
|
||||
|
||||
DWORD GetSize();
|
||||
|
||||
void Destroy();
|
||||
|
||||
DWORD m_dwWrittenAt;
|
||||
|
||||
private:
|
||||
IMAGE_RESOURCE_DIRECTORY m_rdDir;
|
||||
vector<CResourceDirectoryEntry*> m_vEntries;
|
||||
};
|
||||
|
||||
class CResourceDirectoryEntry {
|
||||
public:
|
||||
CResourceDirectoryEntry(char* szName, CResourceDirectory* rdSubDir);
|
||||
CResourceDirectoryEntry(char* szName, CResourceDataEntry* rdeData);
|
||||
virtual ~CResourceDirectoryEntry();
|
||||
|
||||
bool HasName();
|
||||
char* GetName();
|
||||
int GetNameLength();
|
||||
|
||||
WORD GetId();
|
||||
|
||||
bool IsDataDirectory();
|
||||
CResourceDirectory* GetSubDirectory();
|
||||
|
||||
CResourceDataEntry* GetDataEntry();
|
||||
|
||||
DWORD m_dwWrittenAt;
|
||||
|
||||
private:
|
||||
bool m_bHasName;
|
||||
union {
|
||||
char* 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 // #ifdef RESOURCE_EDITOR_NO_API
|
||||
|
||||
#endif // !defined(AFX_RESOURCEEDITOR_H__683BF710_E805_4093_975B_D5729186A89A__INCLUDED_)
|
72
Source/Script1.rc
Normal file
72
Source/Script1.rc
Normal file
|
@ -0,0 +1,72 @@
|
|||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.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
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON DISCARDABLE "icon.ico"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
5
Source/afxres.h
Normal file
5
Source/afxres.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include <windows.h>
|
||||
|
||||
#ifndef IDC_STATIC
|
||||
#define IDC_STATIC -1
|
||||
#endif
|
1971
Source/build.cpp
Normal file
1971
Source/build.cpp
Normal file
File diff suppressed because it is too large
Load diff
169
Source/build.h
Normal file
169
Source/build.h
Normal file
|
@ -0,0 +1,169 @@
|
|||
#ifndef _BUILD_H_
|
||||
#define _BUILD_H_
|
||||
|
||||
#include "strlist.h"
|
||||
#include "lineparse.h"
|
||||
|
||||
#include "exehead/fileform.h"
|
||||
#include "exehead/config.h"
|
||||
|
||||
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
|
||||
// Changed by Amir Szekely 31st July 2002
|
||||
#include "compressor.h"
|
||||
#include "czlib.h"
|
||||
#include "cbzip2.h"
|
||||
|
||||
#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
|
||||
|
||||
#ifdef NSIS_CONFIG_CRC_SUPPORT
|
||||
extern "C"
|
||||
{
|
||||
unsigned long CRC32(unsigned long crc, const unsigned char *buf, unsigned int len);
|
||||
};
|
||||
#endif
|
||||
|
||||
#define PS_OK 0
|
||||
#define PS_EOF 1
|
||||
#define PS_ENDIF 2
|
||||
#define PS_ELSE 3
|
||||
#define PS_ELSE_IF0 4
|
||||
#define PS_ELSE_IF1 5
|
||||
#define PS_ERROR 50
|
||||
#define IS_PS_ELSE(x) (( x ) >= PS_ELSE && ( x ) <= PS_ELSE_IF1)
|
||||
|
||||
class CEXEBuild {
|
||||
public:
|
||||
CEXEBuild();
|
||||
~CEXEBuild();
|
||||
|
||||
// to add a warning to the compiler's warning list.
|
||||
void warning(const char *s, ...);
|
||||
|
||||
// to add a defined thing.
|
||||
void define(const char *p, const char *v="");
|
||||
|
||||
// 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 *lineptr);
|
||||
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;
|
||||
|
||||
private:
|
||||
// tokens.cpp
|
||||
int get_commandtoken(char *s, int *np, int *op);
|
||||
|
||||
// script.cpp
|
||||
int parseScript(FILE *fp, const char *curfilename, int *lineptr, int ignore);
|
||||
void ps_addtoline(const char *str, GrowBuf &linedata, StringList &hist);
|
||||
int doParse(const char *str, FILE *fp, const char *curfilename, int *lineptr, int ignore);
|
||||
int doCommand(int which_token, LineParser &line, FILE *fp, const char *curfilename, int linecnt);
|
||||
int do_add_file(const char *lgss, int attrib, int recurse, int linecnt, int *total_files, const char *name_override=0);
|
||||
GrowBuf m_linebuild; // used for concatenating lines
|
||||
|
||||
void ERROR_MSG(const char *s, ...);
|
||||
void SCRIPT_MSG(const char *s, ...);
|
||||
void INFO_MSG(const char *s, ...);
|
||||
|
||||
// build.cpp functions used mostly by script.cpp
|
||||
int getcurdbsize();
|
||||
int add_section(const char *secname, const char *file, int line, const char *defname, int expand);
|
||||
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 add_label(const char *name);
|
||||
int add_entry(const entry *ent);
|
||||
int add_data(const char *data, int length, IGrowBuf *dblock=NULL); // returns offset
|
||||
int add_string(const char *string); // returns offset (in string table)
|
||||
int add_string_main(const char *string, int process=1); // returns offset (in string table)
|
||||
int add_string_uninst(const char *string, int process=1); // returns offset (in string table)
|
||||
int preprocess_string(char *out, const char *in);
|
||||
|
||||
int make_sure_not_in_secorfunc(const char *str);
|
||||
|
||||
// build.cpp functions used mostly within build.cpp
|
||||
int datablock_optimize(int start_offset);
|
||||
void printline(int l);
|
||||
int process_jump(LineParser &line, int wt, int *offs);
|
||||
|
||||
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);
|
||||
|
||||
// a whole bunch O data.
|
||||
|
||||
// Added by Amir Szekely 31st July 2002
|
||||
ICompressor *compressor;
|
||||
CZlib zlib_comressor;
|
||||
CBzip2 bzip2_compressor;
|
||||
bool build_compressor_set;
|
||||
bool build_compress_whole;
|
||||
|
||||
int has_called_write_output;
|
||||
|
||||
char build_packname[1024], build_packcmd[1024];
|
||||
int build_overwrite, build_compress, build_crcchk,
|
||||
build_datesave, build_optimize_datablock;
|
||||
|
||||
header build_header;
|
||||
int uninstall_mode;
|
||||
uninstall_header build_uninst;
|
||||
int uninstall_size,uninstall_size_full;
|
||||
int uninstaller_writes_used;
|
||||
|
||||
char build_output_filename[1024];
|
||||
char cur_out_path[1024];
|
||||
|
||||
int subsection_open_cnt;
|
||||
StringList 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;
|
||||
int build_sections_req,build_sections_div;
|
||||
|
||||
StringList ns_func, ns_label; // function and label namespaces
|
||||
|
||||
int build_cursection_isfunc;
|
||||
section *build_cursection;
|
||||
GrowBuf build_sections;
|
||||
GrowBuf build_entries,ubuild_entries, *cur_entries;
|
||||
GrowBuf build_functions, ubuild_functions, *cur_functions;
|
||||
GrowBuf build_labels, ubuild_labels, *cur_labels;
|
||||
StringList build_strlist,ubuild_strlist;
|
||||
|
||||
MMapBuf build_datablock, ubuild_datablock; // use GrowBuf here instead of MMapBuf if you want
|
||||
IGrowBuf *cur_datablock;
|
||||
|
||||
unsigned char *header_data_new;
|
||||
int exeheader_size_new;
|
||||
int enabled_bitmap_offset;
|
||||
int icon_offset;
|
||||
int m_inst_fileused;
|
||||
int m_uninst_fileused;
|
||||
bool branding_image_found; // Added by Amir Szekely 29nd July 2002
|
||||
WORD branding_image_id; // Added by Amir Szekely 29nd July 2002
|
||||
unsigned char *m_unicon_data;
|
||||
int deflateToFile(FILE *fp, char *buf, int len); // len==0 to flush
|
||||
};
|
||||
|
||||
#endif //_BUILD_H_
|
1100
Source/bzip2/blocksort.c
Normal file
1100
Source/bzip2/blocksort.c
Normal file
File diff suppressed because it is too large
Load diff
790
Source/bzip2/bzlib.c
Normal file
790
Source/bzip2/bzlib.c
Normal file
|
@ -0,0 +1,790 @@
|
|||
#include "../exehead/config.h"
|
||||
#if (defined(EXEHEAD) && defined(NSIS_COMPRESS_USE_BZIP2)) || !defined(EXEHEAD)
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- 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_private.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 BZ_API(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;
|
||||
strm->total_in_lo32 = 0;
|
||||
strm->total_in_hi32 = 0;
|
||||
strm->total_out_lo32 = 0;
|
||||
strm->total_out_hi32 = 0;
|
||||
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 BZ_API(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 BZ_API(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
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
/*--- Decompression stuff ---*/
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(BZ2_bzDecompressInit)
|
||||
( bz_stream* strm)
|
||||
{
|
||||
DState* s;
|
||||
|
||||
s = BZALLOC( sizeof(DState) );
|
||||
if (s == NULL) return BZ_MEM_ERROR;
|
||||
s->strm = strm;
|
||||
strm->state = s;
|
||||
s->state = BZ_X_BLKHDR_1;
|
||||
// s->bsLive = 0;
|
||||
// s->bsBuff = 0;
|
||||
strm->total_in_lo32 = 0;
|
||||
strm->total_in_hi32 = 0;
|
||||
strm->total_out_lo32 = 0;
|
||||
strm->total_out_hi32 = 0;
|
||||
#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
|
||||
s->ll16 = BZALLOC( NSIS_COMPRESS_BZIP2_LEVEL*100000 * sizeof(UInt16) );
|
||||
s->ll4 = BZALLOC(
|
||||
((1 + NSIS_COMPRESS_BZIP2_LEVEL*100000) >> 1) * sizeof(UChar)
|
||||
);
|
||||
if (s->ll16 == NULL || s->ll4 == NULL) return (BZ_MEM_ERROR);
|
||||
#else
|
||||
s->tt = BZALLOC( NSIS_COMPRESS_BZIP2_LEVEL * 100000 * sizeof(Int32) );
|
||||
if (s->tt == NULL) return (BZ_MEM_ERROR);
|
||||
#endif
|
||||
// s->currBlockNo = 0;
|
||||
|
||||
return BZ_OK;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
__inline__ Int32 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;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NSIS_COMPRESS_BZIP2_SMALLMODE
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void unRLE_obuf_to_output_SMALL ( DState* s )
|
||||
{
|
||||
UChar k1;
|
||||
|
||||
if (s->blockRandomised) {
|
||||
|
||||
while (True) {
|
||||
/* try to finish existing run */
|
||||
while (True) {
|
||||
if (s->strm->avail_out == 0) return;
|
||||
if (s->state_out_len == 0) break;
|
||||
*( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
|
||||
s->state_out_len--;
|
||||
s->strm->next_out++;
|
||||
s->strm->avail_out--;
|
||||
s->strm->total_out_lo32++;
|
||||
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
|
||||
}
|
||||
|
||||
/* 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); BZ_RAND_UPD_MASK;
|
||||
k1 ^= BZ_RAND_MASK; 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); BZ_RAND_UPD_MASK;
|
||||
k1 ^= BZ_RAND_MASK; 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); BZ_RAND_UPD_MASK;
|
||||
k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
||||
if (s->nblock_used == s->save_nblock+1) continue;
|
||||
if (k1 != s->k0) { s->k0 = k1; continue; };
|
||||
|
||||
BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
|
||||
k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
||||
s->state_out_len = ((Int32)k1) + 4;
|
||||
BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
|
||||
s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
while (True) {
|
||||
/* try to finish existing run */
|
||||
while (True) {
|
||||
if (s->strm->avail_out == 0) return;
|
||||
if (s->state_out_len == 0) break;
|
||||
*( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
|
||||
s->state_out_len--;
|
||||
s->strm->next_out++;
|
||||
s->strm->avail_out--;
|
||||
s->strm->total_out_lo32++;
|
||||
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
|
||||
}
|
||||
|
||||
/* 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 unRLE_obuf_to_output_FAST ( DState* s )
|
||||
{
|
||||
UChar k1;
|
||||
|
||||
if (s->blockRandomised) {
|
||||
|
||||
while (True) {
|
||||
/* try to finish existing run */
|
||||
while (True) {
|
||||
if (s->strm->avail_out == 0) return;
|
||||
if (s->state_out_len == 0) break;
|
||||
*( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
|
||||
BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
|
||||
s->state_out_len--;
|
||||
s->strm->next_out++;
|
||||
s->strm->avail_out--;
|
||||
s->strm->total_out_lo32++;
|
||||
if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
|
||||
}
|
||||
|
||||
/* 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_FAST(k1); BZ_RAND_UPD_MASK;
|
||||
k1 ^= BZ_RAND_MASK; 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_FAST(k1); BZ_RAND_UPD_MASK;
|
||||
k1 ^= BZ_RAND_MASK; 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_FAST(k1); BZ_RAND_UPD_MASK;
|
||||
k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
||||
if (s->nblock_used == s->save_nblock+1) continue;
|
||||
if (k1 != s->k0) { s->k0 = k1; continue; };
|
||||
|
||||
BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
|
||||
k1 ^= BZ_RAND_MASK; s->nblock_used++;
|
||||
s->state_out_len = ((Int32)k1) + 4;
|
||||
BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
|
||||
s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* restore */
|
||||
// UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC;
|
||||
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_tt = s->tt;
|
||||
UInt32 c_tPos = s->tPos;
|
||||
char* cs_next_out = s->strm->next_out;
|
||||
unsigned int cs_avail_out = s->strm->avail_out;
|
||||
/* end restore */
|
||||
|
||||
UInt32 avail_out_INIT = cs_avail_out;
|
||||
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;
|
||||
BZ_UPDATE_CRC ( c_calculatedBlockCRC, 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;
|
||||
BZ_UPDATE_CRC ( c_calculatedBlockCRC, 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:
|
||||
total_out_lo32_old = s->strm->total_out_lo32;
|
||||
s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
|
||||
if (s->strm->total_out_lo32 < total_out_lo32_old)
|
||||
s->strm->total_out_hi32++;
|
||||
|
||||
/* save */
|
||||
// s->calculatedBlockCRC = c_calculatedBlockCRC;
|
||||
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->tt = c_tt;
|
||||
s->tPos = c_tPos;
|
||||
s->strm->next_out = cs_next_out;
|
||||
s->strm->avail_out = cs_avail_out;
|
||||
/* end save */
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
|
||||
{
|
||||
DState* s;
|
||||
s = strm->state;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
AssertH ( 0, 6001 );
|
||||
|
||||
return 0; /*NOTREACHED*/
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm )
|
||||
{
|
||||
DState* s;
|
||||
s = strm->state;
|
||||
|
||||
#ifndef NSIS_COMPRESS_BZIP2_SMALLMODE
|
||||
BZFREE(s->tt);
|
||||
#else
|
||||
BZFREE(s->ll16);
|
||||
BZFREE(s->ll4);
|
||||
#endif
|
||||
BZFREE(strm->state);
|
||||
strm->state = NULL;
|
||||
|
||||
return BZ_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
174
Source/bzip2/bzlib.h
Normal file
174
Source/bzip2/bzlib.h
Normal file
|
@ -0,0 +1,174 @@
|
|||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- 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
|
||||
|
||||
#define BZ_NO_STDIO 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#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)
|
||||
|
||||
typedef
|
||||
struct {
|
||||
char *next_in;
|
||||
unsigned int avail_in;
|
||||
unsigned int total_in_lo32;
|
||||
unsigned int total_in_hi32;
|
||||
|
||||
char *next_out;
|
||||
unsigned int avail_out;
|
||||
unsigned int total_out_lo32;
|
||||
unsigned int total_out_hi32;
|
||||
|
||||
void *state;
|
||||
|
||||
void *opaque;
|
||||
}
|
||||
bz_stream;
|
||||
|
||||
|
||||
#ifndef BZ_IMPORT
|
||||
#define BZ_EXPORT
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <stdio.h>
|
||||
# include <windows.h>
|
||||
# ifdef small
|
||||
/* windows.h define small to char */
|
||||
# undef small
|
||||
# endif
|
||||
# ifdef BZ_EXPORT
|
||||
# define BZ_API(func) WINAPI func
|
||||
# define BZ_EXTERN extern
|
||||
# else
|
||||
/* import windows dll dynamically */
|
||||
# define BZ_API(func) (WINAPI * func)
|
||||
# define BZ_EXTERN
|
||||
# endif
|
||||
#else
|
||||
# define BZ_API(func) func
|
||||
# define BZ_EXTERN extern
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Core (low-level) library functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
|
||||
bz_stream* strm,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
|
||||
bz_stream* strm,
|
||||
int action
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
|
||||
bz_stream *strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
|
||||
bz_stream *strm
|
||||
);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
474
Source/bzip2/bzlib_private.h
Normal file
474
Source/bzip2/bzlib_private.h
Normal file
|
@ -0,0 +1,474 @@
|
|||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Private header file for the library. ---*/
|
||||
/*--- bzlib_private.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_PRIVATE_H
|
||||
#define _BZLIB_PRIVATE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
|
||||
|
||||
/*-- General stuff. --*/
|
||||
|
||||
#define BZ_VERSION "1.0.1, 23-June-2000"
|
||||
|
||||
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)
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __inline__ /* */
|
||||
#endif
|
||||
|
||||
#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) /* */
|
||||
|
||||
|
||||
#define BZALLOC(items) GlobalAlloc(GPTR,items)
|
||||
#define BZFREE(addr) { if (addr) GlobalFree(addr); }
|
||||
|
||||
|
||||
/*-- 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))
|
||||
|
||||
|
||||
|
||||
/*-- Stuff for randomising repetitive blocks. --*/
|
||||
|
||||
extern Int16 BZ2_rNums[512];
|
||||
|
||||
#define BZ_RAND_DECLS \
|
||||
Int32 rNToGo; \
|
||||
Int32 rTPos \
|
||||
|
||||
#define BZ_RAND_INIT_MASK \
|
||||
s->rNToGo = 0; \
|
||||
s->rTPos = 0 \
|
||||
|
||||
#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
|
||||
|
||||
#define BZ_RAND_UPD_MASK \
|
||||
if (s->rNToGo == 0) { \
|
||||
s->rNToGo = BZ2_rNums[s->rTPos]; \
|
||||
s->rTPos++; \
|
||||
if (s->rTPos == 512) s->rTPos = 0; \
|
||||
} \
|
||||
s->rNToGo--;
|
||||
|
||||
|
||||
|
||||
/*-- Stuff for doing CRCs. --*/
|
||||
|
||||
//extern UInt32 BZ2_crc32Table[256];
|
||||
|
||||
#define BZ_INITIALISE_CRC(crcVar)
|
||||
/* \
|
||||
{ \
|
||||
crcVar = 0xffffffffL; \
|
||||
}
|
||||
*/
|
||||
|
||||
#define BZ_FINALISE_CRC(crcVar)
|
||||
|
||||
/* \
|
||||
{ \
|
||||
crcVar = ~(crcVar); \
|
||||
}
|
||||
*/
|
||||
|
||||
#define BZ_UPDATE_CRC(crcVar,cha)
|
||||
/*
|
||||
\
|
||||
{ \
|
||||
crcVar = (crcVar << 8) ^ \
|
||||
BZ2_crc32Table[(crcVar >> 24) ^ \
|
||||
((UChar)cha)]; \
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*-- 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;
|
||||
BZ_RAND_DECLS;
|
||||
|
||||
/* 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 );
|
||||
|
||||
|
||||
|
||||
/*-- 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
|
||||
|
||||
|
||||
|
||||
/*-- Structure holding all the decompression-side stuff. --*/
|
||||
|
||||
typedef
|
||||
struct {
|
||||
/* pointer back to the struct bz_stream */
|
||||
bz_stream* strm;
|
||||
|
||||
/* state indicator for this stream */
|
||||
Int32 state;
|
||||
|
||||
/* for doing the final run-length decoding */
|
||||
UChar state_out_ch;
|
||||
Int32 state_out_len;
|
||||
Bool blockRandomised;
|
||||
BZ_RAND_DECLS;
|
||||
|
||||
/* the buffer for bit stream reading */
|
||||
UInt32 bsBuff;
|
||||
Int32 bsLive;
|
||||
|
||||
/* misc administratium */
|
||||
Int32 currBlockNo;
|
||||
Int32 verbosity;
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform */
|
||||
Int32 origPtr;
|
||||
UInt32 tPos;
|
||||
Int32 k0;
|
||||
Int32 unzftab[256];
|
||||
Int32 nblock_used;
|
||||
Int32 cftab[257];
|
||||
Int32 cftabCopy[257];
|
||||
|
||||
#ifndef NSIS_COMPRESS_BZIP2_SMALLMODE
|
||||
/* for undoing the Burrows-Wheeler transform (FAST) */
|
||||
UInt32 *tt;
|
||||
#else
|
||||
/* for undoing the Burrows-Wheeler transform (SMALL) */
|
||||
UInt16 *ll16;
|
||||
UChar *ll4;
|
||||
#endif
|
||||
|
||||
/* stored and calculated CRCs */
|
||||
// UInt32 storedBlockCRC;
|
||||
// UInt32 storedCombinedCRC;
|
||||
// UInt32 calculatedBlockCRC;
|
||||
//UInt32 calculatedCombinedCRC;
|
||||
|
||||
/* 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 */
|
||||
Int32 save_i;
|
||||
Int32 save_j;
|
||||
Int32 save_t;
|
||||
Int32 save_alphaSize;
|
||||
Int32 save_nGroups;
|
||||
Int32 save_nSelectors;
|
||||
Int32 save_EOB;
|
||||
Int32 save_groupNo;
|
||||
Int32 save_groupPos;
|
||||
Int32 save_nextSym;
|
||||
Int32 save_nblockMAX;
|
||||
Int32 save_nblock;
|
||||
Int32 save_es;
|
||||
Int32 save_N;
|
||||
Int32 save_curr;
|
||||
Int32 save_zt;
|
||||
Int32 save_zn;
|
||||
Int32 save_zvec;
|
||||
Int32 save_zj;
|
||||
Int32 save_gSel;
|
||||
Int32 save_gMinlen;
|
||||
Int32* save_gLimit;
|
||||
Int32* save_gBase;
|
||||
Int32* save_gPerm;
|
||||
|
||||
}
|
||||
DState;
|
||||
|
||||
|
||||
|
||||
/*-- 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;
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
/*-- externs for decompression. --*/
|
||||
|
||||
extern Int32
|
||||
BZ2_indexIntoF ( Int32, Int32* );
|
||||
|
||||
extern Int32
|
||||
BZ2_decompress ( DState* );
|
||||
|
||||
extern void
|
||||
BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
|
||||
Int32, Int32, Int32 );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
|
||||
|
||||
#ifdef BZ_NO_STDIO
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib_private.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
681
Source/bzip2/compress.c
Normal file
681
Source/bzip2/compress.c
Normal file
|
@ -0,0 +1,681 @@
|
|||
/*-------------------------------------------------------------*/
|
||||
/*--- 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_private.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
|
||||
__inline__
|
||||
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 );
|
||||
#if 0
|
||||
bsPutUChar ( s, 0x41 );
|
||||
bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
|
||||
bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
|
||||
#endif
|
||||
|
||||
/*-- Now the block's CRC, so it is in a known place. --*/
|
||||
// bsPutUInt32 ( s, s->blockCRC );
|
||||
|
||||
/*--
|
||||
Now a single bit indicating (non-)randomisation.
|
||||
As of version 0.9.5, we use a better sorting algorithm
|
||||
which makes randomisation unnecessary. So always set
|
||||
the randomised bit to 'no'. Of course, the decoder
|
||||
still needs to be able to handle randomised blocks
|
||||
so as to maintain backwards compatibility with
|
||||
older versions of bzip2.
|
||||
--*/
|
||||
bsW(s,1,0);
|
||||
|
||||
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 );
|
||||
#if 0
|
||||
bsPutUChar ( s, 0x72 );
|
||||
bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
|
||||
bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
|
||||
#endif
|
||||
// bsPutUInt32 ( s, s->combinedCRC );
|
||||
bsFinishWrite ( s );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end compress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
569
Source/bzip2/decompress.c
Normal file
569
Source/bzip2/decompress.c
Normal file
|
@ -0,0 +1,569 @@
|
|||
#include "../exehead/config.h"
|
||||
#ifdef NSIS_COMPRESS_USE_BZIP2
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- 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.
|
||||
--*/
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void makeMaps_d ( DState* s )
|
||||
{
|
||||
Int32 i;
|
||||
s->nInUse = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
if (s->inUse[i]) {
|
||||
s->seqToUnseq[s->nInUse] = i;
|
||||
s->nInUse++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define RETURN(rrr) \
|
||||
{ retVal = rrr; goto save_state_and_return; };
|
||||
|
||||
|
||||
static int __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;
|
||||
break;
|
||||
}
|
||||
if (s->strm->avail_in == 0) return 1;
|
||||
s->bsBuff = (s->bsBuff << 8) | ((UInt32) (*((UChar*)(s->strm->next_in))));
|
||||
s->bsLive += 8;
|
||||
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++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GET_BITS(lll,vvv,nnn) \
|
||||
case lll: s->state = lll; \
|
||||
{ int vtmp; if (__mygetbits(&vtmp,nnn,s)) RETURN(BZ_OK) \
|
||||
(vvv) = vtmp; }
|
||||
|
||||
#define GET_UCHAR(lll,uuu) \
|
||||
GET_BITS(lll,uuu,8)
|
||||
|
||||
#define GET_BIT(lll,uuu) \
|
||||
GET_BITS(lll,uuu,1)
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define GET_MTF_VAL(label1,label2,lval) \
|
||||
{ \
|
||||
if (groupPos == 0) { \
|
||||
groupNo++; \
|
||||
if (groupNo >= nSelectors) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
groupPos = BZ_G_SIZE; \
|
||||
gSel = s->selector[groupNo]; \
|
||||
gMinlen = s->minLens[gSel]; \
|
||||
gLimit = &(s->limit[gSel][0]); \
|
||||
gPerm = &(s->perm[gSel][0]); \
|
||||
gBase = &(s->base[gSel][0]); \
|
||||
} \
|
||||
groupPos--; \
|
||||
zn = gMinlen; \
|
||||
GET_BITS(label1, zvec, zn); \
|
||||
while (1) { \
|
||||
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 BZ2_decompress ( DState* s )
|
||||
{
|
||||
UChar uc;
|
||||
Int32 retVal;
|
||||
Int32 minLen, maxLen;
|
||||
bz_stream* strm = s->strm;
|
||||
|
||||
/* stuff that needs to be saved/restored */
|
||||
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;
|
||||
|
||||
/*restore from the save area*/
|
||||
i = s->save_i;
|
||||
j = s->save_j;
|
||||
t = s->save_t;
|
||||
alphaSize = s->save_alphaSize;
|
||||
nGroups = s->save_nGroups;
|
||||
nSelectors = s->save_nSelectors;
|
||||
EOB = s->save_EOB;
|
||||
groupNo = s->save_groupNo;
|
||||
groupPos = s->save_groupPos;
|
||||
nextSym = s->save_nextSym;
|
||||
nblockMAX = s->save_nblockMAX;
|
||||
nblock = s->save_nblock;
|
||||
es = s->save_es;
|
||||
N = s->save_N;
|
||||
curr = s->save_curr;
|
||||
zt = s->save_zt;
|
||||
zn = s->save_zn;
|
||||
zvec = s->save_zvec;
|
||||
zj = s->save_zj;
|
||||
gSel = s->save_gSel;
|
||||
gMinlen = s->save_gMinlen;
|
||||
gLimit = s->save_gLimit;
|
||||
gBase = s->save_gBase;
|
||||
gPerm = s->save_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->currBlockNo++;
|
||||
|
||||
GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
|
||||
|
||||
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;
|
||||
}
|
||||
makeMaps_d ( s );
|
||||
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;
|
||||
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;
|
||||
do {
|
||||
if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
|
||||
if (nextSym == BZ_RUNB) es = es + (1+1) * N;
|
||||
N = N * 2;
|
||||
GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
|
||||
}
|
||||
while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
|
||||
|
||||
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;
|
||||
if (s->blockRandomised) {
|
||||
BZ_RAND_INIT_MASK;
|
||||
BZ_GET_SMALL(s->k0); s->nblock_used++;
|
||||
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
|
||||
} else {
|
||||
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;
|
||||
if (s->blockRandomised) {
|
||||
BZ_RAND_INIT_MASK;
|
||||
BZ_GET_FAST(s->k0); s->nblock_used++;
|
||||
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
|
||||
} else {
|
||||
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_i = i;
|
||||
s->save_j = j;
|
||||
s->save_t = t;
|
||||
s->save_alphaSize = alphaSize;
|
||||
s->save_nGroups = nGroups;
|
||||
s->save_nSelectors = nSelectors;
|
||||
s->save_EOB = EOB;
|
||||
s->save_groupNo = groupNo;
|
||||
s->save_groupPos = groupPos;
|
||||
s->save_nextSym = nextSym;
|
||||
s->save_nblockMAX = nblockMAX;
|
||||
s->save_nblock = nblock;
|
||||
s->save_es = es;
|
||||
s->save_N = N;
|
||||
s->save_curr = curr;
|
||||
s->save_zt = zt;
|
||||
s->save_zn = zn;
|
||||
s->save_zvec = zvec;
|
||||
s->save_zj = zj;
|
||||
s->save_gSel = gSel;
|
||||
s->save_gMinlen = gMinlen;
|
||||
s->save_gLimit = gLimit;
|
||||
s->save_gBase = gBase;
|
||||
s->save_gPerm = gPerm;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end decompress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
#endif
|
229
Source/bzip2/huffman.c
Normal file
229
Source/bzip2/huffman.c
Normal file
|
@ -0,0 +1,229 @@
|
|||
/*-------------------------------------------------------------*/
|
||||
/*--- 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.
|
||||
--*/
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
#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 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 ---*/
|
||||
/*-------------------------------------------------------------*/
|
127
Source/bzip2/randtable.c
Normal file
127
Source/bzip2/randtable.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
#include "../exehead/config.h"
|
||||
#ifdef NSIS_COMPRESS_USE_BZIP2
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Table for randomising repetitive blocks ---*/
|
||||
/*--- randtable.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.
|
||||
--*/
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------*/
|
||||
Int16 BZ2_rNums[512] = {
|
||||
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
|
||||
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
|
||||
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
|
||||
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
|
||||
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
|
||||
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
|
||||
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
|
||||
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
|
||||
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
|
||||
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
|
||||
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
|
||||
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
|
||||
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
|
||||
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
|
||||
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
|
||||
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
|
||||
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
|
||||
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
|
||||
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
|
||||
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
|
||||
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
|
||||
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
|
||||
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
|
||||
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
|
||||
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
|
||||
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
|
||||
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
|
||||
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
|
||||
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
|
||||
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
|
||||
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
|
||||
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
|
||||
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
|
||||
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
|
||||
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
|
||||
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
|
||||
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
|
||||
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
|
||||
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
|
||||
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
|
||||
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
|
||||
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
|
||||
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
|
||||
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
|
||||
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
|
||||
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
|
||||
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
|
||||
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
|
||||
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
|
||||
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
|
||||
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
|
||||
936, 638
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end randtable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
#endif
|
51
Source/cbzip2.h
Normal file
51
Source/cbzip2.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
#ifndef __CBZIP2_H__
|
||||
#define __CBZIP2_H__
|
||||
|
||||
#include "compressor.h"
|
||||
#include "bzip2/bzlib.h"
|
||||
|
||||
class CBzip2 : public ICompressor {
|
||||
public:
|
||||
int Init(int level) {
|
||||
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) {
|
||||
return BZ2_bzCompress(stream, finish?BZ_FINISH:0);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private:
|
||||
bz_stream *stream;
|
||||
};
|
||||
|
||||
#endif
|
22
Source/compressor.h
Normal file
22
Source/compressor.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef __COMPRESSOR_H__
|
||||
#define __COMPRESSOR_H__
|
||||
|
||||
#define C_OK 0
|
||||
#define C_FINISH TRUE
|
||||
|
||||
class ICompressor {
|
||||
public:
|
||||
virtual int Init(int level) = 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;
|
||||
};
|
||||
|
||||
#endif
|
34
Source/crc32.c
Normal file
34
Source/crc32.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include "exehead/config.h"
|
||||
#ifdef NSIS_CONFIG_CRC_SUPPORT
|
||||
|
||||
// this is based on the (slow,small) CRC32 implementation from zlib.
|
||||
|
||||
static unsigned long crc_table[256];
|
||||
|
||||
static void make_crc_table()
|
||||
{
|
||||
unsigned long c;
|
||||
int n, k;
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
{
|
||||
c = (unsigned long)n;
|
||||
for (k = 0; k < 8; k++) c = (c >> 1) ^ (c & 1 ? 0xedb88320L : 0);
|
||||
crc_table[n] = c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// actually CRC32, but we put it in here so we don't
|
||||
// have to modify the other code.
|
||||
unsigned long CRC32(unsigned long crc, const unsigned char *buf, unsigned int len)
|
||||
{
|
||||
if (!crc_table[1]) make_crc_table();
|
||||
crc = crc ^ 0xffffffffL;
|
||||
while (len-- > 0) {
|
||||
crc = crc_table[(crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
|
||||
}
|
||||
return crc ^ 0xffffffffL;
|
||||
}
|
||||
|
||||
#endif
|
51
Source/czlib.h
Normal file
51
Source/czlib.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
#ifndef __CZLIB_H__
|
||||
#define __CZLIB_H__
|
||||
|
||||
#include "compressor.h"
|
||||
#include "zlib/ZLIB.H"
|
||||
|
||||
class CZlib : public ICompressor {
|
||||
public:
|
||||
int Init(int level) {
|
||||
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;
|
||||
}
|
||||
|
||||
private:
|
||||
z_stream *stream;
|
||||
};
|
||||
|
||||
#endif
|
17
Source/exedata.cpp
Normal file
17
Source/exedata.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "exedata.h"
|
||||
|
||||
#ifdef NSIS_CONFIG_COMPONENTPAGE
|
||||
#include "exehead/Release-zlib/bitmap1.h"
|
||||
#endif
|
||||
#include "exehead/Release-zlib/icon.h"
|
||||
#include "exehead/Release-zlib/unicon.h"
|
||||
#include "exehead/Release-zlib/exehead_zlib.h"
|
||||
#include "exehead/Release-bzip2/exehead_bzip2.h"
|
||||
// Changed by Amir Szekely 31st July 2002
|
||||
int zlib_exeheader_size=sizeof(zlib_header_data);
|
||||
int bzip2_exeheader_size=sizeof(bzip2_header_data);
|
||||
int exeheader_size=0;
|
||||
|
||||
// Changed by Amir Szekely 8th July 2002
|
||||
int icondata_size=sizeof(icon_data)-22;
|
||||
int unicondata_size=sizeof(unicon_data)-22;
|
16
Source/exedata.h
Normal file
16
Source/exedata.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef _EXEDATA_H_
|
||||
#define _EXEDATA_H_
|
||||
|
||||
extern int zlib_exeheader_size;
|
||||
extern int bzip2_exeheader_size;
|
||||
extern int exeheader_size;
|
||||
extern int icondata_size;
|
||||
extern int unicondata_size;
|
||||
|
||||
extern unsigned char zlib_header_data[];
|
||||
extern unsigned char bzip2_header_data[];
|
||||
extern unsigned char icon_data[];
|
||||
extern unsigned char unicon_data[];
|
||||
extern unsigned char bitmap1_data[630];
|
||||
|
||||
#endif //_EXEDATA_H_
|
364
Source/exehead/Main.c
Normal file
364
Source/exehead/Main.c
Normal file
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
Nullsoft "SuperPimp" Installation System - main.c - executable header main code
|
||||
|
||||
Copyright (C) 1999-2002 Nullsoft, Inc.
|
||||
|
||||
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.
|
||||
|
||||
This source distribution includes portions of zlib. see zlib/zlib.h for
|
||||
its license and so forth. Note that this license is also borrowed from zlib.
|
||||
*/
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include "resource.h"
|
||||
#include "util.h"
|
||||
#include "fileform.h"
|
||||
#include "state.h"
|
||||
#include "ui.h"
|
||||
|
||||
#include "lang.h"
|
||||
|
||||
extern unsigned long CRC32(unsigned long crc, const unsigned char *buf, unsigned int len);
|
||||
|
||||
#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
|
||||
#ifdef NSIS_CONFIG_CRC_SUPPORT
|
||||
static const char *g_crcinvalid=_LANG_INVALIDCRC;
|
||||
#else
|
||||
static const char *g_crcinvalid=_LANG_INVALIDINST;
|
||||
#endif
|
||||
|
||||
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
|
||||
static const char *g_errorcopyinginstall=_LANG_UNINSTINITERROR;
|
||||
#endif
|
||||
|
||||
char g_caption[NSIS_MAX_STRLEN*2];
|
||||
int g_filehdrsize;
|
||||
HWND g_hwnd;
|
||||
|
||||
static int m_length;
|
||||
static int m_pos;
|
||||
|
||||
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
|
||||
#ifdef NSIS_CONFIG_CRC_SUPPORT
|
||||
static 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)
|
||||
{
|
||||
static char bt[64];
|
||||
wsprintf(bt,_LANG_VERIFYINGINST,MulDiv(m_pos,100,m_length));
|
||||
|
||||
SetWindowText(hwndDlg,bt);
|
||||
SetDlgItemText(hwndDlg,IDC_STR,bt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif//NSIS_CONFIG_CRC_SUPPORT
|
||||
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, int nCmdShow)
|
||||
{
|
||||
static int ret;
|
||||
static const char *m_Err;
|
||||
#ifdef NSIS_CONFIG_CRC_SUPPORT
|
||||
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
|
||||
static HWND hwnd;
|
||||
#endif
|
||||
static int crc;
|
||||
static char no_crc;
|
||||
static char do_crc;
|
||||
#endif//NSIS_CONFIG_CRC_SUPPORT
|
||||
#if defined(NSIS_CONFIG_SILENT_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
|
||||
static char silent;
|
||||
#endif//NSIS_CONFIG_SILENT_SUPPORT && NSIS_CONFIG_VISIBLE_SUPPORT
|
||||
int left;
|
||||
|
||||
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
|
||||
unsigned int verify_time=GetTickCount()+1000;
|
||||
#endif
|
||||
char *cmdline=state_command_line;
|
||||
char *realcmds;
|
||||
char seekchar=' ';
|
||||
|
||||
InitCommonControls();
|
||||
lstrcpyn(state_command_line,GetCommandLine(),NSIS_MAX_STRLEN);
|
||||
|
||||
if (*cmdline == '\"') seekchar = *cmdline++;
|
||||
|
||||
while (*cmdline && *cmdline != seekchar) if (*cmdline) cmdline++;
|
||||
if (*cmdline) cmdline++;
|
||||
realcmds=cmdline;
|
||||
|
||||
do
|
||||
{
|
||||
#ifdef NSIS_CONFIG_CRC_SUPPORT
|
||||
#endif//NSIS_CONFIG_CRC_SUPPORT
|
||||
while (*cmdline == ' ') if (*cmdline) cmdline++;
|
||||
if (cmdline[0] != '/') break;
|
||||
cmdline++;
|
||||
#if defined(NSIS_CONFIG_VISIBLE_SUPPORT) && defined(NSIS_CONFIG_SILENT_SUPPORT)
|
||||
if (cmdline[0] == 'S' && (cmdline[1] == ' ' || !cmdline[1]))
|
||||
{
|
||||
silent++;
|
||||
cmdline+=2;
|
||||
}
|
||||
else
|
||||
#endif//NSIS_CONFIG_SILENT_SUPPORT && NSIS_CONFIG_VISIBLE_SUPPORT
|
||||
#ifdef NSIS_CONFIG_CRC_SUPPORT
|
||||
if (cmdline[0] == 'N' &&
|
||||
cmdline[1] == 'C' &&
|
||||
cmdline[2] == 'R' &&
|
||||
cmdline[3] == 'C' &&
|
||||
(cmdline[4] == ' ' || !cmdline[4]))
|
||||
{
|
||||
no_crc++;
|
||||
cmdline+=4;
|
||||
}
|
||||
else
|
||||
#endif//NSIS_CONFIG_CRC_SUPPORT
|
||||
if (cmdline[0] == 'D' && cmdline[1] == '=')
|
||||
{
|
||||
cmdline[-2]=0; // keep this from being passed to uninstaller if necessary
|
||||
lstrcpy(state_install_directory,cmdline+2);
|
||||
cmdline+=lstrlen(cmdline);
|
||||
}
|
||||
else while (*cmdline && *cmdline != ' ') if (*cmdline) cmdline++;
|
||||
}
|
||||
while (*cmdline);
|
||||
|
||||
lstrcpy(g_caption,_LANG_GENERIC_ERROR);
|
||||
|
||||
g_hInstance=GetModuleHandle(NULL);
|
||||
GetModuleFileName(g_hInstance,state_exe_directory,NSIS_MAX_STRLEN);
|
||||
|
||||
g_db_hFile=myOpenFile(state_exe_directory,GENERIC_READ,OPEN_EXISTING);
|
||||
if (g_db_hFile==INVALID_HANDLE_VALUE)
|
||||
{
|
||||
m_Err = _LANG_CANTOPENSELF;
|
||||
goto end;
|
||||
}
|
||||
|
||||
// make state_exe_directory point to dir, not full exe.
|
||||
|
||||
trimslashtoend(state_exe_directory);
|
||||
|
||||
left = m_length = GetFileSize(g_db_hFile,NULL);
|
||||
while (left > 0)
|
||||
{
|
||||
static char temp[512];
|
||||
DWORD l=left;
|
||||
if (l > 512) l=512;
|
||||
if (!ReadFile(g_db_hFile,temp,l,&l,NULL))
|
||||
{
|
||||
m_Err=g_crcinvalid;
|
||||
#if defined(NSIS_CONFIG_CRC_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
|
||||
if (hwnd) DestroyWindow(hwnd);
|
||||
#endif//NSIS_CONFIG_CRC_SUPPORT
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!g_filehdrsize)
|
||||
{
|
||||
int dbl;
|
||||
dbl=isheader((firstheader*)temp);
|
||||
if (dbl)
|
||||
{
|
||||
int a=*(int*)temp;
|
||||
g_filehdrsize=m_pos;
|
||||
if (dbl > left)
|
||||
{
|
||||
m_Err=g_crcinvalid;
|
||||
goto end;
|
||||
}
|
||||
#if defined(NSIS_CONFIG_SILENT_SUPPORT) && defined(NSIS_CONFIG_VISIBLE_SUPPORT)
|
||||
if (a&FH_FLAGS_SILENT) silent++;
|
||||
#endif//NSIS_CONFIG_SILENT_SUPPORT && NSIS_CONFIG_VISIBLE_SUPPORT
|
||||
|
||||
#ifdef NSIS_CONFIG_CRC_SUPPORT
|
||||
// Changed by Amir Szekely 23rd July 2002 (CRCCheck force)
|
||||
if ((no_crc && !(a&FH_FLAGS_FORCE_CRC)) || !(a&FH_FLAGS_CRC)) break; // if first bit is not set, then no crc checking.
|
||||
|
||||
do_crc++;
|
||||
|
||||
#ifndef NSIS_CONFIG_CRC_ANAL
|
||||
left=dbl-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
|
||||
break;
|
||||
#endif//!NSIS_CONFIG_CRC_SUPPORT
|
||||
}
|
||||
}
|
||||
#ifdef NSIS_CONFIG_CRC_SUPPORT
|
||||
|
||||
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
|
||||
|
||||
#ifdef NSIS_CONFIG_SILENT_SUPPORT
|
||||
else if (!silent)
|
||||
#endif//NSIS_CONFIG_SILENT_SUPPORT
|
||||
{
|
||||
if (hwnd)
|
||||
{
|
||||
static MSG msg;
|
||||
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) DispatchMessage(&msg);
|
||||
}
|
||||
else if (GetTickCount() > verify_time)
|
||||
hwnd=CreateDialog(g_hInstance,MAKEINTRESOURCE(IDD_VERIFY),GetDesktopWindow(),verProc);
|
||||
}
|
||||
#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) m_Err=g_crcinvalid;
|
||||
else
|
||||
{
|
||||
#ifdef NSIS_CONFIG_CRC_SUPPORT
|
||||
if (do_crc)
|
||||
{
|
||||
DWORD l;
|
||||
int fcrc;
|
||||
SetFilePointer(g_db_hFile,m_pos,NULL,FILE_BEGIN);
|
||||
if (!ReadFile(g_db_hFile,&fcrc,4,&l,NULL) || crc != fcrc)
|
||||
{
|
||||
m_Err=g_crcinvalid;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
#endif//NSIS_CONFIG_CRC_SUPPORT
|
||||
SetFilePointer(g_db_hFile,g_filehdrsize,NULL,FILE_BEGIN);
|
||||
|
||||
if (loadHeaders()) m_Err=g_crcinvalid;
|
||||
}
|
||||
if (m_Err) goto end;
|
||||
|
||||
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
|
||||
if (g_is_uninstaller)
|
||||
{
|
||||
if (cmdline[0] == '_' && cmdline[1] == '=' && cmdline[2])
|
||||
{
|
||||
cmdline[-1]=0;
|
||||
cmdline+=2;
|
||||
if (is_valid_instpath(cmdline))
|
||||
{
|
||||
lstrcpy(state_install_directory,cmdline);
|
||||
lstrcpy(state_output_directory,cmdline);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Err = g_errorcopyinginstall;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int x,done=0;
|
||||
|
||||
for (x = 0; x < 26; x ++)
|
||||
{
|
||||
static char s[]="A~NSISu_.exe";
|
||||
static char buf2[NSIS_MAX_STRLEN*2];
|
||||
static char ibuf[NSIS_MAX_STRLEN];
|
||||
|
||||
buf2[0]='\"';
|
||||
GetTempPath(sizeof(buf2)-1,buf2+1);
|
||||
lstrcat(buf2,s);
|
||||
|
||||
DeleteFile(buf2+1); // clean up after all the other ones if they are there
|
||||
|
||||
if (!done)
|
||||
{
|
||||
// get current name
|
||||
int l=GetModuleFileName(g_hInstance,ibuf,sizeof(ibuf));
|
||||
// check if it is ?~NSISu_.exe - if so, fuck it
|
||||
if (!lstrcmpi(ibuf+l-(sizeof(s)-2),s+1)) break;
|
||||
|
||||
// copy file
|
||||
if (CopyFile(ibuf,buf2+1,FALSE))
|
||||
{
|
||||
HANDLE hProc;
|
||||
#ifdef NSIS_SUPPORT_MOVEONREBOOT
|
||||
MoveFileOnReboot(buf2+1,NULL);
|
||||
#endif
|
||||
if (state_install_directory[0]) lstrcpy(ibuf,state_install_directory);
|
||||
else trimslashtoend(ibuf);
|
||||
if (!is_valid_instpath(ibuf)) break;
|
||||
done++;
|
||||
lstrcat(buf2,"\" ");
|
||||
lstrcat(buf2,realcmds);
|
||||
lstrcat(buf2," _=");
|
||||
lstrcat(buf2,ibuf);
|
||||
GetTempPath(sizeof(ibuf),ibuf);
|
||||
hProc=myCreateProcess(buf2,ibuf);
|
||||
if (hProc) CloseHandle(hProc);
|
||||
else m_Err = g_errorcopyinginstall;
|
||||
}
|
||||
}
|
||||
s[0]++;
|
||||
}
|
||||
if (!done) m_Err=g_errorcopyinginstall;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
|
||||
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
|
||||
#ifdef NSIS_CONFIG_SILENT_SUPPORT
|
||||
if (!g_inst_cmnheader->silent_install) g_inst_cmnheader->silent_install=silent;
|
||||
#endif//NSIS_CONFIG_SILENT_SUPPORT
|
||||
#endif//NSIS_CONFIG_VISIBLE_SUPPORT
|
||||
|
||||
ret=ui_doinstall();
|
||||
|
||||
#ifdef NSIS_CONFIG_LOG
|
||||
log_write(1);
|
||||
#endif//NSIS_CONFIG_LOG
|
||||
end:
|
||||
if (g_db_hFile!=INVALID_HANDLE_VALUE) CloseHandle(g_db_hFile);
|
||||
#ifdef NSIS_COMPRESS_WHOLE
|
||||
if (dbd_hFile!=INVALID_HANDLE_VALUE) CloseHandle(dbd_hFile);
|
||||
#endif
|
||||
if (m_Err) MessageBox(NULL,m_Err,g_caption,MB_OK|MB_ICONSTOP);
|
||||
ExitProcess(ret);
|
||||
}
|
||||
|
81
Source/exehead/Makefile
Normal file
81
Source/exehead/Makefile
Normal file
|
@ -0,0 +1,81 @@
|
|||
# -- Objects and source files --
|
||||
SRCS = bgbg.c exec.c fileform.c main.c ui.c util.c ../crc32.c ../zlib/infblock.c ../zlib/infcodes.c ../zlib/inflate.c ../zlib/inftrees.c ../zlib/infutil.c ../bzip2/bzlib.c ../bzip2/decompress.c ../bzip2/huffman.c ../bzip2/randtable.c
|
||||
OBJS = bgbg.o exec.o fileform.o main.o ui.o util.o resource.res crc32.o infblock.o infcodes.o inflate.o inftrees.o infutil.o bzlib.o decompress.o huffman.o randtable.o
|
||||
LIBS = -lole32 -lgdi32 -lversion -luuid -lcomctl32 -lkernel32 -luser32 -lshell32 -ladvapi32
|
||||
|
||||
# -- Programs --
|
||||
CC = gcc
|
||||
RC = windres
|
||||
RM = del
|
||||
|
||||
# -- Compilers and linker flags --
|
||||
DEFINES = -DWIN32 -D_WINDOWS_ -DEXEHEAD -DWinMain=WinMainCRTStartup
|
||||
CFLAGS = -Os -fomit-frame-pointer -fno-inline $(DEFINES)
|
||||
LFLAGS = -s -mwindows -nostdlib -nostartfiles -Wl,--enable-stdcall-fixup
|
||||
RCFLAGS = --input-format rc --output-format coff
|
||||
|
||||
all : exehead
|
||||
|
||||
exehead : $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LFLAGS) -o exehead.exe $(OBJS) $(LIBS)
|
||||
bin2h exehead.exe Release\exehead.h header_data
|
||||
bin2h bitmap1.bmp Release\bitmap1.h bitmap1_data
|
||||
bin2h bitmap2.bmp Release\bitmap2.h bitmap2_data
|
||||
bin2h nsis.ico Release\icon.h icon_data
|
||||
bin2h uninst.ico Release\unicon.h unicon_data
|
||||
|
||||
# -- Dependencies --
|
||||
bgbg.o : bgbg.c resource.h config.h Makefile
|
||||
exec.o : exec.c fileform.h util.h state.h ui.h exec.h config.h lang.h Makefile
|
||||
fileform.o : fileform.c fileform.h util.h state.h ../zlib/zlib.h ../zlib/zconf.h ui.h config.h Makefile
|
||||
main.o : main.c resource.h util.h fileform.h state.h ui.h ../zlib/zlib.h ../zlib/zconf.h config.h lang.h Makefile
|
||||
ui.o : ui.c resource.h fileform.h state.h ui.h config.h Makefile
|
||||
util.o : util.c util.h state.h fileform.h ui.h config.h Makefile
|
||||
|
||||
# -- Special command line for the resource file --
|
||||
resource.res : resource.rc resource.h config.h Makefile
|
||||
$(RC) $(RCFLAGS) -o resource.res -i resource.rc
|
||||
|
||||
crc32.o : ../crc32.c config.h Makefile
|
||||
$(CC) $(CFLAGS) -c ../crc32.c -o crc32.o
|
||||
|
||||
|
||||
# -- Special command lines for zlib --
|
||||
infblock.o : ../zlib/infblock.c ../zlib/zutil.h ../zlib/infblock.h ../zlib/inftrees.h ../zlib/infcodes.h ../zlib/infutil.h ../zlib/zlib.h ../zlib/zconf.h Makefile
|
||||
$(CC) $(CFLAGS) -c ../zlib/infblock.c -o infblock.o
|
||||
|
||||
infcodes.o : ../zlib/infcodes.c ../zlib/zutil.h ../zlib/inftrees.h ../zlib/infblock.h ../zlib/infcodes.h ../zlib/infutil.h ../zlib/zlib.h ../zlib/zconf.h Makefile
|
||||
$(CC) $(CFLAGS) -c ../zlib/infcodes.c -o infcodes.o
|
||||
|
||||
inflate.o : ../zlib/inflate.c ../zlib/zutil.h ../zlib/infblock.h ../zlib/zlib.h ../zlib/zconf.h Makefile
|
||||
$(CC) $(CFLAGS) -c ../zlib/inflate.c -o inflate.o
|
||||
|
||||
inftrees.o : ../zlib/inftrees.c ../zlib/zutil.h ../zlib/inftrees.h ../zlib/zlib.h ../zlib/zconf.h Makefile
|
||||
$(CC) $(CFLAGS) -c ../zlib/inftrees.c -o inftrees.o
|
||||
|
||||
infutil.o : ../zlib/infutil.c ../zlib/zutil.h ../zlib/infblock.h ../zlib/inftrees.h ../zlib/infcodes.h ../zlib/infutil.h ../zlib/zlib.h ../zlib/zconf.h Makefile
|
||||
$(CC) $(CFLAGS) -c ../zlib/infutil.c -o infutil.o
|
||||
|
||||
# -- Special command lines for bzip2 --
|
||||
bzlib.o : ../bzip2/bzlib.c ../bzip2/bzlib.h ../bzip2/bzlib_private.h config.h
|
||||
$(CC) $(CFLAGS) -c ../bzip2/bzlib.c -o bzlib.o
|
||||
|
||||
decompress.o : ../bzip2/decompress.c ../bzip2/bzlib.h ../bzip2/bzlib_private.h config.h
|
||||
$(CC) $(CFLAGS) -c ../bzip2/decompress.c -o decompress.o
|
||||
|
||||
huffman.o : ../bzip2/huffman.c ../bzip2/bzlib.h ../bzip2/bzlib_private.h config.h
|
||||
$(CC) $(CFLAGS) -c ../bzip2/huffman.c -o huffman.o
|
||||
|
||||
randtable.o : ../bzip2/randtable.c ../bzip2/bzlib.h ../bzip2/bzlib_private.h config.h
|
||||
$(CC) $(CFLAGS) -c ../bzip2/randtable.c -o randtable.o
|
||||
|
||||
# -- Clean script --
|
||||
clean ::
|
||||
$(RM) *.o
|
||||
$(RM) resource.res
|
||||
$(RM) exehead.exe
|
||||
$(RM) Release\exehead.h
|
||||
$(RM) Release\bitmap1.h
|
||||
$(RM) Release\bitmap2.h
|
||||
$(RM) Release\icon.h
|
||||
$(RM) Release\unicon.h
|
1237
Source/exehead/Ui.c
Normal file
1237
Source/exehead/Ui.c
Normal file
File diff suppressed because it is too large
Load diff
5
Source/exehead/afxres.h
Normal file
5
Source/exehead/afxres.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include <windows.h>
|
||||
|
||||
#ifndef IDC_STATIC
|
||||
#define IDC_STATIC -1
|
||||
#endif
|
90
Source/exehead/bgbg.c
Normal file
90
Source/exehead/bgbg.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifdef NSIS_SUPPORT_BGBG
|
||||
|
||||
static int m_color1, m_color2, m_textcolor;
|
||||
|
||||
static LRESULT CALLBACK BG_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_PAINT:
|
||||
{
|
||||
static PAINTSTRUCT ps;
|
||||
HFONT newFont, oldFont;
|
||||
HDC hdc=BeginPaint(hwnd,&ps);
|
||||
RECT r;
|
||||
int y;
|
||||
GetClientRect(hwnd,&r);
|
||||
// this portion by Drew Davidson, drewdavidson@mindspring.com
|
||||
|
||||
// JF: made slower, reduced to 4 pixels high, because I like how it looks better/
|
||||
for (y = r.top; y < r.bottom; y += 4)
|
||||
{
|
||||
int rv,gv,bv;
|
||||
RECT rect;
|
||||
HBRUSH brush;
|
||||
rv = GetRValue(m_color2) * y / r.bottom + GetRValue(m_color1) * (r.bottom - y) / r.bottom;
|
||||
gv = GetGValue(m_color2) * y / r.bottom + GetGValue(m_color1) * (r.bottom - y) / r.bottom;
|
||||
bv = GetBValue(m_color2) * y / r.bottom + GetBValue(m_color1) * (r.bottom - y) / r.bottom;
|
||||
brush = CreateSolidBrush(RGB(rv,gv,bv));
|
||||
SetRect(&rect, r.left, y, r.right, y+4);
|
||||
// note that we don't need to do "SelectObject(hdc, brush)"
|
||||
// because FillRect lets us specify the brush as a parameter.
|
||||
FillRect(hdc, &rect, brush);
|
||||
DeleteObject(brush);
|
||||
}
|
||||
|
||||
if (m_textcolor != -1)
|
||||
{
|
||||
newFont = CreateFont(40,0,0,0,FW_BOLD,TRUE,FALSE,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH,"Garamond");
|
||||
if (newFont)
|
||||
{
|
||||
static char buf[256];
|
||||
r.left+=16;
|
||||
r.top+=8;
|
||||
GetWindowText(hwnd,buf,sizeof(buf));
|
||||
SetBkMode(hdc,TRANSPARENT);
|
||||
SetTextColor(hdc,m_textcolor);
|
||||
oldFont = SelectObject(hdc,newFont);
|
||||
DrawText(hdc,buf,-1,&r,DT_TOP|DT_LEFT|DT_SINGLELINE);
|
||||
SelectObject(hdc,oldFont);
|
||||
DeleteObject(newFont);
|
||||
}
|
||||
}
|
||||
EndPaint(hwnd,&ps);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProc(hwnd,uMsg,wParam,lParam);
|
||||
}
|
||||
|
||||
|
||||
HWND bgWnd_Init(HINSTANCE hInstance, char *title, int color1, int color2, int color3)
|
||||
{
|
||||
RECT vp;
|
||||
char classname[4]="_Nb";
|
||||
static WNDCLASS wc;
|
||||
wc.style = CS_VREDRAW | CS_HREDRAW;
|
||||
wc.lpfnWndProc = BG_WndProc;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON2));
|
||||
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
|
||||
wc.lpszClassName = classname;
|
||||
|
||||
if (!RegisterClass(&wc)) return 0;
|
||||
|
||||
m_color1=color1;
|
||||
m_color2=color2;
|
||||
m_textcolor=color3;
|
||||
|
||||
SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0);
|
||||
|
||||
return CreateWindow(classname,title,WS_VISIBLE|WS_OVERLAPPED|WS_THICKFRAME|WS_CAPTION|WS_SYSMENU|WS_MAXIMIZEBOX|WS_MINIMIZEBOX,
|
||||
vp.left,vp.top,vp.right-vp.left,vp.bottom-vp.top,GetDesktopWindow(),NULL,hInstance,NULL);
|
||||
}
|
||||
|
||||
|
||||
#endif //NSIS_SUPPORT_BGBG
|
60
Source/exehead/bin2h.c
Normal file
60
Source/exehead/bin2h.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* Generates a .h file from a binary file.
|
||||
** v1.2 - 3/8/01
|
||||
** Copyright (C) 1996-2001 Justin Frankel
|
||||
** Public domain.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int length;
|
||||
FILE *in, *out;
|
||||
char *outfilename;
|
||||
char *token;
|
||||
int total_bytes=0;
|
||||
|
||||
if (argc != 4) {
|
||||
fprintf(stderr,"Usage: bin2h file.dat outfile.h token_name\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
in = fopen(argv[1],"rb");
|
||||
|
||||
if (!in) {
|
||||
fprintf(stderr,"Error: file not found\n");
|
||||
return 1;
|
||||
}
|
||||
out = fopen(argv[2],"wt");
|
||||
|
||||
if (!out) {
|
||||
fclose(in);
|
||||
fprintf(stderr,"Error: could not open output file\n");
|
||||
return 1;
|
||||
}
|
||||
fseek(in,0,SEEK_END);
|
||||
length=ftell(in);
|
||||
fseek(in,0,SEEK_SET);
|
||||
|
||||
outfilename = argv[2];
|
||||
token = argv[3];
|
||||
fprintf(out,"unsigned char %s[%d] = { \n",token,length);
|
||||
for (;;) {
|
||||
static int firsttime;
|
||||
static int linecount;
|
||||
int c;
|
||||
if (++linecount > 10) {
|
||||
linecount = 0;
|
||||
fprintf(out,",\n ");
|
||||
}
|
||||
else if (firsttime) fprintf(out,", ");
|
||||
firsttime = 1;
|
||||
c = fgetc(in);
|
||||
if (feof(in)) break;
|
||||
total_bytes++;
|
||||
fprintf(out,"%i",c);
|
||||
}
|
||||
fprintf(out,"};\n",token);
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
fprintf(stderr,"%s -> %s (%d bytes)\n\n",argv[1],token,total_bytes);
|
||||
return 0;
|
||||
}
|
BIN
Source/exehead/bin2h.exe
Executable file
BIN
Source/exehead/bin2h.exe
Executable file
Binary file not shown.
BIN
Source/exehead/bitmap1.bmp
Normal file
BIN
Source/exehead/bitmap1.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 886 B |
260
Source/exehead/config.h
Normal file
260
Source/exehead/config.h
Normal file
|
@ -0,0 +1,260 @@
|
|||
#ifndef NSIS_CONFIG_H
|
||||
#define NSIS_CONFIG_H
|
||||
|
||||
#ifndef APSTUDIO_INVOKED // keep msdev's resource editor from mangling the .rc file
|
||||
|
||||
// NSIS_MAX_STRLEN defines the maximum string length for internal variables
|
||||
// and stack entries. 1024 should be plenty, but if you are doing crazy registry
|
||||
// shit, you might want to bump it up. Generally it adds about 16-32x the memory,
|
||||
// so setting this to 4096 from 1024 will add around 64k of memory usage (not
|
||||
// really a big deal, but not usually needed).
|
||||
#define NSIS_MAX_STRLEN 1024
|
||||
|
||||
|
||||
// NSIS_MAX_INST_TYPES specified the maximum install types.
|
||||
// note that this should not exceed 30, ever.
|
||||
#define NSIS_MAX_INST_TYPES 8
|
||||
|
||||
// NSIS_CONFIG_UNINSTALL_SUPPORT enables the uninstaller
|
||||
// support. Comment it out if your installers don't need
|
||||
// uninstallers
|
||||
// adds approximately 2kb.
|
||||
#define NSIS_CONFIG_UNINSTALL_SUPPORT
|
||||
|
||||
// NSIS_CONFIG_LICENSEPAGE enables support for the installer to
|
||||
// present a license page.
|
||||
#define NSIS_CONFIG_LICENSEPAGE
|
||||
|
||||
// NSIS_CONFIG_LICENSEPAGE enables support for the installer to
|
||||
// present a page.where you can select what sections are installed.
|
||||
// with this disabled, all sections are installed.
|
||||
#define NSIS_CONFIG_COMPONENTPAGE
|
||||
|
||||
// NSIS_CONFIG_SILENT_SUPPORT enables support for making installers
|
||||
// that are completely silent.
|
||||
#define NSIS_CONFIG_SILENT_SUPPORT
|
||||
|
||||
// NSIS_CONFIG_VISIBLE_SUPPORT enables support for making installers
|
||||
// that are visible.
|
||||
#define NSIS_CONFIG_VISIBLE_SUPPORT
|
||||
|
||||
|
||||
// Changed by Amir Szekely 31st July 2002
|
||||
// Now supports runtime choice of compression method
|
||||
|
||||
// NSIS_CONFIG_COMPRESSION_SUPPORT enables support for making installers
|
||||
// that use compression (recommended).
|
||||
#define NSIS_CONFIG_COMPRESSION_SUPPORT
|
||||
// compression specific options
|
||||
|
||||
// NSIS_ZLIB_COMPRESS_WHOLE makes all install data in zlib installers
|
||||
// compressed together. Runtime requirements are increased, but potential
|
||||
// for compression is as well. Adds approximately 1kb of disk footprint,
|
||||
// and requires that the installer create a (potentially large) temporary
|
||||
// file in the temp directory.
|
||||
// #define NSIS_ZLIB_COMPRESS_WHOLE
|
||||
|
||||
// NSIS_BZIP2_COMPRESS_WHOLE makes all install data in bzip2 installers
|
||||
// compressed together. Runtime requirements are increased, but potential
|
||||
// for compression is as well. Adds approximately 1kb of disk footprint,
|
||||
// and requires that the installer create a (potentially large) temporary
|
||||
// file in the temp directory.
|
||||
#define NSIS_BZIP2_COMPRESS_WHOLE
|
||||
|
||||
// if NSIS_COMPRESS_BZIP2_SMALLMODE is defined, bzip2's decompressor uses
|
||||
// bzip2's alternative decompression method that uses a lot less memory, at
|
||||
// the expense of speed. not recommended.
|
||||
// #define NSIS_COMPRESS_BZIP2_SMALLMODE
|
||||
|
||||
// if NSIS_COMPRESS_BZIP2_LEVEL is defined, it overrides the default bzip2
|
||||
// compression window size of 9 (1-9 is valid)
|
||||
// 9 uses the most memory, but typically compresses best (recommended).
|
||||
// 1 uses the least memory, but typically compresses the worst.
|
||||
#define NSIS_COMPRESS_BZIP2_LEVEL 9
|
||||
|
||||
|
||||
// NSIS_CONFIG_CRC_SUPPORT enables support for installer verification.
|
||||
// HIGHLY recommended.
|
||||
#define NSIS_CONFIG_CRC_SUPPORT
|
||||
|
||||
// NSIS_CONFIG_CRC_ANAL makes the CRC verification extremely careful, meaning
|
||||
// extra bytes on the end of file, or the first 512 bytes changing, will give
|
||||
// error. Enable this if you are paranoid, otherwise leaving it off seems safe
|
||||
// (and is less prone to reporting virii). If you will be digitally signing your
|
||||
// installers, leave this off (the default).
|
||||
// #define NSIS_CONFIG_CRC_ANAL
|
||||
|
||||
|
||||
// NSIS_CONFIG_LOG enables the logging facility.
|
||||
// turning this on (by uncommenting it) adds about
|
||||
// 3kb, but can be useful in debugging your installers.
|
||||
// NOT ENABLED BY DEFAULT.
|
||||
// #define NSIS_CONFIG_LOG
|
||||
|
||||
// NSIS_SUPPORT_BGBG enables support for the blue (well, whatever
|
||||
// color you want) gradient background window.
|
||||
#define NSIS_SUPPORT_BGBG
|
||||
|
||||
|
||||
// NSIS_SUPPORT_CODECALLBACKS enables support for installer code callbacks.
|
||||
// recommended, as it uses a minimum of space and allows for neat functionality.
|
||||
#define NSIS_SUPPORT_CODECALLBACKS
|
||||
|
||||
|
||||
// NSIS_SUPPORT_MOVEONREBOOT enables support for uninstallers that automatically
|
||||
// delete themselves from the temp directory, as well as the reboot moving/deleting
|
||||
// modes of Delete and Rename. Adds about 512 gay bytes..
|
||||
#define NSIS_SUPPORT_MOVEONREBOOT
|
||||
|
||||
/////////////// the following are instruction enabling defines ///////////////
|
||||
|
||||
// NSIS_SUPPORT_ACTIVEXREG enables activeX plug-in registration
|
||||
// and deregistration, as well as CallInstDLL
|
||||
#define NSIS_SUPPORT_ACTIVEXREG
|
||||
|
||||
// NSIS_SUPPORT_INTOPTS enables support for IntCmp, IntCmpU, IntOp, and IntFmt.
|
||||
#define NSIS_SUPPORT_INTOPTS
|
||||
|
||||
// NSIS_SUPPORT_STROPTS enables support for StrCmp, StrCpy, and StrLen, as well as Get*Local.
|
||||
#define NSIS_SUPPORT_STROPTS
|
||||
|
||||
// NSIS_SUPPORT_STACK enables support for the stack (Push, Pop, Exch)
|
||||
#define NSIS_SUPPORT_STACK
|
||||
|
||||
// NSIS_SUPPORT_FILEFUNCTIONS enables support for FileOpen,FileClose, FileSeek, FileRead, and FileWrite.
|
||||
#define NSIS_SUPPORT_FILEFUNCTIONS
|
||||
|
||||
// NSIS_SUPPORT_FINDFIRST enables support for FindFirst, FindNext, and FindClose.
|
||||
#define NSIS_SUPPORT_FINDFIRST
|
||||
|
||||
// NSIS_SUPPORT_CREATESHORTCUT enables support for CreateShortCut.
|
||||
#define NSIS_SUPPORT_CREATESHORTCUT
|
||||
|
||||
// NSIS_SUPPORT_INIFILES enables support for ReadINIStr and WriteINIStr.
|
||||
#define NSIS_SUPPORT_INIFILES
|
||||
|
||||
// NSIS_SUPPORT_REGISTRYFUNCTIONS enables support for ReadRegStr, ReadRegDWORD, WriteRegStr, etc etc etc.
|
||||
#define NSIS_SUPPORT_REGISTRYFUNCTIONS
|
||||
|
||||
// NSIS_SUPPORT_COPYFILES enables support for CopyFiles
|
||||
#define NSIS_SUPPORT_COPYFILES
|
||||
|
||||
// NSIS_SUPPORT_REBOOT enables support for Reboot, IfRebootFlag, SetRebootFlag
|
||||
#define NSIS_SUPPORT_REBOOT
|
||||
|
||||
// NSIS_SUPPORT_FNUTIL enables support for GetFullPathName, GetTempFileName, and SearchPath
|
||||
#define NSIS_SUPPORT_FNUTIL
|
||||
|
||||
// NSIS_SUPPORT_EXECUTE enables support for Exec and ExecWait
|
||||
#define NSIS_SUPPORT_EXECUTE
|
||||
|
||||
// NSIS_SUPPORT_SHELLEXECUTE enables support for ExecShell
|
||||
#define NSIS_SUPPORT_SHELLEXECUTE
|
||||
|
||||
// NSIS_SUPPORT_GETDLLVERSION enables support for GetDLLVersion
|
||||
#define NSIS_SUPPORT_GETDLLVERSION
|
||||
|
||||
// NSIS_SUPPORT_GETFILETIME enables support for GetFileTime
|
||||
#define NSIS_SUPPORT_GETFILETIME
|
||||
|
||||
// NSIS_SUPPORT_HWNDS enables support for FindWindow, SendMessage, and IsWindow
|
||||
#define NSIS_SUPPORT_HWNDS
|
||||
|
||||
// NSIS_SUPPORT_ENVIRONMENT enables support for ReadEnvStr and ExpandEnvStrings
|
||||
#define NSIS_SUPPORT_ENVIRONMENT
|
||||
|
||||
// NSIS_SUPPORT_RMDIR enables support for RMDir
|
||||
#define NSIS_SUPPORT_RMDIR
|
||||
|
||||
// NSIS_SUPPORT_FILE enables support for File (extracting files)
|
||||
#define NSIS_SUPPORT_FILE
|
||||
|
||||
// NSIS_SUPPORT_DELETE enables support for Delete (delete files)
|
||||
#define NSIS_SUPPORT_DELETE
|
||||
|
||||
// NSIS_SUPPORT_RENAME enables support for Rename (rename files)
|
||||
#define NSIS_SUPPORT_RENAME
|
||||
|
||||
// NSIS_SUPPORT_MESSAGEBOX enables support for MessageBox
|
||||
#define NSIS_SUPPORT_MESSAGEBOX
|
||||
|
||||
|
||||
|
||||
// fixes
|
||||
#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
|
||||
#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
|
||||
#error compression is enabled but both zlib and bzip2 are disabled.
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef NSIS_COMPRESS_USE_ZLIB
|
||||
#ifdef NSIS_COMPRESS_USE_BZIP2
|
||||
#error both zlib and bzip2 are enabled.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef NSIS_COMPRESS_USE_ZLIB
|
||||
#ifdef NSIS_ZLIB_COMPRESS_WHOLE
|
||||
#define NSIS_COMPRESS_WHOLE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef NSIS_COMPRESS_USE_BZIP2
|
||||
#ifdef NSIS_BZIP2_COMPRESS_WHOLE
|
||||
#define NSIS_COMPRESS_WHOLE
|
||||
#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
|
||||
|
||||
#if NSIS_MAX_INST_TYPES > 30
|
||||
#error NSIS_MAX_INST_TYPES > 30
|
||||
#endif
|
||||
|
||||
#endif//!APSTUDIO_INVOKED
|
||||
|
||||
#endif // NSIS_CONFIG_H
|
1423
Source/exehead/exec.c
Normal file
1423
Source/exehead/exec.c
Normal file
File diff suppressed because it is too large
Load diff
7
Source/exehead/exec.h
Normal file
7
Source/exehead/exec.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef _EXEC_H_
|
||||
#define _EXEC_H_
|
||||
|
||||
int ExecuteCodeSegment(entry *entries, int pos, HWND hwndProgress); // returns 0 on success
|
||||
|
||||
|
||||
#endif//_EXEC_H_
|
251
Source/exehead/exehead-bzip2.dsp
Normal file
251
Source/exehead/exehead-bzip2.dsp
Normal file
|
@ -0,0 +1,251 @@
|
|||
# Microsoft Developer Studio Project File - Name="exehead_bzip2" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=exehead_bzip2 - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "exehead-bzip2.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "exehead-bzip2.mak" CFG="exehead_bzip2 - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "exehead_bzip2 - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release-bzip2"
|
||||
# PROP Intermediate_Dir "Release-bzip2"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O1 /Oy /D "_WINDOWS" /D "EXEHEAD" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "WIN32_LEAN_AND_MEAN" /D "NSIS_COMPRESS_USE_BZIP2" /FD /c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib shell32.lib /nologo /entry:"WinMain" /subsystem:windows /pdb:none /machine:I386 /nodefaultlib /out:"Release-bzip2/exehead_bzip2.exe" /opt:nowin98
|
||||
# Begin Special Build Tool
|
||||
SOURCE="$(InputPath)"
|
||||
PostBuild_Desc=generating include file for makenssi
|
||||
PostBuild_Cmds=bin2h Release-bzip2\exehead_bzip2.exe Release-bzip2\exehead_bzip2.h bzip2_header_data
|
||||
# End Special Build Tool
|
||||
# Begin Target
|
||||
|
||||
# Name "exehead_bzip2 - Win32 Release"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Group "zlib"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "headers"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Infblock.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Infcodes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Inftrees.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Infutil.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Zconf.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Zlib.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\INFBLOCK.C
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\INFCODES.C
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\INFLATE.C
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\INFTREES.C
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\INFUTIL.C
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "bzip2"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\bzlib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\bzlib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\bzlib_private.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\decompress.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\huffman.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\randtable.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bgbg.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\crc32.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\exec.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\fileform.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Main.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Ui.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\config.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\exec.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\fileform.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\state.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ui.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bitmap1.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bitmap2.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bitmap3.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\icon3.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsis.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nullsoft.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\uninst.ico
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\exehead.xml
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
251
Source/exehead/exehead-zlib.dsp
Normal file
251
Source/exehead/exehead-zlib.dsp
Normal file
|
@ -0,0 +1,251 @@
|
|||
# Microsoft Developer Studio Project File - Name="exehead_zlib" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101
|
||||
|
||||
CFG=exehead_zlib - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "exehead-zlib.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "exehead-zlib.mak" CFG="exehead_zlib - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "exehead_zlib - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release-zlib"
|
||||
# PROP Intermediate_Dir "Release-zlib"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O1 /Oy /D "_WINDOWS" /D "EXEHEAD" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "WIN32_LEAN_AND_MEAN" /D "NSIS_COMPRESS_USE_ZLIB" /FD /c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
|
||||
# ADD LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib shell32.lib /nologo /entry:"WinMain" /subsystem:windows /pdb:none /machine:I386 /nodefaultlib /out:"Release-zlib/exehead_zlib.exe" /opt:nowin98
|
||||
# Begin Special Build Tool
|
||||
SOURCE="$(InputPath)"
|
||||
PostBuild_Desc=generating include file for makenssi
|
||||
PostBuild_Cmds=bin2h Release-zlib\exehead_zlib.exe Release-zlib\exehead_zlib.h zlib_header_data bin2h bitmap1.bmp Release-zlib\bitmap1.h bitmap1_data bin2h nsis.ico Release-zlib\icon.h icon_data bin2h uninst.ico Release-zlib\unicon.h unicon_data
|
||||
# End Special Build Tool
|
||||
# Begin Target
|
||||
|
||||
# Name "exehead_zlib - Win32 Release"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Group "zlib"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "headers"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Infblock.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Infcodes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Inftrees.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Infutil.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Zconf.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\Zlib.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\INFBLOCK.C
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\INFCODES.C
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\INFLATE.C
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\INFTREES.C
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\zlib\INFUTIL.C
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "bzip2"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\bzlib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\bzlib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\bzlib_private.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\decompress.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\huffman.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\bzip2\randtable.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bgbg.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\crc32.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\exec.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\fileform.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Main.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Ui.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\config.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\exec.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\fileform.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lang.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\state.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ui.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bitmap1.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bitmap2.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bitmap3.bmp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\icon3.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsis.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nullsoft.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\uninst.ico
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\exehead.xml
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
10
Source/exehead/exehead.xml
Normal file
10
Source/exehead/exehead.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?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.</description>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*" />
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
323
Source/exehead/fileform.c
Normal file
323
Source/exehead/fileform.c
Normal file
|
@ -0,0 +1,323 @@
|
|||
#include <windows.h>
|
||||
#include "fileform.h"
|
||||
#include "util.h"
|
||||
#include "state.h"
|
||||
|
||||
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
|
||||
#ifdef NSIS_COMPRESS_USE_ZLIB
|
||||
#include "../zlib/zlib.h"
|
||||
#endif
|
||||
|
||||
#ifdef NSIS_COMPRESS_USE_BZIP2
|
||||
#include "../bzip2/bzlib.h"
|
||||
static int bz2_needreinit;
|
||||
#define z_stream bz_stream
|
||||
#define inflateInit(x) { if (BZ2_bzDecompressInit(x)<0) return -1; }
|
||||
#define inflate(x) BZ2_bzDecompress(x)
|
||||
#define inflateReset(x) { if (bz2_needreinit) { BZ2_bzDecompressEnd(x); inflateInit(x); } bz2_needreinit=1; }
|
||||
#define Z_OK BZ_OK
|
||||
#define Z_STREAM_END BZ_STREAM_END
|
||||
#endif//NSIS_COMPRESS_USE_BZIP2
|
||||
|
||||
#endif
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
static char *g_db_strtab;
|
||||
|
||||
static int g_db_offset;
|
||||
HANDLE g_db_hFile;
|
||||
|
||||
#ifdef NSIS_COMPRESS_WHOLE
|
||||
HANDLE dbd_hFile=INVALID_HANDLE_VALUE;
|
||||
static int dbd_size, dbd_pos, dbd_srcpos, dbd_fulllen;
|
||||
#endif//NSIS_COMPRESS_WHOLE
|
||||
|
||||
int isheader(firstheader *h)
|
||||
{
|
||||
if ((h->flags & (~FH_FLAGS_MASK)) ||
|
||||
h->siginfo != FH_SIG ||
|
||||
h->nsinst[2] != FH_INT3 ||
|
||||
h->nsinst[1] != FH_INT2 ||
|
||||
h->nsinst[0] != FH_INT1) return 0;
|
||||
return h->length_of_all_following_data;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
|
||||
static z_stream g_inflate_stream;
|
||||
#endif
|
||||
|
||||
int loadHeaders(void)
|
||||
{
|
||||
DWORD r;
|
||||
void *data;
|
||||
firstheader h;
|
||||
|
||||
if (!ReadFile(g_db_hFile,(LPVOID)&h,sizeof(h),&r,NULL) || r != sizeof(h) || !isheader(&h)) return -1;
|
||||
|
||||
data=(void*)GlobalAlloc(GMEM_FIXED,h.length_of_header);
|
||||
|
||||
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
|
||||
inflateInit(&g_inflate_stream);
|
||||
#endif
|
||||
|
||||
#ifdef NSIS_COMPRESS_WHOLE
|
||||
inflateReset(&g_inflate_stream);
|
||||
|
||||
{
|
||||
char fn[MAX_PATH],fno[MAX_PATH];
|
||||
GetTempPath(sizeof(fn),fn);
|
||||
GetTempFileName(fn,"nsi",0,fno);
|
||||
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)
|
||||
{
|
||||
MessageBox(NULL,"Error writing temp file",g_caption,MB_OK);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
dbd_srcpos=SetFilePointer(g_db_hFile,0,NULL,FILE_CURRENT);
|
||||
dbd_fulllen=dbd_srcpos-sizeof(h)+h.length_of_all_following_data-((h.flags&FH_FLAGS_CRC)?4:0);
|
||||
#endif
|
||||
|
||||
if (GetCompressedDataFromDataBlockToMemory(-1,data,h.length_of_header) != h.length_of_header)
|
||||
{
|
||||
MessageBox(NULL,"Error reading installer info block",g_caption,MB_OK);
|
||||
GlobalFree((HGLOBAL)data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef NSIS_COMPRESS_WHOLE
|
||||
g_db_offset=SetFilePointer(g_db_hFile,0,NULL,FILE_CURRENT);
|
||||
#else
|
||||
g_db_offset=dbd_pos;
|
||||
#endif
|
||||
|
||||
g_inst_combinedheader=data;
|
||||
|
||||
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
|
||||
if (h.flags&FH_FLAGS_UNINSTALL)
|
||||
{
|
||||
g_is_uninstaller++;
|
||||
g_inst_entry=(entry *) ((g_inst_uninstheader) + 1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
g_inst_section=(section *) (g_inst_header + 1);
|
||||
g_inst_entry=(entry *) (g_inst_section + g_inst_header->num_sections);
|
||||
}
|
||||
g_db_strtab = (char *)(g_inst_entry + g_inst_cmnheader->num_entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *GetStringFromStringTab(int offs)
|
||||
{
|
||||
if (offs < 0) return "";
|
||||
return g_db_strtab+offs;
|
||||
}
|
||||
|
||||
#define IBUFSIZE 16384
|
||||
#define OBUFSIZE 32768
|
||||
|
||||
// returns -3 if compression error/eof/etc
|
||||
|
||||
#ifndef NSIS_COMPRESS_WHOLE
|
||||
|
||||
static int _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;
|
||||
DWORD r;
|
||||
|
||||
outbuffer = outbuf?outbuf:(inbuffer+IBUFSIZE);
|
||||
|
||||
if (offset>=0)
|
||||
{
|
||||
/*
|
||||
int lp=SetFilePointer(g_db_hFile,0,NULL,FILE_CURRENT);
|
||||
if (lp > g_db_offset+offset)
|
||||
{
|
||||
char buf[1023];
|
||||
wsprintf(buf,"going from %d to %d",lp,g_db_offset+offset);
|
||||
MessageBox(NULL,buf,"seeking back",MB_OK);
|
||||
}
|
||||
*/
|
||||
SetFilePointer(g_db_hFile,g_db_offset+offset,NULL,FILE_BEGIN);
|
||||
}
|
||||
|
||||
if (!ReadFile(g_db_hFile,(LPVOID)&input_len,sizeof(int),&r,NULL)) return -3;
|
||||
|
||||
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
|
||||
else if (input_len & 0x80000000) // compressed
|
||||
{
|
||||
inflateReset(&g_inflate_stream);
|
||||
input_len &= 0x7fffffff; // take off top bit.
|
||||
|
||||
while (input_len > 0)
|
||||
{
|
||||
DWORD r;
|
||||
int err;
|
||||
|
||||
if (!ReadFile(g_db_hFile,(LPVOID)inbuffer,min(input_len,IBUFSIZE),&r,NULL)) return -3;
|
||||
|
||||
g_inflate_stream.next_in = inbuffer;
|
||||
g_inflate_stream.avail_in = r;
|
||||
input_len-=r;
|
||||
|
||||
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;
|
||||
|
||||
if (!u) break;
|
||||
|
||||
if (!outbuf)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
|
||||
else
|
||||
{
|
||||
if (!outbuf)
|
||||
{
|
||||
while (input_len > 0)
|
||||
{
|
||||
DWORD t;
|
||||
if (!ReadFile(g_db_hFile,(LPVOID)inbuffer,min(input_len,outbuffer_len),&r,NULL)) return -3;
|
||||
if (!WriteFile(hFileOut,inbuffer,r,&t,NULL) || r!=t) return -2;
|
||||
retval+=r;
|
||||
input_len-=r;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ReadFile(g_db_hFile,(LPVOID)outbuf,min(input_len,outbuflen),&r,NULL)) return -3;
|
||||
retval=r;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
#else//NSIS_COMPRESS_WHOLE
|
||||
|
||||
static char _inbuffer[IBUFSIZE];
|
||||
static char _outbuffer[OBUFSIZE];
|
||||
static int __ensuredata(int amount)
|
||||
{
|
||||
int needed=amount-(dbd_size-dbd_pos);
|
||||
if (needed>0)
|
||||
{
|
||||
SetFilePointer(g_db_hFile,dbd_srcpos,NULL,FILE_BEGIN);
|
||||
SetFilePointer(dbd_hFile,dbd_size,NULL,FILE_BEGIN);
|
||||
for (;;)
|
||||
{
|
||||
int err;
|
||||
DWORD or;
|
||||
if (!ReadFile(g_db_hFile,(LPVOID)_inbuffer,min(IBUFSIZE,dbd_fulllen-dbd_srcpos),&or,NULL)) return -1;
|
||||
dbd_srcpos+=or;
|
||||
g_inflate_stream.next_in=_inbuffer;
|
||||
g_inflate_stream.avail_in=or;
|
||||
do
|
||||
{
|
||||
DWORD r,t;
|
||||
g_inflate_stream.next_out=_outbuffer;
|
||||
g_inflate_stream.avail_out=OBUFSIZE;
|
||||
err=inflate(&g_inflate_stream);
|
||||
if (err<0)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
r=g_inflate_stream.next_out-_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 || !or) 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);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _dodecomp(int offset, HANDLE hFileOut, char *outbuf, int outbuflen)
|
||||
{
|
||||
DWORD r;
|
||||
int input_len;
|
||||
int retval;
|
||||
if (offset>=0)
|
||||
{
|
||||
dbd_pos=g_db_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;
|
||||
if (!ReadFile(dbd_hFile,(LPVOID)_inbuffer,min(input_len,IBUFSIZE),&r,NULL)) return -3;
|
||||
if (!WriteFile(hFileOut,_inbuffer,r,&t,NULL) || r!=t) 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
|
||||
|
||||
|
||||
int GetCompressedDataFromDataBlock(int offset, HANDLE hFileOut)
|
||||
{
|
||||
return _dodecomp(offset,hFileOut,NULL,0);
|
||||
}
|
||||
|
||||
int GetCompressedDataFromDataBlockToMemory(int offset, char *out, int out_len)
|
||||
{
|
||||
return _dodecomp(offset,NULL,out,out_len);
|
||||
}
|
324
Source/exehead/fileform.h
Normal file
324
Source/exehead/fileform.h
Normal file
|
@ -0,0 +1,324 @@
|
|||
#include "config.h"
|
||||
|
||||
#ifndef _FILEFORM_H_
|
||||
#define _FILEFORM_H_
|
||||
|
||||
|
||||
// stored in file:
|
||||
// exehead (~34k)
|
||||
// firstheader (~28 bytes)
|
||||
// hdrinfo (4 bytes describing length/compression)::
|
||||
// (if install)
|
||||
// header (~228 bytes)
|
||||
// sections (20 bytes each)
|
||||
// (if uninstall)
|
||||
// uninstall_header (~116 bytes)
|
||||
// entries (24 bytes each)
|
||||
// string table
|
||||
// datablock
|
||||
// (hdrinfo+datablock is at least 512 bytes if CRC enabled)
|
||||
// CRC (optional - 4 bytes)
|
||||
|
||||
|
||||
#define MAX_ENTRY_OFFSETS 5
|
||||
|
||||
|
||||
// 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_SETSFCONTEXT, // SetShellVarContext: 1: [isAll]
|
||||
EW_HIDEWINDOW, // HideWindow: 0
|
||||
EW_BRINGTOFRONT, // BringToFront: 0
|
||||
EW_SETWINDOWCLOSE, // SetWindowClose: 1 [0: no window close at end, 1: window close at end]
|
||||
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_IFERRORS, //a IfErrors: 3 [jump if error, jump if not error, new_erflag]
|
||||
EW_RENAME, // Rename: 3 [old, new, rebootok]
|
||||
EW_GETFULLPATHNAME, // GetFullPathName: 2 [output, input, ?lfn:sfn]
|
||||
EW_SEARCHPATH, // SearchPath: 2 [output, filename]
|
||||
EW_GETTEMPFILENAME, // GetTempFileName: 1 [output]
|
||||
EW_EXTRACTFILE, // File to extract: 5,[overwriteflag, output filename, compressed filedata, filedatetimelow, filedatetimehigh]
|
||||
// overwriteflag: 0x1 = no. 0x0=force, 0x2=try, 0x3=if date is newer
|
||||
EW_DELETEFILE, // Delete File: 2, [filename, rebootok]
|
||||
EW_MESSAGEBOX, // MessageBox: 5,[MB_flags,text,retv1:retv2,moveonretv1:moveonretv2]
|
||||
EW_RMDIR, // RMDir: 2 [path, recursiveflag]
|
||||
EW_STRLEN, // StrLen: 2 [output, input]
|
||||
EW_ASSIGNVAR, // Assign: 4 [variable (0-9) to assign, string to assign, maxlen, startpos]
|
||||
EW_STRCMP, // StrCmp: 4 [str1, str2, jump_if_equal, jump_if_not_equal] (case-insensitive)
|
||||
EW_READENVSTR, // ReadEnvStr/ExpandEnvStrings: 3 [output, string_with_env_variables, IsRead]
|
||||
EW_INTCMP, // IntCmp: 5 [val1, val2, equal, val1<val2, val1>val2]
|
||||
EW_INTCMPU, // IntCmpU: 5 [val1, val2, equal, val1<val2, val1>val2]
|
||||
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]
|
||||
EW_PUSHPOP, // Push/Pop/Exchange: 3 [variable/string, ?pop:push, ?exch]
|
||||
|
||||
EW_FINDWINDOW, // FindWindow: 5, [outputvar,window class,window name, window_parent, window_after]
|
||||
EW_SENDMESSAGE, // SendMessage: 5 [output, hwnd, msg, lparam, wparam]
|
||||
EW_ISWINDOW, // IsWindow: 3 [hwnd, jump_if_window, jump_if_notwindow]
|
||||
EW_SETDLGITEMTEXT, // SetDlgItemText: 2 [item_id, text]
|
||||
|
||||
EW_SHELLEXEC, // ShellExecute program: 4, [shell action, complete commandline, parameters, showwindow]
|
||||
|
||||
EW_EXECUTE, // Execute program: 3,[complete command line,waitflag,>=0?output errorcode]
|
||||
|
||||
EW_GETFILETIME, // GetFileTime; 3 [file highout lowout]
|
||||
|
||||
EW_GETDLLVERSION, // GetDLLVersion: 3 [file highout lowout]
|
||||
|
||||
EW_REGISTERDLL, // Register DLL: 3,[DLL file name, string ptr of function to call, text to put in display (<0 if none/pass parms)]
|
||||
|
||||
EW_CREATESHORTCUT, // Make Shortcut: 5, [link file, target file, parameters, icon file, iconindex|show mode<<8|hotkey<<16]
|
||||
|
||||
EW_COPYFILES, // CopyFiles: 3 [source mask, destination location, flags]
|
||||
|
||||
EW_REBOOT, // Reboot: 1 [0xbadf00d]
|
||||
EW_IFREBOOTFLAG, // IfRebootFlag: 2 [if reboot flag set, if not reboot flag]
|
||||
EW_SETREBOOTFLAG, // SetRebootFlag: 1 [new value]
|
||||
|
||||
EW_WRITEINI, // Write INI String: 4, [Section, Name, Value, INI File]
|
||||
EW_READINISTR, // ReadINIStr: 4 [output, section, name, ini_file]
|
||||
|
||||
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]
|
||||
|
||||
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]
|
||||
|
||||
EW_FINDCLOSE, // FindClose: 1 [handle]
|
||||
EW_FINDNEXT, // FindNext: 2 [output, handle]
|
||||
EW_FINDFIRST, // FindFirst: 2 [filespec, output, handleoutput]
|
||||
|
||||
EW_WRITEUNINSTALLER, // WriteUninstaller: 1 [name]
|
||||
|
||||
EW_LOG, // LogText: 2 [0, text] / LogSet: [1, logstate]
|
||||
|
||||
EW_SECTIONSET, // SectionSetText: 3: [idx, 0, text]
|
||||
// SectionGetText: 3: [idx, 1, output]
|
||||
// SectionSetFlags: 3: [idx, 2, flags]
|
||||
// SectionGetFlags: 3: [idx, 3, output]
|
||||
|
||||
EW_SETBRANDINGIMAGE, // SetBrandingImage: 1: [Bitmap file]
|
||||
|
||||
// instructions not actually implemented in exehead, but used in compiler.
|
||||
EW_GETLABELADDR, // both of these get converted to EW_ASSIGNVAR
|
||||
EW_GETFUNCTIONADDR,
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
// used for section->default_state
|
||||
#define DFS_SET 0x80000000
|
||||
#define DFS_RO 0x40000000
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int flags; // &1=CRC, &2=uninstall, &4=silent
|
||||
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;
|
||||
|
||||
// Settings common to both installers and uninstallers
|
||||
typedef struct
|
||||
{
|
||||
// unprocessed strings
|
||||
int branding_ptr;
|
||||
int cancelbutton_ptr;
|
||||
int showdetailsbutton_ptr;
|
||||
int completed_ptr;
|
||||
int closebutton_ptr; // "Close"
|
||||
int name_ptr; // name of installer
|
||||
|
||||
// processed strings
|
||||
int caption_ptr; // name of installer + " Setup" or whatever.
|
||||
int subcaption_ptrs[5];
|
||||
|
||||
#ifdef NSIS_SUPPORT_FILE
|
||||
int fileerrtext_ptr;
|
||||
#endif
|
||||
|
||||
int num_entries; // total number of entries
|
||||
|
||||
#ifdef NSIS_SUPPORT_BGBG
|
||||
int bg_color1, bg_color2, bg_textcolor;
|
||||
#endif
|
||||
int lb_bg, lb_fg, license_bg;
|
||||
|
||||
#ifdef NSIS_SUPPORT_CODECALLBACKS
|
||||
// .on* calls
|
||||
int code_onInit;
|
||||
int code_onInstSuccess;
|
||||
int code_onInstFailed;
|
||||
int code_onUserAbort;
|
||||
int code_onNextPage;
|
||||
#endif//NSIS_SUPPORT_CODECALLBACKS
|
||||
|
||||
char show_details;
|
||||
char progress_flags;
|
||||
#ifdef NSIS_CONFIG_SILENT_SUPPORT
|
||||
char silent_install;
|
||||
#endif//NSIS_CONFIG_SILENT_SUPPORT
|
||||
// additional flags
|
||||
char misc_flags; // auto_close=&1, no_show_dirpage=&2, no_show_icon&4, no_rootdir&8;
|
||||
|
||||
} common_header;
|
||||
|
||||
// Settings specific to installers
|
||||
typedef struct
|
||||
{
|
||||
// common settings
|
||||
common_header common;
|
||||
|
||||
// these first strings are literals (should not be encoded)
|
||||
int backbutton_ptr;
|
||||
int nextbutton_ptr;
|
||||
int browse_ptr; // "Browse..."
|
||||
int installbutton_ptr; // "Install"
|
||||
int spacerequired_ptr; // "Space required: "
|
||||
int spaceavailable_ptr; // "Space available: "
|
||||
int custom_ptr; // Custom
|
||||
int text_ptr; // directory page text
|
||||
int dirsubtext_ptr; // directory text2
|
||||
#ifdef NSIS_CONFIG_COMPONENTPAGE
|
||||
int componenttext_ptr; // component page text
|
||||
int componentsubtext_ptr[2];
|
||||
#endif
|
||||
#ifdef NSIS_CONFIG_LICENSEPAGE
|
||||
int licensetext_ptr; // license page text
|
||||
int licensedata_ptr; // license text
|
||||
int licensebutton_ptr; // license button text
|
||||
int license_bg; // license background color
|
||||
#endif//NSIS_CONFIG_LICENSEPAGE
|
||||
|
||||
int install_reg_rootkey, install_reg_key_ptr, install_reg_value_ptr;
|
||||
|
||||
#ifdef NSIS_CONFIG_COMPONENTPAGE
|
||||
int install_types_ptr[NSIS_MAX_INST_TYPES]; // -1 if not used. can describe as lite, normal, full, etc.
|
||||
#endif
|
||||
|
||||
// below here, the strings are processed (can have variables etc)
|
||||
int install_directory_ptr; // default install dir.
|
||||
|
||||
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
|
||||
int uninstdata_offset; // -1 if no uninst data.
|
||||
int uninsticon_size;
|
||||
#endif
|
||||
|
||||
#ifdef NSIS_CONFIG_COMPONENTPAGE
|
||||
int no_custom_instmode_flag;
|
||||
#endif
|
||||
|
||||
int num_sections; // total number of sections
|
||||
|
||||
#ifdef NSIS_SUPPORT_CODECALLBACKS
|
||||
// .on* calls
|
||||
int code_onPrevPage;
|
||||
int code_onVerifyInstDir;
|
||||
#ifdef NSIS_CONFIG_COMPONENTPAGE
|
||||
int code_onSelChange;
|
||||
#endif//NSIS_CONFIG_COMPONENTPAGE
|
||||
#endif//NSIS_SUPPORT_CODECALLBACKS
|
||||
|
||||
} header;
|
||||
|
||||
// Settings specific to uninstallers
|
||||
typedef struct
|
||||
{
|
||||
// common settings
|
||||
common_header common;
|
||||
|
||||
// unprocessed strings
|
||||
int uninstbutton_ptr;
|
||||
int uninstalltext_ptr;
|
||||
int uninstalltext2_ptr;
|
||||
|
||||
int code;
|
||||
int code_size;
|
||||
|
||||
} uninstall_header;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int name_ptr; // '' for non-optional components
|
||||
int default_state; // bits 0-30 set for each of the different install_types, if any.
|
||||
// DFS_SET and DFS_RO can be set too
|
||||
int code;
|
||||
int code_size;
|
||||
int size_kb;
|
||||
int expand;
|
||||
} section;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int which;
|
||||
int offsets[MAX_ENTRY_OFFSETS]; // count and meaning of offsets depend on 'which'
|
||||
} entry;
|
||||
|
||||
|
||||
#define FH_FLAGS_MASK 15
|
||||
#define FH_FLAGS_CRC 1
|
||||
#define FH_FLAGS_UNINSTALL 2
|
||||
#ifdef NSIS_CONFIG_SILENT_SUPPORT
|
||||
#define FH_FLAGS_SILENT 4
|
||||
#endif
|
||||
// Added by Amir Szekely 23rd July 2002
|
||||
#define FH_FLAGS_FORCE_CRC 8
|
||||
|
||||
#define FH_SIG 0xDEADBEEF
|
||||
|
||||
// neato surprise signature that goes in firstheader. :)
|
||||
#define FH_INT1 0x6C6C754E
|
||||
#define FH_INT2 0x74666F73
|
||||
#define FH_INT3 0x74736E49
|
||||
|
||||
// the following are only used/implemented in exehead, not makensis.
|
||||
|
||||
int 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)
|
||||
int loadHeaders(void);
|
||||
|
||||
extern HANDLE g_db_hFile;
|
||||
extern int g_quit_flag;
|
||||
|
||||
const char *GetStringFromStringTab(int offs);
|
||||
int GetCompressedDataFromDataBlock(int offset, HANDLE hFileOut);
|
||||
int GetCompressedDataFromDataBlockToMemory(int offset, char *out, int out_len);
|
||||
|
||||
// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value.
|
||||
#define VAR_CODES_START (256 - 35)
|
||||
|
||||
|
||||
#endif //_FILEFORM_H_
|
57
Source/exehead/lang.h
Normal file
57
Source/exehead/lang.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
#ifndef _NSIS_LANG_H_
|
||||
#define _NSIS_LANG_H_
|
||||
|
||||
// generic startup strings (these will never be overridable)
|
||||
#define _LANG_INVALIDCRC "Installer verification failed.\r\n\r\n" \
|
||||
"This could be the result of an incomplete download,\r\n" \
|
||||
"a failing disk, or (possibly) corruption from a virus." \
|
||||
"\r\n\r\nYou can try to force an install using the /NCRC\r\n" \
|
||||
"command line switch (but it is NOT recommended)"
|
||||
|
||||
#define _LANG_INVALIDINST "Installer corrupted.\r\n\r\n" \
|
||||
"This could be the result of an incomplete download"
|
||||
|
||||
|
||||
#define _LANG_UNINSTINITERROR "Error initializing uninstaller"
|
||||
|
||||
#define _LANG_VERIFYINGINST "verifying installer: %d%%"
|
||||
|
||||
#define _LANG_CANTOPENSELF "Can't open self"
|
||||
|
||||
#define _LANG_GENERIC_ERROR "NSIS ERROR"
|
||||
|
||||
|
||||
#define LANG_STR(x) (x)
|
||||
|
||||
// instruction strings (these may someday be stored in the datablock or string table, and accessed
|
||||
// via LANG_STR()
|
||||
#define LANG_DELETEFILE "Delete file: "
|
||||
#define LANG_DLLREGERROR "Error registering DLL"
|
||||
#define LANG_REMOVEDIR "Remove directory: "
|
||||
#define LANG_OUTPUTDIR "Output directory: "
|
||||
#define LANG_CREATEDIR "Create directory: "
|
||||
#define LANG_RENAME "Rename: "
|
||||
#define LANG_RENAMEONREBOOT "Rename on reboot: "
|
||||
#define LANG_SKIPPED "Skipped: "
|
||||
#define LANG_CANTWRITE "Can't write: "
|
||||
#define LANG_EXTRACT "Extract: "
|
||||
#define LANG_ERRORWRITING "Extract: error writing to file "
|
||||
#define LANG_ERRORDECOMPRESSING "Error decompressing data! Corrupted installer?"
|
||||
#define LANG_DELETEONREBOOT "Delete on reboot: "
|
||||
#define LANG_EXECSHELL "ExecShell: "
|
||||
#define LANG_EXECUTE "Execute: "
|
||||
#define LANG_CANNOTFINDSYMBOL "Could not find symbol: "
|
||||
#define LANG_COULDNOTLOAD "Could not load: "
|
||||
#define LANG_NOOLE "No OLE for: "
|
||||
#define LANG_ERRORCREATINGSHORTCUT "Error creating shortcut: "
|
||||
#define LANG_CREATESHORTCUT "Create shortcut: "
|
||||
#define LANG_COPYTO "Copy to "
|
||||
#define LANG_COPYFAILED "Copy failed"
|
||||
#define LANG_ERRORCREATING "Error creating: "
|
||||
#define LANG_CREATEDUNINST "Created uninstaller: "
|
||||
#define LANG_INSTCORRUPTED "Install corrupted: invalid opcode"
|
||||
|
||||
|
||||
|
||||
|
||||
#endif//_NSIS_LANG_H_
|
BIN
Source/exehead/nsis.ico
Normal file
BIN
Source/exehead/nsis.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
63
Source/exehead/resource.h
Normal file
63
Source/exehead/resource.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by resource.rc
|
||||
//
|
||||
#define IDC_BACK 3
|
||||
#define IDD_DIALOG1 101
|
||||
#define IDI_ICON1 102
|
||||
#define IDD_DIALOG2 102
|
||||
#define IDD_LICENSE 102
|
||||
#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 IDB_BITMAP1 109
|
||||
#define IDB_BITMAP2 110
|
||||
#define IDI_ICON3 110
|
||||
#define IDD_VERIFY 111
|
||||
#define IDB_BITMAP3 111
|
||||
#define IDC_EDIT1 1000
|
||||
#define IDC_BROWSE 1001
|
||||
#define IDC_COPYRIGHT 1003
|
||||
#define IDC_PROGRESS1 1004
|
||||
#define IDC_PROGRESS2 1005
|
||||
#define IDC_INTROTEXT 1006
|
||||
#define IDC_WMA 1007
|
||||
#define IDC_CHECK1 1008
|
||||
#define IDC_MJF 1008
|
||||
#define IDC_VERSION 1009
|
||||
#define IDC_DIRCAPTION 1011
|
||||
#define IDC_STATUSTEXT 1014
|
||||
#define IDC_LICTEXT 1015
|
||||
#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_INSTVER 1024
|
||||
#define IDC_UNINSTTEXT 1025
|
||||
#define IDC_PROGRESSTEXT 1026
|
||||
#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
|
||||
|
||||
// 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 1034
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
247
Source/exehead/resource.rc
Normal file
247
Source/exehead/resource.rc
Normal file
|
@ -0,0 +1,247 @@
|
|||
//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) DIALOG DISCARDABLE 0, 0, 266, 130
|
||||
#else
|
||||
IDD_LICENSE DIALOG DISCARDABLE 0, 0, 266, 130
|
||||
#endif
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
ICON IDI_ICON2,IDC_ULICON,0,0,20,20
|
||||
LTEXT "",IDC_INTROTEXT,25,0,241,23
|
||||
CONTROL "",IDC_EDIT1,"RICHEDIT",ES_MULTILINE | ES_READONLY |
|
||||
WS_VSCROLL | WS_BORDER,0,24,266,105
|
||||
END
|
||||
#endif
|
||||
|
||||
#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_VISIBLE_SUPPORT)
|
||||
#if defined(APSTUDIO_INVOKED)
|
||||
IDD_DIR$(NSIS_CONFIG_VISIBLE_SUPPORT) DIALOG DISCARDABLE 0, 0, 266, 130
|
||||
#else
|
||||
IDD_DIR DIALOG DISCARDABLE 0, 0, 266, 130
|
||||
#endif
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
EDITTEXT IDC_DIR,11,49,188,12,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "",IDC_BROWSE,203,48,50,14
|
||||
ICON IDI_ICON2,IDC_ULICON,0,0,20,20
|
||||
CONTROL "",IDC_SELDIRTEXT,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,
|
||||
0,36,265,8
|
||||
CONTROL "",IDC_SPACEAVAILABLE,"Static",SS_LEFTNOWORDWRAP |
|
||||
WS_GROUP,0,122,265,8
|
||||
CONTROL "",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE |
|
||||
WS_TABSTOP,12,65,118,10
|
||||
CONTROL "",IDC_SPACEREQUIRED,"Static",SS_LEFTNOWORDWRAP |
|
||||
WS_GROUP,0,111,265,8
|
||||
LTEXT "",IDC_INTROTEXT,25,0,241,34
|
||||
END
|
||||
#endif
|
||||
|
||||
#if defined(APSTUDIO_INVOKED) || defined(NSIS_CONFIG_COMPONENTPAGE)
|
||||
#if defined(APSTUDIO_INVOKED)
|
||||
IDD_SELCOM$(NSIS_CONFIG_COMPONENTPAGE) DIALOG DISCARDABLE 0, 0, 266, 130
|
||||
#else
|
||||
IDD_SELCOM DIALOG DISCARDABLE 0, 0, 266, 130
|
||||
#endif
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
COMBOBOX IDC_COMBO1,114,25,152,102,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
ICON IDI_ICON2,IDC_ULICON,0,0,20,20
|
||||
LTEXT "",IDC_TEXT2,0,40,108,21
|
||||
CONTROL "",IDC_TEXT1,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,0,27,
|
||||
108,8
|
||||
CONTROL "",IDC_SPACEREQUIRED,"Static",SS_LEFTNOWORDWRAP |
|
||||
WS_GROUP,0,111,111,8
|
||||
LTEXT "",IDC_INTROTEXT,25,0,241,25
|
||||
CONTROL "Tree1",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) DIALOG DISCARDABLE 0, 0, 280, 162
|
||||
#else
|
||||
IDD_INST DIALOG DISCARDABLE 0, 0, 280, 162
|
||||
#endif
|
||||
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
PUSHBUTTON "",IDOK,223,142,50,14
|
||||
PUSHBUTTON "",IDCANCEL,7,142,50,14
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,138,267,1
|
||||
CONTROL "",IDC_CHILDRECT,"Static",SS_BLACKRECT | NOT WS_VISIBLE,
|
||||
7,6,266,130
|
||||
PUSHBUTTON "",IDC_BACK,171,142,50,14,NOT WS_VISIBLE
|
||||
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) DIALOG DISCARDABLE 0, 0, 266, 130
|
||||
#else
|
||||
IDD_INSTFILES DIALOG DISCARDABLE 0, 0, 266, 130
|
||||
#endif
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
CONTROL "",IDC_PROGRESS1,"msctls_progress32",NOT WS_VISIBLE |
|
||||
WS_BORDER,24,10,241,11
|
||||
CONTROL "",IDC_PROGRESS2,"msctls_progress32",PBS_SMOOTH | NOT
|
||||
WS_VISIBLE | WS_BORDER,24,10,241,11
|
||||
CONTROL "",IDC_INTROTEXT,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,
|
||||
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,20,20
|
||||
PUSHBUTTON "",IDC_SHOWDETAILS,0,28,50,14,NOT WS_TABSTOP
|
||||
END
|
||||
#endif
|
||||
|
||||
#if defined(APSTUDIO_INVOKED) || defined(_NSIS_CONFIG_UNINSTDLG)
|
||||
#if defined(APSTUDIO_INVOKED)
|
||||
IDD_UNINST$(_NSIS_CONFIG_UNINSTDLG) DIALOG DISCARDABLE 0, 0, 266, 130
|
||||
#else
|
||||
IDD_UNINST DIALOG DISCARDABLE 0, 0, 266, 130
|
||||
#endif
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
ICON IDI_ICON2,IDC_ULICON,0,1,20,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) DIALOG DISCARDABLE 0, 0, 162, 22
|
||||
#else
|
||||
IDD_VERIFY DIALOG DISCARDABLE 0, 0, 162, 22
|
||||
#endif
|
||||
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE
|
||||
FONT 8, "MS Sans Serif"
|
||||
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
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
11
Source/exehead/state.h
Normal file
11
Source/exehead/state.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
extern char g_usrvars[24][NSIS_MAX_STRLEN];
|
||||
#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])
|
||||
|
||||
extern char g_caption[NSIS_MAX_STRLEN*2];
|
||||
extern HWND g_hwnd;
|
||||
extern int g_filehdrsize;
|
||||
extern HANDLE g_hInstance;
|
||||
extern HWND insthwnd,insthwndbutton;
|
21
Source/exehead/ui.h
Normal file
21
Source/exehead/ui.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef _UI_H_
|
||||
#define _UI_H_
|
||||
|
||||
int ui_doinstall(void);
|
||||
void update_status_text(const char *text1, const char *text2);
|
||||
extern int ui_st_updateflag;
|
||||
|
||||
extern char g_autoclose;
|
||||
extern void *g_inst_combinedheader;
|
||||
extern section *g_inst_section;
|
||||
extern entry *g_inst_entry;
|
||||
|
||||
#define g_inst_header ((header *)g_inst_combinedheader)
|
||||
#define g_inst_cmnheader ((common_header *)g_inst_combinedheader)
|
||||
|
||||
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
|
||||
#define g_inst_uninstheader ((uninstall_header *)g_inst_combinedheader)
|
||||
extern int g_is_uninstaller;
|
||||
#endif
|
||||
|
||||
#endif//_UI_H_
|
BIN
Source/exehead/uninst.ico
Normal file
BIN
Source/exehead/uninst.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
548
Source/exehead/util.c
Normal file
548
Source/exehead/util.c
Normal file
|
@ -0,0 +1,548 @@
|
|||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include "util.h"
|
||||
#include "state.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "fileform.h"
|
||||
#include "ui.h"
|
||||
|
||||
#ifdef NSIS_CONFIG_LOG
|
||||
char g_log_file[1024];
|
||||
#endif
|
||||
|
||||
char g_usrvars[24][NSIS_MAX_STRLEN];
|
||||
|
||||
HANDLE g_hInstance;
|
||||
|
||||
HANDLE myCreateProcess(char *cmd, char *dir)
|
||||
{
|
||||
PROCESS_INFORMATION ProcInfo={0,};
|
||||
STARTUPINFO StartUp={0,};
|
||||
StartUp.cb=sizeof(StartUp);
|
||||
if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, dir, &StartUp, &ProcInfo))
|
||||
return NULL;
|
||||
if (NULL != ProcInfo.hThread) CloseHandle( ProcInfo.hThread );
|
||||
return ProcInfo.hProcess;
|
||||
}
|
||||
|
||||
|
||||
void addtrailingslash(char *str)
|
||||
{
|
||||
if (lastchar(str)!='\\') lstrcat(str,"\\");
|
||||
}
|
||||
|
||||
char lastchar(const char *str)
|
||||
{
|
||||
return *CharPrev(str,str+lstrlen(str));
|
||||
}
|
||||
|
||||
void trimslashtoend(char *buf)
|
||||
{
|
||||
char *p=scanendslash(buf);
|
||||
if (p<buf) p=buf;
|
||||
*p=0;
|
||||
}
|
||||
|
||||
|
||||
char *scanendslash(const char *str)
|
||||
{
|
||||
char *s=CharPrev(str,str+lstrlen(str));
|
||||
if (!*str) return (char*)str-1;
|
||||
for (;;)
|
||||
{
|
||||
char *t;
|
||||
if ('\\' == *s) return s;
|
||||
t=CharPrev(str,s);
|
||||
if (t==s) return (char*)str-1;
|
||||
s=t;
|
||||
}
|
||||
}
|
||||
|
||||
int validpathspec(char *ubuf)
|
||||
{
|
||||
return ((ubuf[0]=='\\' && ubuf[1]=='\\') || (ubuf[0] && *(ubuf+1)==':'));
|
||||
}
|
||||
|
||||
int is_valid_instpath(char *s)
|
||||
{
|
||||
int ivp=0;
|
||||
// if 8 is set, req is 0, which means rootdirs are not allowed.
|
||||
int req=!(g_inst_cmnheader->misc_flags&8);
|
||||
if (s[0] == '\\' && s[1] == '\\') // \\ path
|
||||
{
|
||||
if (lastchar(s)!='\\') ivp++;
|
||||
while (*s)
|
||||
{
|
||||
if (*s == '\\') ivp++;
|
||||
if (*s) s++;
|
||||
}
|
||||
ivp/=5-req;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*s)
|
||||
{
|
||||
if (*s) s++;
|
||||
if (*s == ':')
|
||||
{
|
||||
if (*s) s++;
|
||||
if (*s == '\\')
|
||||
{
|
||||
if (*s) s++;
|
||||
if (req || (*s && *s != '\\')) ivp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ivp;
|
||||
}
|
||||
|
||||
static char *findinmem(char *a, char *b, int len_of_a)
|
||||
{
|
||||
if (len_of_a<0) len_of_a=lstrlen(a);
|
||||
len_of_a -= lstrlen(b);
|
||||
while (*a && len_of_a >= 0)
|
||||
{
|
||||
char *t=a,*u=b;
|
||||
while (*t && *t == *u)
|
||||
{
|
||||
t++;
|
||||
u++;
|
||||
}
|
||||
if (!*u) return a;
|
||||
a++;
|
||||
len_of_a--;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void *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++;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
HANDLE myOpenFile(const char *fn, DWORD da, DWORD cd)
|
||||
{
|
||||
return CreateFile(fn,da,FILE_SHARE_READ,NULL,cd,0,NULL);
|
||||
}
|
||||
|
||||
#ifdef NSIS_SUPPORT_MOVEONREBOOT
|
||||
BOOL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew)
|
||||
{
|
||||
BOOL fOk = 0;
|
||||
HMODULE hLib=LoadLibrary("kernel32.dll");
|
||||
if (hLib)
|
||||
{
|
||||
typedef BOOL (WINAPI *mfea_t)(LPCSTR lpExistingFileName,LPCSTR lpNewFileName,DWORD dwFlags);
|
||||
mfea_t mfea;
|
||||
mfea=(mfea_t) GetProcAddress(hLib,"MoveFileExA");
|
||||
if (mfea)
|
||||
{
|
||||
fOk=mfea(pszExisting, pszNew, MOVEFILE_DELAY_UNTIL_REBOOT|MOVEFILE_REPLACE_EXISTING);
|
||||
}
|
||||
FreeLibrary(hLib);
|
||||
}
|
||||
|
||||
if (!fOk)
|
||||
{
|
||||
static char szRenameLine[1024];
|
||||
static char wininit[1024];
|
||||
static char tmpbuf[1024];
|
||||
int cchRenameLine;
|
||||
char *szRenameSec = "[Rename]\r\n";
|
||||
HANDLE hfile, hfilemap;
|
||||
DWORD dwFileSize, dwRenameLinePos;
|
||||
static const char nulint[4]="NUL";
|
||||
|
||||
if (pszNew) GetShortPathName(pszNew,tmpbuf,1024);
|
||||
else *((int *)tmpbuf) = *((int *)nulint);
|
||||
// wininit is used as a temporary here
|
||||
GetShortPathName(pszExisting,wininit,1024);
|
||||
cchRenameLine = wsprintf(szRenameLine,"%s=%s\r\n",tmpbuf,wininit);
|
||||
|
||||
GetWindowsDirectory(wininit, 1024-16);
|
||||
lstrcat(wininit, "\\wininit.ini");
|
||||
hfile = CreateFile(wininit,
|
||||
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
|
||||
if (hfile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
dwFileSize = GetFileSize(hfile, NULL);
|
||||
hfilemap = CreateFileMapping(hfile, NULL, PAGE_READWRITE, 0, dwFileSize + cchRenameLine + 10, NULL);
|
||||
|
||||
if (hfilemap != NULL)
|
||||
{
|
||||
LPSTR pszWinInit = (LPSTR) MapViewOfFile(hfilemap, FILE_MAP_WRITE, 0, 0, 0);
|
||||
|
||||
if (pszWinInit != NULL)
|
||||
{
|
||||
int do_write=0;
|
||||
LPSTR pszRenameSecInFile = findinmem(pszWinInit, szRenameSec,-1);
|
||||
if (pszRenameSecInFile == NULL)
|
||||
{
|
||||
lstrcpy(pszWinInit+dwFileSize, szRenameSec);
|
||||
dwFileSize += 10;
|
||||
dwRenameLinePos = dwFileSize;
|
||||
do_write++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *pszFirstRenameLine = findinmem(pszRenameSecInFile, "\n",-1)+1;
|
||||
int l=pszWinInit + dwFileSize-pszFirstRenameLine;
|
||||
if (!findinmem(pszFirstRenameLine,szRenameLine,l))
|
||||
{
|
||||
void* data=(void*)GlobalAlloc(GMEM_FIXED,l);
|
||||
mini_memcpy(data, pszFirstRenameLine, l);
|
||||
mini_memcpy(pszFirstRenameLine + cchRenameLine, data, l);
|
||||
GlobalFree((HGLOBAL)data);
|
||||
|
||||
dwRenameLinePos = pszFirstRenameLine - pszWinInit;
|
||||
do_write++;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_write)
|
||||
{
|
||||
mini_memcpy(&pszWinInit[dwRenameLinePos], szRenameLine,cchRenameLine);
|
||||
dwFileSize += cchRenameLine;
|
||||
}
|
||||
|
||||
UnmapViewOfFile(pszWinInit);
|
||||
|
||||
fOk++;
|
||||
}
|
||||
CloseHandle(hfilemap);
|
||||
}
|
||||
SetFilePointer(hfile, dwFileSize, NULL, FILE_BEGIN);
|
||||
SetEndOfFile(hfile);
|
||||
CloseHandle(hfile);
|
||||
}
|
||||
}
|
||||
return fOk;
|
||||
}
|
||||
#endif
|
||||
|
||||
void recursive_create_directory(char *directory)
|
||||
{
|
||||
char *tp;
|
||||
char *p;
|
||||
p=directory;
|
||||
while (*p == ' ') if (*p) p++;
|
||||
if (!*p) return;
|
||||
tp=*p?p+1:p;
|
||||
if (*tp == ':' && tp[1] == '\\') p=tp+2;
|
||||
else if (p[0] == '\\' && p[1] == '\\')
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < 2; x ++)
|
||||
{
|
||||
while (*p != '\\' && *p) if (*p) p++; // skip host then share
|
||||
if (*p) if (*p) p++;
|
||||
}
|
||||
|
||||
}
|
||||
else return;
|
||||
while (*p)
|
||||
{
|
||||
while (*p != '\\' && *p) if (*p) p++;
|
||||
if (!*p) CreateDirectory(directory,NULL);
|
||||
else
|
||||
{
|
||||
*p=0;
|
||||
CreateDirectory(directory,NULL);
|
||||
*p++ = '\\';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void myRegGetStr(HKEY root, const char *sub, const char *name, char *out)
|
||||
{
|
||||
HKEY hKey;
|
||||
*out=0;
|
||||
if (RegOpenKeyEx(root,sub,0,KEY_READ,&hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD l = NSIS_MAX_STRLEN;
|
||||
DWORD t;
|
||||
if (RegQueryValueEx(hKey,name,NULL,&t,out,&l ) != ERROR_SUCCESS || t != REG_SZ) *out=0;
|
||||
out[NSIS_MAX_STRLEN-1]=0;
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char g_all_user_var_flag;
|
||||
|
||||
static void queryShellFolders(const char *name, char *out)
|
||||
{
|
||||
char f=g_all_user_var_flag;
|
||||
again:
|
||||
|
||||
myRegGetStr(g_all_user_var_flag?HKEY_LOCAL_MACHINE:HKEY_CURRENT_USER,
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
|
||||
name+(f?0:7),out);
|
||||
if (!out[0])
|
||||
{
|
||||
if (f)
|
||||
{
|
||||
f=0; goto again;
|
||||
}
|
||||
GetTempPath(NSIS_MAX_STRLEN,out);
|
||||
}
|
||||
}
|
||||
|
||||
char ps_tmpbuf[NSIS_MAX_STRLEN*2];
|
||||
|
||||
|
||||
void process_string_fromtab(char *out, int offs)
|
||||
{
|
||||
process_string(ps_tmpbuf,GetStringFromStringTab(offs));
|
||||
lstrcpyn(out,ps_tmpbuf,NSIS_MAX_STRLEN);
|
||||
}
|
||||
|
||||
void myitoa(char *s, int d) { wsprintf(s,"%d",d); }
|
||||
int myatoi(char *s)
|
||||
{
|
||||
unsigned int v=0;
|
||||
if (*s == '0' && (s[1] == 'x' || s[1] == 'X'))
|
||||
{
|
||||
s+=2;
|
||||
for (;;)
|
||||
{
|
||||
int c=*s++;
|
||||
if (c >= '0' && c <= '9') c-='0';
|
||||
else if (c >= 'a' && c <= 'f') c-='a'-10;
|
||||
else if (c >= 'A' && c <= 'F') c-='A'-10;
|
||||
else break;
|
||||
v<<=4;
|
||||
v+=c;
|
||||
}
|
||||
}
|
||||
else if (*s == '0' && s[1] <= '7' && s[1] >= '0')
|
||||
{
|
||||
s++;
|
||||
for (;;)
|
||||
{
|
||||
int c=*s++;
|
||||
if (c >= '0' && c <= '7') c-='0';
|
||||
else break;
|
||||
v<<=3;
|
||||
v+=c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int sign=0;
|
||||
if (*s == '-') { s++; sign++; }
|
||||
for (;;)
|
||||
{
|
||||
int c=*s++ - '0';
|
||||
if (c < 0 || c > 9) break;
|
||||
v*=10;
|
||||
v+=c;
|
||||
}
|
||||
if (sign) return -(int) v;
|
||||
}
|
||||
return (int)v;
|
||||
}
|
||||
|
||||
|
||||
int process_string_fromtab_toint(int offs)
|
||||
{
|
||||
process_string(ps_tmpbuf,GetStringFromStringTab(offs));
|
||||
return myatoi(ps_tmpbuf);
|
||||
}
|
||||
|
||||
// Dave Laundon's simplified process_string
|
||||
void process_string(char *out, const char *in)
|
||||
{
|
||||
char *outsave = out;
|
||||
while (*in && out - outsave < NSIS_MAX_STRLEN)
|
||||
{
|
||||
int nVarIdx = (unsigned char)*in++;
|
||||
if (nVarIdx < VAR_CODES_START)
|
||||
{
|
||||
*out++ = nVarIdx;
|
||||
}
|
||||
else if (nVarIdx == 255)
|
||||
{
|
||||
*out++ = *in++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD f;
|
||||
switch (nVarIdx) // The order of this list must match that in ..\strlist.cpp (err, build.cpp -J)
|
||||
{
|
||||
case VAR_CODES_START + 0: // HWNDPARENT
|
||||
wsprintf(out, "%u", (unsigned int)g_hwnd);
|
||||
break;
|
||||
case VAR_CODES_START + 1: // 0
|
||||
case VAR_CODES_START + 2: // 1
|
||||
case VAR_CODES_START + 3: // 2
|
||||
case VAR_CODES_START + 4: // 3
|
||||
case VAR_CODES_START + 5: // 4
|
||||
case VAR_CODES_START + 6: // 5
|
||||
case VAR_CODES_START + 7: // 6
|
||||
case VAR_CODES_START + 8: // 7
|
||||
case VAR_CODES_START + 9: // 8
|
||||
case VAR_CODES_START + 10: // 9
|
||||
case VAR_CODES_START + 11: // R0
|
||||
case VAR_CODES_START + 12: // R1
|
||||
case VAR_CODES_START + 13: // R2
|
||||
case VAR_CODES_START + 14: // R3
|
||||
case VAR_CODES_START + 15: // R4
|
||||
case VAR_CODES_START + 16: // R5
|
||||
case VAR_CODES_START + 17: // R6
|
||||
case VAR_CODES_START + 18: // R7
|
||||
case VAR_CODES_START + 19: // R8
|
||||
case VAR_CODES_START + 20: // R9
|
||||
case VAR_CODES_START + 21: // CMDLINE
|
||||
case VAR_CODES_START + 22: // INSTDIR
|
||||
case VAR_CODES_START + 23: // OUTDIR
|
||||
case VAR_CODES_START + 24: // EXEDIR
|
||||
lstrcpy(out, g_usrvars[nVarIdx - (VAR_CODES_START + 1)]);
|
||||
break;
|
||||
|
||||
case VAR_CODES_START + 25: // PROGRAMFILES
|
||||
myRegGetStr(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProgramFilesDir", out);
|
||||
if (!*out)
|
||||
lstrcpy(out, "C:\\Program Files");
|
||||
break;
|
||||
|
||||
case VAR_CODES_START + 26: // SMPROGRAMS
|
||||
case VAR_CODES_START + 27: // SMSTARTUP
|
||||
case VAR_CODES_START + 28: // DESKTOP
|
||||
case VAR_CODES_START + 29: // STARTMENU
|
||||
{
|
||||
static const char *tab[]={
|
||||
"Common Programs",
|
||||
"Common Startup",
|
||||
"Common Desktop",
|
||||
"Common Start Menu"
|
||||
};
|
||||
queryShellFolders(tab[nVarIdx-(VAR_CODES_START+26)], out);
|
||||
}
|
||||
break;
|
||||
|
||||
case VAR_CODES_START + 30: // QUICKLAUNCH
|
||||
queryShellFolders("Common AppData", out);
|
||||
lstrcat(out, "\\Microsoft\\Internet Explorer\\Quick Launch");
|
||||
f = GetFileAttributes(out);
|
||||
if (f != (DWORD)-1 && (f & FILE_ATTRIBUTE_DIRECTORY))
|
||||
break;
|
||||
case VAR_CODES_START + 31: // TEMP
|
||||
GetTempPath(NSIS_MAX_STRLEN, out);
|
||||
break;
|
||||
|
||||
case VAR_CODES_START + 32: // WINDIR
|
||||
GetWindowsDirectory(out, NSIS_MAX_STRLEN);
|
||||
break;
|
||||
|
||||
case VAR_CODES_START + 33: // SYSDIR
|
||||
GetSystemDirectory(out, NSIS_MAX_STRLEN);
|
||||
break;
|
||||
|
||||
#if VAR_CODES_START + 33 >= 255
|
||||
#error "Too many variables! Extend VAR_CODES_START!"
|
||||
#endif
|
||||
} // switch
|
||||
// remove trailing slash
|
||||
while (*out && *(out+1)) out++;
|
||||
if (nVarIdx > 21+VAR_CODES_START && *out == '\\') // only if not $0 to $R9, $CMDLINE, or $HWNDPARENT
|
||||
*out = 0;
|
||||
if (*out) out++;
|
||||
} // >= VAR_CODES_START
|
||||
} // while
|
||||
*out = 0;
|
||||
}
|
||||
#ifdef NSIS_CONFIG_LOG
|
||||
|
||||
char log_text[4096];
|
||||
int log_dolog;
|
||||
void log_write(int close)
|
||||
{
|
||||
extern char g_log_file[1024];
|
||||
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 = CreateFile(g_log_file,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,0,NULL);
|
||||
if (fp!=INVALID_HANDLE_VALUE)
|
||||
SetFilePointer(fp,0,NULL,FILE_END);
|
||||
}
|
||||
if (fp!=INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD d;
|
||||
lstrcat(log_text,"\r\n");
|
||||
WriteFile(fp,log_text,lstrlen(log_text),&d,NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef NSIS_SUPPORT_CREATESHORTCUT
|
||||
int CreateShortCut(HWND hwnd, LPCSTR pszShortcutFile, LPCSTR pszIconFile, int iconindex, LPCSTR pszExe, LPCSTR pszArg, LPCSTR workingdir, int showmode, int hotkey)
|
||||
{
|
||||
HRESULT hres;
|
||||
int rv=1;
|
||||
IShellLink* psl;
|
||||
hres=OleInitialize(NULL);
|
||||
if (hres != S_FALSE && hres != S_OK) return rv;
|
||||
|
||||
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,pszExe);
|
||||
psl->lpVtbl->SetWorkingDirectory(psl,workingdir);
|
||||
if (showmode) psl->lpVtbl->SetShowCmd(psl,showmode);
|
||||
if (hotkey) psl->lpVtbl->SetHotkey(psl,(unsigned short)hotkey);
|
||||
if (pszIconFile) psl->lpVtbl->SetIconLocation(psl,pszIconFile,iconindex);
|
||||
if (pszArg)
|
||||
{
|
||||
psl->lpVtbl->SetArguments(psl,pszArg);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
WCHAR wsz[1024];
|
||||
MultiByteToWideChar(CP_ACP, 0, pszShortcutFile, -1, wsz, 1024);
|
||||
hres=ppf->lpVtbl->Save(ppf,(const WCHAR*)wsz,TRUE);
|
||||
if (SUCCEEDED(hres)) rv=0;
|
||||
}
|
||||
ppf->lpVtbl->Release(ppf);
|
||||
}
|
||||
psl->lpVtbl->Release(psl);
|
||||
}
|
||||
OleUninitialize();
|
||||
return rv;
|
||||
}
|
||||
#endif//NSIS_SUPPORT_CREATESHORTCUT
|
47
Source/exehead/util.h
Normal file
47
Source/exehead/util.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include "config.h"
|
||||
|
||||
void recursive_create_directory(char *directory);
|
||||
|
||||
extern char ps_tmpbuf[NSIS_MAX_STRLEN*2];
|
||||
void process_string(char *out, const char *in);
|
||||
void process_string_fromtab(char *out, int offs);
|
||||
int process_string_fromtab_toint(int offs);
|
||||
void myRegGetStr(HKEY root, const char *sub, const char *name, char *out);
|
||||
int myatoi(char *s);
|
||||
void myitoa(char *s, int d);
|
||||
|
||||
|
||||
#ifdef NSIS_CONFIG_LOG
|
||||
extern char log_text[NSIS_MAX_STRLEN*4];
|
||||
void log_write(int close);
|
||||
#define log_printf(x1) wsprintf(log_text,x1); log_write(0)
|
||||
#define log_printf2(x1,x2) wsprintf(log_text,x1,x2); log_write(0)
|
||||
#define log_printf3(x1,x2,x3) wsprintf(log_text,x1,x2,x3); log_write(0)
|
||||
#define log_printf4(x1,x2,x3,x4) wsprintf(log_text,x1,x2,x3,x4); log_write(0)
|
||||
#define log_printf5(x1,x2,x3,x4,x5) wsprintf(log_text,x1,x2,x3,x4,x5); log_write(0)
|
||||
#define log_printf6(x1,x2,x3,x4,x5,x6) wsprintf(log_text,x1,x2,x3,x4,x5,x6); log_write(0)
|
||||
#define log_printf8(x1,x2,x3,x4,x5,x6,x7,x8) wsprintf(log_text,x1,x2,x3,x4,x5,x6,x7,x8); log_write(0)
|
||||
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_printf8(x1,x2,x3,x4,x5,x6,x7,x8)
|
||||
#endif
|
||||
|
||||
HANDLE myCreateProcess(char *cmd, char *dir);
|
||||
|
||||
HANDLE myOpenFile(const char *fn, DWORD da, DWORD cd);
|
||||
int CreateShortCut(HWND hwnd, LPCSTR pszShortcutFile, LPCSTR pszIconFile, int iconindex, LPCSTR pszExe, LPCSTR pszArg, LPCSTR workingdir, int showmode, int hotkey);
|
||||
int validpathspec(char *ubuf);
|
||||
void addtrailingslash(char *str);
|
||||
char lastchar(const char *str);
|
||||
void trimslashtoend(char *buf);
|
||||
char *scanendslash(const char *str);
|
||||
int is_valid_instpath(char *s);
|
||||
BOOL MoveFileOnReboot(LPCTSTR pszExisting, LPCTSTR pszNew);
|
||||
void *mini_memcpy(void *out, const void *in, int len);
|
BIN
Source/icon.ico
Normal file
BIN
Source/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
150
Source/lineparse.h
Normal file
150
Source/lineparse.h
Normal file
|
@ -0,0 +1,150 @@
|
|||
#ifndef _LINEPARSE_H_
|
||||
#define _LINEPARSE_H_
|
||||
|
||||
class LineParser {
|
||||
public:
|
||||
|
||||
LineParser()
|
||||
{
|
||||
m_nt=m_eat=0;
|
||||
m_tokens=0;
|
||||
}
|
||||
|
||||
~LineParser()
|
||||
{
|
||||
freetokens();
|
||||
}
|
||||
|
||||
int parse(char *line) // returns -1 on error
|
||||
{
|
||||
freetokens();
|
||||
int n=doline(line);
|
||||
if (n) return n;
|
||||
if (m_nt)
|
||||
{
|
||||
m_tokens=(char**)malloc(sizeof(char*)*m_nt);
|
||||
n=doline(line);
|
||||
if (n)
|
||||
{
|
||||
freetokens();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getnumtokens() { return m_nt-m_eat; }
|
||||
|
||||
void eattoken() { m_eat++; }
|
||||
|
||||
double 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 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 *gettoken_str(int token)
|
||||
{
|
||||
token+=m_eat;
|
||||
if (token < 0 || token >= m_nt) return "";
|
||||
return m_tokens[token];
|
||||
}
|
||||
int 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;
|
||||
}
|
||||
private:
|
||||
void 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 doline(char *line)
|
||||
{
|
||||
m_nt=0;
|
||||
while (*line == ' ' || *line == '\t') line++;
|
||||
while (*line)
|
||||
{
|
||||
int lstate=0; // 1=", 2=`, 4='
|
||||
if (*line == ';' || *line == '#') break;
|
||||
if (*line == '\"') lstate=1;
|
||||
else if (*line == '\'') lstate=2;
|
||||
else if (*line == '`') lstate=4;
|
||||
if (lstate) line++;
|
||||
int nc=0;
|
||||
while (*line)
|
||||
{
|
||||
if (lstate==1 && *line =='\"') break;
|
||||
if (lstate==2 && *line =='\'') break;
|
||||
if (lstate==4 && *line =='`') break;
|
||||
if (!lstate && (*line == ' ' || *line == '\t')) break;
|
||||
line++;
|
||||
nc++;
|
||||
}
|
||||
if (m_tokens)
|
||||
{
|
||||
m_tokens[m_nt]=(char*)malloc(nc+1);
|
||||
strncpy(m_tokens[m_nt],line-nc,nc);
|
||||
m_tokens[m_nt][nc]=0;
|
||||
}
|
||||
m_nt++;
|
||||
if (lstate)
|
||||
{
|
||||
if (*line) line++;
|
||||
else return -2;
|
||||
}
|
||||
while (*line == ' ' || *line == '\t') line++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int m_eat;
|
||||
int m_nt;
|
||||
char **m_tokens;
|
||||
};
|
||||
#endif//_LINEPARSE_H_
|
379
Source/makenssi.cpp
Normal file
379
Source/makenssi.cpp
Normal file
|
@ -0,0 +1,379 @@
|
|||
const char *NSIS_VERSION="v2.0a2";
|
||||
|
||||
/*
|
||||
Nullsoft "SuperPimp" Installation System - makensis.cpp - installer compiler code
|
||||
May 21st, 2002
|
||||
|
||||
Copyright (C) 1999-2002 Nullsoft, Inc.
|
||||
|
||||
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.
|
||||
|
||||
This source distribution includes portions of zlib. see zlib/zlib.h for
|
||||
its license and so forth. Note that this license is also borrowed from zlib.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "build.h"
|
||||
#include "util.h"
|
||||
#include "exedata.h"
|
||||
|
||||
|
||||
int g_noconfig;
|
||||
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();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CEXEBuild build;
|
||||
int do_cd=0;
|
||||
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;
|
||||
|
||||
if (argc > 1 && argv[1][0]=='/' && (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 && argv[tmpargpos][0]=='/' && (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;
|
||||
}
|
||||
fprintf(g_output,"MakeNSIS %s - Copyright 1999-2002 Nullsoft, Inc.\n"
|
||||
"\n"
|
||||
"Portions Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler (zlib).\n"
|
||||
"Includes portions derived from bzip2 (see documentation for details).\n"
|
||||
"Contributors: nnop@newmail.ru, Ryan Geiss, Andras Varga, Drew Davidson, Peter Windridge, Dave Laundon, Robert Rainwater, Yaroslav Faybishenko, Jeff Doozan, et al.\n\n",NSIS_VERSION);
|
||||
fflush(g_output);
|
||||
}
|
||||
|
||||
atexit(myatexit);
|
||||
|
||||
signal(SIGINT,sigint);
|
||||
|
||||
if (!g_output) g_output=stdout;
|
||||
while (argpos < argc)
|
||||
{
|
||||
if (argv[argpos][0]=='/' && (argv[argpos][1]=='D' || argv[argpos][1]=='d') && argv[argpos][2])
|
||||
{
|
||||
char *p=argv[argpos]+2;
|
||||
if (p[0])
|
||||
{
|
||||
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
|
||||
{
|
||||
build.warning("command line /D requires argument (i.e. \"/Ddefine\"). ignored.");
|
||||
}
|
||||
}
|
||||
else if (argv[argpos][0]=='/' && (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][0]=='/' && (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],"/CD")) do_cd=1;
|
||||
else if (argv[argpos][0] == '/' && (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],"/NOCONFIG")) g_noconfig=1;
|
||||
else if (!stricmp(argv[argpos],"/PAUSE")) g_dopause=1;
|
||||
else if (!stricmp(argv[argpos],"/LICENSE"))
|
||||
{
|
||||
if (build.display_info)
|
||||
{
|
||||
fprintf(g_output,"This software is provided 'as-is', without any express or implied warranty. In\n"
|
||||
"no event will the authors be held liable for any damages arising from the use\n"
|
||||
"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");
|
||||
fflush(g_output);
|
||||
}
|
||||
nousage++;
|
||||
}
|
||||
else if (!stricmp(argv[argpos],"/CMDHELP"))
|
||||
{
|
||||
if (argpos < argc-1)
|
||||
build.print_help(argv[++argpos]);
|
||||
else
|
||||
build.print_help(NULL);
|
||||
nousage++;
|
||||
}
|
||||
else if (!stricmp(argv[argpos],"/HDRINFO"))
|
||||
{
|
||||
if (build.display_info)
|
||||
{
|
||||
fprintf(g_output,"EXE header size of %d bytes, info header size of %d bytes.\n", exeheader_size,sizeof(firstheader));
|
||||
fprintf(g_output,"Install header size of %d bytes, uninstall header size of %d bytes.\n",sizeof(header),sizeof(uninstall_header));
|
||||
fprintf(g_output,"Section size of %d bytes, instruction size of %d bytes.\n",sizeof(section),sizeof(entry));
|
||||
char *p=build.definedlist.defines.get();
|
||||
char *p2=build.definedlist.values.get();
|
||||
int x=0;
|
||||
fprintf(g_output,"\nDefined symbols: ");
|
||||
while (x < build.definedlist.defines.getlen())
|
||||
{
|
||||
if (x) fprintf(g_output,",");;
|
||||
fprintf(g_output,"%s",p+x);
|
||||
if (*p2) fprintf(g_output,"=%s",p2);
|
||||
|
||||
x+=strlen(p+x)+1;
|
||||
p2+=strlen(p2)+1;
|
||||
}
|
||||
if (!x) fprintf(g_output,"none");
|
||||
fprintf(g_output,"\n");
|
||||
fflush(g_output);
|
||||
}
|
||||
nousage++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (argv[argpos][0]=='/') break;
|
||||
files_processed++;
|
||||
if (!strcmp(argv[argpos],"-")) g_dopause=0;
|
||||
if (!g_noconfig)
|
||||
{
|
||||
g_noconfig=1;
|
||||
char exepath[1024];
|
||||
strncpy(exepath,argv[0],1023);
|
||||
exepath[1023]=0;
|
||||
char *p=exepath;
|
||||
while (*p) p++;
|
||||
while (p > exepath && *p != '\\') p=CharPrev(exepath,p);
|
||||
if (p>exepath) p++;
|
||||
strcpy(p,"nsisconf.nsi");
|
||||
FILE *cfg=fopen(exepath,"rt");
|
||||
if (cfg)
|
||||
{
|
||||
if (build.display_script)
|
||||
{
|
||||
fprintf(g_output,"\n\nProcessing config: \n");
|
||||
fflush(g_output);
|
||||
}
|
||||
int lc=0;
|
||||
int ret=build.process_script(cfg,exepath,&lc);
|
||||
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",lc);
|
||||
fflush(g_output);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
char sfile[1024];
|
||||
if (!strcmp(argv[argpos],"-"))
|
||||
{
|
||||
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)
|
||||
{
|
||||
fprintf(g_output,"Can't open script \"%s\"\n",sfile);
|
||||
fflush(g_output);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (do_cd)
|
||||
{
|
||||
char dirbuf[1024],*p;
|
||||
GetFullPathName(sfile,sizeof(dirbuf),dirbuf,&p);
|
||||
p=dirbuf;
|
||||
while (*p) p++;
|
||||
while (p > dirbuf && *p != '\\') p=CharPrev(dirbuf,p);
|
||||
*p=0;
|
||||
if (dirbuf[0])
|
||||
{
|
||||
if (build.display_script)
|
||||
{
|
||||
fprintf(g_output,"Changing directory to: \"%s\"\n",dirbuf);
|
||||
fflush(g_output);
|
||||
}
|
||||
SetCurrentDirectory(dirbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (build.display_script)
|
||||
{
|
||||
fprintf(g_output,"\n\nProcessing script file: \"%s\"\n",sfile);
|
||||
fflush(g_output);
|
||||
}
|
||||
int lc=0;
|
||||
int ret=build.process_script(fp,sfile,&lc);
|
||||
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,lc);
|
||||
fflush(g_output);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
argpos++;
|
||||
}
|
||||
|
||||
if (argpos<argc || (!files_processed && !cmds_processed))
|
||||
{
|
||||
if (build.display_errors && !nousage)
|
||||
{
|
||||
fprintf(g_output,"Usage:\n"
|
||||
" makensis [options] [script.nsi | - [...]]\n"
|
||||
" options are:\n"
|
||||
" /CMDHELP item prints out help for 'item', or lists all commands\n"
|
||||
" /HDRINFO prints information about what options makensis was compiled with\n"
|
||||
" /LICENSE prints the makensis software license\n");
|
||||
fprintf(g_output,
|
||||
" /Vx verbosity where x is 4=all,3=no script,2=no info,1=no warnings,0=none\n"
|
||||
" /Ofile specifies a text file to log compiler output (default is stdout)\n"
|
||||
" /PAUSE pauses after execution\n"
|
||||
" /NOCONFIG disables inclusion of <path to makensis.exe>\\nsisconf.nsi\n"
|
||||
" /CD makes makensis change the current directory to that of the .nsi file\n"
|
||||
" /Ddefine[=value] defines the symbol \"define\" for the script [to value]\n"
|
||||
" /Xscriptcmd executes scriptcmd in script (i.e. \"/XOutFile poop.exe\")\n"
|
||||
" for script file name, you can use - to read from the standard input\n");
|
||||
fflush(g_output);
|
||||
}
|
||||
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;
|
||||
}
|
247
Source/makenssi.dsp
Normal file
247
Source/makenssi.dsp
Normal file
|
@ -0,0 +1,247 @@
|
|||
# Microsoft Developer Studio Project File - Name="makenssi" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=makenssi - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "makenssi.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "makenssi.mak" CFG="makenssi - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "makenssi - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /Ob2 /D "_CONSOLE" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "WIN32_LEAN_AND_MEAN" /FD /c
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../makensis.exe" /opt:nowin98
|
||||
# Begin Target
|
||||
|
||||
# Name "makenssi - Win32 Release"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Group "zlib"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "headers"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zlib\Deflate.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zlib\Infblock.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zlib\Infcodes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zlib\Inftrees.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zlib\Infutil.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zlib\Zconf.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zlib\Zlib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zlib\Zutil.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zlib\deflate.c
|
||||
# ADD CPP /G6
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\zlib\trees.c
|
||||
# ADD CPP /G6
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "bzip2"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bzip2\blocksort.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bzip2\bzlib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bzip2\bzlib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bzip2\bzlib_private.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bzip2\compress.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\bzip2\huffman.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\build.cpp
|
||||
# ADD CPP /G6
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\crc32.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DialogTemplate.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\exedata.cpp
|
||||
# ADD CPP /G6
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\makenssi.cpp
|
||||
# ADD CPP /G6
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ResourceEditor.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\script.cpp
|
||||
# ADD CPP /Ot /Ow /Oy
|
||||
# SUBTRACT CPP /Og
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tokens.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.cpp
|
||||
# ADD CPP /G6
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\build.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cbzip2.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\compressor.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\czlib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\DialogTemplate.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\exedata.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lineparse.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\ResourceEditor.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\strlist.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\tokens.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\util.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\icon.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Script1.rc
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\makensis.htm
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\makensis.nsi
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
59
Source/makenssi.dsw
Normal file
59
Source/makenssi.dsw
Normal file
|
@ -0,0 +1,59 @@
|
|||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "exehead_bzip2"=".\exehead\exehead-bzip2.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "exehead_zlib"=".\exehead\exehead-zlib.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "makenssi"=".\makenssi.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name exehead_bzip2
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name exehead_zlib
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
1
Source/makenssi.ncb
Normal file
1
Source/makenssi.ncb
Normal file
|
@ -0,0 +1 @@
|
|||
Microsoft C/C++ program database 2.00
|
BIN
Source/makenssi.opt
Normal file
BIN
Source/makenssi.opt
Normal file
Binary file not shown.
260
Source/makenssi.plg
Normal file
260
Source/makenssi.plg
Normal file
|
@ -0,0 +1,260 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: exehead_bzip2 - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating command line "rc.exe /l 0x409 /fo"Release-bzip2/resource.res" /d "NDEBUG" "C:\Program Files\NSIS\Source\exehead\resource.rc""
|
||||
Creating temporary file "F:\Temp\WinTemp\RSP2E5.tmp" with contents
|
||||
[
|
||||
/nologo /ML /W3 /GX /O1 /Oy /D "_WINDOWS" /D "EXEHEAD" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "WIN32_LEAN_AND_MEAN" /D "NSIS_COMPRESS_USE_BZIP2" /Fo"Release-bzip2/" /Fd"Release-bzip2/" /FD /c
|
||||
"C:\Program Files\NSIS\Source\zlib\INFBLOCK.C"
|
||||
"C:\Program Files\NSIS\Source\zlib\INFCODES.C"
|
||||
"C:\Program Files\NSIS\Source\zlib\INFLATE.C"
|
||||
"C:\Program Files\NSIS\Source\zlib\INFTREES.C"
|
||||
"C:\Program Files\NSIS\Source\zlib\INFUTIL.C"
|
||||
"C:\Program Files\NSIS\Source\bzip2\bzlib.c"
|
||||
"C:\Program Files\NSIS\Source\bzip2\decompress.c"
|
||||
"C:\Program Files\NSIS\Source\bzip2\huffman.c"
|
||||
"C:\Program Files\NSIS\Source\bzip2\randtable.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\bgbg.c"
|
||||
"C:\Program Files\NSIS\Source\crc32.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\exec.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\fileform.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\Main.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\Ui.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\util.c"
|
||||
]
|
||||
Creating command line "cl.exe @F:\Temp\WinTemp\RSP2E5.tmp"
|
||||
Creating temporary file "F:\Temp\WinTemp\RSP2E6.tmp" with contents
|
||||
[
|
||||
comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib shell32.lib /nologo /entry:"WinMain" /subsystem:windows /pdb:none /machine:I386 /nodefaultlib /out:"Release-bzip2/exehead_bzip2.exe" /opt:nowin98
|
||||
".\Release-bzip2\INFBLOCK.OBJ"
|
||||
".\Release-bzip2\INFCODES.OBJ"
|
||||
".\Release-bzip2\INFLATE.OBJ"
|
||||
".\Release-bzip2\INFTREES.OBJ"
|
||||
".\Release-bzip2\INFUTIL.OBJ"
|
||||
".\Release-bzip2\bzlib.obj"
|
||||
".\Release-bzip2\decompress.obj"
|
||||
".\Release-bzip2\huffman.obj"
|
||||
".\Release-bzip2\randtable.obj"
|
||||
".\Release-bzip2\bgbg.obj"
|
||||
".\Release-bzip2\crc32.obj"
|
||||
".\Release-bzip2\exec.obj"
|
||||
".\Release-bzip2\fileform.obj"
|
||||
".\Release-bzip2\Main.obj"
|
||||
".\Release-bzip2\Ui.obj"
|
||||
".\Release-bzip2\util.obj"
|
||||
".\Release-bzip2\resource.res"
|
||||
]
|
||||
Creating command line "link.exe @F:\Temp\WinTemp\RSP2E6.tmp"
|
||||
<h3>Output Window</h3>
|
||||
Compiling resources...
|
||||
Compiling...
|
||||
INFBLOCK.C
|
||||
INFCODES.C
|
||||
INFLATE.C
|
||||
INFTREES.C
|
||||
INFUTIL.C
|
||||
bzlib.c
|
||||
decompress.c
|
||||
huffman.c
|
||||
randtable.c
|
||||
bgbg.c
|
||||
crc32.c
|
||||
exec.c
|
||||
fileform.c
|
||||
Main.c
|
||||
Ui.c
|
||||
util.c
|
||||
Generating Code...
|
||||
Linking...
|
||||
Creating temporary file "F:\Temp\WinTemp\RSP2E8.bat" with contents
|
||||
[
|
||||
@echo off
|
||||
bin2h Release-bzip2\exehead_bzip2.exe Release-bzip2\exehead_bzip2.h bzip2_header_data
|
||||
]
|
||||
Creating command line "F:\Temp\WinTemp\RSP2E8.bat"
|
||||
generating include file for makenssi
|
||||
Release-bzip2\exehead_bzip2.exe -> bzip2_header_data (38400 bytes)
|
||||
|
||||
<h3>
|
||||
--------------------Configuration: exehead_zlib - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating command line "rc.exe /l 0x409 /fo"Release-zlib/resource.res" /d "NDEBUG" "C:\Program Files\NSIS\Source\exehead\resource.rc""
|
||||
Creating temporary file "F:\Temp\WinTemp\RSP2E9.tmp" with contents
|
||||
[
|
||||
/nologo /ML /W3 /GX /O1 /Oy /D "_WINDOWS" /D "EXEHEAD" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "WIN32_LEAN_AND_MEAN" /D "NSIS_COMPRESS_USE_ZLIB" /Fo"Release-zlib/" /Fd"Release-zlib/" /FD /c
|
||||
"C:\Program Files\NSIS\Source\zlib\INFBLOCK.C"
|
||||
"C:\Program Files\NSIS\Source\zlib\INFCODES.C"
|
||||
"C:\Program Files\NSIS\Source\zlib\INFLATE.C"
|
||||
"C:\Program Files\NSIS\Source\zlib\INFTREES.C"
|
||||
"C:\Program Files\NSIS\Source\zlib\INFUTIL.C"
|
||||
"C:\Program Files\NSIS\Source\bzip2\bzlib.c"
|
||||
"C:\Program Files\NSIS\Source\bzip2\decompress.c"
|
||||
"C:\Program Files\NSIS\Source\bzip2\huffman.c"
|
||||
"C:\Program Files\NSIS\Source\bzip2\randtable.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\bgbg.c"
|
||||
"C:\Program Files\NSIS\Source\crc32.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\exec.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\fileform.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\Main.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\Ui.c"
|
||||
"C:\Program Files\NSIS\Source\exehead\util.c"
|
||||
]
|
||||
Creating command line "cl.exe @F:\Temp\WinTemp\RSP2E9.tmp"
|
||||
Creating temporary file "F:\Temp\WinTemp\RSP2EA.tmp" with contents
|
||||
[
|
||||
comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib shell32.lib /nologo /entry:"WinMain" /subsystem:windows /pdb:none /machine:I386 /nodefaultlib /out:"Release-zlib/exehead_zlib.exe" /opt:nowin98
|
||||
".\Release-zlib\INFBLOCK.OBJ"
|
||||
".\Release-zlib\INFCODES.OBJ"
|
||||
".\Release-zlib\INFLATE.OBJ"
|
||||
".\Release-zlib\INFTREES.OBJ"
|
||||
".\Release-zlib\INFUTIL.OBJ"
|
||||
".\Release-zlib\bzlib.obj"
|
||||
".\Release-zlib\decompress.obj"
|
||||
".\Release-zlib\huffman.obj"
|
||||
".\Release-zlib\randtable.obj"
|
||||
".\Release-zlib\bgbg.obj"
|
||||
".\Release-zlib\crc32.obj"
|
||||
".\Release-zlib\exec.obj"
|
||||
".\Release-zlib\fileform.obj"
|
||||
".\Release-zlib\Main.obj"
|
||||
".\Release-zlib\Ui.obj"
|
||||
".\Release-zlib\util.obj"
|
||||
".\Release-zlib\resource.res"
|
||||
]
|
||||
Creating command line "link.exe @F:\Temp\WinTemp\RSP2EA.tmp"
|
||||
<h3>Output Window</h3>
|
||||
Compiling resources...
|
||||
Compiling...
|
||||
INFBLOCK.C
|
||||
INFCODES.C
|
||||
INFLATE.C
|
||||
INFTREES.C
|
||||
INFUTIL.C
|
||||
bzlib.c
|
||||
decompress.c
|
||||
huffman.c
|
||||
randtable.c
|
||||
bgbg.c
|
||||
crc32.c
|
||||
exec.c
|
||||
fileform.c
|
||||
Main.c
|
||||
Ui.c
|
||||
util.c
|
||||
Generating Code...
|
||||
Linking...
|
||||
Creating temporary file "F:\Temp\WinTemp\RSP2EC.bat" with contents
|
||||
[
|
||||
@echo off
|
||||
bin2h Release-zlib\exehead_zlib.exe Release-zlib\exehead_zlib.h zlib_header_data
|
||||
bin2h bitmap1.bmp Release-zlib\bitmap1.h bitmap1_data
|
||||
bin2h nsis.ico Release-zlib\icon.h icon_data
|
||||
bin2h uninst.ico Release-zlib\unicon.h unicon_data
|
||||
]
|
||||
Creating command line "F:\Temp\WinTemp\RSP2EC.bat"
|
||||
generating include file for makenssi
|
||||
Release-zlib\exehead_zlib.exe -> zlib_header_data (37888 bytes)
|
||||
|
||||
bitmap1.bmp -> bitmap1_data (886 bytes)
|
||||
|
||||
nsis.ico -> icon_data (766 bytes)
|
||||
|
||||
uninst.ico -> unicon_data (766 bytes)
|
||||
|
||||
<h3>
|
||||
--------------------Configuration: makenssi - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating command line "rc.exe /l 0x409 /fo"Release/Script1.res" /d "NDEBUG" "C:\Program Files\NSIS\Source\Script1.rc""
|
||||
Creating temporary file "F:\Temp\WinTemp\RSP2ED.tmp" with contents
|
||||
[
|
||||
/nologo /G6 /ML /W3 /GX /O2 /Ob2 /D "_CONSOLE" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "WIN32_LEAN_AND_MEAN" /Fo"Release/" /Fd"Release/" /FD /c
|
||||
"C:\Program Files\NSIS\Source\zlib\deflate.c"
|
||||
"C:\Program Files\NSIS\Source\zlib\trees.c"
|
||||
"C:\Program Files\NSIS\Source\build.cpp"
|
||||
"C:\Program Files\NSIS\Source\exedata.cpp"
|
||||
"C:\Program Files\NSIS\Source\makenssi.cpp"
|
||||
"C:\Program Files\NSIS\Source\util.cpp"
|
||||
]
|
||||
Creating command line "cl.exe @F:\Temp\WinTemp\RSP2ED.tmp"
|
||||
Creating temporary file "F:\Temp\WinTemp\RSP2EE.tmp" with contents
|
||||
[
|
||||
/nologo /ML /W3 /GX /O2 /Ob2 /D "_CONSOLE" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "WIN32_LEAN_AND_MEAN" /Fo"Release/" /Fd"Release/" /FD /c
|
||||
"C:\Program Files\NSIS\Source\bzip2\blocksort.c"
|
||||
"C:\Program Files\NSIS\Source\bzip2\bzlib.c"
|
||||
"C:\Program Files\NSIS\Source\bzip2\compress.c"
|
||||
"C:\Program Files\NSIS\Source\bzip2\huffman.c"
|
||||
"C:\Program Files\NSIS\Source\crc32.c"
|
||||
"C:\Program Files\NSIS\Source\DialogTemplate.cpp"
|
||||
"C:\Program Files\NSIS\Source\ResourceEditor.cpp"
|
||||
"C:\Program Files\NSIS\Source\tokens.cpp"
|
||||
]
|
||||
Creating command line "cl.exe @F:\Temp\WinTemp\RSP2EE.tmp"
|
||||
Creating temporary file "F:\Temp\WinTemp\RSP2EF.tmp" with contents
|
||||
[
|
||||
/nologo /ML /W3 /GX /Ot /Ow /Oy /Ob2 /D "_CONSOLE" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "WIN32_LEAN_AND_MEAN" /Fo"Release/" /Fd"Release/" /FD /c
|
||||
"C:\Program Files\NSIS\Source\script.cpp"
|
||||
]
|
||||
Creating command line "cl.exe @F:\Temp\WinTemp\RSP2EF.tmp"
|
||||
Creating temporary file "F:\Temp\WinTemp\RSP2F0.tmp" with contents
|
||||
[
|
||||
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib version.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../makensis.exe" /opt:nowin98
|
||||
".\Release\deflate.obj"
|
||||
".\Release\trees.obj"
|
||||
".\Release\blocksort.obj"
|
||||
".\Release\bzlib.obj"
|
||||
".\Release\compress.obj"
|
||||
".\Release\huffman.obj"
|
||||
".\Release\build.obj"
|
||||
".\Release\crc32.obj"
|
||||
".\Release\DialogTemplate.obj"
|
||||
".\Release\exedata.obj"
|
||||
".\Release\makenssi.obj"
|
||||
".\Release\ResourceEditor.obj"
|
||||
".\Release\script.obj"
|
||||
".\Release\tokens.obj"
|
||||
".\Release\util.obj"
|
||||
".\Release\Script1.res"
|
||||
]
|
||||
Creating command line "link.exe @F:\Temp\WinTemp\RSP2F0.tmp"
|
||||
<h3>Output Window</h3>
|
||||
Compiling resources...
|
||||
Compiling...
|
||||
deflate.c
|
||||
trees.c
|
||||
Generating Code...
|
||||
Compiling...
|
||||
build.cpp
|
||||
exedata.cpp
|
||||
makenssi.cpp
|
||||
util.cpp
|
||||
Generating Code...
|
||||
Compiling...
|
||||
blocksort.c
|
||||
bzlib.c
|
||||
compress.c
|
||||
huffman.c
|
||||
crc32.c
|
||||
Generating Code...
|
||||
Compiling...
|
||||
DialogTemplate.cpp
|
||||
ResourceEditor.cpp
|
||||
tokens.cpp
|
||||
Generating Code...
|
||||
Compiling...
|
||||
script.cpp
|
||||
Linking...
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
makensis.exe - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
17
Source/resource.h
Normal file
17
Source/resource.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by Script1.rc
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
#define IDD_DIALOG1 110
|
||||
|
||||
// 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 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
3302
Source/script.cpp
Normal file
3302
Source/script.cpp
Normal file
File diff suppressed because it is too large
Load diff
275
Source/strlist.h
Normal file
275
Source/strlist.h
Normal file
|
@ -0,0 +1,275 @@
|
|||
#ifndef _STRLIST_H_
|
||||
#define _STRLIST_H_
|
||||
|
||||
#include <stdlib.h> // for gcc
|
||||
|
||||
class IGrowBuf
|
||||
{
|
||||
public:
|
||||
virtual int add(const void *data, int len)=0;
|
||||
virtual void resize(int newlen)=0;
|
||||
virtual int getlen()=0;
|
||||
virtual void *get()=0;
|
||||
};
|
||||
|
||||
class GrowBuf : public IGrowBuf
|
||||
{
|
||||
public:
|
||||
GrowBuf() { m_alloc=m_used=0; m_s=NULL; }
|
||||
~GrowBuf() { free(m_s); }
|
||||
|
||||
int 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 resize(int newlen)
|
||||
{
|
||||
int os=m_alloc;
|
||||
m_used=newlen;
|
||||
if (newlen > m_alloc)
|
||||
{
|
||||
void *n;
|
||||
m_alloc = newlen*2 + 32768;
|
||||
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_used && m_alloc > 65535) // only free if you resize to 0 and we're > 64k
|
||||
{
|
||||
m_alloc=0;
|
||||
free(m_s);
|
||||
m_s=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int getlen() { return m_used; }
|
||||
void *get() { return m_s; }
|
||||
|
||||
private:
|
||||
void *m_s;
|
||||
int m_alloc;
|
||||
int m_used;
|
||||
|
||||
};
|
||||
|
||||
class StringList
|
||||
{
|
||||
public:
|
||||
StringList() { }
|
||||
~StringList() { }
|
||||
|
||||
int 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 find(const char *str, int case_sensitive, int *idx=NULL) // returns -1 if not found
|
||||
{
|
||||
char *s=(char*)gr.get();
|
||||
int ml=gr.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 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 idx2pos(int idx)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
char *get() { return (char*)gr.get(); }
|
||||
int getlen() { return gr.getlen(); }
|
||||
private:
|
||||
GrowBuf gr;
|
||||
};
|
||||
|
||||
|
||||
class DefineList
|
||||
{
|
||||
public:
|
||||
DefineList() { }
|
||||
~DefineList() { }
|
||||
|
||||
int add(const char *str, const char *value="")
|
||||
{
|
||||
if (defines.find(str,0)>=0) return 1;
|
||||
|
||||
defines.add(str,0);
|
||||
values.add(value,-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int del(const char *str)
|
||||
{
|
||||
int id;
|
||||
int v=defines.find(str,0,&id);
|
||||
if (v<0) return 1;
|
||||
id=values.idx2pos(id);
|
||||
if (id<0)return 1;
|
||||
defines.delbypos(v);
|
||||
values.delbypos(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *find(const char *str) // returns NULL if not found
|
||||
{
|
||||
int id;
|
||||
int v=defines.find(str,0,&id);
|
||||
if (v<0) return NULL;
|
||||
v=values.idx2pos(id);
|
||||
if (v<0) return NULL;
|
||||
return (char*)values.get()+v;
|
||||
}
|
||||
|
||||
StringList defines, values;
|
||||
};
|
||||
|
||||
|
||||
class MMapBuf : public IGrowBuf
|
||||
{
|
||||
public:
|
||||
MMapBuf()
|
||||
{
|
||||
m_hFile = INVALID_HANDLE_VALUE;
|
||||
m_hFileMap = 0;
|
||||
m_mapping=NULL;
|
||||
m_gb_u=0;
|
||||
m_alloc=m_used=0;
|
||||
}
|
||||
~MMapBuf()
|
||||
{
|
||||
if (m_mapping) UnmapViewOfFile(m_mapping);
|
||||
if (m_hFileMap) CloseHandle(m_hFileMap);
|
||||
if (m_hFile != INVALID_HANDLE_VALUE) CloseHandle(m_hFile);
|
||||
}
|
||||
|
||||
int add(const void *data, int len)
|
||||
{
|
||||
if (len<=0) return 0;
|
||||
resize(getlen()+len);
|
||||
memcpy((char*)get()+getlen()-len,data,len);
|
||||
return getlen()-len;
|
||||
}
|
||||
|
||||
void resize(int newlen)
|
||||
{
|
||||
if (!m_gb_u && newlen < (16<<20)) // still in db mode
|
||||
{
|
||||
m_gb.resize(newlen);
|
||||
return;
|
||||
}
|
||||
m_gb_u=1;
|
||||
m_used=newlen;
|
||||
if (newlen > m_alloc)
|
||||
{
|
||||
if (m_mapping) UnmapViewOfFile(m_mapping);
|
||||
if (m_hFileMap) CloseHandle(m_hFileMap);
|
||||
m_hFileMap=0;
|
||||
m_mapping=NULL;
|
||||
m_alloc = newlen + (16<<20); // add 16mb to top of mapping
|
||||
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,NULL);
|
||||
}
|
||||
if (m_hFile != INVALID_HANDLE_VALUE)
|
||||
m_hFileMap=CreateFileMapping(m_hFile,NULL,PAGE_READWRITE,0,m_alloc,NULL);
|
||||
if (m_hFileMap)
|
||||
m_mapping=MapViewOfFile(m_hFileMap,FILE_MAP_WRITE,0,0,m_alloc);
|
||||
if (!m_mapping)
|
||||
{
|
||||
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",m_alloc);
|
||||
fflush(g_output);
|
||||
}
|
||||
quit();
|
||||
}
|
||||
if (m_gb.getlen())
|
||||
{
|
||||
memcpy(m_mapping,m_gb.get(),m_gb.getlen());
|
||||
m_gb.resize(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int getlen() { if (m_gb_u) return m_used; return m_gb.getlen(); }
|
||||
void *get() { if (m_gb_u) return m_mapping; return m_gb.get(); }
|
||||
|
||||
private:
|
||||
GrowBuf m_gb;
|
||||
int m_gb_u;
|
||||
|
||||
HANDLE m_hFile, m_hFileMap;
|
||||
void *m_mapping;
|
||||
int m_alloc, m_used;
|
||||
};
|
||||
|
||||
|
||||
#endif//_STRLIST_H_
|
226
Source/tokens.cpp
Normal file
226
Source/tokens.cpp
Normal file
|
@ -0,0 +1,226 @@
|
|||
#include <windows.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;
|
||||
} tokenType;
|
||||
|
||||
|
||||
static tokenType tokenlist[TOK__LAST] =
|
||||
{
|
||||
{TOK_ABORT,"Abort",0,1,"[message]"},
|
||||
{TOK_ADDBRANDINGIMAGE,"AddBrandingImage",2,0,"(top|left) (height|width)"},
|
||||
{TOK_ADDSIZE,"AddSize",1,0,"size_to_add_to_section_in_kb"},
|
||||
{TOK_AUTOCLOSE,"AutoCloseWindow",1,0,"(false|true)"},
|
||||
{TOK_BGGRADIENT,"BGGradient",0,3,"(off | [top_color [bottom_color [text_color]]])"},
|
||||
{TOK_BRANDINGTEXT,"BrandingText",1,0,"installer_text"},
|
||||
{TOK_BRINGTOFRONT,"BringToFront",0,0,""},
|
||||
{TOK_CALL,"Call",1,0,"function_name | [:label_name]"},
|
||||
{TOK_CALLINSTDLL,"CallInstDLL",2,0,"dll_path_on_target.dll function"},
|
||||
{TOK_CAPTION,"Caption",1,0,"installer_caption"},
|
||||
{TOK_CHANGEUI,"ChangeUI",1,0,"ui_file.exe"},
|
||||
{TOK_CLEARERRORS,"ClearErrors",0,0,""},
|
||||
{TOK_COMPTEXT,"ComponentText",0,3,"[component_page_description] [component_subtext1] [component_subtext2]"},
|
||||
{TOK_GETDLLVERSION,"GetDLLVersion",3,0,"filename $(user_var: high output) $(user_var: low output)"},
|
||||
{TOK_GETDLLVERSIONLOCAL,"GetDLLVersionLocal",3,0,"localfilename $(user_var: high output) $(user_var: low output)"},
|
||||
{TOK_GETFILETIME,"GetFileTime",3,0,"file $(user_var: high output) $(user_var: low output)"},
|
||||
{TOK_GETFILETIMELOCAL,"GetFileTimeLocal",3,0,"localfile $(user_var: high output) $(user_var: low output)"},
|
||||
{TOK_COPYFILES,"CopyFiles",2,3,"[/SILENT] [/FILESONLY] source_path destination_path [total_size_in_kb]"},
|
||||
{TOK_CRCCHECK,"CRCCheck",1,0,"(on|force|off)"},
|
||||
{TOK_CREATEDIR,"CreateDirectory",1,0,"directory_name"},
|
||||
{TOK_CREATESHORTCUT,"CreateShortCut",2,5,"shortcut_name.lnk shortcut_target [parameters [icon_file [icon index [showmode [hotkey]]]]]\n showmode=(SW_SHOWNORMAL|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED)\n hotkey=(ALT|CONTROL|EXT|SHIFT)|(F1-F24|A-Z)"},
|
||||
{TOK_DBOPTIMIZE,"SetDatablockOptimize",1,0,"(off|on)"},
|
||||
{TOK_DELETEINISEC,"DeleteINISec",2,0,"ini_file section_name"},
|
||||
{TOK_DELETEINISTR,"DeleteINIStr",3,0,"ini_file section_name entry_name"},
|
||||
{TOK_DELETEREGKEY,"DeleteRegKey",2,1,"[/ifempty] root_key subkey\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"},
|
||||
{TOK_DELETEREGVALUE,"DeleteRegValue",3,0,"root_key subkey entry_name\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"},
|
||||
{TOK_DELETE,"Delete",1,1,"[/REBOOTOK] filespec"},
|
||||
{TOK_DETAILPRINT,"DetailPrint",1,0,"message"},
|
||||
{TOK_DIRTEXT,"DirText",0,3,"[directory_page_description] [directory_page_subtext] [browse button text]"},
|
||||
{TOK_DIRSHOW,"DirShow",1,0,"(show|hide)"},
|
||||
{TOK_ROOTDIRINST,"AllowRootDirInstall",1,0,"(true|false)"},
|
||||
{TOK_CHECKBITMAP,"CheckBitmap",1,0,"local_bitmap.bmp"},
|
||||
{TOK_ENUMREGKEY,"EnumRegKey",4,0,"$(user_var: output) rootkey subkey index\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"},
|
||||
{TOK_ENUMREGVAL,"EnumRegValue",4,0,"$(user_var: output) rootkey subkey index\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"},
|
||||
{TOK_EXCH,"Exch",0,1,"[$(user_var)] | [stack_item_index]"},
|
||||
{TOK_EXEC,"Exec",1,0,"command_line"},
|
||||
{TOK_EXECWAIT,"ExecWait",1,1,"command_line [$(user_var: return value)]"},
|
||||
{TOK_EXECSHELL,"ExecShell",2,2,"(open|print|etc) command_line [parameters [showmode]]\n showmode=(SW_SHOWNORMAL|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED)"},
|
||||
{TOK_EXPANDENVSTRS,"ExpandEnvStrings",2,0,"$(user_var: output) string"},
|
||||
{TOK_FINDWINDOW,"FindWindow",2,3,"$(user_var: handle output) WindowClass [WindowTitle] [Window_Parent] [Child_After]"},
|
||||
{TOK_FINDCLOSE,"FindClose",1,0,"$(user_var: handle input)"},
|
||||
{TOK_FINDFIRST,"FindFirst",3,0,"$(user_var: handle output) $(user_var: filename output) filespec"},
|
||||
{TOK_FINDNEXT,"FindNext",2,0,"$(user_var: handle input) $(user_var: filename output)"},
|
||||
{TOK_FILE,"File",1,-1,"([/a] [/r] filespec [...]|/oname=outfile one_file_only)"},
|
||||
{TOK_FILECLOSE,"FileClose",1,0,"$(user_var: handle input)"},
|
||||
{TOK_FILEERRORTEXT,"FileErrorText",0,1,"[text (can contain $0)]"},
|
||||
{TOK_FILEOPEN,"FileOpen",3,0,"$(user_var: handle output) filename openmode\n openmode=r|w|a"},
|
||||
{TOK_FILEREAD,"FileRead",2,1,"$(user_var: handle input) $(user_var: text output) [maxlen]"},
|
||||
{TOK_FILEWRITE,"FileWrite",2,0,"$(user_var: handle input) text"},
|
||||
{TOK_FILEREADBYTE,"FileReadByte",2,0,"$(user_var: handle input) $(user_var: bytevalue output)"},
|
||||
{TOK_FILEWRITEBYTE,"FileWriteByte",2,0,"$(user_var: handle input) bytevalue"},
|
||||
{TOK_FILESEEK,"FileSeek",2,2,"$(user_var: handle input) offset [mode] [$(user_var: new position output)]\n mode=SET|CUR|END"},
|
||||
{TOK_FUNCTION,"Function",1,0,"function_name"},
|
||||
{TOK_FUNCTIONEND,"FunctionEnd",0,0,""},
|
||||
{TOK_SEARCHPATH,"SearchPath",2,0,"$(user_var: result) filename"},
|
||||
{TOK_GETFULLPATHNAME,"GetFullPathName",2,1,"[/SHORT] $(user_var: result) path_or_file"},
|
||||
{TOK_GETTEMPFILENAME,"GetTempFileName",1,0,"$(user_var: name output)"},
|
||||
{TOK_HIDEWINDOW,"HideWindow",0,0,""},
|
||||
{TOK_ICON,"Icon",1,0,"local_icon.ico"},
|
||||
{TOK_IFERRORS,"IfErrors",1,1,"label_to_goto_if_errors [label_to_goto_if_no_errors]"},
|
||||
{TOK_IFFILEEXISTS,"IfFileExists",2,1,"filename label_to_goto_if_file_exists [label_to_goto_otherwise]"},
|
||||
{TOK_IFREBOOTFLAG,"IfRebootFlag",1,1,"jump_if_set [jump_if_not_set]"},
|
||||
{TOK_INSTALLDIRREGKEY,"InstallDirRegKey",3,0,"root_key subkey entry_name\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"},
|
||||
{TOK_INSTCOLORS,"InstallColors",1,1,"(/windows | (foreground_color background_color))"},
|
||||
{TOK_INSTDIR,"InstallDir",1,0,"default_install_directory"},
|
||||
{TOK_INSTPROGRESSFLAGS,"InstProgressFlags",0,-1,"[flag [...]]\n flag={smooth|colored}"},
|
||||
{TOK_INSTTYPE,"InstType",1,0,"(/NOCUSTOM|/CUSTOMSTRING=CustomStr|TypeName)"},
|
||||
{TOK_INTOP,"IntOp",3,1,"$(user_var: result) val1 OP [val2]\n OP=(+ - * / % | & ^ ~ ! || &&)"},
|
||||
{TOK_INTCMP,"IntCmp",3,2,"val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"},
|
||||
{TOK_INTCMPU,"IntCmpU",3,2,"val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"},
|
||||
{TOK_INTFMT,"IntFmt",3,0,"$(user_var: output) format_string input"},
|
||||
{TOK_ISWINDOW,"IsWindow",2,1,"hwnd jump_if_window [jump_if_not_window]"},
|
||||
{TOK_GOTO,"Goto",1,0,"label"},
|
||||
{TOK_LICENSEDATA,"LicenseData",1,0,"local_file_that_has_license_text.txt"},
|
||||
{TOK_LICENSETEXT,"LicenseText",1,1,"license_page_description [license_button_text]"},
|
||||
{TOK_LICENSEBKCOLOR,"LicenseBkColor",1,0,"background_color"},
|
||||
{TOK_LOGSET,"LogSet",1,0,"on|off"},
|
||||
{TOK_LOGTEXT,"LogText",1,0,"text"},
|
||||
{TOK_MESSAGEBOX,"MessageBox",2,4,"mode messagebox_text [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_TOPMOST|MB_SETFOREGROUND|MB_RIGHT"},
|
||||
{TOK_NOP,"Nop",0,0,""},
|
||||
{TOK_NAME,"Name",1,0,"installer_name"},
|
||||
{TOK_OUTFILE,"OutFile",1,0,"install_output.exe"},
|
||||
{TOK_POP,"Pop",1,0,"$(user_var: output)"},
|
||||
{TOK_PUSH,"Push",1,0,"string"},
|
||||
{TOK_QUIT,"Quit",0,0,""},
|
||||
{TOK_READINISTR,"ReadINIStr",4,0,"$(user_var: output) ini_file section entry_name"},
|
||||
{TOK_READREGDWORD,"ReadRegDWORD",4,0,"$(user_var: output) rootkey subkey entry\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"},
|
||||
{TOK_READREGSTR,"ReadRegStr",4,0,"$(user_var: output) rootkey subkey entry\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"},
|
||||
{TOK_READENVSTR,"ReadEnvStr",2,0,"$(user_var: output) name"},
|
||||
{TOK_REBOOT,"Reboot",0,0,""},
|
||||
{TOK_REGDLL,"RegDLL",1,1,"dll_path_on_target.dll [entrypoint_symbol]"},
|
||||
{TOK_RENAME,"Rename",2,1,"[/REBOOTOK] source_file destination_file"},
|
||||
{TOK_RET,"Return",0,0,""},
|
||||
{TOK_RMDIR,"RMDir",1,1,"[/r] directory_name"},
|
||||
{TOK_SECTION,"Section",0,3,"[/e] [section_name|-section_name] [section index output]"},
|
||||
{TOK_SUBSECTION,"SubSection",1,1,"[/e] subsection_name"},
|
||||
{TOK_SUBSECTIONEND,"SubSectionEnd",0,0,""},
|
||||
{TOK_SECTIONSETFLAGS,"SectionSetFlags",2,0,"section_index flags"},
|
||||
{TOK_SECTIONGETFLAGS,"SectionGetFlags",2,0,"section_index $(user_var: output flags)"},
|
||||
{TOK_SECTIONGETTEXT,"SectionGetText",2,0,"section_index $(user_var: output text)"},
|
||||
{TOK_SECTIONSETTEXT,"SectionSetText",2,0,"section_index text_string"},
|
||||
{TOK_SECTIONEND,"SectionEnd",0,0,""},
|
||||
{TOK_SECTIONIN,"SectionIn",1,-1,"InstTypeIdx [InstTypeIdx [...]]"},
|
||||
{TOK_SENDMESSAGE,"SendMessage",4,1,"hwnd message wparam lparam [$(user_var: return value)]"},
|
||||
{TOK_SETAUTOCLOSE,"SetAutoClose",1,0,"(false|true)"},
|
||||
{TOK_SETBRANDINGIMAGE,"SetBrandingImage",1,2,"[/IMGID=image_item_id_in_dialog] [/RESIZETOFIT] bitmap.bmp"},
|
||||
{TOK_SETCOMPRESS,"SetCompress",1,0,"(off|auto|force)"},
|
||||
{TOK_SETCOMPRESSOR,"SetCompressor",1,0,"(zlib|bzip2)"},
|
||||
{TOK_SETDATESAVE,"SetDateSave",1,0,"(off|on)"},
|
||||
{TOK_SETDETAILSVIEW,"SetDetailsView",1,0,"(hide|show)"},
|
||||
{TOK_SETDETAILSPRINT,"SetDetailsPrint",1,0,"(none|listonly|textonly|both)"},
|
||||
{TOK_SETFILEATTRIBUTES,"SetFileAttributes",2,0,"file attribute[|attribute[...]]\n attribute=(NORMAL|ARCHIVE|HIDDEN|OFFLINE|READONLY|SYSTEM|TEMPORARY|0)"},
|
||||
{TOK_SETFONT,"SetFont",2,0,"font_face_name font_size"},
|
||||
{TOK_SETERRORS,"SetErrors",0,0,""},
|
||||
{TOK_SETDLGITEMTEXT,"SetDlgItemText",2,0,"item text"},
|
||||
{TOK_SETOUTPATH,"SetOutPath",1,0,"output_path"},
|
||||
{TOK_SETOVERWRITE,"SetOverwrite",1,0,"(on|off|try|ifnewer)"},
|
||||
{TOK_SETREBOOTFLAG,"SetRebootFlag",1,0,"true|false"},
|
||||
{TOK_SETSHELLVARCONTEXT,"SetShellVarContext",1,0,"all|current"},
|
||||
{TOK_SHOWDETAILS,"ShowInstDetails",1,0,"(hide|show|nevershow)"},
|
||||
{TOK_SHOWDETAILSUNINST,"ShowUninstDetails",1,0,"(hide|show|nevershow)"},
|
||||
{TOK_SILENTINST,"SilentInstall",1,0,"(normal|silent|silentlog)"},
|
||||
{TOK_SILENTUNINST,"SilentUnInstall",1,0,"(normal|silent)"},
|
||||
{TOK_SLEEP,"Sleep",1,0,"sleep_time_in_ms"},
|
||||
{TOK_STRCMP,"StrCmp",3,1,"str1 str2 label_to_goto_if_equal [label_to_goto_if_not]"},
|
||||
{TOK_STRCPY,"StrCpy",2,2,"$(user_var: output) str [maxlen] [startoffset]"},
|
||||
{TOK_STRLEN,"StrLen",2,0,"$(user_var: length output) str"},
|
||||
{TOK_SUBCAPTION,"SubCaption",2,0,"page_number(0-4) new_subcaption"},
|
||||
{TOK_UNINSTALLEXENAME,"UninstallExeName",0,0,"no longer supported, use WriteUninstaller from section."},
|
||||
{TOK_UNINSTICON,"UninstallIcon",1,0,"icon_on_local_system.ico"},
|
||||
{TOK_UNINSTTEXT,"UninstallText",1,1,"Text_to_go_on_uninstall page [subtext]"},
|
||||
{TOK_UNINSTCAPTION,"UninstallCaption",1,0,"uninstaller_caption"},
|
||||
{TOK_UNINSTSUBCAPTION,"UninstallSubCaption",2,0,"page_number(0-2) new_subcaption"},
|
||||
{TOK_UNREGDLL,"UnRegDLL",1,0,"dll_path_on_target.dll"},
|
||||
{TOK_WINDOWICON,"WindowIcon",1,0,"on|off"},
|
||||
{TOK_WRITEINISTR,"WriteINIStr",4,0,"ini_file section_name entry_name new_value"},
|
||||
{TOK_WRITEREGBIN,"WriteRegBin",4,0,"rootkey subkey entry_name hex_string_like_12848412AB\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"},
|
||||
{TOK_WRITEREGDWORD,"WriteRegDWORD",4,0,"rootkey subkey entry_name new_value_dword\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"},
|
||||
{TOK_WRITEREGSTR,"WriteRegStr",4,0,"rootkey subkey entry_name new_value_string\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"},
|
||||
{TOK_WRITEREGEXPANDSTR,"WriteRegExpandStr",4,0,"rootkey subkey entry_name new_value_string\n root_key=(HKCR|HKLM|HKCU|HKU|HKCC|HKDD|HKPD)"},
|
||||
{TOK_WRITEUNINSTALLER,"WriteUninstaller",1,0,"uninstall_exe_name"},
|
||||
{TOK_XPSTYLE, "XPStyle",1,0,"(on|off)"},
|
||||
{TOK_P_PACKEXEHEADER,"!packhdr",2,0,"temp_file_name command_line_to_compress_that_temp_file"},
|
||||
{TOK_P_SYSTEMEXEC,"!system",1,2,"command (<|>|<>|=|ignore) retval"},
|
||||
{TOK_P_INCLUDE,"!include",1,0,"filename.nsi"},
|
||||
{TOK_P_CD,"!cd",1,0,"absolute_or_relative_new_directory"},
|
||||
{TOK_P_IFDEF,"!ifdef",1,-1,"symbol [| symbol2 [& symbol3 [...]]]"},
|
||||
{TOK_P_IFNDEF,"!ifndef",1,-1,"symbol [| symbol2 [& symbol3 [...]]]"},
|
||||
{TOK_P_ENDIF,"!endif",0,0,""},
|
||||
{TOK_P_DEFINE,"!define",1,1,"symbol [value]"},
|
||||
{TOK_P_UNDEF,"!undef",1,1,"symbol [value]"},
|
||||
{TOK_P_ELSE,"!else",0,-1,"[ifdef|ifndef symbol [|symbol2 [& symbol3 [...]]]]"},
|
||||
{TOK_P_ECHO,"!echo",1,0,"message"},
|
||||
{TOK_P_WARNING,"!warning",0,1,"[warning_message]"},
|
||||
{TOK_P_ERROR,"!error",0,1,"[error_message]"},
|
||||
|
||||
{TOK_P_VERBOSE,"!verbose",1,0,"verbose_level"},
|
||||
|
||||
{TOK_P_MACRO,"!macro",1,-1,"macroname [parms ...]"},
|
||||
{TOK_P_MACROEND,"!macroend",0,0,""},
|
||||
{TOK_P_INSERTMACRO,"!insertmacro",1,-1,"macroname [parms ...]"},
|
||||
|
||||
|
||||
{TOK_MISCBUTTONTEXT,"MiscButtonText",0,4,"[back button text] [next button text] [cancel button text] [close button text]"},
|
||||
{TOK_DETAILSBUTTONTEXT,"DetailsButtonText",0,1,"[details button text]"},
|
||||
{TOK_UNINSTBUTTONTEXT,"UninstallButtonText",0,1,"[uninstall button text]"},
|
||||
{TOK_INSTBUTTONTEXT,"InstallButtonText",0,1,"[install button text]"},
|
||||
{TOK_SPACETEXTS,"SpaceTexts",0,2,"[space required text] [space available text]"},
|
||||
{TOK_COMPLETEDTEXT,"CompletedText",0,1,"[completed text]"},
|
||||
|
||||
{TOK_GETFUNCTIONADDR,"GetFunctionAddress",2,0,"output function"},
|
||||
{TOK_GETLABELADDR,"GetLabelAddress",2,0,"output label"},
|
||||
{TOK_GETCURRENTADDR,"GetCurrentAddress",1,0,"output"},
|
||||
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int CEXEBuild::get_commandtoken(char *s, int *np, int *op)
|
||||
{
|
||||
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;
|
||||
return tokenlist[x].id;
|
||||
}
|
||||
return -1;
|
||||
}
|
192
Source/tokens.h
Normal file
192
Source/tokens.h
Normal file
|
@ -0,0 +1,192 @@
|
|||
#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_LICENSETEXT,
|
||||
TOK_LICENSEDATA,
|
||||
TOK_LICENSEBKCOLOR,
|
||||
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_BGGRADIENT,
|
||||
TOK_INSTCOLORS,
|
||||
TOK_SUBCAPTION,
|
||||
TOK_UNINSTSUBCAPTION,
|
||||
TOK_BRANDINGTEXT,
|
||||
TOK_FILEERRORTEXT,
|
||||
TOK_INSTPROGRESSFLAGS,
|
||||
TOK_XPSTYLE,
|
||||
TOK_CHANGEUI,
|
||||
TOK_ADDBRANDINGIMAGE,
|
||||
TOK_SETFONT,
|
||||
TOK_SETCOMPRESSOR,
|
||||
|
||||
TOK_MISCBUTTONTEXT,
|
||||
TOK_DETAILSBUTTONTEXT,
|
||||
TOK_UNINSTBUTTONTEXT,
|
||||
TOK_INSTBUTTONTEXT,
|
||||
TOK_SPACETEXTS,
|
||||
TOK_COMPLETEDTEXT,
|
||||
|
||||
// system "preprocessor"ish tokens
|
||||
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_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,
|
||||
|
||||
// section/function shit
|
||||
TOK_SECTION,
|
||||
TOK_SECTIONEND,
|
||||
TOK_SECTIONIN,
|
||||
TOK_SUBSECTION,
|
||||
TOK_SUBSECTIONEND,
|
||||
TOK_FUNCTION,
|
||||
TOK_FUNCTIONEND,
|
||||
TOK_ADDSIZE,
|
||||
|
||||
// flag setters
|
||||
TOK_SETDATESAVE,
|
||||
TOK_SETOVERWRITE,
|
||||
TOK_SETCOMPRESS,
|
||||
TOK_DBOPTIMIZE,
|
||||
|
||||
// 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_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_STRCPY,
|
||||
TOK_STRCMP,
|
||||
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_SETDLGITEMTEXT,
|
||||
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_SETSHELLVARCONTEXT,
|
||||
|
||||
|
||||
TOK__LAST
|
||||
};
|
||||
|
||||
#endif//_TOKENS_H_
|
292
Source/util.cpp
Normal file
292
Source/util.cpp
Normal file
|
@ -0,0 +1,292 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <conio.h>
|
||||
#include "exedata.h"
|
||||
#include "exehead/fileform.h"
|
||||
#include "util.h"
|
||||
#include "strlist.h"
|
||||
|
||||
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=_getch()) != '\r' && a != 27/*esc*/);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns 0 if everything is OK
|
||||
// Returns -1 the bitmap file is invalid or has the wrong size
|
||||
int update_bitmap(CResourceEditor* re, WORD id, char* filename, int width/*=0*/, int height/*=0*/) {
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if (!f) return -1;
|
||||
|
||||
if (fgetc(f) != 'B' || fgetc(f) != 'M') {
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (width != 0) {
|
||||
LONG biWidth;
|
||||
fseek(f, 18, SEEK_SET); // Seek to the width member of the header
|
||||
fread(&biWidth, sizeof(LONG), 1, f);
|
||||
if (width != biWidth) {
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (height != 0) {
|
||||
LONG biHeight;
|
||||
fseek(f, 22, SEEK_SET); // Seek to the height member of the header
|
||||
fread(&biHeight, sizeof(LONG), 1, f);
|
||||
if (height != abs(biHeight)) {
|
||||
fclose(f);
|
||||
return -1; // Bitmap height can be negative too...
|
||||
}
|
||||
}
|
||||
|
||||
DWORD dwSize;
|
||||
fseek(f, 2, SEEK_SET);
|
||||
fread(&dwSize, sizeof(DWORD), 1, f);
|
||||
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 -1;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
re->UpdateResource(RT_BITMAP, MAKEINTRESOURCE(id), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), bitmap, dwSize);
|
||||
|
||||
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
|
||||
|
||||
// Added by Amir Szekely 8th July 2002
|
||||
// replace_icon, must get an initialized resource editor
|
||||
// return values:
|
||||
// 0 - All OK
|
||||
// -1 - Bad icon file
|
||||
int replace_icon(CResourceEditor* re, WORD wIconId, char* filename)
|
||||
{
|
||||
FILE* f = fopen(filename, "rb");
|
||||
if (!f) return -1;
|
||||
|
||||
IconGroupHeader igh;
|
||||
fread(&igh, sizeof(IconGroupHeader), 1, f);
|
||||
|
||||
if (igh.wIsIcon != 1 && igh.wReserved != 0) return -1;
|
||||
|
||||
BYTE* rsrcIconGroup = (BYTE*)malloc(sizeof(IconGroupHeader) + igh.wCount*SIZEOF_RSRC_ICON_GROUP_ENTRY);
|
||||
if (!rsrcIconGroup) throw bad_alloc();
|
||||
|
||||
CopyMemory(rsrcIconGroup, &igh, sizeof(IconGroupHeader));
|
||||
|
||||
RsrcIconGroupEntry* ige = (RsrcIconGroupEntry*)(rsrcIconGroup + sizeof(IconGroupHeader));
|
||||
|
||||
int iNewIconSize = 0;
|
||||
|
||||
for (int i = 0; i < igh.wCount; i++) {
|
||||
fread(ige, sizeof(FileIconGroupEntry)-sizeof(DWORD), 1, f);
|
||||
ige->wRsrcId = i+1;
|
||||
|
||||
DWORD dwOffset;
|
||||
fread(&dwOffset, sizeof(DWORD), 1, f);
|
||||
|
||||
fpos_t pos;
|
||||
fgetpos(f, &pos);
|
||||
|
||||
if (fseek(f, dwOffset, SEEK_SET)) return -1;
|
||||
BYTE* iconData = (BYTE*)malloc(ige->dwRawSize);
|
||||
if (!iconData) throw bad_alloc();
|
||||
fread(iconData, sizeof(BYTE), ige->dwRawSize, f);
|
||||
re->UpdateResource(RT_ICON, MAKEINTRESOURCE(i+1), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), iconData, ige->dwRawSize);
|
||||
free(iconData);
|
||||
|
||||
fsetpos(f, &pos);
|
||||
|
||||
// Every icon entry should be 8 aligned
|
||||
iNewIconSize += ((ige->dwRawSize%8 == 0) ? ige->dwRawSize : ige->dwRawSize - (ige->dwRawSize%8) + 8);
|
||||
|
||||
// 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->UpdateResource(RT_GROUP_ICON, MAKEINTRESOURCE(wIconId), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), rsrcIconGroup, sizeof(IconGroupHeader) + igh.wCount*SIZEOF_RSRC_ICON_GROUP_ENTRY);
|
||||
|
||||
icondata_size = iNewIconSize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Added by Amir Szekely 8th July 2002
|
||||
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
|
||||
// returns the data of the uninstaller icon that should replace the installer icon data
|
||||
// return values:
|
||||
// 0 - Bad icon file
|
||||
// Anything else - Pointer to the uninstaller icon data
|
||||
unsigned char* generate_uninstall_icon_data(char* filename)
|
||||
{
|
||||
int i;
|
||||
|
||||
FILE* f = fopen(filename, "rb");
|
||||
if (!f) return 0;
|
||||
|
||||
IconGroupHeader igh;
|
||||
if (!fread(&igh, sizeof(IconGroupHeader), 1, f)) return 0;
|
||||
|
||||
if (igh.wIsIcon != 1 && igh.wReserved != 0) return 0;
|
||||
|
||||
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)) return 0;
|
||||
offsets[i] = ige.dwImageOffset;
|
||||
rawSizes[i] = ige.dwRawSize;
|
||||
iNewIconSize += ige.dwRawSize;
|
||||
}
|
||||
|
||||
// First DWORD tells how many icons this array contains
|
||||
// Before each icon come two DWORDs, one for size and the other for offset (set later)
|
||||
iNewIconSize += sizeof(DWORD)*(1 + igh.wCount*2);
|
||||
|
||||
BYTE* pbUninstIcon = (BYTE*)malloc(iNewIconSize);
|
||||
if (!pbUninstIcon) throw bad_alloc();
|
||||
|
||||
BYTE* seeker = pbUninstIcon;
|
||||
|
||||
*(DWORD*)seeker = igh.wCount;
|
||||
seeker += sizeof(DWORD);
|
||||
|
||||
for (i = 0; i < igh.wCount; i++) {
|
||||
*(DWORD*)seeker = rawSizes[i];
|
||||
seeker += sizeof(DWORD);
|
||||
*(DWORD*)seeker = 0;
|
||||
seeker += sizeof(DWORD);
|
||||
fseek(f, offsets[i], SEEK_SET);
|
||||
fread(seeker, 1, rawSizes[i], f);
|
||||
seeker += rawSizes[i];
|
||||
}
|
||||
|
||||
free(offsets);
|
||||
free(rawSizes);
|
||||
|
||||
unicondata_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,"\ngenerate_unicons_offsets: %s -- failing!\n", y);return 0;}
|
||||
|
||||
int find_in_dir(PRESOURCE_DIRECTORY rd, WORD id) {
|
||||
for (int i = rd->Header.NumberOfNamedEntries; i < rd->Header.NumberOfNamedEntries + rd->Header.NumberOfIdEntries; i++) {
|
||||
if (rd->Entries[i].Id == id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Fill the array of icons for uninstall with their offsets
|
||||
// Returns 0 if failed, anything else is icon_offset.
|
||||
int generate_unicons_offsets(unsigned char* exeHeader, unsigned char* uninstIconData) {
|
||||
int i;
|
||||
|
||||
MY_ASSERT(PIMAGE_DOS_HEADER(exeHeader)->e_magic != IMAGE_DOS_SIGNATURE, "invalid dos header");
|
||||
|
||||
PIMAGE_NT_HEADERS ntHeaders = PIMAGE_NT_HEADERS(exeHeader + PIMAGE_DOS_HEADER(exeHeader)->e_lfanew);
|
||||
|
||||
MY_ASSERT(ntHeaders->Signature != IMAGE_NT_SIGNATURE, "invalid nt headers");
|
||||
|
||||
DWORD dwResourceSectionVA = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
|
||||
PIMAGE_SECTION_HEADER sectionHeadersArray = IMAGE_FIRST_SECTION(ntHeaders);
|
||||
|
||||
for (i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++)
|
||||
if (dwResourceSectionVA == sectionHeadersArray[i].VirtualAddress)
|
||||
break;
|
||||
|
||||
MY_ASSERT(i == ntHeaders->FileHeader.NumberOfSections, "can't find resource section");
|
||||
|
||||
PRESOURCE_DIRECTORY rdRoot = PRESOURCE_DIRECTORY(exeHeader + sectionHeadersArray[i].PointerToRawData);
|
||||
|
||||
int idx = find_in_dir(rdRoot, WORD(RT_ICON));
|
||||
MY_ASSERT(idx == -1, "no icons?!");
|
||||
MY_ASSERT(!rdRoot->Entries[idx].DataIsDirectory, "bad resource directory");
|
||||
|
||||
PRESOURCE_DIRECTORY rdIcons = PRESOURCE_DIRECTORY(rdRoot->Entries[idx].OffsetToDirectory + DWORD(rdRoot));
|
||||
|
||||
unsigned char* seeker = uninstIconData;
|
||||
MY_ASSERT(*(DWORD*)seeker != rdIcons->Header.NumberOfIdEntries, "number of icons doesn't match");
|
||||
seeker += sizeof(DWORD);
|
||||
|
||||
for (i = 0; i < rdIcons->Header.NumberOfIdEntries; i++) { // Icons dir can't have named entries
|
||||
MY_ASSERT(!rdIcons->Entries[i].DataIsDirectory, "bad resource directory");
|
||||
PRESOURCE_DIRECTORY rd = PRESOURCE_DIRECTORY(rdIcons->Entries[i].OffsetToDirectory + DWORD(rdRoot));
|
||||
MY_ASSERT(rd->Entries[0].DataIsDirectory, "bad resource directory");
|
||||
PIMAGE_RESOURCE_DATA_ENTRY rde = PIMAGE_RESOURCE_DATA_ENTRY(rd->Entries[0].OffsetToData + DWORD(rdRoot));
|
||||
|
||||
DWORD dwSize = *(DWORD*)seeker;
|
||||
seeker += sizeof(DWORD);
|
||||
MY_ASSERT(dwSize != rde->Size, "installer, uninstaller icon size mismatch");
|
||||
// Set offset
|
||||
*(DWORD*)seeker = rde->OffsetToData + DWORD(rdRoot) - dwResourceSectionVA - DWORD(exeHeader);
|
||||
seeker += sizeof(DWORD) + dwSize;
|
||||
}
|
||||
MY_ASSERT(i == 0, "no icons found");
|
||||
|
||||
return PIMAGE_RESOURCE_DATA_ENTRY(PRESOURCE_DIRECTORY(rdIcons->Entries[0].OffsetToDirectory + DWORD(rdRoot))->Entries[0].OffsetToData + DWORD(rdRoot))->OffsetToData + DWORD(rdRoot) - dwResourceSectionVA - DWORD(exeHeader);
|
||||
}
|
||||
#endif // NSIS_CONFIG_UNINSTALL_SUPPORT
|
24
Source/util.h
Normal file
24
Source/util.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
#include "ResourceEditor.h"
|
||||
|
||||
// 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, char* filename, int width=0, int height=0);
|
||||
|
||||
// reads icon file filename and places its icons in the resource wIconId using resource editor re. Also updates icondata_size.
|
||||
int replace_icon(CResourceEditor* re, WORD wIconId, 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(char* filename);
|
||||
// Fill the array of icons for uninstall with their offsets
|
||||
int generate_unicons_offsets(unsigned char* exeHeader, unsigned char* uninstIconData);
|
||||
#endif NSIS_CONFIG_UNINSTALL_SUPPORT
|
||||
|
||||
#endif //_UTIL_H_
|
238
Source/zlib/DEFLATE.H
Normal file
238
Source/zlib/DEFLATE.H
Normal file
|
@ -0,0 +1,238 @@
|
|||
/* 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
|
309
Source/zlib/INFBLOCK.C
Normal file
309
Source/zlib/INFBLOCK.C
Normal file
|
@ -0,0 +1,309 @@
|
|||
#include "../exehead/config.h"
|
||||
#ifdef NSIS_COMPRESS_USE_ZLIB
|
||||
/* infblock.c -- interpret and process block types to last block
|
||||
* Copyright (C) 1995-1998 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "infblock.h"
|
||||
#include "inftrees.h"
|
||||
#include "infcodes.h"
|
||||
#include "infutil.h"
|
||||
|
||||
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
|
||||
|
||||
/* simplify the use of the inflate_huft type with some defines */
|
||||
#define exop word.what.Exop
|
||||
#define bits word.what.Bits
|
||||
|
||||
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};
|
||||
|
||||
|
||||
void inflate_blocks_reset(s, z, c)
|
||||
inflate_blocks_statef *s;
|
||||
z_streamp z;
|
||||
uLongf *c;
|
||||
{
|
||||
if (c) *c = s->check;
|
||||
if (s->mode == BTREE || s->mode == DTREE)
|
||||
ZFREE(z, s->sub.trees.blens);
|
||||
if (s->mode == CODES)
|
||||
inflate_codes_free(s->sub.decode.codes, z);
|
||||
s->mode = TYPE;
|
||||
s->bitk = 0;
|
||||
s->bitb = 0;
|
||||
s->read = s->write = s->window;
|
||||
Tracev((stderr, "inflate: blocks reset\n"));
|
||||
}
|
||||
|
||||
int inflate_blocks_getssize()
|
||||
{
|
||||
return sizeof(struct inflate_blocks_state);
|
||||
}
|
||||
|
||||
void inflate_blocks_init(z_streamp z,inflate_blocks_statef *s)
|
||||
{
|
||||
s->end = s->window + (1 << DEF_WBITS);
|
||||
s->mode = TYPE;
|
||||
inflate_blocks_reset(s, z, Z_NULL);
|
||||
}
|
||||
|
||||
int inflate_blocks(s, z, r)
|
||||
inflate_blocks_statef *s;
|
||||
z_streamp z;
|
||||
int r;
|
||||
{
|
||||
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 */
|
||||
|
||||
/* 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;
|
||||
s->last = t & 1;
|
||||
switch (t >> 1)
|
||||
{
|
||||
case 0: /* stored */
|
||||
Tracev((stderr, "inflate: stored block%s\n",
|
||||
s->last ? " (last)" : ""));
|
||||
DUMPBITS(3)
|
||||
t = k & 7; /* go to byte boundary */
|
||||
DUMPBITS(t)
|
||||
s->mode = LENS; /* get length of stored block */
|
||||
break;
|
||||
case 1: /* fixed */
|
||||
Tracev((stderr, "inflate: fixed codes block%s\n",
|
||||
s->last ? " (last)" : ""));
|
||||
{
|
||||
uInt bl, bd;
|
||||
inflate_huft *tl, *td;
|
||||
|
||||
inflate_trees_fixed(&bl, &bd, &tl, &td, z);
|
||||
s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
|
||||
if (s->sub.decode.codes == Z_NULL)
|
||||
{
|
||||
r = Z_MEM_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
}
|
||||
DUMPBITS(3)
|
||||
s->mode = CODES;
|
||||
break;
|
||||
case 2: /* dynamic */
|
||||
Tracev((stderr, "inflate: dynamic codes block%s\n",
|
||||
s->last ? " (last)" : ""));
|
||||
DUMPBITS(3)
|
||||
s->mode = TABLE;
|
||||
break;
|
||||
case 3: /* illegal */
|
||||
DUMPBITS(3)
|
||||
s->mode = BAD;
|
||||
// z->msg = (char*)"err";//invalid block type";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
break;
|
||||
case LENS:
|
||||
NEEDBITS(32)
|
||||
if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
|
||||
{
|
||||
s->mode = BAD;
|
||||
// z->msg = (char*)"err";//invalid stored block lengths";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
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 ? DRY : TYPE);
|
||||
break;
|
||||
case STORED:
|
||||
if (n == 0)
|
||||
LEAVE
|
||||
NEEDOUT
|
||||
t = s->sub.left;
|
||||
if (t > n) t = n;
|
||||
if (t > m) t = m;
|
||||
zmemcpy(q, p, t);
|
||||
p += t; n -= t;
|
||||
q += t; m -= t;
|
||||
if ((s->sub.left -= t) != 0)
|
||||
break;
|
||||
Tracev((stderr, "inflate: stored end, %lu total out\n",
|
||||
z->total_out + (q >= s->read ? q - s->read :
|
||||
(s->end - s->read) + (q - s->window))));
|
||||
s->mode = s->last ? DRY : TYPE;
|
||||
break;
|
||||
case TABLE:
|
||||
NEEDBITS(14)
|
||||
s->sub.trees.table = t = (uInt)b & 0x3fff;
|
||||
#ifndef PKZIP_BUG_WORKAROUND
|
||||
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
|
||||
{
|
||||
s->mode = BAD;
|
||||
// z->msg = (char*)"err";//too many length or distance symbols";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
#endif
|
||||
t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
|
||||
if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
|
||||
{
|
||||
r = Z_MEM_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
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.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
|
||||
DUMPBITS(3)
|
||||
}
|
||||
while (s->sub.trees.index < 19)
|
||||
s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
|
||||
s->sub.trees.bb = 7;
|
||||
t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
|
||||
&s->sub.trees.tb, s->hufts, z);
|
||||
if (t != Z_OK)
|
||||
{
|
||||
ZFREE(z, s->sub.trees.blens);
|
||||
r = t;
|
||||
if (r == Z_DATA_ERROR)
|
||||
s->mode = BAD;
|
||||
LEAVE
|
||||
}
|
||||
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.blens[s->sub.trees.index++] = c;
|
||||
}
|
||||
else /* c == 16..18 */
|
||||
{
|
||||
i = c == 18 ? 7 : c - 14;
|
||||
j = c == 18 ? 11 : 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))
|
||||
{
|
||||
ZFREE(z, s->sub.trees.blens);
|
||||
s->mode = BAD;
|
||||
// z->msg = (char*)"err";//invalid bit length repeat";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
|
||||
do {
|
||||
s->sub.trees.blens[i++] = c;
|
||||
} while (--j);
|
||||
s->sub.trees.index = i;
|
||||
}
|
||||
}
|
||||
s->sub.trees.tb = Z_NULL;
|
||||
{
|
||||
uInt bl, bd;
|
||||
inflate_huft *tl, *td;
|
||||
inflate_codes_statef *c;
|
||||
|
||||
bl = 9; /* must be <= 9 for lookahead assumptions */
|
||||
bd = 6; /* must be <= 9 for lookahead assumptions */
|
||||
t = s->sub.trees.table;
|
||||
t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
|
||||
s->sub.trees.blens, &bl, &bd, &tl, &td,
|
||||
s->hufts, z);
|
||||
ZFREE(z, s->sub.trees.blens);
|
||||
if (t != Z_OK)
|
||||
{
|
||||
if (t == (uInt)Z_DATA_ERROR)
|
||||
s->mode = BAD;
|
||||
r = t;
|
||||
LEAVE
|
||||
}
|
||||
Tracev((stderr, "inflate: trees ok\n"));
|
||||
if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
|
||||
{
|
||||
r = Z_MEM_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
s->sub.decode.codes = c;
|
||||
}
|
||||
s->mode = CODES;
|
||||
case CODES:
|
||||
UPDATE
|
||||
if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
|
||||
return inflate_flush(s, z, r);
|
||||
r = Z_OK;
|
||||
inflate_codes_free(s->sub.decode.codes, z);
|
||||
LOAD
|
||||
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))));
|
||||
if (!s->last)
|
||||
{
|
||||
s->mode = TYPE;
|
||||
break;
|
||||
}
|
||||
s->mode = DRY;
|
||||
case DRY:
|
||||
FLUSH
|
||||
if (s->read != s->write)
|
||||
LEAVE
|
||||
s->mode = DONE;
|
||||
case DONE:
|
||||
r = Z_STREAM_END;
|
||||
LEAVE
|
||||
case BAD:
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
default:
|
||||
r = Z_STREAM_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int inflate_blocks_free(s, z)
|
||||
inflate_blocks_statef *s;
|
||||
z_streamp z;
|
||||
{
|
||||
inflate_blocks_reset(s, z, Z_NULL);
|
||||
ZFREE(z, s);
|
||||
Tracev((stderr, "inflate: blocks freed\n"));
|
||||
return Z_OK;
|
||||
}
|
||||
#endif
|
32
Source/zlib/INFBLOCK.H
Normal file
32
Source/zlib/INFBLOCK.H
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* infblock.h -- header to use infblock.c
|
||||
* Copyright (C) 1995-1998 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
struct inflate_blocks_state;
|
||||
typedef struct inflate_blocks_state FAR inflate_blocks_statef;
|
||||
|
||||
extern inflate_blocks_statef * inflate_blocks_new OF((
|
||||
z_streamp z)); /* window size */
|
||||
|
||||
extern int inflate_blocks OF((
|
||||
inflate_blocks_statef *,
|
||||
z_streamp ,
|
||||
int)); /* initial return code */
|
||||
|
||||
extern void inflate_blocks_reset OF((
|
||||
inflate_blocks_statef *,
|
||||
z_streamp ,
|
||||
uLongf *)); /* check value on output */
|
||||
|
||||
extern int inflate_blocks_free OF((
|
||||
inflate_blocks_statef *,
|
||||
z_streamp));
|
||||
|
||||
extern void inflate_set_dictionary OF((
|
||||
inflate_blocks_statef *s,
|
||||
const Bytef *d, /* dictionary */
|
||||
uInt n)); /* dictionary length */
|
||||
|
||||
extern int inflate_blocks_sync_point OF((
|
||||
inflate_blocks_statef *s));
|
246
Source/zlib/INFCODES.C
Normal file
246
Source/zlib/INFCODES.C
Normal file
|
@ -0,0 +1,246 @@
|
|||
#include "../exehead/config.h"
|
||||
#ifdef NSIS_COMPRESS_USE_ZLIB
|
||||
/* infcodes.c -- process literals and length/distance pairs
|
||||
* Copyright (C) 1995-1998 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
#include "infblock.h"
|
||||
#include "infcodes.h"
|
||||
#include "infutil.h"
|
||||
|
||||
/* simplify the use of the inflate_huft type with some defines */
|
||||
#define exop word.what.Exop
|
||||
#define bits word.what.Bits
|
||||
|
||||
typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
|
||||
START, /* x: set up for LEN */
|
||||
LEN, /* i: get length/literal/eob next */
|
||||
LENEXT, /* i: getting length extra (have base) */
|
||||
DIST, /* i: get distance next */
|
||||
DISTEXT, /* i: getting distance extra */
|
||||
COPY, /* o: copying bytes in window, waiting for space */
|
||||
LIT, /* o: got literal, waiting for output space */
|
||||
WASH, /* o: got eob, possibly still output waiting */
|
||||
END, /* x: got eob and all data flushed */
|
||||
BADCODE} /* x: got error */
|
||||
inflate_codes_mode;
|
||||
|
||||
/* inflate codes private state */
|
||||
struct inflate_codes_state {
|
||||
|
||||
/* mode */
|
||||
inflate_codes_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 */
|
||||
|
||||
};
|
||||
|
||||
|
||||
inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
|
||||
uInt bl, bd;
|
||||
inflate_huft *tl;
|
||||
inflate_huft *td; /* need separate declaration for Borland C++ */
|
||||
z_streamp z;
|
||||
{
|
||||
inflate_codes_statef *c;
|
||||
|
||||
if ((c = (inflate_codes_statef *)
|
||||
ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
|
||||
{
|
||||
c->mode = START;
|
||||
c->lbits = (Byte)bl;
|
||||
c->dbits = (Byte)bd;
|
||||
c->ltree = tl;
|
||||
c->dtree = td;
|
||||
Tracev((stderr, "inflate: codes new\n"));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
int inflate_codes(s, z, r)
|
||||
inflate_blocks_statef *s;
|
||||
z_streamp z;
|
||||
int r;
|
||||
{
|
||||
uInt j; /* temporary storage */
|
||||
inflate_huft *t; /* temporary pointer */
|
||||
uInt e; /* extra bits or operation */
|
||||
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 */
|
||||
Bytef *f; /* pointer to copy strings from */
|
||||
inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
|
||||
|
||||
/* copy input/output information to locals (UPDATE macro restores) */
|
||||
LOAD
|
||||
|
||||
/* process input and output based on current state */
|
||||
while (1) switch (c->mode)
|
||||
{ /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
|
||||
case START: /* x: set up for LEN */
|
||||
c->sub.code.need = c->lbits;
|
||||
c->sub.code.tree = c->ltree;
|
||||
c->mode = LEN;
|
||||
case LEN: /* i: get length/literal/eob next */
|
||||
j = c->sub.code.need;
|
||||
NEEDBITS(j)
|
||||
t = c->sub.code.tree + ((uInt)b & (uInt)inflate_mask[j]);
|
||||
DUMPBITS(t->bits)
|
||||
e = (uInt)(t->exop);
|
||||
if (e == 0) /* literal */
|
||||
{
|
||||
c->sub.lit = t->base;
|
||||
Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", t->base));
|
||||
c->mode = LIT;
|
||||
break;
|
||||
}
|
||||
if (e & 16) /* length */
|
||||
{
|
||||
c->sub.copy.get = e & 15;
|
||||
c->len = t->base;
|
||||
c->mode = LENEXT;
|
||||
break;
|
||||
}
|
||||
if ((e & 64) == 0) /* next table */
|
||||
{
|
||||
c->sub.code.need = e;
|
||||
c->sub.code.tree = t + t->base;
|
||||
break;
|
||||
}
|
||||
if (e & 32) /* end of block */
|
||||
{
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
c->mode = WASH;
|
||||
break;
|
||||
}
|
||||
c->mode = BADCODE; /* invalid code */
|
||||
// z->msg = (char*)"err";//invalid literal/length code";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
case LENEXT: /* i: getting length extra (have base) */
|
||||
j = c->sub.copy.get;
|
||||
NEEDBITS(j)
|
||||
c->len += (uInt)b & (uInt)inflate_mask[j];
|
||||
DUMPBITS(j)
|
||||
c->sub.code.need = c->dbits;
|
||||
c->sub.code.tree = c->dtree;
|
||||
Tracevv((stderr, "inflate: length %u\n", c->len));
|
||||
c->mode = DIST;
|
||||
case DIST: /* i: get distance next */
|
||||
j = c->sub.code.need;
|
||||
NEEDBITS(j)
|
||||
t = c->sub.code.tree + ((uInt)b & (uInt)inflate_mask[j]);
|
||||
DUMPBITS(t->bits)
|
||||
e = (uInt)(t->exop);
|
||||
if (e & 16) /* distance */
|
||||
{
|
||||
c->sub.copy.get = e & 15;
|
||||
c->sub.copy.dist = t->base;
|
||||
c->mode = DISTEXT;
|
||||
break;
|
||||
}
|
||||
if ((e & 64) == 0) /* next table */
|
||||
{
|
||||
c->sub.code.need = e;
|
||||
c->sub.code.tree = t + t->base;
|
||||
break;
|
||||
}
|
||||
c->mode = BADCODE; /* invalid code */
|
||||
// z->msg = (char*)"err";//invalid distance code";
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
case DISTEXT: /* i: getting distance extra */
|
||||
j = c->sub.copy.get;
|
||||
NEEDBITS(j)
|
||||
c->sub.copy.dist += (uInt)b & (uInt)inflate_mask[j];
|
||||
DUMPBITS(j)
|
||||
Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
|
||||
c->mode = COPY;
|
||||
case COPY: /* o: copying bytes in window, waiting for space */
|
||||
#ifndef __TURBOC__ /* Turbo C bug for following expression */
|
||||
f = (uInt)(q - s->window) < c->sub.copy.dist ?
|
||||
s->end - (c->sub.copy.dist - (q - s->window)) :
|
||||
q - c->sub.copy.dist;
|
||||
#else
|
||||
f = q - c->sub.copy.dist;
|
||||
if ((uInt)(q - s->window) < c->sub.copy.dist)
|
||||
f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
|
||||
#endif
|
||||
while (c->len)
|
||||
{
|
||||
NEEDOUT
|
||||
OUTBYTE(*f++)
|
||||
if (f == s->end)
|
||||
f = s->window;
|
||||
c->len--;
|
||||
}
|
||||
c->mode = START;
|
||||
break;
|
||||
case LIT: /* o: got literal, waiting for output space */
|
||||
NEEDOUT
|
||||
OUTBYTE(c->sub.lit)
|
||||
c->mode = START;
|
||||
break;
|
||||
case WASH: /* o: got eob, possibly more output */
|
||||
if (k > 7) /* return unused byte, if any */
|
||||
{
|
||||
Assert(k < 16, "inflate_codes grabbed too many bytes")
|
||||
k -= 8;
|
||||
n++;
|
||||
p--; /* can always return one */
|
||||
}
|
||||
FLUSH
|
||||
if (s->read != s->write)
|
||||
LEAVE
|
||||
c->mode = END;
|
||||
case END:
|
||||
r = Z_STREAM_END;
|
||||
LEAVE
|
||||
case BADCODE: /* x: got error */
|
||||
r = Z_DATA_ERROR;
|
||||
LEAVE
|
||||
default:
|
||||
r = Z_STREAM_ERROR;
|
||||
LEAVE
|
||||
}
|
||||
#ifdef NEED_DUMMY_RETURN
|
||||
return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void inflate_codes_free(c, z)
|
||||
inflate_codes_statef *c;
|
||||
z_streamp z;
|
||||
{
|
||||
ZFREE(z, c);
|
||||
Tracev((stderr, "inflate: codes free\n"));
|
||||
}
|
||||
#endif
|
22
Source/zlib/INFCODES.H
Normal file
22
Source/zlib/INFCODES.H
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* infcodes.h -- header to use infcodes.c
|
||||
* Copyright (C) 1995-1998 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
struct inflate_codes_state;
|
||||
typedef struct inflate_codes_state FAR inflate_codes_statef;
|
||||
|
||||
extern inflate_codes_statef *inflate_codes_new OF((
|
||||
uInt, uInt,
|
||||
inflate_huft *, inflate_huft *,
|
||||
z_streamp ));
|
||||
|
||||
extern int inflate_codes OF((
|
||||
inflate_blocks_statef *,
|
||||
z_streamp ,
|
||||
int));
|
||||
|
||||
extern void inflate_codes_free OF((
|
||||
inflate_codes_statef *,
|
||||
z_streamp ));
|
||||
|
65
Source/zlib/INFLATE.C
Normal file
65
Source/zlib/INFLATE.C
Normal file
|
@ -0,0 +1,65 @@
|
|||
#include "../exehead/config.h"
|
||||
#ifdef NSIS_COMPRESS_USE_ZLIB
|
||||
/* inflate.c -- zlib interface to inflate modules
|
||||
* Copyright (C) 1995-1998 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
|
||||
* this has been HEAVILY modified for NSIS use, and is no longer compatible
|
||||
* with the stock zlib.
|
||||
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "infblock.h"
|
||||
|
||||
struct inflate_blocks_state { int dummy; }; /* for buggy compilers */
|
||||
|
||||
|
||||
/* inflate private state */
|
||||
struct internal_state {
|
||||
|
||||
/* mode dependent information */
|
||||
union {
|
||||
uInt method; /* if FLAGS, method byte */
|
||||
struct {
|
||||
uLong was; /* computed check value */
|
||||
uLong need; /* stream check value */
|
||||
} check; /* if CHECK, check values to compare */
|
||||
uInt marker; /* if BAD, inflateSync's marker bytes count */
|
||||
} sub; /* submode */
|
||||
|
||||
inflate_blocks_statef blocks; /* current inflate_blocks state */
|
||||
};
|
||||
|
||||
|
||||
int inflateReset(z_streamp z)
|
||||
{
|
||||
if (z == Z_NULL || z->state == Z_NULL)
|
||||
return Z_STREAM_ERROR;
|
||||
z->total_in = z->total_out = 0;
|
||||
inflate_blocks_reset(&z->state->blocks, z, Z_NULL);
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
|
||||
int inflateInit(z_streamp z)
|
||||
{
|
||||
int inflate_blocks_getssize();
|
||||
void inflate_blocks_init(z_streamp z,inflate_blocks_statef *s);
|
||||
|
||||
if ((z->state =
|
||||
(struct internal_state FAR *) ZALLOC(z,1,sizeof(struct internal_state)+inflate_blocks_getssize())) == Z_NULL)
|
||||
return Z_MEM_ERROR;
|
||||
|
||||
inflate_blocks_init(z,&z->state->blocks);
|
||||
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
|
||||
int inflate(z_streamp z)
|
||||
{
|
||||
return inflate_blocks(&z->state->blocks, z, Z_OK);
|
||||
}
|
||||
|
||||
#endif
|
324
Source/zlib/INFTREES.C
Normal file
324
Source/zlib/INFTREES.C
Normal file
|
@ -0,0 +1,324 @@
|
|||
#include "../exehead/config.h"
|
||||
#ifdef NSIS_COMPRESS_USE_ZLIB
|
||||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||
* Copyright (C) 1995-1998 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
|
||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
|
||||
/* simplify the use of the inflate_huft type with some defines */
|
||||
#define exop word.what.Exop
|
||||
#define bits word.what.Bits
|
||||
|
||||
/* 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};
|
||||
|
||||
#define BMAX 15 /* maximum bit length of any code */
|
||||
|
||||
local int 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--)
|
||||
{
|
||||
/* here i is the Huffman code of length k bits for value *p */
|
||||
/* make tables up to required level */
|
||||
while (k > w + l)
|
||||
{
|
||||
h++;
|
||||
w += l; /* previous table always l bits */
|
||||
|
||||
/* compute minimum size table less than or equal to l bits */
|
||||
z = g - w;
|
||||
z = z > (uInt)l ? l : z; /* table size upper limit */
|
||||
if ((f = 1 << (j = k - w)) > 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) /* try smaller tables up to z bits */
|
||||
{
|
||||
if ((f <<= 1) <= *++xp)
|
||||
break; /* enough codes to use up j 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 - l);
|
||||
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 */
|
||||
}
|
||||
|
||||
/* 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 inflate_trees_bits(c, bb, tb, hp, z)
|
||||
uIntf *c; /* 19 code lengths */
|
||||
uIntf *bb; /* bits tree desired/actual depth */
|
||||
inflate_huft * FAR *tb; /* bits tree result */
|
||||
inflate_huft *hp; /* space for trees */
|
||||
z_streamp z; /* for messages */
|
||||
{
|
||||
int r;
|
||||
uInt hn = 0; /* hufts used in space */
|
||||
|
||||
r = huft_build(c, 19, 19, (short *)Z_NULL, (short*)Z_NULL,
|
||||
tb, bb, hp, &hn);
|
||||
if (r == Z_BUF_ERROR || *bb == 0)
|
||||
{
|
||||
return Z_DATA_ERROR;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
|
||||
uInt nl; /* number of literal/length codes */
|
||||
uInt nd; /* number of distance codes */
|
||||
uIntf *c; /* that many (total) code lengths */
|
||||
uIntf *bl; /* literal desired/actual bit depth */
|
||||
uIntf *bd; /* distance desired/actual bit depth */
|
||||
inflate_huft * FAR *tl; /* literal/length tree result */
|
||||
inflate_huft * FAR *td; /* distance tree result */
|
||||
inflate_huft *hp; /* space for trees */
|
||||
z_streamp z; /* for messages */
|
||||
{
|
||||
int r;
|
||||
uInt hn = 0; /* hufts used in space */
|
||||
|
||||
/* build literal/length tree */
|
||||
r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn);
|
||||
if (r != Z_OK || *bl == 0)
|
||||
{
|
||||
if (r != Z_MEM_ERROR) return Z_DATA_ERROR;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* build distance tree */
|
||||
r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn);
|
||||
if (r != Z_OK || (*bd == 0 && nl > 257))
|
||||
{
|
||||
if (r != Z_MEM_ERROR) return Z_DATA_ERROR;
|
||||
return r;
|
||||
}
|
||||
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
|
||||
/* build fixed tables only once--keep them here */
|
||||
local int fixed_built = 0;
|
||||
#define FIXEDH 544 /* number of hufts used by fixed tables */
|
||||
local inflate_huft fixed_mem[FIXEDH];
|
||||
local uInt fixed_bl;
|
||||
local uInt fixed_bd;
|
||||
local inflate_huft *fixed_tl;
|
||||
local inflate_huft *fixed_td;
|
||||
|
||||
|
||||
int inflate_trees_fixed(bl, bd, tl, td, z)
|
||||
uIntf *bl; /* literal desired/actual bit depth */
|
||||
uIntf *bd; /* distance desired/actual bit depth */
|
||||
inflate_huft * FAR *tl; /* literal/length tree result */
|
||||
inflate_huft * FAR *td; /* distance tree result */
|
||||
z_streamp z; /* for memory allocation */
|
||||
{
|
||||
/* build fixed tables if not already */
|
||||
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 < 144; k++) c[k] = 8;
|
||||
for (; k < 256; k++) c[k] = 9;
|
||||
for (; k < 280; k++) c[k] = 7;
|
||||
for (; k < 288; k++) c[k] = 8;
|
||||
fixed_bl = 9;
|
||||
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;
|
||||
fixed_bd = 5;
|
||||
huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, fixed_mem, &f);
|
||||
|
||||
/* done */
|
||||
fixed_built = 1;
|
||||
}
|
||||
*bl = fixed_bl;
|
||||
*bd = fixed_bd;
|
||||
*tl = fixed_tl;
|
||||
*td = fixed_td;
|
||||
return Z_OK;
|
||||
}
|
||||
#endif
|
45
Source/zlib/INFTREES.H
Normal file
45
Source/zlib/INFTREES.H
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* inftrees.h -- header to use inftrees.c
|
||||
* Copyright (C) 1995-1998 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
||||
typedef struct inflate_huft_s FAR inflate_huft;
|
||||
|
||||
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
|
||||
|
||||
extern int inflate_trees_bits OF((
|
||||
uIntf *,
|
||||
uIntf *,
|
||||
inflate_huft * FAR *,
|
||||
inflate_huft *,
|
||||
z_streamp));
|
||||
|
||||
extern int inflate_trees_dynamic OF((
|
||||
uInt,
|
||||
uInt,
|
||||
uIntf *,
|
||||
uIntf *,
|
||||
uIntf *,
|
||||
inflate_huft * FAR *,
|
||||
inflate_huft * FAR *,
|
||||
inflate_huft *,
|
||||
z_streamp));
|
||||
|
||||
extern int inflate_trees_fixed OF((
|
||||
uIntf *,
|
||||
uIntf *,
|
||||
inflate_huft * FAR *,
|
||||
inflate_huft * FAR *,
|
||||
z_streamp));
|
87
Source/zlib/INFUTIL.C
Normal file
87
Source/zlib/INFUTIL.C
Normal file
|
@ -0,0 +1,87 @@
|
|||
#include "../exehead/config.h"
|
||||
#ifdef NSIS_COMPRESS_USE_ZLIB
|
||||
/* inflate_util.c -- data and routines common to blocks and codes
|
||||
* Copyright (C) 1995-1998 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "infblock.h"
|
||||
#include "inftrees.h"
|
||||
#include "infcodes.h"
|
||||
#include "infutil.h"
|
||||
|
||||
struct inflate_codes_state {int dummy;}; /* for buggy compilers */
|
||||
|
||||
/* And'ing with mask[n] masks the lower n bits */
|
||||
unsigned short inflate_mask[17] = {
|
||||
0x0000,
|
||||
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
|
||||
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
|
||||
};
|
||||
|
||||
int __myleave(inflate_blocks_statef *s, z_streamp z, int r, int b, int k, Bytef *p, int n, Bytef *q)
|
||||
{
|
||||
UPDATE
|
||||
return inflate_flush(s,z,r);
|
||||
}
|
||||
|
||||
/* copy as much as possible from the sliding window to the output area */
|
||||
int inflate_flush(s, z, r)
|
||||
inflate_blocks_statef *s;
|
||||
z_streamp z;
|
||||
int r;
|
||||
{
|
||||
uInt n;
|
||||
Bytef *p;
|
||||
Bytef *q;
|
||||
|
||||
/* local copies of source and destination pointers */
|
||||
p = z->next_out;
|
||||
q = s->read;
|
||||
|
||||
/* compute number of bytes to copy as far as end of window */
|
||||
n = (uInt)((q <= s->write ? s->write : s->end) - q);
|
||||
if (n > z->avail_out) n = z->avail_out;
|
||||
if (n && r == Z_BUF_ERROR) r = Z_OK;
|
||||
|
||||
/* update counters */
|
||||
z->avail_out -= n;
|
||||
z->total_out += n;
|
||||
|
||||
/* copy as far as end of window */
|
||||
zmemcpy(p, q, n);
|
||||
p += 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;
|
||||
|
||||
/* compute bytes to copy */
|
||||
n = (uInt)(s->write - q);
|
||||
if (n > z->avail_out) n = z->avail_out;
|
||||
if (n && r == Z_BUF_ERROR) r = Z_OK;
|
||||
|
||||
/* update counters */
|
||||
z->avail_out -= n;
|
||||
z->total_out += n;
|
||||
|
||||
/* copy */
|
||||
zmemcpy(p, q, n);
|
||||
p += n;
|
||||
q += n;
|
||||
}
|
||||
|
||||
/* update pointers */
|
||||
z->next_out = p;
|
||||
s->read = q;
|
||||
|
||||
/* done */
|
||||
return r;
|
||||
}
|
||||
#endif
|
97
Source/zlib/INFUTIL.H
Normal file
97
Source/zlib/INFUTIL.H
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* infutil.h -- types and macros common to blocks and codes
|
||||
* Copyright (C) 1995-1998 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#ifndef _INFUTIL_H
|
||||
#define _INFUTIL_H
|
||||
|
||||
typedef enum {
|
||||
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_block_mode;
|
||||
|
||||
/* inflate blocks semi-private state */
|
||||
struct inflate_blocks_state {
|
||||
|
||||
/* mode */
|
||||
inflate_block_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 *blens; /* 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
|
||||
*codes;
|
||||
} decode; /* if CODES, current state */
|
||||
} sub; /* submode */
|
||||
uInt last; /* true if this block is the last block */
|
||||
|
||||
/* 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 << DEF_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 */
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* defines for inflate input/output */
|
||||
/* update pointers and return */
|
||||
#define UPDBITS {s->bitb=b;s->bitk=k;}
|
||||
#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
|
||||
#define UPDOUT {s->write=q;}
|
||||
#define UPDATE {UPDBITS UPDIN UPDOUT}
|
||||
#define LEAVE return __myleave(s,z,r,b,k,p,n,q);
|
||||
extern int __myleave(inflate_blocks_statef *s, z_streamp z, int r, int b, int k, Bytef *p, int n, Bytef *q);
|
||||
|
||||
/* get bytes and bits */
|
||||
#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
|
||||
|
||||
|
||||
#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
|
||||
#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 r=inflate_flush(s,z,r); LOADOUT}
|
||||
#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
|
||||
#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
|
||||
/* load local pointers */
|
||||
#define LOAD {LOADIN LOADOUT}
|
||||
|
||||
/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
|
||||
extern unsigned short inflate_mask[17];
|
||||
|
||||
/* copy as much as possible from the sliding window to the output area */
|
||||
extern int inflate_flush OF((
|
||||
inflate_blocks_statef *,
|
||||
z_streamp ,
|
||||
int));
|
||||
|
||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
|
||||
#endif
|
58
Source/zlib/ZCONF.H
Normal file
58
Source/zlib/ZCONF.H
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* 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$ */
|
||||
|
||||
#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 */
|
157
Source/zlib/ZLIB.H
Normal file
157
Source/zlib/ZLIB.H
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
Note: this version of zlib has been hacked up quite a bit in order to reduce
|
||||
the size of the EXE header and to remove what we didn't need.
|
||||
For the complete real thing, go to:
|
||||
|
||||
http://www.info-zip.org/pub/infozip/zlib/
|
||||
|
||||
Peace,
|
||||
|
||||
-Justin
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* 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"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
struct internal_state;
|
||||
|
||||
typedef struct z_stream_s {
|
||||
Bytef *next_in; /* next input byte */
|
||||
uInt avail_in; /* number of bytes available at next_in */
|
||||
uLong total_in; /* total nb of input bytes read so far */
|
||||
|
||||
Bytef *next_out; /* next output byte should be put there */
|
||||
uInt avail_out; /* remaining free space at next_out */
|
||||
uLong total_out; /* total nb of bytes output so far */
|
||||
|
||||
// char *msg; /* last error message, NULL if no error */
|
||||
struct internal_state FAR *state; /* not visible by applications */
|
||||
|
||||
} 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)
|
||||
#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)
|
||||
/* 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));
|
||||
ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
|
||||
|
||||
int 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));
|
||||
int inflateReset(z_streamp z);
|
||||
|
||||
|
||||
/* 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));
|
||||
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
|
||||
const char *version, int stream_size));
|
||||
#define deflateInit(strm, level) \
|
||||
deflateInit_((strm), (level), "", sizeof(z_stream))
|
||||
|
||||
extern int inflateInit(z_streamp z);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ZLIB_H */
|
68
Source/zlib/ZUTIL.H
Normal file
68
Source/zlib/ZUTIL.H
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* 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$ */
|
||||
|
||||
#ifndef _Z_UTIL_H
|
||||
#define _Z_UTIL_H
|
||||
|
||||
#include <windows.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
|
||||
#include "../exehead/util.h"
|
||||
#define zmemcpy mini_memcpy
|
||||
#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) GlobalAlloc(GPTR,(items)*(size))
|
||||
#define ZFREE(strm, addr) { if (addr) GlobalFree(addr); }
|
||||
#define TRY_FREE(s, p) { ZFREE(s, p); }
|
||||
#define ERR_RETURN(strm,err) return (err)
|
||||
|
||||
#endif /* _Z_UTIL_H */
|
986
Source/zlib/deflate.c
Normal file
986
Source/zlib/deflate.c
Normal file
|
@ -0,0 +1,986 @@
|
|||
/* 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_stored OF((deflate_state *s, int flush));
|
||||
local block_state deflate_fast OF((deflate_state *s, int flush));
|
||||
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 4096
|
||||
#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[10] = {
|
||||
/* good lazy nice chain */
|
||||
/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
|
||||
/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
|
||||
/* 2 */ {4, 5, 16, 8, deflate_fast},
|
||||
/* 3 */ {4, 6, 32, 32, deflate_fast},
|
||||
|
||||
/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
|
||||
/* 5 */ {8, 16, 32, 32, deflate_slow},
|
||||
/* 6 */ {8, 16, 128, 128, deflate_slow},
|
||||
/* 7 */ {8, 32, 128, 256, deflate_slow},
|
||||
/* 8 */ {32, 128, 258, 1024, deflate_slow},
|
||||
/* 9 */ {32, 258, 258, 4096, 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;
|
||||
|
||||
// strm->msg = Z_NULL;
|
||||
|
||||
if (level == Z_DEFAULT_COMPRESSION) level = 6;
|
||||
#ifdef FASTEST
|
||||
level = 1;
|
||||
#endif
|
||||
|
||||
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 > 15 || 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[s->level].func;
|
||||
|
||||
if (func != configuration_table[level].func && strm->total_in != 0) {
|
||||
/* Flush the last buffer: */
|
||||
err = deflate(strm, Z_PARTIAL_FLUSH);
|
||||
}
|
||||
if (s->level != level) {
|
||||
s->level = level;
|
||||
s->max_lazy_match = configuration_table[level].max_lazy;
|
||||
s->good_match = configuration_table[level].good_length;
|
||||
s->nice_match = configuration_table[level].nice_length;
|
||||
s->max_chain_length = configuration_table[level].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[s->level].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[s->level].max_lazy;
|
||||
s->good_match = configuration_table[s->level].good_length;
|
||||
s->nice_match = configuration_table[s->level].nice_length;
|
||||
s->max_chain_length = configuration_table[s->level].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
|
||||
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_stored(s, flush)
|
||||
deflate_state *s;
|
||||
int flush;
|
||||
{
|
||||
/* Stored blocks are limited to 0xffff bytes, pending_buf is limited
|
||||
* to pending_buf_size, and each stored block has a 5 byte header:
|
||||
*/
|
||||
ulg max_block_size = 0xffff;
|
||||
ulg max_start;
|
||||
|
||||
if (max_block_size > s->pending_buf_size - 5) {
|
||||
max_block_size = s->pending_buf_size - 5;
|
||||
}
|
||||
|
||||
/* Copy as much as possible from input to output: */
|
||||
for (;;) {
|
||||
/* Fill the window as much as possible: */
|
||||
if (s->lookahead <= 1) {
|
||||
|
||||
Assert(s->strstart < s->w_size+MAX_DIST(s) ||
|
||||
s->block_start >= (long)s->w_size, "slide too late");
|
||||
|
||||
fill_window(s);
|
||||
if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
|
||||
|
||||
if (s->lookahead == 0) break; /* flush the current block */
|
||||
}
|
||||
Assert(s->block_start >= 0L, "block gone");
|
||||
|
||||
s->strstart += s->lookahead;
|
||||
s->lookahead = 0;
|
||||
|
||||
/* Emit a stored block if pending_buf will be full: */
|
||||
max_start = s->block_start + max_block_size;
|
||||
if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
|
||||
/* strstart == 0 is possible when wraparound on 16-bit machine */
|
||||
s->lookahead = (uInt)(s->strstart - max_start);
|
||||
s->strstart = (uInt)max_start;
|
||||
FLUSH_BLOCK(s, 0);
|
||||
}
|
||||
if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
|
||||
FLUSH_BLOCK(s, 0);
|
||||
}
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return flush == Z_FINISH ? finish_done : block_done;
|
||||
}
|
||||
|
||||
local block_state deflate_fast(s, flush)
|
||||
deflate_state *s;
|
||||
int flush;
|
||||
{
|
||||
IPos hash_head = NIL; /* head of the hash chain */
|
||||
int bflush; /* set if current block must be flushed */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (hash_head != NIL && 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 >= MIN_MATCH) {
|
||||
check_match(s, s->strstart, s->match_start, s->match_length);
|
||||
|
||||
_tr_tally_dist(s, s->strstart - s->match_start,
|
||||
s->match_length - MIN_MATCH, bflush);
|
||||
|
||||
s->lookahead -= s->match_length;
|
||||
|
||||
/* Insert new strings in the hash table only if the match length
|
||||
* is not too large. This saves time but degrades compression.
|
||||
*/
|
||||
#ifndef FASTEST
|
||||
if (s->match_length <= s->max_insert_length &&
|
||||
s->lookahead >= MIN_MATCH) {
|
||||
s->match_length--; /* string at strstart already in hash table */
|
||||
do {
|
||||
s->strstart++;
|
||||
INSERT_STRING(s, s->strstart, hash_head);
|
||||
/* strstart never exceeds WSIZE-MAX_MATCH, so there are
|
||||
* always MIN_MATCH bytes ahead.
|
||||
*/
|
||||
} while (--s->match_length != 0);
|
||||
s->strstart++;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
s->strstart += s->match_length;
|
||||
s->match_length = 0;
|
||||
s->ins_h = s->window[s->strstart];
|
||||
UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
|
||||
#if MIN_MATCH != 3
|
||||
Call UPDATE_HASH() MIN_MATCH-3 more times
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
/* No match, output a literal byte */
|
||||
Tracevv((stderr,"%c", s->window[s->strstart]));
|
||||
_tr_tally_lit (s, s->window[s->strstart], bflush);
|
||||
s->lookahead--;
|
||||
s->strstart++;
|
||||
}
|
||||
if (bflush) FLUSH_BLOCK(s, 0);
|
||||
}
|
||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
||||
return flush == Z_FINISH ? finish_done : block_done;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
883
Source/zlib/trees.c
Normal file
883
Source/zlib/trees.c
Normal file
|
@ -0,0 +1,883 @@
|
|||
/* 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);
|
||||
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++);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue