MakeNSIS can now generate Unicode or Ansi installers based on a script attribute. SCons generates both Ansi and Unicode stubs and plugins.

The official plugins are now stored in architecture specific subdirectories under NSIS\Plugins. !AddPluginDir also gained a new (optional) architecture flag because MakeNSIS now stores separate plugin information for each target architecture. Storing plugins in the root of the Plugins directory is no longer supported.

MinGW does not implement the unicode CRT startup functions so the entry point functions and linker parameters had to be changed. The unicode tools use the ansi entry point and a small helper function that calls into the real code: _tmain has full argc+argv emulation while wWinMain does not pass the command line parameters. The stubs do not use any CRT functions and have no CRT or unicode helper code, they call our entry point directly.



git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6269 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2012-10-13 01:47:50 +00:00
parent 8f330bbbdf
commit 7cc150c464
73 changed files with 936 additions and 713 deletions

View file

@ -6,6 +6,11 @@
#include <windowsx.h>
#include <nsis/pluginapi.h> // nsis plugin
#ifndef LWA_COLORKEY
# define LWA_COLORKEY 1
# define LWA_ALPHA 2
#endif
HINSTANCE g_hInstance;
#define RESOLUTION 32 // 30 fps ;) (32? I like SHR more than iDIV ;)
@ -120,7 +125,7 @@ void SetTransparentRegion(HWND myWnd)
GlobalFree(bmp_orig);
}
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call,
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call,
LPVOID lpReserved)
{
g_hInstance = hInst;

View file

@ -168,7 +168,7 @@ void __declspec(dllexport) destroy(HWND hwndParent, int string_size, TCHAR *vari
}
}
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
hInstance = hInst;
if (hwBanner && ul_reason_for_call == DLL_PROCESS_DETACH)

View file

@ -111,8 +111,7 @@ NSISFunc(SetBg) {
return;
}
WNDCLASSEX wc = {
sizeof(WNDCLASSEX),
WNDCLASS wc = {
CS_VREDRAW|CS_HREDRAW,
WndProc,
0,
@ -123,9 +122,8 @@ NSISFunc(SetBg) {
0,
0,
_T("NSISBGImage"),
0
};
ATOM atomClass = RegisterClassEx(&wc);
ATOM atomClass = RegisterClass(&wc);
if (!atomClass) {
my_pushstring(_T("can't create window"));
return;

View file

@ -8,7 +8,7 @@
#define NSISFunction(funcname) void __declspec(dllexport) funcname(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters *extra)
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
return TRUE;
}

View file

@ -24,29 +24,31 @@ example = Split("""
extdll.inc
""")
Import('env plugin_env plugin_uenv')
Import('env plugin_env plugin_uenv GetArcSuffix PerformPluginExtrasDistOperationOnce')
unicodetarget = 'UNICODE' in env['CPPDEFINES']
lib_targetT = lib_target
plugin_envT = plugin_env
if unicodetarget:
plugin_envT = plugin_uenv
lib_targetT = lib_target + '-' + GetArcSuffix(plugin_envT, unicodetarget)
# build library
if unicodetarget:
lib_targetT = lib_targetT + 'W'
api_uenv = plugin_uenv.Clone()
api_uenv.Append(CPPPATH = ['#Source/exehead'])
libW = api_uenv.Library(lib_targetT, lib_files)
lib = libW
else:
api_env = plugin_env.Clone()
api_env.Append(CPPPATH = ['#Source/exehead'])
libA = api_env.Library(lib_targetT, lib_files)
lib = libA
api_envT = plugin_envT.Clone()
api_envT.Append(CPPPATH = ['#Source/exehead']) # For api.h
lib = api_envT.Library(lib_targetT, lib_files)
# distribute library, files and examples
if PerformPluginExtrasDistOperationOnce(plugin_envT, unicodetarget):
env.DistributeExamples(api_files, path='Plugin/nsis')
env.DistributeExamples(example, path='Plugin')
if env['PLATFORM'] == 'win32':
env.DistributeExamples(lib, path='Plugin/nsis')
else:
example += lib_files
@ -56,20 +58,14 @@ else:
if env.has_key('PREFIX_PLUGINAPI_LIB'):
env.Distribute(lib, None, 'pluginapi_lib', '', 'nsis', 'pluginapi', 'pluginapi')
if not unicodetarget:
env.DistributeExamples(api_files, path='Plugin/nsis')
env.DistributeExamples(example, path='Plugin')
# make sure all the other plug-ins can use the library
if unicodetarget:
envT = plugin_uenv
env.Install('#$BUILD_PREFIX/api/nsis', libW)
else:
envT = plugin_env
env.Install('#$BUILD_PREFIX/api/nsis', api_files + libA)
if PerformPluginExtrasDistOperationOnce(plugin_envT, unicodetarget):
env.Install('#$BUILD_PREFIX/api/nsis', api_files)
envT.Append(CPPPATH = ['#$BUILD_PREFIX/api'])
envT.Append(LIBPATH = ['#$BUILD_PREFIX/api/nsis'])
envT.Append(LIBS = [lib_targetT])
env.Install('#$BUILD_PREFIX/api/nsis', lib)
plugin_envT.Append(CPPPATH = ['#$BUILD_PREFIX/api'])
plugin_envT.Append(LIBPATH = ['#$BUILD_PREFIX/api/nsis'])
plugin_envT.Append(LIBS = [lib_targetT])

View file

@ -34,7 +34,7 @@ void __declspec(dllexport) myFunction(HWND hwndParent, int string_size,
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_hInstance=hInst;
return TRUE;

View file

@ -22,19 +22,25 @@
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
#endif
#ifndef _TCHAR_DEFINED
#define _TCHAR_DEFINED
#if !defined(_NATIVE_WCHAR_T_DEFINED) && !defined(_WCHAR_T_DEFINED)
typedef unsigned short TCHAR;
#else
typedef wchar_t TCHAR;
typedef wchar_t _TUCHAR;
#endif
#endif
// program
#define _tmain wmain
#define _tWinMain wWinMain
#define _tenviron _wenviron
#define __targv __wargv
// printfs
#define _ftprintf fwprintf
#define _sntprintf _snwprintf
#if defined(_MSC_VER) && (_MSC_VER<=1200)
#if (defined(_MSC_VER) && (_MSC_VER<=1310)) || defined(__MINGW32__)
# define _stprintf swprintf
#else
# define _stprintf _swprintf
@ -42,7 +48,11 @@ typedef wchar_t _TUCHAR;
#define _tprintf wprintf
#define _vftprintf vfwprintf
#define _vsntprintf _vsnwprintf
#define _vstprintf _vswprintf
#if defined(_MSC_VER) && (_MSC_VER<=1310)
# define _vstprintf vswprintf
#else
# define _vstprintf _vswprintf
#endif
// scanfs
#define _tscanf wscanf
@ -119,12 +129,13 @@ typedef wchar_t _TUCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif
typedef char TCHAR;
typedef unsigned char _TUCHAR;
#ifndef _TCHAR_DEFINED
#define _TCHAR_DEFINED
typedef char TCHAR;
#endif
// program
#define _tmain main
#define _tWinMain WinMain
#define _tenviron environ
#define __targv __argv

View file

@ -656,11 +656,11 @@ LRESULT WINAPI WMCommandProc(HWND hWnd, UINT id, HWND hwndCtl, UINT codeNotify)
LPSHELLFOLDER sf;
ULONG eaten;
LPITEMIDLIST root;
int ccRoot = (lstrlen(pField->pszRoot) * 2) + 2;
SHGetDesktopFolder(&sf);
#ifdef _UNICODE
sf->ParseDisplayName(hConfigWindow, NULL, pField->pszRoot, &eaten, &root, NULL);
#else
int ccRoot = (lstrlen(pField->pszRoot) * 2) + 2;
LPWSTR pwszRoot = (LPWSTR) MALLOC(ccRoot);
MultiByteToWideChar(CP_ACP, 0, pField->pszRoot, -1, pwszRoot, ccRoot);
sf->ParseDisplayName(hConfigWindow, NULL, pwszRoot, &eaten, &root, NULL);
@ -1592,9 +1592,9 @@ extern "C" void __declspec(dllexport) show(HWND hwndParent, int string_size,
showCfgDlg();
}
extern "C" BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
extern "C" BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
m_hInstance=(HINSTANCE) hInst;
m_hInstance=hInst;
return TRUE;
}

View file

@ -237,7 +237,7 @@ void __declspec(dllexport) LangDialog(HWND hwndParent, int string_size,
}
}
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_hInstance=hInst;
return TRUE;

View file

@ -80,6 +80,7 @@ int GetTLBVersion(tstring& filepath, DWORD& high, DWORD & low)
#endif
}
NSIS_ENTRYPOINT_TMAIN
int _tmain(int argc, TCHAR* argv[])
{

View file

@ -1,5 +1,6 @@
// Unicode support by Jim Park & Olivier Marcoux
#include "../../../Source/Platform.h"
#include <windows.h>
#include <tchar.h>
@ -15,7 +16,8 @@ void RegDll(TCHAR *file);
void RegTypeLib(TCHAR *file);
void DeleteFileOnReboot(TCHAR *pszFile);
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
NSIS_ENTRYPOINT_GUINOCRT
EXTERN_C void NSISWinMainNOCRT()
{
TCHAR *cmdline;
TCHAR seekchar = _T(' ');
@ -33,7 +35,6 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
if (*cmdline++ != _T('/'))
{
ExitProcess(1);
return 0;
}
if (*cmdline == _T('S'))
@ -113,7 +114,6 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdL
}
ExitProcess(0);
return 0;
}
void SafeWow64EnableWow64FsRedirection(BOOL Wow64FsEnableRedirection)

View file

@ -13,6 +13,5 @@ libs = Split("""
""")
Import('BuildUtil')
Import('_tWinMain')
BuildUtil(target, files, libs, entry = _tWinMain, nodeflib = True, file_name = 'RegTool.bin')
BuildUtil(target, files, libs, entry = 'NSISWinMainNOCRT', nodeflib = True, file_name = 'RegTool.bin')

View file

@ -13,7 +13,7 @@
#define NSISFunction(funcname) extern "C" void __declspec(dllexport) funcname(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop)
extern "C" BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
extern "C" BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
return TRUE;
}

View file

@ -1,8 +1,7 @@
// Unicode support by Jim Park -- 08/23/2007
#include <windows.h>
#include "../../Source/Platform.h"
#include <commctrl.h>
#include "../ExDLL/nsis_tchar.h"
#include "resource.h"
#define CBL(x) {x,_T(#x)}
@ -231,10 +230,8 @@ BOOL CALLBACK DialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) {
return 0;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
NSIS_ENTRYPOINT_GUINOCRT
EXTERN_C void NSISWinMainNOCRT()
{
InitCommonControls();
@ -246,6 +243,5 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
);
ExitProcess(0);
return 0;
}

View file

@ -19,7 +19,6 @@ libs = Split("""
""")
Import('BuildUtil')
Import('_tWinMain')
BuildUtil(target, files, libs, res = res, resources = resources, entry = _tWinMain)
BuildUtil(target, files, libs, res = res, resources = resources, entry = 'NSISWinMainNOCRT')

View file

@ -45,7 +45,6 @@ docs = Split("""
""")
Import('BuildUtil')
Import('_tWinMain')
BuildUtil(
target,
@ -53,7 +52,7 @@ BuildUtil(
libs,
res = res,
resources = resources,
entry = _tWinMain,
entry = None,
defines = ['RELEASE=2.3'],
docs = docs,
root_util = True

View file

@ -42,7 +42,8 @@ NFINDREPLACE g_find;
extern NTOOLBAR g_toolbar;
int g_symbol_set_mode;
int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, TCHAR *cmdParam, int cmdShow) {
NSIS_ENTRYPOINT_SIMPLEGUI
int WINAPI _tWinMain(HINSTANCE hInst,HINSTANCE hOldInst,LPTSTR CmdLineParams,int ShowCmd) {
MSG msg;
int status;
HACCEL haccel;
@ -50,7 +51,7 @@ int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, TCHAR *cmdParam, int
memset(&g_sdata,0,sizeof(NSCRIPTDATA));
memset(&g_resize,0,sizeof(NRESIZEDATA));
memset(&g_find,0,sizeof(NFINDREPLACE));
g_sdata.hInstance=GetModuleHandle(0);
g_sdata.hInstance=hInst;
g_sdata.symbols = NULL;
g_sdata.sigint_event = CreateEvent(NULL, FALSE, FALSE, _T("makensis win32 signint event"));
RestoreSymbols();
@ -84,7 +85,6 @@ int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, TCHAR *cmdParam, int
if (g_sdata.sigint_event) CloseHandle(g_sdata.sigint_event);
FreeLibrary(hRichEditDLL);
FinalizeUpdate();
ExitProcess(msg.wParam);
return msg.wParam;
}

View file

@ -24,9 +24,9 @@
#define MAKENSIS_H
#define _WIN32_IE 0x0400
#include "../../Source/Platform.h"
#include <windows.h>
#include <commctrl.h>
#include "../ExDLL/nsis_tchar.h"
#include "utils.h"
#define _RICHEDIT_VER 0x0200
#include <richedit.h>
@ -38,7 +38,7 @@
#define NSIS_UPDATE "http://nsis.sourceforge.net/update.php?version="
#define NSIS_DL_URL "http://nsis.sourceforge.net/download/"
#define USAGE _T("Usage:\r\n\r\n - File | Load Script...\r\n - Drag the .nsi file into this window\r\n - Right click the .nsi file and choose \"Compile NSIS Script\"")
#define COPYRIGHT _T("Copyright © 2002 Robert Rainwater")
#define COPYRIGHT _T("Copyright (C) 2002 Robert Rainwater")
#define CONTRIB _T("Fritz Elfert, Justin Frankel, Amir Szekely, Sunil Kamath, Joost Verburg")
#define DOCPATH "http://nsis.sourceforge.net/Docs/"
#define LOCALDOCS _T("\\NSIS.chm")
@ -144,7 +144,6 @@ int compressor_strings[] = {IDS_SCRIPT,
extern const TCHAR* NSISW_VERSION;
int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hPrevInst, TCHAR *cmdParam, int cmdShow);
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
DWORD WINAPI MakeNSISProc(LPVOID p);
BOOL CALLBACK DialogResize(HWND hWnd, LPARAM /* unused*/);

View file

@ -22,11 +22,11 @@
Unicode support by Jim Park -- 08/17/2007
*/
#include "makensisw.h"
#define REALSTR(x) #x
#define STR(x) REALSTR(x)
#define TSTRINGIFY_(x) _T(#x)
#define TSTRINGIFY(x) TSTRINGIFY_(x)
#ifdef RELEASE
const TCHAR *NSISW_VERSION = _T("MakeNSISW ") _T(STR(RELEASE)) _T(" (NSIS Compiler Interface)");
const TCHAR *NSISW_VERSION = _T("MakeNSISW ") TSTRINGIFY(RELEASE) _T(" (NSIS Compiler Interface)");
#else
const TCHAR *NSISW_VERSION = _T("MakeNSISW ") __TDATE__;
#endif

View file

@ -49,10 +49,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_hInstance=hInst;
return TRUE;
return TRUE;
}
void __declspec(dllexport) show(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop)

View file

@ -427,10 +427,10 @@ BOOL CALLBACK dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
return 0;
}
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_hInstance=hInst;
return TRUE;
return TRUE;
}
void AddFolderFromReg(int nFolder)

View file

@ -1,6 +1,6 @@
#include <windows.h>
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
return TRUE;
}

View file

@ -1229,11 +1229,11 @@ failure is raised if _osplatform is not set. The assertion is reported by
the same means as used for the _RPT0 macro. This leads to an endless recursion.
*/
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpReserved)
{
g_hInstance=(HINSTANCE)hInst;
g_hInstance=hInst;
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
if (DLL_PROCESS_ATTACH == fdwReason)
{
// change the protection of return command
VirtualProtect(&retexpr, sizeof(retexpr), PAGE_EXECUTE_READWRITE, (PDWORD)&LastStackPlace);

View file

@ -18,10 +18,9 @@ libs = Split("""
""")
Import('BuildUtil env')
Import('_tWinMain')
code = env.Object(code)
for ui in uis:
ui = BuildUtil(ui, [code], libs, entry = _tWinMain, res = ui + '.rc', contrib = True, path = 'UIs')
ui = BuildUtil(ui, [code], libs, res = ui + '.rc', contrib = True, path = 'UIs')
env.Alias('UIs', ui)

View file

@ -2,15 +2,15 @@
//
// Unicode support by Jim Park -- 08/10/2007
#include "../../Source/Platform.h"
#include <windows.h>
#include <commctrl.h>
#include "../ExDLL/nsis_tchar.h"
#include "resource.h"
HINSTANCE g_hInstance;
HWND m_curwnd;
TCHAR* windows[] = {
const TCHAR* windows[] = {
MAKEINTRESOURCE(IDD_LICENSE),
MAKEINTRESOURCE(IDD_SELCOM),
MAKEINTRESOURCE(IDD_DIR),
@ -76,29 +76,16 @@ BOOL CALLBACK DialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) {
break;
}
break;
}
return 0;
}
return 0;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
NSIS_ENTRYPOINT_SIMPLEGUI
int WINAPI _tWinMain(HINSTANCE hInst,HINSTANCE hOldInst,LPTSTR CmdLineParams,int ShowCmd)
{
InitCommonControls();
g_hInstance = hInst;
LoadLibrary(_T("RichEd32.dll"));
g_hInstance = GetModuleHandle(0);
DialogBox(
GetModuleHandle(0),
MAKEINTRESOURCE(IDD_INST),
0,
DialogProc
);
ExitProcess(0);
return 0;
return DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_INST),0,DialogProc);
}

View file

@ -148,7 +148,7 @@ void __declspec(dllexport) GetOriginalAccountType(HWND hwndParent, int string_si
pushstring(GetAccountTypeHelper(FALSE));
}
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
return TRUE;
}

View file

@ -56,6 +56,10 @@ inline bool ISSINGLESWITCHCHAR(const TCHAR c) { return ( OPT_CHAR==(c) || (OPT_C
#include <fstream>
#include <sstream>
#ifdef _WIN32
#include "../../../../Source/Platform.h"
NSIS_ENTRYPOINT_TMAIN
#endif
int _tmain( int argc, TCHAR * argv[] ) {
tout << _T("GenPat v3.1\n");
tout << _T("===========\n\n(c) 2001-2005 Van de Sande Productions\n");

View file

@ -174,7 +174,7 @@ void __declspec(dllexport) GetFileMD5(HWND hwndParent, int string_size,
}
#endif
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
g_hInstance=hInst;
return TRUE;
}

View file

@ -593,8 +593,8 @@ void __declspec(dllexport) Show(HWND hwndParent, int string_size, TCHAR *variabl
SetWindowLongPtr(hwndParent, DWLP_DLGPROC, (LONG_PTR) g_dialog.parentOriginalWndproc);
}
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
g_hInstance = (HINSTANCE) hInst;
g_hInstance = hInst;
return TRUE;
}

View file

@ -40,7 +40,7 @@ void ExecScript(BOOL log);
void LogMessage(const TCHAR *pStr, BOOL bOEM);
TCHAR *my_strstr(TCHAR *a, TCHAR *b);
unsigned int my_atoi(TCHAR *s);
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow);
int WINAPI AsExeWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow);
void __declspec(dllexport) Exec(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop) {
g_hwndParent=hwndParent;
@ -67,7 +67,7 @@ void __declspec(dllexport) ExecToStack(HWND hwndParent, int string_size, TCHAR *
}
HINSTANCE g_hInst;
BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) {
g_hInst = hInst;
return TRUE;
}
@ -176,7 +176,7 @@ void ExecScript(int log) {
// WinMain will have the address of the WinMain function in memory.
// Getting the difference gets you the relative location of the
// WinMain function.
pNTHeaders->OptionalHeader.AddressOfEntryPoint = (DWORD)_tWinMain - (DWORD)g_hInst;
pNTHeaders->OptionalHeader.AddressOfEntryPoint = (DWORD_PTR)AsExeWinMain - (DWORD_PTR)g_hInst;
UnmapViewOfFile(pMapView);
}
CloseHandle(hMapping);
@ -476,12 +476,12 @@ unsigned int my_atoi(TCHAR *s) {
return (int)v;
}
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
int WINAPI AsExeWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
DWORD Ret;
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
TCHAR command_line[1024];
TCHAR command_line[1024]; //BUGBUG
TCHAR seekchar=_T(' ');
TCHAR *cmdline;

View file

@ -1,3 +1,5 @@
#include "../../Source/Platform.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
@ -66,13 +68,12 @@ const TCHAR *g_options=_T("");//_T("/V3");
static BOOL CALLBACK DlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,
LPTSTR lpszCmdParam, int nCmdShow)
NSIS_ENTRYPOINT_SIMPLEGUI
int WINAPI _tWinMain(HINSTANCE hInst,HINSTANCE hOldInst,LPTSTR CmdLineParams,int ShowCmd)
{
g_hInstance=hInstance;
InitCommonControls();
return DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),GetDesktopWindow(),DlgProc);
g_hInstance=hInst;
return DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_DIALOG1),0,DlgProc);
}
TCHAR tempzip_path[1024];

View file

@ -27,9 +27,9 @@ Adds another include directory to the include directories list. This list is sea
\S1{addplugindir} !addplugindir
\c directory
\c [/x86-ansi | /x86-unicode] directory
Causes the NSIS compiler to scan the given directory for plug-in DLLs.
Causes the NSIS compiler to scan the given directory for plug-in DLLs. If you don't specify the plug-in architecture it is assumed to match the current target architecture. If the architecture does not match the installer will probably crash!
\c !addplugindir myplugin
\c MyPlugin::SomeFunction

View file

@ -87,22 +87,11 @@ This command sets the overwrite flag which is used by the \R{file}{File} command
\c File program.cfg # config file we don't want to overwrite
\c SetOverwrite on
\S2{atargetminimalos} TargetMinimalOS
\S2{aunicodetarget} Unicode
\c X.Y
\c true|\\<b\\>false\\</b\\>
This command sets the minimal OS version of the target Windows system required in order to run the installer. This will NOT make the installer test for OS compatibility, but it will indicate which Windows APIs will be available for use by the installer program. The installer will not be able to execute on older systems.
In particular, if you indicate a minimal OS of 5.0 or more, MakeNSIS will generate a \R{intro-unicode}{Unicode installer} (as Windows 2000 and more recent are Unicode fully-compatible OSes).
\c TargetMinimalOS 4.0 ; target Windows 9x/NT4 or more recent (Default)
\c TargetMinimalOS 5.0 ; target Windows 2000 or more recent / make a Unicode installer
\c TargetMinimalOS 5.1 ; target Windows XP or more recent / make a Unicode installer
\c TargetMinimalOS 6.0 ; target Windows Vista or more recent / make a Unicode installer
\c TargetMinimalOS 6.1 ; target Windows Seven or more recent / make a Unicode installer
Check the various \W{http://msdn.microsoft.com/en-us/library/ms724833.aspx}{version numbers of Windows}.
Generate a \R{intro-unicode}{Unicode installer}. It can only be used outside of sections and functions and before any data is compressed.
\S1{versioninfo} Version Information

View file

@ -152,8 +152,8 @@ The NSIS script format and the format used for interface dialogs are easy, docum
\H{intro-unicode} Unicode installers
Starting with MakeNSIS v?.??, you can choose to create Unicode installers by using \R{atargetminimalos}{TargetMinimalOS} with a value greater than or equal to 5.0.
These installers will work only under Windows 2000 or more recent (depending on the value you chose), but they will allow you to display your installer in any Unicode language supported by the OS.
Starting with MakeNSIS v3.0 you can choose to create Unicode installers by setting the \R{aunicodetarget}{Unicode} attribute.
These installers will not work on Windows 95/98/ME but they will allow you to display your installer in any Unicode language supported by the OS.
When building a Unicode installer, NSIS variables can hold Unicode characters (0000-FFFF). There should be no need to modify your existing scripts.
If you want to read/write Unicode files, specific instructions have been added to read/write UTF-16LE strings from/to disk.

View file

@ -7,7 +7,7 @@ The NSIS development kit installer sets up your computer so that you can compile
If you want to use MakeNSIS on the command line, the syntax of the makensis command is:
\c makensis [option | script.nsi | - [...]]
\c makensis [ option | script.nsi | - ] [...]
\S1{usagereference} Options

View file

@ -1,6 +1,11 @@
;NSIS Setup Script
;--------------------------------
!ifdef VER_MAJOR & VER_MINOR
!define /ifndef VER_REVISION 0
!define /ifndef VER_BUILD 0
!endif
!ifndef VERSION
!define VERSION 'anonymous-build'
!endif
@ -14,6 +19,7 @@
OutFile ..\nsis-${VERSION}-setup.exe
!endif
Unicode true
SetCompressor /SOLID lzma
InstType "Full"
@ -34,15 +40,6 @@ RequestExecutionLevel admin
!include "Memento.nsh"
!include "WordFunc.nsh"
;--------------------------------
;Functions
!ifdef VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD
!insertmacro VersionCompare
!endif
;--------------------------------
;Definitions
@ -101,9 +98,23 @@ Page custom PageReinstall PageLeaveReinstall
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Version information
!ifdef VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD
VIProductVersion ${VER_MAJOR}.${VER_MINOR}.${VER_REVISION}.${VER_BUILD}
VIAddVersionKey "FileVersion" "${VERSION}"
VIAddVersionKey "FileDescription" "NSIS Setup"
!endif
;--------------------------------
;Installer Sections
!macro InstallPlugin pi
File "/oname=$InstDir\Plugins\x86-ansi\${pi}.dll" ..\Plugins\x86-ansi\${pi}.dll
File "/oname=$InstDir\Plugins\x86-unicode\${pi}.dll" ..\Plugins\x86-unicode\${pi}.dll
!macroend
${MementoSection} "NSIS Core Files (required)" SecCore
SetDetailsPrint textonly
@ -136,13 +147,18 @@ ${MementoSection} "NSIS Core Files (required)" SecCore
!endif
SetOutPath $INSTDIR\Stubs
File ..\Stubs\bzip2
File ..\Stubs\bzip2_solid
File ..\Stubs\lzma
File ..\Stubs\lzma_solid
File ..\Stubs\zlib
File ..\Stubs\zlib_solid
File ..\Stubs\uninst
!macro InstallStub stub
File ..\Stubs\${stub}-x86-ansi
File ..\Stubs\${stub}-x86-unicode
!macroend
!insertmacro InstallStub bzip2
!insertmacro InstallStub bzip2_solid
!insertmacro InstallStub lzma
!insertmacro InstallStub lzma_solid
!insertmacro InstallStub zlib
!insertmacro InstallStub zlib_solid
SetOutPath $INSTDIR\Include
File ..\Include\WinMessages.nsh
@ -198,8 +214,9 @@ ${MementoSection} "NSIS Core Files (required)" SecCore
File ..\Bin\LibraryLocal.exe
File ..\Bin\RegTool.bin
SetOutPath $INSTDIR\Plugins
File ..\Plugins\TypeLib.dll
CreateDirectory $INSTDIR\Plugins\x86-ansi
CreateDirectory $INSTDIR\Plugins\x86-unicode
!insertmacro InstallPlugin TypeLib
ReadRegStr $R0 HKCR ".nsi" ""
StrCmp $R0 "NSISFile" 0 +2
@ -284,7 +301,7 @@ ${MementoSection} "Script Examples" SecExample
SetOutPath $INSTDIR\Examples\Plugin\nsis
File ..\Examples\Plugin\nsis\pluginapi.h
File /nonfatal ..\Examples\Plugin\nsis\pluginapi.lib
File /nonfatal ..\Examples\Plugin\nsis\pluginapi*.lib
File ..\Examples\Plugin\nsis\api.h
File ..\Examples\Plugin\nsis\nsis_tchar.h
@ -488,8 +505,7 @@ ${MementoSection} "Banner" SecPluginsBanner
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\Banner.dll
!insertmacro InstallPlugin Banner
SetOutPath $INSTDIR\Docs\Banner
File ..\Docs\Banner\Readme.txt
SetOutPath $INSTDIR\Examples\Banner
@ -503,8 +519,7 @@ ${MementoSection} "Language DLL" SecPluginsLangDLL
SetDetailsPrint listonly
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\LangDLL.dll
!insertmacro InstallPlugin LangDLL
${MementoSectionEnd}
${MementoSection} "nsExec" SecPluginsnsExec
@ -515,8 +530,7 @@ ${MementoSection} "nsExec" SecPluginsnsExec
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\nsExec.dll
!insertmacro InstallPlugin nsExec
SetOutPath $INSTDIR\Docs\nsExec
File ..\Docs\nsExec\nsExec.txt
SetOutPath $INSTDIR\Examples\nsExec
@ -531,8 +545,7 @@ ${MementoSection} "Splash" SecPluginsSplash
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\splash.dll
!insertmacro InstallPlugin splash
SetOutPath $INSTDIR\Docs\Splash
File ..\Docs\Splash\splash.txt
SetOutPath $INSTDIR\Examples\Splash
@ -547,8 +560,7 @@ ${MementoSection} "AdvSplash" SecPluginsSplashT
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\advsplash.dll
!insertmacro InstallPlugin advsplash
SetOutPath $INSTDIR\Docs\AdvSplash
File ..\Docs\AdvSplash\advsplash.txt
SetOutPath $INSTDIR\Examples\AdvSplash
@ -563,8 +575,7 @@ ${MementoSection} "BgImage" SecPluginsBgImage
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\BgImage.dll
!insertmacro InstallPlugin BgImage
SetOutPath $INSTDIR\Docs\BgImage
File ..\Docs\BgImage\BgImage.txt
SetOutPath $INSTDIR\Examples\BgImage
@ -579,8 +590,7 @@ ${MementoSection} "InstallOptions" SecPluginsIO
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\InstallOptions.dll
!insertmacro InstallPlugin InstallOptions
SetOutPath $INSTDIR\Docs\InstallOptions
File ..\Docs\InstallOptions\Readme.html
File ..\Docs\InstallOptions\Changelog.txt
@ -603,8 +613,7 @@ ${MementoSection} "nsDialogs" SecPluginsDialogs
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\nsDialogs.dll
!insertmacro InstallPlugin nsDialogs
SetOutPath $INSTDIR\Examples\nsDialogs
File ..\Examples\nsDialogs\example.nsi
File ..\Examples\nsDialogs\InstallOptions.nsi
@ -624,8 +633,7 @@ ${MementoSection} "Math" SecPluginsMath
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\Math.dll
!insertmacro InstallPlugin Math
SetOutPath $INSTDIR\Docs\Math
File ..\Docs\Math\Math.txt
SetOutPath $INSTDIR\Examples\Math
@ -644,8 +652,7 @@ ${MementoSection} "NSISdl" SecPluginsNSISDL
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\nsisdl.dll
!insertmacro InstallPlugin nsisdl
SetOutPath $INSTDIR\Docs\NSISdl
File ..\Docs\NSISdl\ReadMe.txt
File ..\Docs\NSISdl\License.txt
@ -659,8 +666,7 @@ ${MementoSection} "System" SecPluginsSystem
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\System.dll
!insertmacro InstallPlugin System
SetOutPath $INSTDIR\Docs\System
File ..\Docs\System\System.html
File ..\Docs\System\WhatsNew.txt
@ -679,8 +685,7 @@ ${MementoSection} "StartMenu" SecPluginsStartMenu
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\StartMenu.dll
!insertmacro InstallPlugin StartMenu
SetOutPath $INSTDIR\Docs\StartMenu
File ..\Docs\StartMenu\Readme.txt
SetOutPath $INSTDIR\Examples\StartMenu
@ -695,8 +700,7 @@ ${MementoSection} "UserInfo" SecPluginsUserInfo
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\UserInfo.dll
!insertmacro InstallPlugin UserInfo
SetOutPath $INSTDIR\Examples\UserInfo
File ..\Examples\UserInfo\UserInfo.nsi
${MementoSectionEnd}
@ -709,8 +713,7 @@ ${MementoSection} "Dialer" SecPluginsDialer
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\Dialer.dll
!insertmacro InstallPlugin Dialer
SetOutPath $INSTDIR\Docs\Dialer
File ..\Docs\Dialer\Dialer.txt
${MementoSectionEnd}
@ -723,8 +726,7 @@ ${MementoSection} "VPatch" SecPluginsVPatch
SectionIn 1
SetOutPath $INSTDIR\Plugins
File ..\Plugins\VPatch.dll
!insertmacro InstallPlugin VPatch
SetOutPath $INSTDIR\Examples\VPatch
File ..\Examples\VPatch\example.nsi
File ..\Examples\VPatch\oldfile.txt
@ -807,7 +809,7 @@ Section -post
WriteRegStr HKLM "${MEMENTO_REGISTRY_KEY}" "DisplayVersion" "${VERSION}"
!ifdef VER_MAJOR & VER_MINOR & VER_REVISION & VER_BUILD
WriteRegDWORD HKLM "${MEMENTO_REGISTRY_KEY}" "VersionMajor" "${VER_MAJOR}"
WriteRegDWORD HKLM "${MEMENTO_REGISTRY_KEY}" "VersionMinor" "${VER_MINOR}.${VER_REVISION}"
WriteRegDWORD HKLM "${MEMENTO_REGISTRY_KEY}" "VersionMinor" "${VER_MINOR}"
!endif
WriteRegStr HKLM "${MEMENTO_REGISTRY_KEY}" "URLInfoAbout" "http://nsis.sourceforge.net/"
WriteRegStr HKLM "${MEMENTO_REGISTRY_KEY}" "HelpLink" "http://nsis.sourceforge.net/Support"
@ -871,15 +873,15 @@ Var ReinstallPageCheck
Function PageReinstall
ReadRegStr $R0 HKLM "Software\NSIS" ""
ReadRegStr $R1 HKLM "${MEMENTO_REGISTRY_KEY}" "UninstallString"
${IfThen} "$R0$R1" == "" ${|} Abort ${|}
${If} $R0 == ""
Abort
${EndIf}
StrCpy $R4 "older"
ReadRegDWORD $R0 HKLM "Software\NSIS" "VersionMajor"
ReadRegDWORD $R1 HKLM "Software\NSIS" "VersionMinor"
ReadRegDWORD $R2 HKLM "Software\NSIS" "VersionRevision"
ReadRegDWORD $R3 HKLM "Software\NSIS" "VersionBuild"
${IfThen} $R0 = 0 ${|} StrCpy $R4 "unknown" ${|} ; Anonymous builds have no version number
StrCpy $R0 $R0.$R1.$R2.$R3
${VersionCompare} ${VER_MAJOR}.${VER_MINOR}.${VER_REVISION}.${VER_BUILD} $R0 $R0
@ -890,7 +892,7 @@ Function PageReinstall
!insertmacro MUI_HEADER_TEXT "Already Installed" "Choose the maintenance option to perform."
StrCpy $R0 "2"
${ElseIf} $R0 == 1
StrCpy $R1 "An older version of NSIS is installed on your system. It's recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue."
StrCpy $R1 "An $R4 version of NSIS is installed on your system. It's recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue."
StrCpy $R2 "Uninstall before installing"
StrCpy $R3 "Do not uninstall"
!insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install NSIS."
@ -952,31 +954,36 @@ Function PageLeaveReinstall
StrCmp $R0 "1" 0 +2
StrCmp $R1 "1" reinst_uninstall reinst_done
StrCmp $R0 "2" 0 +3
StrCmp $R0 "2" 0 reinst_done
StrCmp $R1 "1" reinst_done reinst_uninstall
reinst_uninstall:
ReadRegStr $R1 HKLM "${MEMENTO_REGISTRY_KEY}" "UninstallString"
;Run uninstaller
HideWindow
HideWindow
ClearErrors
ExecWait '$R1 _?=$INSTDIR'
BringToFront
IfErrors no_remove_uninstaller
IfFileExists "$INSTDIR\Bin\makensis.exe" no_remove_uninstaller
Delete $R1
RMDir $INSTDIR
StrCpy $R1 ""
no_remove_uninstaller:
StrCmp "" $R1 0 +3
MessageBox MB_ICONEXCLAMATION "Unable to uninstall!"
Abort
StrCmp $R0 "2" 0 +2
Quit
BringToFront
reinst_done:
FunctionEnd

View file

@ -4,7 +4,7 @@ Import('defenv')
### flags
defenv['ENTRY_FLAG'] = lambda x: ''
defenv['ENTRY_FLAG'] = lambda x,u: ''
defenv['MAP_FLAG'] = ''
defenv['EXCEPTION_FLAG'] = ''
defenv['NODEFLIBS_FLAG'] = ''
@ -12,6 +12,7 @@ defenv['C_FLAG'] = ''
defenv['CPP_FLAG'] = ''
defenv['CPP_REQUIRES_STDLIB'] = 0
defenv['SUBSYS_CON'] = ''
defenv['SUBSYS_WIN'] = ''
defenv['MSVCRT_FLAG'] = ''
defenv['STDCALL'] = ''
@ -19,15 +20,23 @@ defenv['STDCALL'] = ''
defenv.Append(CPPDEFINES = [('NSISCALL', '$STDCALL')])
### unicode
tdefenv = defenv.Clone()
if tdefenv['UNICODE']:
tdefenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
### stub environment
stub_env = defenv.Clone()
stub_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
stub_uenv = stub_env.Clone()
stub_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
### makensis environment
makensis_env = defenv.Clone()
makensis_env = tdefenv.Clone()
makensis_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
@ -35,13 +44,16 @@ makensis_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
plugin_env = defenv.Clone(no_import_lib = 1)
plugin_uenv = plugin_env.Clone()
plugin_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
### util environment
util_env = defenv.Clone()
util_env = tdefenv.Clone()
### cross-platform util environment
cp_util_env = util_env.Clone()
cp_util_env = tdefenv.Clone()
cp_util_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
@ -53,4 +65,4 @@ test_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
# return
Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_env plugin_env')
Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_uenv plugin_uenv')

View file

@ -14,9 +14,9 @@ def cross_env(env):
### flags
def entry(x):
if x == 'WinMain':
x = '_WinMain@16'
def entry(x,u):
if x == 'NSISWinMainNOCRT':
x = '_' + x
elif x == 'DllMain':
x = '_DllMain@12'
return '-Wl,-e%s' % x
@ -30,6 +30,7 @@ defenv['CPP_FLAG'] = '-xc++'
defenv['ALIGN_FLAG'] = '-Wl,--file-alignment,512'
defenv['CPP_REQUIRES_STDLIB'] = 1
defenv['SUBSYS_CON'] = '-Wl,--subsystem,console'
defenv['SUBSYS_WIN'] = '-Wl,--subsystem,windows'
defenv['MSVCRT_FLAG'] = ''
defenv['STDCALL'] = '"__attribute__((__stdcall__))"'
@ -66,6 +67,11 @@ def TestStrip(ctx):
if defenv['DEBUG']:
defenv.Append(CCFLAGS = '-g')
### unicode
tdefenv = defenv.Clone()
if tdefenv['UNICODE']:
tdefenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
### stub environment
stub_env = defenv.Clone()
@ -84,12 +90,14 @@ if not defenv['DEBUG'] and defenv['STRIP'] and defenv['STRIP_W32']:
stub_env.Append(LINKFLAGS = ['-mwindows']) # build windows executables
stub_env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG']) # no standard libraries
stub_env.Append(LINKFLAGS = ['$ALIGN_FLAG']) # 512 bytes align
stub_env.Append(LINKFLAGS = ['-Wl,-e,_WinMain@16']) # entry point
stub_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
stub_uenv = stub_env.Clone()
stub_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
### makensis environment
makensis_env = defenv.Clone()
makensis_env = tdefenv.Clone()
makensis_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
@ -122,12 +130,18 @@ plugin_env.Append(LINKFLAGS = ['$ALIGN_FLAG']) # 512 bytes align
plugin_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
plugin_env.Append(LINKFLAGS = ['-static-libgcc']) # remove libgcc*.dll dependency
plugin_uenv = plugin_env.Clone()
plugin_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
### cross-platform util environment
cp_util_env = defenv.Clone()
cp_util_env = tdefenv.Clone()
cp_util_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
if cp_util_env['PLATFORM'] == 'win32':
cp_util_env.Append(LINKFLAGS = ['$ALIGN_FLAG'])
if not defenv['DEBUG']:
cp_util_env.Append(CCFLAGS = ['-O2']) # optimize
cp_util_env.Append(CCFLAGS = ['-Wall']) # all warnings
@ -145,6 +159,7 @@ cross_env(util_env)
util_env.Append(LINKFLAGS = ['-mwindows']) # build windows executables
util_env.Append(LINKFLAGS = ['$ALIGN_FLAG']) # 512 bytes align
conf = FlagsConfigure(util_env)
if not defenv['DEBUG'] and defenv['STRIP'] and defenv['STRIP_W32']:
util_env.Append(LINKFLAGS = ['-s']) # strip
@ -177,6 +192,8 @@ conf.Finish()
#
stub_env.Append(LINKFLAGS = ['-T', File('linker_script').rfile()])
stub_uenv.Append(LINKFLAGS = ['-T', File('linker_script').rfile()])
#
# GCC requires some functions from the CRT to be present, if certain
@ -314,4 +331,4 @@ if makensis_env['PLATFORM'] == 'hpux':
### return
Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_env plugin_env')
Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_uenv plugin_uenv')

View file

@ -4,7 +4,7 @@ Import('defenv')
### flags
defenv['ENTRY_FLAG'] = lambda x: ''
defenv['ENTRY_FLAG'] = lambda x,u: ''
defenv['MAP_FLAG'] = ''
defenv['EXCEPTION_FLAG'] = ''
defenv['NODEFLIBS_FLAG'] = ''
@ -12,6 +12,7 @@ defenv['C_FLAG'] = ''
defenv['CPP_FLAG'] = ''
defenv['CPP_REQUIRES_STDLIB'] = 0
defenv['SUBSYS_CON'] = ''
defenv['SUBSYS_WIN'] = ''
defenv['MSVCRT_FLAG'] = ''
defenv['STDCALL'] = ''
@ -19,15 +20,22 @@ defenv['STDCALL'] = ''
defenv.Append(CPPDEFINES = [('NSISCALL', '$STDCALL')])
### unicode
tdefenv = defenv.Clone()
if tdefenv['UNICODE']:
tdefenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
### stub environment
stub_env = defenv.Clone()
stub_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
stub_uenv = stub_env.Clone()
stub_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
### makensis environment
makensis_env = defenv.Clone()
makensis_env = tdefenv.Clone()
makensis_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
@ -107,13 +115,16 @@ makensis_conf.Finish()
plugin_env = defenv.Clone(no_import_lib = 1)
plugin_uenv = plugin_env.Clone()
plugin_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
### util environment
util_env = defenv.Clone()
util_env = tdefenv.Clone()
### cross-platform util environment
cp_util_env = util_env.Clone()
cp_util_env = tdefenv.Clone()
cp_util_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
@ -125,4 +136,4 @@ test_env.Append(CPPPATH = ['#$BUILD_CONFIG'])
# return
Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_env plugin_env')
Return('stub_env makensis_env plugin_env util_env cp_util_env test_env stub_uenv plugin_uenv')

View file

@ -10,13 +10,19 @@ if SCons.__version__ == '1.3.0':
# force inclusion of Platform SDK, sometimes ignored by SCons 1.3.0 due to environment contamination
defenv.Tool('mssdk')
defenv['ENTRY_FLAG'] = lambda x: '/entry:' + x
def entry(x,u):
if x == 'WinMain' and u:
x = 'w' + x
return '/entry:' + x
defenv['ENTRY_FLAG'] = entry
defenv['MAP_FLAG'] = '/map'
defenv['NODEFLIBS_FLAG'] = '/NODEFAULTLIB'
defenv['C_FLAG'] = '/TC'
defenv['CPP_FLAG'] = '/TP'
defenv['CPP_REQUIRES_STDLIB'] = 0
defenv['SUBSYS_CON'] = '/subsystem:console'
defenv['SUBSYS_WIN'] = '/subsystem:windows'
defenv['MSVCRT_FLAG'] = '/MD'
defenv['STDCALL'] = '__stdcall'
@ -112,9 +118,7 @@ stub_env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG']) # no default libraries
stub_env.Append(LINKFLAGS = ['$MAP_FLAG']) # generate map file
stub_uenv = stub_env.Clone()
stub_uenv.Append(LINKFLAGS = ['/entry:wWinMain']) # Unicode entry point
stub_uenv.Append(CPPDEFINES = ['_UNICODE', 'UNICODE'])
stub_env.Append(LINKFLAGS = ['/entry:WinMain']) # ANSI entry point
### makensis environment
@ -228,28 +232,19 @@ def add_file(file):
conf = stub_env.Configure()
if defenv['UNICODE']:
int64test = """
#include <windows.h>
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPTSTR lpszCmdParam, int nCmdShow) {
ULARGE_INTEGER *i = 0;
return (int)(i->QuadPart >> 10);
}
"""
else:
int64test = """
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, int nCmdShow) {
ULARGE_INTEGER *i = 0;
return (int)(i->QuadPart >> 10);
}
"""
int64test = """
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam, int nCmdShow) {
ULARGE_INTEGER *i = 0;
return (int)(i->QuadPart >> 10);
}
"""
if not conf.TryLink(int64test, '.c'):
stub_env.Append(CPPDEFINES = ['_NSIS_NO_INT64_SHR'])
stub_uenv.Append(CPPDEFINES = ['_NSIS_NO_INT64_SHR'])
conf.Finish()
conf.Finish()
#
# MSVC 2005 requires the memset CRT function to be present
@ -260,7 +255,7 @@ conf = defenv.Configure(custom_tests = { 'CheckRequirement' : check_requirement
if conf.CheckRequirement('memset', 'char c[128] = "test";'):
add_file('memset.c')
conf.Finish()
conf.Finish()
### return

View file

@ -204,13 +204,11 @@ if 'NSIS_CONFIG_CONST_DATA_PATH' in defenv['NSIS_CPPDEFINES']:
# Need this early for the config header files to be placed in
if defenv['UNICODE']:
_tWinMain = 'wWinMain'
if defenv['DEBUG']:
defenv.Replace(BUILD_PREFIX = 'build/udebug')
else:
defenv.Replace(BUILD_PREFIX = 'build/urelease')
else:
_tWinMain = 'WinMain'
if defenv['DEBUG']:
defenv.Replace(BUILD_PREFIX = 'build/debug')
else:
@ -278,6 +276,50 @@ f.write('#define NSIS_VERSION _T("v%s")\n' % defenv['VERSION'])
f.close()
######################################################################
####### Common Functions ###
######################################################################
def SafeFile(f):
from types import StringType
if isinstance(f, StringType):
return File(f)
return f
def MakeFileList(files):
return Flatten(File(files))
def AddEnvStandardFlags(env, defines=None, flags=None, libs=None, entry=None, nodeflib=None):
if defines:
env.Append(CPPDEFINES = defines)
if flags:
env.Append(CCFLAGS = flags)
if libs:
env.Append(LIBS = libs)
if entry:
unicodestr = "None"
if 'UNICODE' in env['CPPDEFINES']:
unicodestr = "True"
env.Append(LINKFLAGS = ['${ENTRY_FLAG("%s",%s)}' % (entry,unicodestr)])
if nodeflib:
env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG']) # no default libraries
def AppendRES(env, source, res, resources):
if res:
target = MakeFileList(res)[0].name.replace('.rc', '-rc')
target_res = env.RES(target, res)
if resources:
env.Depends(target_res, resources)
source.append(target_res)
def CleanMap(env, target, target_name):
env.Clean(target, File(target_name + '.map'))
######################################################################
####### Functions ###
######################################################################
@ -294,17 +336,6 @@ defenv.Execute(Delete('$ZIPDISTDIR'))
defenv.Execute(Delete('$INSTDISTDIR'))
defenv.Execute(Delete('$TESTDISTDIR'))
def SafeFile(f):
from types import StringType
if isinstance(f, StringType):
return File(f)
return f
def MakeFileList(files):
return Flatten(File(files))
def Distribute(files, names, component, path, subpath, alias, install_alias=None):
from types import StringType
@ -347,8 +378,8 @@ def DistributeW32Bin(files, names=[], path='', alias=None):
def DistributeStubs(files, names=[], path='', alias=None):
return defenv.Distribute(files, names, 'data', 'Stubs', path, alias, 'stubs')
def DistributePlugin(files, names=[], path='', alias=None):
return defenv.Distribute(files, names, 'data', 'Plugins', path, alias, 'plugins')
def DistributePlugin(files, names=[], arcsubpath='', alias=None):
return defenv.Distribute(files, names, 'data', 'Plugins', arcsubpath, alias, 'plugins')
def DistributeContrib(files, names=[], path='', alias=None):
return defenv.Distribute(files, names, 'data', 'Contrib', path, alias, 'contrib')
@ -400,6 +431,12 @@ defenv.DistributeExamples = DistributeExamples
defenv.Sign = Sign
defenv.TestScript = TestScript
def DistributeExtras(env, target, examples, docs):
if examples:
env.DistributeExamples(examples, path=target)
if docs:
env.DistributeDocs(docs, path=target)
######################################################################
####### Environments ###
######################################################################
@ -464,6 +501,19 @@ plugin_uenv = envs[7]
Export('stub_env makensis_env plugin_env plugin_uenv util_env cp_util_env test_env')
def GetArcCPU(env):
if (not env.has_key('TARGET_ARCH')) or env['TARGET_ARCH'] == 'x86':
return 'x86'
return env['TARGET_ARCH']
def GetArcSuffix(env, unicode = None):
if unicode is None:
unicode = 'UNICODE' in env['CPPDEFINES']
suff = '-unicode'
if not unicode:
suff = '-ansi'
return GetArcCPU(env) + suff
######################################################################
####### Distribution ###
######################################################################
@ -533,11 +583,13 @@ def BuildStub(compression, solid, unicode):
if solid:
suffix = '_solid'
if unicode:
suffix += '.5_0'
env = stub_uenv.Clone()
else:
env = stub_env.Clone()
suffix = suffix + '-' + GetArcSuffix(env, unicode)
AddEnvStandardFlags(env, entry='NSISWinMainNOCRT')
build_dir = '$BUILD_PREFIX/stub_%s%s' % (compression, suffix)
@ -559,8 +611,9 @@ for stub in stubs:
BuildStub(stub, False, True)
BuildStub(stub, True, True)
BuildStub(stub, False, False)
BuildStub(stub, True, False)
if GetArcCPU(defenv)=='x86':
BuildStub(stub, False, False)
BuildStub(stub, True, False)
defenv.DistributeStubs('Source/exehead/uninst.ico',names='uninst')
@ -582,52 +635,21 @@ if defenv['PLATFORM'] == 'win32':
else:
defenv.DistributeBin(makensis, alias='install-compiler')
######################################################################
####### Common Functions ###
######################################################################
def AddEnvStandardFlags(env, defines, flags, libs, entry, nodeflib):
if defines:
env.Append(CPPDEFINES = defines)
if flags:
env.Append(CCFLAGS = flags)
if libs:
env.Append(LIBS = libs)
if entry:
env.Append(LINKFLAGS = ['${ENTRY_FLAG("%s")}' % entry])
if nodeflib:
env.Append(LINKFLAGS = ['$NODEFLIBS_FLAG']) # no default libraries
def AppendRES(env, source, res, resources):
if res:
target = MakeFileList(res)[0].name.replace('.rc', '-rc')
target_res = env.RES(target, res)
if resources:
env.Depends(target_res, resources)
source.append(target_res)
def CleanMap(env, target, target_name):
env.Clean(target, File(target_name + '.map'))
def DistributeExtras(env, target, examples, docs):
if examples:
env.DistributeExamples(examples, path=target)
if docs:
env.DistributeDocs(docs, path=target)
######################################################################
####### Plug-ins ###
######################################################################
def PerformPluginExtrasDistOperationOnce(env, unicode):
#SCons does not like it if you install the same file multiple times
return GetArcCPU(defenv)==GetArcCPU(env) and (defenv['UNICODE']==unicode)
def BuildPluginWorker(target, source, libs, examples = None, docs = None,
entry = 'DllMain', res = None, resources = None,
defines = None, flags = None, nodeflib = True,
cppused = False, unicode = False):
basename = target
if unicode:
env = plugin_uenv.Clone()
target = target + 'W'
else:
env = plugin_env.Clone()
@ -650,10 +672,10 @@ def BuildPluginWorker(target, source, libs, examples = None, docs = None,
if str(i)[-4:].lower() == '.dll':
plugin = i
break
env.DistributePlugin(plugin)
env.DistributePlugin(plugin, arcsubpath = GetArcSuffix(env, unicode))
if not unicode: # distribute extras only for ANSI builds
DistributeExtras(env, target, examples, docs)
if PerformPluginExtrasDistOperationOnce(env, unicode): # only distribute extras once
DistributeExtras(env, basename, examples, docs)
def BuildPlugin(target, source, libs, examples = None, docs = None,
entry = 'DllMain', res = None, resources = None,
@ -663,20 +685,22 @@ def BuildPlugin(target, source, libs, examples = None, docs = None,
BuildPluginWorker(target, source, libs, examples, docs, entry, res, resources, defines, flags, nodeflib, cppused, unicodetarget)
for plugin in plugin_libs + plugins:
if plugin in defenv['SKIPPLUGINS']:
continue
srcpath = 'Contrib/' + plugin
build_dir = '$BUILD_PREFIX/' + plugin
pvariants = [{'suff':'', 'e':plugin_env.Clone()}]
pvariants = [{'e':plugin_env.Clone()}] # BUGBUG64: Only build unicode plugins
if defenv['UNICODE']:
pvariants += [{'suff':'W', 'e':plugin_uenv.Clone()}]
pvariants += [{'e':plugin_uenv.Clone()}]
for pvariant in pvariants:
exports = {'BuildPlugin' : BuildPlugin, 'env' : pvariant['e']}
vdir = build_dir + pvariant['suff']
exports = {
'env' : pvariant['e'],
'BuildPlugin' : BuildPlugin, 'GetArcSuffix' : GetArcSuffix,
'PerformPluginExtrasDistOperationOnce' : PerformPluginExtrasDistOperationOnce
}
vdir = build_dir + '/' + GetArcSuffix(pvariant['e'])
defenv.SConscript(dirs = srcpath, variant_dir = vdir, duplicate = False, exports = exports)
@ -696,14 +720,17 @@ def BuildUtilEnv(defines = None, flags = None, libs = None,
else:
env = cp_util_env.Clone()
platform = env['PLATFORM']
if cli:
env.Append(LINKFLAGS = env['SUBSYS_CON'])
cli = True
if libs and 'z' in libs:
libs.remove('z')
AddZLib(env, platform)
if cli:
env.Append(LINKFLAGS = env['SUBSYS_CON'])
else:
env.Append(LINKFLAGS = env['SUBSYS_WIN'])
AddEnvStandardFlags(env, defines, flags, libs, entry, nodeflib)
return env
@ -751,7 +778,7 @@ for util in utils:
path = 'Contrib/' + util
build_dir = '$BUILD_PREFIX/' + util
exports = {'BuildUtil' : BuildUtil, 'BuildUtilEnv' : BuildUtilEnv, 'env' : util_env, '_tWinMain' : _tWinMain}
exports = {'BuildUtil' : BuildUtil, 'BuildUtilEnv' : BuildUtilEnv, 'env' : util_env}
defenv.SConscript(dirs = path, variant_dir = build_dir, duplicate = False, exports = exports)

View file

@ -21,13 +21,16 @@
// #include "StdAfx.h"
#ifdef WIN32
# include <objbase.h>
#ifdef _WIN32
# include <initguid.h>
# include <objbase.h>
#endif
#ifndef INITGUID
# define INITGUID
#endif
#include "../Platform.h"
#define INITGUID
#include "7zip/ICoder.h"
#include "7zip/Compress/LZ/IMatchFinder.h"

View file

@ -47,14 +47,14 @@ inline bool operator==(REFGUID g1, REFGUID g2)
inline bool operator!=(REFGUID g1, REFGUID g2) { return !(g1 == g2); }
#endif
#endif // GUID_DEFINED
#ifdef __cplusplus
#define MY_EXTERN_C extern "C"
#else
#define MY_EXTERN_C extern
#endif
#endif // GUID_DEFINED
#ifdef DEFINE_GUID
#undef DEFINE_GUID

View file

@ -603,7 +603,7 @@ BYTE* CDialogTemplate::Save(DWORD& dwSize) {
}
// Write class variant length array
WCHAR *szClass = m_vItems[i]->szClass;
const WCHAR *szClass = m_vItems[i]->szClass;
#ifdef _UNICODE
if (!IS_INTRESOURCE(szClass) && m_build_unicode && !_wcsicmp(szClass, L"RichEdit20A"))
szClass = L"RichEdit20W"; // transmute ANSI RichEdit control into Unicode RichEdit

View file

@ -108,7 +108,7 @@ typedef DWORDLONG ULONGLONG,*PULONGLONG;
#define _snprintf snprintf
#define _vsnprintf vsnprintf
#endif
#endif // ?WIN32
#ifndef INT_MAX
#include <limits.h>
@ -121,6 +121,17 @@ typedef DWORDLONG ULONGLONG,*PULONGLONG;
# define ULONG_PTR unsigned long
#endif
#ifdef __cplusplus
#include <algorithm>
#if defined(_MSC_VER) && _MSC_VER <= 1200
#define STD_MIN std::_MIN
#define STD_MAX std::_MAX
#else
#define STD_MIN (std::min) // This works even when windows.h defines min/max
#define STD_MAX (std::max)
#endif
#endif
#ifdef _countof
#define COUNTOF _countof
#else
@ -724,6 +735,9 @@ typedef DWORDLONG ULONGLONG,*PULONGLONG;
# define IMAGE_DIRECTORY_ENTRY_EXPORT 0
# define IMAGE_SIZEOF_SHORT_NAME 8
#endif
#ifndef IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
#endif
// structures
@ -860,7 +874,6 @@ typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER;
# define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x0b01
# define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x0b02
#endif
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
@ -912,4 +925,41 @@ typedef struct tagVS_FIXEDFILEINFO {
# pragma pack()
#endif
// MinGW does not implement the unicode CRT startup functions
#if (defined(_UNICODE) && defined(_WIN32)) && defined(__MINGW32__)
# define NSIS_ENTRYPOINT_TMAIN \
int _tmain(int argc,WCHAR**argv); \
EXTERN_C int main(int ac,char**cav) { \
WCHAR**av=CommandLineToArgvW(GetCommandLineW(),&ac); \
if (!av) { \
_tprintf(_T("wmain: Error %u\n"),ac = GetLastError()); \
return ac; \
} \
ac = _tmain(ac,av); \
/*LEAK: LocalFree(av);*/ \
return ac; \
}
# define NSIS_ENTRYPOINT_SIMPLEGUI \
int WINAPI _tWinMain(HINSTANCE hI,HINSTANCE hOld,LPTSTR cl,int sc); \
EXTERN_C int WINAPI WinMain(HINSTANCE hI,HINSTANCE hOld,char*cl,int sc) \
{return _tWinMain(hI,0,0,sc);}
# ifdef __cplusplus
# define NSIS_ENTRYPOINT_GUINOCRT \
EXTERN_C void NSISWinMainNOCRT(); \
int WINAPI WinMain(HINSTANCE hI,HINSTANCE hOld,char*cl,int sc) \
{NSISWinMainNOCRT();return 0;}
# endif
#endif
#ifndef NSIS_ENTRYPOINT_TMAIN
# define NSIS_ENTRYPOINT_TMAIN
#endif
#ifndef NSIS_ENTRYPOINT_SIMPLEGUI // _tWinMain with valid hInstance, calls ExitProcess
# define NSIS_ENTRYPOINT_SIMPLEGUI
#endif
#ifndef NSIS_ENTRYPOINT_GUINOCRT
# define NSIS_ENTRYPOINT_GUINOCRT
#endif
#endif

View file

@ -40,7 +40,52 @@ using namespace std;
extern FILE *g_output;
void Plugins::FindCommands(const tstring &path, bool displayInfo)
namespace {
template <class C, class K>
bool contains(const C& cntnr, const K& key)
{
return cntnr.find(key) != cntnr.end();
}
template <class C, class K>
const typename C::const_iterator get_iterator(const C& cntnr, const K& key)
{
assert( contains(cntnr, key) );
return cntnr.find(key);
}
template <class C, class K>
typename C::const_iterator::value_type get_value(const C& cntnr, const K& key)
{
return *get_iterator(cntnr,key);
}
template <class C, class K>
typename C::value_type::second_type get_paired_value(const C& cntnr, const K& key)
{
return get_iterator(cntnr,key)->second;
}
template <class V,class C, class K>
V get_paired_value(const C& cntnr, const K& key, const V& defval)
{
typename C::const_iterator it = cntnr.find(key);
return cntnr.end() == it ? defval : it->second;
}
}
static inline tstring GetDllName(const tstring&command)
{
return get_string_prefix(command, _T("::"));
}
static inline void PrintCommandSig(const tstring sig)
{
_ftprintf(g_output, _T(" + %s\n"), sig.c_str());
}
void Plugins::AddPluginsDir(const tstring &path, bool displayInfo)
{
boost::scoped_ptr<dir_reader> dr( new_dir_reader() );
dr->read(path);
@ -71,11 +116,10 @@ struct NSISException : public NSISExceptionInner
namespace {
// This function slurps the whole file into the vector.
// Modified so the huge vector isn't returned by value.
void read_file(const tstring& filename, vector<unsigned char>& data) {
void read_file(const tstring& filename, vector<unsigned char>& data)
{
FILE*file = FOPEN(filename.c_str(), ("rb"));
if (!file) throw NSISException(_T("Can't open file '") + filename + _T("'"));
MANAGE_WITH(file, fclose);
bool succ = false;
@ -104,9 +148,10 @@ void Plugins::GetExports(const tstring &pathToDll, bool displayInfo)
}
tstring dllName = remove_file_extension(get_file_name(pathToDll));
#ifdef _UNICODE
bool unicodeDll = dllName[dllName.size()-1] == 'W';
#endif
if (DllHasDataHandle(dllName))
{
m_dllname_conflicts.insert(dllName);
}
FIX_ENDIAN_INT16_INPLACE(NTHeaders->FileHeader.Characteristics);
if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
@ -135,19 +180,16 @@ void Plugins::GetExports(const tstring &pathToDll, bool displayInfo)
LPDWORD names = (LPDWORD)((ULONG_PTR)exports + na - ExportDirVA);
for (DWORD j = 0; j < FIX_ENDIAN_INT32(exports->NumberOfNames); j++)
{
if (0 == j) m_dllname_to_path[dllName] = pathToDll;
const string name = string((char*)exports + FIX_ENDIAN_INT32(names[j]) - ExportDirVA);
const tstring signature = dllName + _T("::") + tstring(CtoTString(name));
const tstring lcsig = lowercase(signature);
m_command_to_path[lcsig] = pathToDll;
m_command_lowercase_to_command[lcsig] = signature;
#ifdef _UNICODE
const tstring lcsigA = lowercase(dllName.substr(0,dllName.size()-1) + _T("::") + tstring(CtoTString(name)));
if (unicodeDll && m_command_to_path.find(lcsigA) != m_command_to_path.end())
m_unicode_variant[lcsigA] = signature;
else
#endif
const tstring canoniccmd = dllName + _T("::") + tstring(CtoTString(name));
if (displayInfo)
_ftprintf(g_output, _T(" - %s\n"), signature.c_str());
{
bool hadCmd = contains(m_commands, canoniccmd);
if (!hadCmd) PrintCommandSig(canoniccmd);
}
m_commands.insert(canoniccmd);
}
break;
}
@ -155,59 +197,54 @@ void Plugins::GetExports(const tstring &pathToDll, bool displayInfo)
}
}
bool Plugins::IsPluginCommand(const tstring& token) const {
return m_command_to_path.find(lowercase(token)) != m_command_to_path.end();
}
namespace {
template <class Key, class Value>
Value get_value(const map<Key, Value>& the_map,
const Key& key)
int Plugins::GetDllDataHandle(bool uninst, const tstring& command) const
{
assert(the_map.find(key) != the_map.end());
return the_map.find(key)->second;
const tstring dllname = GetDllName(command);
if (uninst)
return get_paired_value(m_dllname_to_unst_datahandle, dllname, -1);
else
return get_paired_value(m_dllname_to_inst_datahandle, dllname, -1);
}
template <class Key, class Value>
Value get_value(const map<Key, Value>& the_map,
const Key& key,
const Value& defaultValue)
void Plugins::SetDllDataHandle(bool uninst, tstring&canoniccmd, int dataHandle)
{
if (the_map.find(key) == the_map.end())
return defaultValue;
return the_map.find(key)->second;
}
const tstring dllname = GetDllName(canoniccmd);
if (uninst)
m_dllname_to_unst_datahandle[dllname] = dataHandle;
else
m_dllname_to_inst_datahandle[dllname] = dataHandle;
}
tstring Plugins::NormalizedCommand(const tstring& command) const {
return get_value(m_command_lowercase_to_command, lowercase(command));
}
tstring Plugins::UseUnicodeVariant(const tstring& command) const {
return get_value(m_unicode_variant, lowercase(command), command);
}
int Plugins::GetPluginHandle(bool uninst, const tstring& command) const {
if (uninst) {
return get_value(m_command_to_uninstall_data_handle, command, -1);
}
else {
return get_value(m_command_to_data_handle, command, -1);
}
}
tstring Plugins::GetPluginPath(const tstring& command) const {
return get_value(m_command_to_path, lowercase(command));
}
void Plugins::SetDllDataHandle(bool uninst, const tstring& command, int dataHandle)
bool Plugins::DllHasDataHandle(const tstring& dllnamelowercase) const
{
if (uninst) {
m_command_to_uninstall_data_handle[command] = dataHandle;
}
else {
m_command_to_data_handle[command] = dataHandle;
}
int h = GetDllDataHandle(false, dllnamelowercase);
if (-1 == h) h = GetDllDataHandle(true, dllnamelowercase);
return -1 != h;
}
bool Plugins::Initialize(const TCHAR*arcsubdir, bool displayInfo)
{
if (m_initialized) return true;
m_initialized = true;
AddPluginsDir(tstring(arcsubdir), displayInfo);
return true;
}
bool Plugins::GetCommandInfo(const tstring&command, tstring&canoniccmd, tstring&dllPath)
{
const tstring dllname = GetDllName(command);
dllPath = get_paired_value(m_dllname_to_path, dllname);
canoniccmd = get_value(m_commands, command);
return !contains(m_dllname_conflicts, dllname);
}
bool Plugins::IsPluginCommand(const tstring& token) const
{
return contains(m_commands, token);
}
#endif

View file

@ -13,35 +13,59 @@
* This software is provided 'as-is', without any express or implied
* warranty.
*
* Unicode support by Jim Park -- 08/21/2007
*/
#ifndef __X18_PLUGINS_H
#define __X18_PLUGINS_H
#ifndef NSIS_EXEHEADPLUGINS_H
#define NSIS_EXEHEADPLUGINS_H
#include <map>
#include <set>
#include "tstring.h"
namespace STLHelpers
{
template<class S, class C>
struct string_nocasecmpless : std::binary_function<S, S, bool>
{
struct cmp : public std::binary_function<C, C, bool>
{
bool operator() (const C&a, const C&b) const
{
return tolower(a) < tolower(b);
}
};
bool operator() (const S&a,const S&b) const
{
return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), cmp());
}
};
}
class Plugins
{
public:
void FindCommands(const tstring& path, bool displayInfo);
typedef STLHelpers::string_nocasecmpless<tstring, tstring::value_type> strnocasecmp;
Plugins() : m_initialized(false) {}
bool Initialize(const TCHAR*arcsubdir, bool displayInfo);
void AddPluginsDir(const tstring& path, bool displayInfo);
bool IsPluginCommand(const tstring& command) const;
tstring NormalizedCommand(const tstring& command) const;
int GetPluginHandle(bool uninst, const tstring& command) const;
tstring GetPluginPath(const tstring& command) const;
tstring UseUnicodeVariant(const tstring& lcsig) const;
void SetDllDataHandle(bool uninst, const tstring& command, int dataHandle);
bool GetCommandInfo(const tstring&command, tstring&canoniccmd, tstring&dllPath);
int GetDllDataHandle(bool uninst, const tstring& command) const;
void SetDllDataHandle(bool uninst, tstring&canoniccmd, int dataHandle);
private: // methods
void GetExports(const tstring &pathToDll, bool displayInfo);
bool DllHasDataHandle(const tstring& dllnamelowercase) const;
private: // data members
std::map<tstring, tstring> m_command_lowercase_to_command;
std::map<tstring, tstring> m_command_to_path;
std::map<tstring, tstring> m_unicode_variant;
std::map<tstring, int> m_command_to_data_handle;
std::map<tstring, int> m_command_to_uninstall_data_handle;
std::set<tstring, strnocasecmp> m_commands;
std::map<tstring, tstring, strnocasecmp> m_dllname_to_path;
std::map<tstring, int, strnocasecmp> m_dllname_to_inst_datahandle;
std::map<tstring, int, strnocasecmp> m_dllname_to_unst_datahandle;
std::set<tstring, strnocasecmp> m_dllname_conflicts;
bool m_initialized;
};
#endif

View file

@ -156,7 +156,7 @@ CResourceEditor::~CResourceEditor() {
// Adds/Replaces/Removes a resource.
// If lpData is 0 UpdateResource removes the resource.
bool CResourceEditor::UpdateResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
bool CResourceEditor::UpdateResourceW(const WCHAR* szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
CResourceDirectory* nameDir = 0;
CResourceDirectory* langDir = 0;
CResourceDataEntry* data = 0;
@ -224,15 +224,14 @@ static WCHAR* ResStringToUnicode(const char *szString) {
else
return wcsdup_fromTchar(szString, CP_ACP);
}
#endif
static void FreeUnicodeResString(WCHAR* szwString) {
if (!IS_INTRESOURCE(szwString))
free(szwString);
}
#endif
bool CResourceEditor::UpdateResource(TCHAR* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
bool CResourceEditor::UpdateResource(const TCHAR* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize) {
#ifdef _UNICODE
return UpdateResourceW(szType, MAKEINTRESOURCEW(szName), wLanguage, lpData, dwSize);
#else
@ -245,7 +244,7 @@ bool CResourceEditor::UpdateResource(TCHAR* szType, WORD szName, LANGID wLanguag
// Returns a copy of the requested resource
// Returns 0 if the requested resource can't be found
BYTE* CResourceEditor::GetResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage) {
BYTE* CResourceEditor::GetResourceW(const WCHAR* szType, WCHAR* szName, LANGID wLanguage) {
if (!m_bKeepData)
throw runtime_error("Can't GetResource() when bKeepData is false");
@ -277,7 +276,7 @@ BYTE* CResourceEditor::GetResourceW(WCHAR* szType, WCHAR* szName, LANGID wLangua
return NULL;
}
BYTE* CResourceEditor::GetResource(TCHAR* szType, WORD szName, LANGID wLanguage) {
BYTE* CResourceEditor::GetResource(const TCHAR* szType, WORD szName, LANGID wLanguage) {
#ifdef _UNICODE
return GetResourceW(szType, MAKEINTRESOURCEW(szName), wLanguage);
#else
@ -290,7 +289,7 @@ BYTE* CResourceEditor::GetResource(TCHAR* szType, WORD szName, LANGID wLanguage)
// Returns the size of the requested resource
// Returns -1 if the requested resource can't be found
int CResourceEditor::GetResourceSizeW(WCHAR* szType, WCHAR* szName, LANGID wLanguage) {
int CResourceEditor::GetResourceSizeW(const WCHAR* szType, WCHAR* szName, LANGID wLanguage) {
CResourceDirectory* nameDir = 0;
CResourceDirectory* langDir = 0;
CResourceDataEntry* data = 0;
@ -316,7 +315,7 @@ int CResourceEditor::GetResourceSizeW(WCHAR* szType, WCHAR* szName, LANGID wLang
return -1;
}
int CResourceEditor::GetResourceSize(TCHAR* szType, WORD szName, LANGID wLanguage) {
int CResourceEditor::GetResourceSize(const TCHAR* szType, WORD szName, LANGID wLanguage) {
#ifdef _UNICODE
return GetResourceSizeW(szType, MAKEINTRESOURCEW(szName), wLanguage);
#else
@ -329,7 +328,7 @@ int CResourceEditor::GetResourceSize(TCHAR* szType, WORD szName, LANGID wLanguag
// Returns the offset of the requested resource in the original PE
// Returns -1 if the requested resource can't be found
DWORD CResourceEditor::GetResourceOffsetW(WCHAR* szType, WCHAR* szName, LANGID wLanguage) {
DWORD CResourceEditor::GetResourceOffsetW(const WCHAR* szType, WCHAR* szName, LANGID wLanguage) {
CResourceDirectory* nameDir = 0;
CResourceDirectory* langDir = 0;
CResourceDataEntry* data = 0;
@ -355,7 +354,7 @@ DWORD CResourceEditor::GetResourceOffsetW(WCHAR* szType, WCHAR* szName, LANGID w
return DWORD(-1);
}
DWORD CResourceEditor::GetResourceOffset(TCHAR* szType, WORD szName, LANGID wLanguage) {
DWORD CResourceEditor::GetResourceOffset(const TCHAR* szType, WORD szName, LANGID wLanguage) {
#ifdef _UNICODE
return GetResourceOffsetW(szType, MAKEINTRESOURCEW(szName), wLanguage);
#else
@ -858,7 +857,7 @@ int CResourceDirectory::CountEntries() {
// Returns the index of a directory entry with the specified name
// Name can be a string or an id
// Returns -1 if can not be found
int CResourceDirectory::Find(WCHAR* szName) {
int CResourceDirectory::Find(const WCHAR* szName) {
if (IS_INTRESOURCE(szName))
return Find((WORD) (ULONG_PTR) szName);
else
@ -934,7 +933,7 @@ void CResourceDirectory::Destroy() {
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CResourceDirectoryEntry::CResourceDirectoryEntry(WCHAR* szName, CResourceDirectory* rdSubDir) {
CResourceDirectoryEntry::CResourceDirectoryEntry(const WCHAR* szName, CResourceDirectory* rdSubDir) {
if (IS_INTRESOURCE(szName)) {
m_bHasName = false;
m_szName = 0;
@ -948,7 +947,7 @@ CResourceDirectoryEntry::CResourceDirectoryEntry(WCHAR* szName, CResourceDirecto
m_rdSubDir = rdSubDir;
}
CResourceDirectoryEntry::CResourceDirectoryEntry(WCHAR* szName, CResourceDataEntry* rdeData) {
CResourceDirectoryEntry::CResourceDirectoryEntry(const WCHAR* szName, CResourceDataEntry* rdeData) {
if (IS_INTRESOURCE(szName)) {
m_bHasName = false;
m_szName = 0;

View file

@ -114,10 +114,10 @@ public:
CResourceEditor(BYTE* pbPE, int iSize, bool bKeepData = true);
virtual ~CResourceEditor();
bool UpdateResource (TCHAR* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
BYTE* GetResource (TCHAR* szType, WORD szName, LANGID wLanguage);
int GetResourceSize (TCHAR* szType, WORD szName, LANGID wLanguage);
DWORD GetResourceOffset(TCHAR* szType, WORD szName, LANGID wLanguage);
bool UpdateResource (const TCHAR* szType, WORD szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
BYTE* GetResource (const TCHAR* szType, WORD szName, LANGID wLanguage);
int GetResourceSize (const TCHAR* szType, WORD szName, LANGID wLanguage);
DWORD GetResourceOffset(const TCHAR* szType, WORD szName, LANGID wLanguage);
void FreeResource(BYTE* pbResource);
// The section name must be in ASCII.
@ -135,10 +135,10 @@ public:
DWORD *pdwSectionIndex = NULL
);
private:
bool UpdateResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
BYTE* GetResourceW(WCHAR* szType, WCHAR* szName, LANGID wLanguage);
int GetResourceSizeW(WCHAR* szType, WCHAR* szName, LANGID wLanguage);
DWORD GetResourceOffsetW(WCHAR* szType, WCHAR* szName, LANGID wLanguage);
bool UpdateResourceW(const WCHAR* szType, WCHAR* szName, LANGID wLanguage, BYTE* lpData, DWORD dwSize);
BYTE* GetResourceW(const WCHAR* szType, WCHAR* szName, LANGID wLanguage);
int GetResourceSizeW(const WCHAR* szType, WCHAR* szName, LANGID wLanguage);
DWORD GetResourceOffsetW(const WCHAR* szType, WCHAR* szName, LANGID wLanguage);
private:
BYTE* m_pbPE;
@ -172,7 +172,7 @@ public:
void AddEntry(CResourceDirectoryEntry* entry);
void RemoveEntry(int i);
int CountEntries();
int Find(WCHAR* szName);
int Find(const WCHAR* szName);
int Find(WORD wId);
DWORD GetSize();
@ -188,8 +188,8 @@ private:
class CResourceDirectoryEntry {
public:
CResourceDirectoryEntry(WCHAR* szName, CResourceDirectory* rdSubDir);
CResourceDirectoryEntry(WCHAR* szName, CResourceDataEntry* rdeData);
CResourceDirectoryEntry(const WCHAR* szName, CResourceDirectory* rdSubDir);
CResourceDirectoryEntry(const WCHAR* szName, CResourceDataEntry* rdeData);
virtual ~CResourceDirectoryEntry();
bool HasName();

View file

@ -41,12 +41,13 @@
#include "ResourceVersionInfo.h"
#include "tstring.h"
#include <stdio.h>
#include <stdarg.h>
#ifndef _WIN32
# include <locale.h>
# include <unistd.h>
# include <limits.h>
# include <stdlib.h>
# include <stdarg.h>
#endif
#include <cassert> // for assert
@ -57,12 +58,6 @@
return rc; \
} while (false)
const LONG available_stub_variants[] =
{
0x00000000, // classic ANSI stub
0x00050000 // Unicode stub for Windows 2000 and more recent (5.0+)
};
using namespace std;
namespace { // begin anonymous namespace
@ -135,9 +130,8 @@ CEXEBuild::CEXEBuild() :
definedlist.add(_T("NSIS_PACKEDVERSION"), NSIS_PACKEDVERSION);
#endif
target_minimal_OS=0;
build_unicode=false;
definedlist.add(_T("NSIS_CHAR_SIZE"), _T("1")); // this can change after a TargetMinimalOS instruction is found
m_target_type=TARGET_X86ANSI;
// automatically generated header file containing all defines
#include <nsis-defines.h>
@ -269,7 +263,7 @@ CEXEBuild::CEXEBuild() :
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
build_plugin_unload=0;
plugins_processed=0;
m_pPlugins=0;
#endif
last_used_lang=NSIS_DEFAULT_LANG;
@ -441,6 +435,8 @@ CEXEBuild::CEXEBuild() :
set_uninstall_mode(0);
set_code_type_predefines();
set_target_architecture_predefines();
}
void CEXEBuild::initialize(const TCHAR *makensis_path)
@ -1802,7 +1798,7 @@ int CEXEBuild::AddVersionInfo()
}
}
catch (exception& err) {
ERROR_MSG(_T("Error adding version information: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("Error adding version information: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
}
@ -2208,7 +2204,7 @@ again:
SCRIPT_MSG(_T("Done!\n"));
}
catch (exception& err) {
ERROR_MSG(_T("\nError: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("\nError: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
@ -2330,7 +2326,7 @@ int CEXEBuild::SetVarsSection()
}
}
catch (exception& err) {
ERROR_MSG(_T("\nError: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("\nError: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
@ -2351,7 +2347,7 @@ int CEXEBuild::SetManifest()
res_editor->UpdateResource(MAKEINTRESOURCE(24), 1, NSIS_DEFAULT_LANG, (LPBYTE) manifest.c_str(), manifest.length());
}
catch (exception& err) {
ERROR_MSG(_T("Error setting manifest: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("Error setting manifest: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
@ -2368,7 +2364,7 @@ int CEXEBuild::UpdatePEHeader()
// terminal services aware
headers->OptionalHeader.DllCharacteristics |= IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE;
} catch (std::runtime_error& err) {
ERROR_MSG(_T("Error updating PE headers: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("Error updating PE headers: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
@ -2569,7 +2565,7 @@ int CEXEBuild::write_output(void)
close_res_editor();
}
catch (exception& err) {
ERROR_MSG(_T("\nError: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("\nError: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
@ -3418,24 +3414,31 @@ void CEXEBuild::notify(notify_e code, const TCHAR *data) const
#endif
}
// Added by Ximon Eighteen 5th August 2002
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
void CEXEBuild::build_plugin_table(void)
int CEXEBuild::initialize_default_plugins(bool newtargetarc)
{
if (plugins_processed)
return;
plugins_processed=1;
if (!m_pPlugins)
{
plugin_used = uninst_plugin_used = false;
newtargetarc = true;
}
if (!newtargetarc) return PS_OK;
m_pPlugins = &m_plugins[m_target_type];
plugin_used = false;
uninst_plugin_used = false;
tstring searchPath = definedlist.find(_T("NSISDIR"));
searchPath += PLATFORM_PATH_SEPARATOR_STR _T("Plugins");
INFO_MSG(_T("Processing plugin dlls: \"%s") PLATFORM_PATH_SEPARATOR_STR _T("*.dll\"\n"),searchPath.c_str());
m_plugins.FindCommands(searchPath, display_info?true:false);
INFO_MSG(_T("\n"));
}
searchPath += PLATFORM_PATH_SEPARATOR_STR _T("Plugins") PLATFORM_PATH_SEPARATOR_STR;
searchPath += get_target_suffix();
#define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags_t, flag)/sizeof(int))
SCRIPT_MSG(_T("Processing default plugins: \"%s") PLATFORM_PATH_SEPARATOR_STR _T("*.dll\"\n"), searchPath.c_str());
if (!m_pPlugins->Initialize(searchPath.c_str(), !!display_script))
{
ERROR_MSG(_T("Error initializing default plugins!\n"));
return PS_ERROR;
}
SCRIPT_MSG(_T("\n"));
return PS_OK;
}
int CEXEBuild::add_plugins_dir_initializer(void)
{
@ -3634,14 +3637,11 @@ void CEXEBuild::VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList)
}
}
#ifdef _UNICODE
int CEXEBuild::set_target_minimal_OS(int major, int minor)
void CEXEBuild::set_target_architecture_predefines()
{
target_minimal_OS = MAKELONG(minor,major);
build_unicode = major>=5;
definedlist.del(_T("NSIS_UNICODE"));
definedlist.del(_T("NSIS_CHAR_SIZE"));
if (build_unicode) // update defines depending on target installer type
if (build_unicode)
{
definedlist.add(_T("NSIS_UNICODE"));
definedlist.add(_T("NSIS_CHAR_SIZE"), _T("2"));
@ -3650,7 +3650,31 @@ int CEXEBuild::set_target_minimal_OS(int major, int minor)
{
definedlist.add(_T("NSIS_CHAR_SIZE"), _T("1"));
}
return load_stub();
}
int CEXEBuild::change_target_architecture()
{
if (build_compressor_set)
{
ERROR_MSG(_T("Error: Can't change target architecture after data already got compressed!\n"));
return PS_ERROR;
}
m_target_type = build_unicode ? TARGET_X86UNICODE : TARGET_X86ANSI;
set_target_architecture_predefines();
int ec = load_stub();
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
if (PS_OK==ec) ec = initialize_default_plugins(true);
#endif
return ec;
}
#ifdef _UNICODE
int CEXEBuild::set_target_charset(bool unicode)
{
build_unicode = unicode;
return change_target_architecture();
}
#endif
@ -3661,26 +3685,29 @@ int CEXEBuild::set_compressor(const tstring& compressor, const bool solid) {
return load_stub();
}
tstring CEXEBuild::get_stub_variant_suffix()
CEXEBuild::TARGETTYPE CEXEBuild::get_target_type(const TCHAR*s) const
{
LONG variant = 0;
for (unsigned int index = 0; index < COUNTOF(available_stub_variants); index++)
{
if (target_minimal_OS >= available_stub_variants[index])
variant = available_stub_variants[index];
else
break;
}
if (variant == 0)
return tstring();
TCHAR buf[32];
_stprintf(buf, _T(".%d_%d"), HIWORD(variant), LOWORD(variant));
return tstring(buf);
for(int i = CEXEBuild::TARGETFIRST; i < CEXEBuild::TARGETCOUNT; ++i)
{
CEXEBuild::TARGETTYPE tt = (CEXEBuild::TARGETTYPE) i;
if (!_tcsicmp(get_target_suffix(tt),s)) return tt;
}
return TARGET_UNKNOWN;
}
const TCHAR* CEXEBuild::get_target_suffix(CEXEBuild::TARGETTYPE tt) const
{
switch(tt)
{
case TARGET_X86ANSI :return _T("x86-ansi");
case TARGET_X86UNICODE:return _T("x86-unicode");
default:return _T("?");
}
}
int CEXEBuild::load_stub()
{
return update_exehead(stub_filename+get_stub_variant_suffix(), &m_exehead_original_size);
return update_exehead(stub_filename+_T("-")+get_target_suffix(), &m_exehead_original_size);
}
int CEXEBuild::update_exehead(const tstring& file, size_t *size/*=NULL*/) {

View file

@ -29,6 +29,7 @@
#include "mmap.h"
#include "manifest.h"
#include "icon.h"
#include <memory.h>
#include "exehead/fileform.h"
#include "exehead/config.h"
@ -48,7 +49,6 @@
#include "czlib.h"
#include "cbzip2.h"
#include "clzma.h"
#endif//NSIS_CONFIG_COMPRESSION_SUPPORT
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
@ -70,10 +70,10 @@
#define TP_ALL (TP_CODE | TP_PG)
enum notify_e {
MAKENSIS_NOTIFY_SCRIPT,
MAKENSIS_NOTIFY_SCRIPT, // main nsi file(s)
MAKENSIS_NOTIFY_WARNING,
MAKENSIS_NOTIFY_ERROR,
MAKENSIS_NOTIFY_OUTPUT
MAKENSIS_NOTIFY_OUTPUT // generated .exe file
};
#define PAGE_CUSTOM 0
@ -84,26 +84,31 @@ enum notify_e {
#define PAGE_UNINSTCONFIRM 5
#define PAGE_COMPLETED 6
#define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags_t, flag)/sizeof(int))
class CEXEBuild {
public:
CEXEBuild();
void initialize(const TCHAR *makensis_path);
~CEXEBuild();
// to add a warning to the compiler's warning list.
void warning(const TCHAR *s, ...);
// warning with file name and line count
void warning_fl(const TCHAR *s, ...);
// to add a defined thing.
void define(const TCHAR *p, const TCHAR *v=TEXT(""));
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
// Added by Ximon Eighteen 5th August 2002
void build_plugin_table(void);
int plugins_processed;
#endif //NSIS_CONFIG_PLUGIN_SUPPORT
void warning(const TCHAR *s, ...); // to add a warning to the compiler's warning list.
void warning_fl(const TCHAR *s, ...); // warning with file name and line count
void ERROR_MSG(const TCHAR *s, ...) const;
void SCRIPT_MSG(const TCHAR *s, ...) const;
void INFO_MSG(const TCHAR *s, ...) const;
typedef enum {
TARGETFIRST,
TARGET_X86ANSI = TARGETFIRST,
TARGET_X86UNICODE,
TARGET_UNKNOWN,
TARGETCOUNT = (TARGET_UNKNOWN-TARGETFIRST)
} TARGETTYPE;
TARGETTYPE m_target_type;
TARGETTYPE get_target_type(const TCHAR*s) const;
const TCHAR* get_target_suffix(CEXEBuild::TARGETTYPE tt) const;
const TCHAR* get_target_suffix() const {return get_target_suffix(m_target_type);}
void set_default_output_filename(const tstring& filename);
@ -119,6 +124,7 @@ class CEXEBuild {
DefineList definedlist; // List of identifiers marked as "defined" like
// C++ macro definitions such as _UNICODE.
void define(const TCHAR *p, const TCHAR *v=TEXT("")); // to add a defined thing.
int display_errors;
int display_script;
@ -138,9 +144,8 @@ class CEXEBuild {
int prepare_uninstaller();
int pack_exe_header();
int set_target_minimal_OS(int major, int minor);
int set_target_charset(bool unicode);
int set_compressor(const tstring& compressor, const bool solid);
tstring get_stub_variant_suffix();
int load_stub();
int update_exehead(const tstring& file, size_t *size=NULL);
void update_exehead(const unsigned char *new_exehead, size_t new_size);
@ -148,6 +153,7 @@ class CEXEBuild {
// tokens.cpp
bool is_valid_token(TCHAR *s);
int get_commandtoken(TCHAR *s, int *np, int *op, int *pos);
const TCHAR* get_commandtoken_name(int tok);
/**
* Returns the current "state" by looking at whether it is in a
@ -210,17 +216,11 @@ class CEXEBuild {
bool inside_comment;
int multiple_entries_instruction; // 1 (true) or 0 (false)
void ERROR_MSG(const TCHAR *s, ...) const;
void SCRIPT_MSG(const TCHAR *s, ...) const;
void INFO_MSG(const TCHAR *s, ...) const;
DefineList *searchParseString(const TCHAR *source_string, LineParser *line, int parmOffs, bool ignCase, bool noErrors);
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
int add_plugins_dir_initializer(void);
#endif //NSIS_CONFIG_PLUGIN_SUPPORT
// build.cpp functions used mostly by script.cpp
void set_target_architecture_predefines();
int change_target_architecture();
void set_code_type_predefines(const TCHAR *value = NULL);
int getcurdbsize();
int add_section(const TCHAR *secname, const TCHAR *defname, int expand=0);
@ -244,11 +244,12 @@ class CEXEBuild {
int preprocess_string(TCHAR *out, const TCHAR *in, WORD codepage=CP_ACP);
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
// Added by Ximon Eighteen 5th August 2002
Plugins m_plugins;
int add_plugins_dir_initializer(void);
int initialize_default_plugins(bool newtargetarc = false);
Plugins m_plugins[TARGETCOUNT], *m_pPlugins;
bool plugin_used;
bool uninst_plugin_used;
int build_plugin_unload;
int build_plugin_unload; // TOK_SETPLUGINUNLOAD
#endif //NSIS_CONFIG_PLUGIN_SUPPORT
// build.cpp functions used mostly within build.cpp
@ -324,7 +325,7 @@ class CEXEBuild {
* variable 'name' for a given language ID.
*
* @return If the language id, the variable name or string is invalid, it will
* return aPS_ERROR. If this function call is overwriting a set user string,
* return a PS_ERROR. If this function call is overwriting a set user string,
* this will return a PS_WARNING.
*/
int SetLangString(TCHAR *name, LANGID lang, const TCHAR *str, BOOL unicode);
@ -336,7 +337,7 @@ class CEXEBuild {
* Sets the user string to the specific NLF_STRINGS id.
*
* @return If the id is invalid or the string is not valid, it will return
* aPS_ERROR. If this function call is overwriting a set user string,
* a PS_ERROR. If this function call is overwriting a set user string,
* this will return a PS_WARNING.
*/
int SetInnerString(int id, TCHAR *str);
@ -403,8 +404,7 @@ class CEXEBuild {
int build_compress_dict_size;
bool no_space_texts;
LONG target_minimal_OS;
bool build_unicode;
bool build_unicode;// generate installer with unicode exehead?
bool has_called_write_output;

View file

@ -141,6 +141,7 @@ typedef unsigned short UInt16;
#ifndef EXEHEAD
#include <stdlib.h>
#define BZALLOC(items) malloc(items)
#define BZFREE(addr) { if (addr) free(addr); }
#define mini_memcpy memcpy

View file

@ -56,7 +56,8 @@ TCHAR *ValidateTempDir()
void *g_SHGetFolderPath;
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPTSTR lpszCmdParam, int nCmdShow)
NSIS_ENTRYPOINT_GUINOCRT
EXTERN_C void NSISWinMainNOCRT()
{
int ret = 0;
const TCHAR *m_Err = _LANG_ERRORWRITINGTEMP;
@ -307,7 +308,6 @@ end:
{
my_MessageBox(m_Err, MB_OK | MB_ICONSTOP | (IDOK << 21));
ExitProcess(2);
return 0;
}
#ifdef NSIS_SUPPORT_REBOOT
@ -341,7 +341,6 @@ end:
ret = g_exec_flags.errlvl;
ExitProcess(ret);
return 0;
}
void NSISCALL CleanUp()

View file

@ -59,6 +59,8 @@ env.Append(CPPDEFINES = ['_WIN32_IE=0x0500'])
if 'NSIS_CONFIG_LOG_STDOUT' in env['NSIS_CPPDEFINES']:
env.Append(LINKFLAGS = env['SUBSYS_CON'])
else:
env.Append(LINKFLAGS = env['SUBSYS_WIN'])
### Compression specific configuration

View file

@ -714,7 +714,7 @@ skipPage:
#include <richedit.h>
#undef _RICHEDIT_VER
static DWORD dwRead;
DWORD CALLBACK StreamLicense(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
DWORD CALLBACK StreamLicense(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
lstrcpyn((LPTSTR)pbBuff,(LPTSTR)(dwCookie+dwRead),cb/sizeof(TCHAR));
*pcb=lstrlen((LPTSTR)pbBuff)*sizeof(TCHAR);
@ -723,11 +723,11 @@ DWORD CALLBACK StreamLicense(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
}
#ifdef _UNICODE
// on-the-fly conversion of Unicode to ANSI (because Windows doesn't recognize Unicode RTF data)
DWORD CALLBACK StreamLicenseRTF(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
DWORD CALLBACK StreamLicenseRTF(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
size_t len = lstrlen(((LPWSTR) dwCookie)+dwRead);
len = min(len, cb/sizeof(WCHAR));
*pcb=WideCharToMultiByte(CP_ACP,0,((LPWSTR) dwCookie)+dwRead,len,pbBuff,cb,NULL,NULL);
*pcb=WideCharToMultiByte(CP_ACP,0,((LPWSTR) dwCookie)+dwRead,len,(char*)pbBuff,cb,NULL,NULL);
// RTF uses only ASCII characters, so we can assume "number of output bytes" = "number of source WChar consumed"
dwRead+=*pcb;
return 0;

View file

@ -49,7 +49,7 @@ NSIS_STRING g_usrvarssection[1];
# ifdef __GNUC__
// GCC does not treat g_usrvarssection as a bss section so we keep the size as small as possible.
// NSIS_STRING g_usrvarssection[31] is required to remove this hack but that really bloats the exehead.
char g_usrvarssection[1] __attribute__((section (NSIS_VARS_SECTION)));
TCHAR g_usrvarssection[1] __attribute__((section (NSIS_VARS_SECTION)));
const NSIS_STRING*const g_usrvarsstart = (const NSIS_STRING*const) g_usrvarssection;
# else
# error Unknown compiler. You must implement the seperate PE section yourself.

View file

@ -416,7 +416,7 @@ int generate_unicons_offsets(LPBYTE exeHeader, size_t exeHeaderSize, LPBYTE unin
catch (const exception& e)
{
if (g_display_errors)
PrintColorFmtMsg_ERR(_T("\nError generating uninstaller icon: %s -- failing!\n"), CtoTString(e.what()));
PrintColorFmtMsg_ERR(_T("\nError generating uninstaller icon: %s -- failing!\n"), CtoTStrParam(e.what()));
return 0;
}

View file

@ -751,7 +751,7 @@ int CEXEBuild::GenerateLangTables() {
#undef ADD_FONT
}
catch (exception& err) {
ERROR_MSG(_T("\nError while applying font: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("\nError while applying font: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
}
@ -814,7 +814,7 @@ int CEXEBuild::GenerateLangTables() {
#undef ADD_FONT
}
catch (exception& err) {
ERROR_MSG(_T("\nError while applying NLF font/RTL: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("\nError while applying NLF font/RTL: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}

View file

@ -28,6 +28,7 @@
#include "build.h"
#include "util.h"
#include "utf.h"
#include <nsis-version.h>
#include <fcntl.h>
@ -135,27 +136,29 @@ static void print_license()
static void print_usage()
{
_ftprintf(g_output,_T("Usage:\n")
_T(" makensis [option | script.nsi | - [...]]\n")
_T(" options are:\n")
_T(" ") OPT_STR _T("CMDHELP item prints out help for 'item', or lists all commands\n")
_T(" ") OPT_STR _T("HDRINFO prints information about what options makensis was compiled with\n")
_T(" ") OPT_STR _T("LICENSE prints the makensis software license\n")
_T(" ") OPT_STR _T("VERSION prints the makensis version and exits\n")
_T(" ") OPT_STR _T("Px sets the compiler process priority, where x is 5=realtime,4=high,\n")
_T(" ") _T(" 3=above normal,2=normal,1=below normal,0=idle\n")
_T(" ") OPT_STR _T("Vx verbosity where x is 4=all,3=no script,2=no info,1=no warnings,0=none\n")
_T(" ") OPT_STR _T("Ofile specifies a text file to log compiler output (default is stdout)\n")
_T(" ") OPT_STR _T("PAUSE pauses after execution\n")
_T(" ") OPT_STR _T("NOCONFIG disables inclusion of <path to makensis.exe>") PLATFORM_PATH_SEPARATOR_STR _T("nsisconf.nsh\n")
_T(" ") OPT_STR _T("NOCD disabled the current directory change to that of the .nsi file\n")
_T(" ") OPT_STR _T("Ddefine[=value] defines the symbol \"define\" for the script [to value]\n")
_T(" ") OPT_STR _T("Xscriptcmd executes scriptcmd in script (i.e. \"") OPT_STR _T("XOutFile poop.exe\")\n")
_T(" parameters are processed by order (") OPT_STR _T("Ddef ins.nsi != ins.nsi ") OPT_STR _T("Ddef)\n")
_T(" for script file name, you can use - to read from the standard input\n")
#ifdef _WIN32
_T(" you can also use - as an option character: -PAUSE as well as /PAUSE\n")
_T(" ") _T("makensis [ option | script.nsi | - ] [...]\n")
_T("\n")
_T("Options:\n")
_T(" ") OPT_STR _T("CMDHELP item prints out help for 'item', or lists all commands\n")
_T(" ") OPT_STR _T("HDRINFO prints information about what options makensis was compiled with\n")
_T(" ") OPT_STR _T("LICENSE prints the makensis software license\n")
_T(" ") OPT_STR _T("VERSION prints the makensis version and exits\n")
_T(" ") OPT_STR _T("Px sets the compiler process priority, where x is 5=realtime,4=high,\n")
_T(" ") _T(" 3=above normal,2=normal,1=below normal,0=idle\n")
_T(" ") OPT_STR _T("Vx verbosity where x is 4=all,3=no script,2=no info,1=no warnings,0=none\n")
_T(" ") OPT_STR _T("Ofile specifies a text file to log compiler output (default is stdout)\n")
_T(" ") OPT_STR _T("PAUSE pauses after execution\n")
_T(" ") OPT_STR _T("NOCONFIG disables inclusion of <path to makensis.exe>") PLATFORM_PATH_SEPARATOR_STR _T("nsisconf.nsh\n")
_T(" ") OPT_STR _T("NOCD disabled the current directory change to that of the .nsi file\n")
_T(" ") OPT_STR _T("Ddefine[=value] defines the symbol \"define\" for the script [to value]\n")
_T(" ") OPT_STR _T("Xscriptcmd executes scriptcmd in script (i.e. \"") OPT_STR _T("XOutFile poop.exe\")\n")
_T(" ") _T(" parameters are processed by order (") OPT_STR _T("Ddef ins.nsi != ins.nsi ") OPT_STR _T("Ddef)\n")
_T("\n")
_T("For script file name, you can use - to read from the standard input\n")
#ifdef _WIN32
_T("You can also use - as an option character: -PAUSE as well as /PAUSE\n")
#endif
_T(" you can use a double-dash to end options processing: makensis -- -ins.nsi\n"));
_T("You can use a double-dash to end options processing: makensis -- -ins.nsi\n"));
fflush(g_output);
}
@ -202,26 +205,15 @@ static int process_config(CEXEBuild& build, tstring& conf)
FILE *cfg=FOPENTEXT2(conf.c_str(),"rt",&unicode);
if (cfg)
{
if (build.display_script)
{
_ftprintf(g_output,_T("Processing config: \n"));
fflush(g_output);
}
build.INFO_MSG(_T("Processing config: %s\n"), conf.c_str());
int ret=build.process_script(cfg,(TCHAR*)conf.c_str(),unicode);
fclose(cfg);
if (ret != PS_OK && ret != PS_EOF)
{
if (build.display_errors)
{
PrintColorFmtMsg_ERR(_T("Error in config on line %d -- aborting creation process\n"),build.linecnt);
}
build.ERROR_MSG(_T("Error in config on line %d -- aborting creation process\n"),build.linecnt);
return 1;
}
if (build.display_script)
{
_ftprintf(g_output,_T("\n"));
fflush(g_output);
}
build.SCRIPT_MSG(_T("\n")); // Extra newline to separate the config from the real script
}
return 0;
}
@ -231,24 +223,13 @@ static int change_to_script_dir(CEXEBuild& build, tstring& script)
tstring dir = get_dir_name(get_full_path(script));
if (!dir.empty())
{
if (build.display_script)
{
_ftprintf(g_output,_T("Changing directory to: \"%s\"\n"),dir.c_str());
fflush(g_output);
}
build.SCRIPT_MSG(_T("Changing directory to: \"%s\"\n"),dir.c_str());
if (_tchdir(dir.c_str()))
{
if (build.display_errors)
{
PrintColorFmtMsg_ERR(_T("Error changing directory to \"%s\"\n"),dir.c_str());
}
build.ERROR_MSG(_T("Error changing directory to \"%s\"\n"),dir.c_str());
return 1;
}
if (build.display_script)
{
_ftprintf(g_output,_T("\n"));
fflush(g_output);
}
build.SCRIPT_MSG(_T("\n"));
}
return 0;
}
@ -257,6 +238,7 @@ static int change_to_script_dir(CEXEBuild& build, tstring& script)
extern "C" void allow_unaligned_data_access();
#endif
NSIS_ENTRYPOINT_TMAIN
int _tmain(int argc, TCHAR **argv)
{
@ -277,8 +259,8 @@ int _tmain(int argc, TCHAR **argv)
int in_files=0;
#ifdef _UNICODE
#if (defined(_MSC_VER) && (_MSC_VER<=1200))
const int _O_U8TEXT=0x40000; // BUGBUG: This is bogus
#ifndef _O_U8TEXT
const int _O_U8TEXT=0x40000; // BUGBUG: This is bogus (Makensis will ONLY work on NT6)
#endif
_setmode(_fileno(stdout), _O_U8TEXT); // set stdout to UTF-8
#ifdef _WIN32
@ -292,7 +274,7 @@ int _tmain(int argc, TCHAR **argv)
}
catch (exception& err)
{
PrintColorFmtMsg_ERR(_T("Error initalizing CEXEBuild: %s\n"), CtoTString(err.what()));
PrintColorFmtMsg_ERR(_T("Error initalizing CEXEBuild: %s\n"), CtoTStrParam(err.what()));
return 1;
}
@ -302,18 +284,18 @@ int _tmain(int argc, TCHAR **argv)
fflush(g_output);
return 0;
}
if (argc > 1 && IS_OPT(argv[tmpargpos]) && (argv[tmpargpos][1]==_T('v') || argv[tmpargpos][1]==_T('V')))
if (argc > 1 && IS_OPT(argv[tmpargpos]) && S7IsChEqualI('v',argv[tmpargpos][1]))
{
if (argv[tmpargpos][2] <= _T('2') && argv[tmpargpos][2] >= _T('0'))
{
no_logo=1;
}
tmpargpos++;
tmpargpos++;
}
if (!no_logo)
{
if (argc > tmpargpos && IS_OPT(argv[tmpargpos]) && (argv[tmpargpos][1]==_T('o') || argv[tmpargpos][1]==_T('O')) && argv[tmpargpos][2])
if (argc > tmpargpos && IS_OPT(argv[tmpargpos]) && S7IsChEqualI('o',argv[tmpargpos][1]) && argv[tmpargpos][2])
{
g_output=FOPENTEXT(argv[tmpargpos]+2,"w");
if (!g_output)
@ -335,21 +317,17 @@ int _tmain(int argc, TCHAR **argv)
in_files=1;
else if (IS_OPT(argv[argpos]) && _tcscmp(argv[argpos], _T("-")) && !in_files)
{
if ((argv[argpos][1]==_T('D') || argv[argpos][1]==_T('d')) && argv[argpos][2])
if (S7IsChEqualI('d',argv[argpos][1]) && argv[argpos][2])
{
TCHAR *p=argv[argpos]+2;
TCHAR *s=_tcsdup(p),*v;
if (build.display_script)
{
_ftprintf(g_output,_T("Command line defined: \"%s\"\n"),p);
fflush(g_output);
}
build.SCRIPT_MSG(_T("Command line defined: \"%s\"\n"),p);
v=_tcsstr(s,_T("="));
if (v) *v++=0;
build.define(s,v?v:_T(""));
free(s);
}
else if ((argv[argpos][1]==_T('X') || argv[argpos][1]==_T('x')) && argv[argpos][2])
else if (S7IsChEqualI('x',argv[argpos][1]) && argv[argpos][2])
{
if (build.process_oneline(argv[argpos]+2,_T("command line"),argpos+1) != PS_OK)
{
@ -357,7 +335,7 @@ int _tmain(int argc, TCHAR **argv)
}
cmds_processed++;
}
else if ((argv[argpos][1]==_T('O') || argv[argpos][1]==_T('o')) && argv[argpos][2])
else if (S7IsChEqualI('o',argv[argpos][1]) && argv[argpos][2])
{
if (!outputtried)
{
@ -371,7 +349,7 @@ int _tmain(int argc, TCHAR **argv)
}
}
else if (!_tcsicmp(&argv[argpos][1],_T("NOCD"))) do_cd=0;
else if ((argv[argpos][1] == _T('V') || argv[argpos][1] == _T('v')) &&
else if (S7IsChEqualI('v',argv[argpos][1]) &&
argv[argpos][2] >= _T('0') && argv[argpos][2] <= _T('4') && !argv[argpos][3])
{
int v=argv[argpos][2]-_T('0');
@ -415,7 +393,7 @@ int _tmain(int argc, TCHAR **argv)
print_stub_info(build);
nousage++;
}
else if ((argv[argpos][1]==_T('P') || argv[argpos][1]==_T('p')) &&
else if (S7IsChEqualI('p',argv[argpos][1]) &&
argv[argpos][2] >= _T('0') && argv[argpos][2] <= _T('5') && !argv[argpos][3])
{
#ifdef _WIN32
@ -504,11 +482,8 @@ int _tmain(int argc, TCHAR **argv)
fp=FOPENTEXT2(sfile,"rt",&unicode);
if (!fp)
{
if (build.display_errors)
{
sfile[_tcslen(sfile)-4]=0;
PrintColorFmtMsg_ERR(_T("Can't open script \"%s\"\n"),sfile);
}
sfile[_tcslen(sfile)-4]=0;
build.ERROR_MSG(_T("Can't open script \"%s\"\n"),sfile);
return 1;
}
}
@ -521,21 +496,14 @@ int _tmain(int argc, TCHAR **argv)
build.set_default_output_filename(remove_file_extension(sfile)+_T(".exe"));
}
if (build.display_script)
{
build.notify(MAKENSIS_NOTIFY_SCRIPT,sfile);
_ftprintf(g_output,_T("Processing script file: \"%s\"\n"),sfile);
fflush(g_output);
}
build.notify(MAKENSIS_NOTIFY_SCRIPT,sfile);
build.INFO_MSG(_T("Processing script file: \"%s\"\n"),sfile);
int ret=build.process_script(fp,sfile,unicode);
if (fp != stdin) fclose(fp);
if (ret != PS_EOF && ret != PS_OK)
{
if (build.display_errors)
{
PrintColorFmtMsg_ERR(_T("Error in script \"%s\" on line %d -- aborting creation process\n"),sfile,build.linecnt);
}
build.ERROR_MSG(_T("Error in script \"%s\" on line %d -- aborting creation process\n"),sfile,build.linecnt);
return 1;
}
}
@ -557,16 +525,13 @@ int _tmain(int argc, TCHAR **argv)
_ftprintf(g_output,_T("\nProcessed "));
if (files_processed) _ftprintf(g_output,_T("%d file%s, "),files_processed,files_processed==1?_T(""):_T("s"));
if (cmds_processed) _ftprintf(g_output,_T("%d command line command%s, "),cmds_processed,cmds_processed==1?_T(""):_T("s"));
_ftprintf(g_output,_T("writing output:\n"));
_ftprintf(g_output,_T("writing output (%s):\n"),build.get_target_suffix());
fflush(g_output);
}
if (build.write_output())
{
if (build.display_errors)
{
PrintColorFmtMsg_ERR(_T("Error - aborting creation process\n"));
}
build.ERROR_MSG(_T("Error - aborting creation process\n"));
return 1;
}
return 0;

View file

@ -20,6 +20,7 @@
#include "manifest.h"
#include <nsis-version.h>
#include "tstring.h"
#include "utf.h"
// Jim Park: The manifest must stay UTF-8. Do not convert.
@ -53,9 +54,9 @@ bool SupportedOSList::append(const TCHAR* osid)
guid = osid;
}
}
else if (!_tcsicmp(osid,"WinVista")) guid = _T("{e2011457-1546-43c5-a5fe-008deee3d3f0}");
else if (!_tcsicmp(osid,"Win7")) guid = _T("{35138b9a-5d96-4fbd-8e2d-a2440225f93a}");
else if (!_tcsicmp(osid,"Win8")) guid = _T("{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}");
else if (!_tcsicmp(osid,_T("WinVista"))) guid = _T("{e2011457-1546-43c5-a5fe-008deee3d3f0}");
else if (!_tcsicmp(osid,_T("Win7"))) guid = _T("{35138b9a-5d96-4fbd-8e2d-a2440225f93a}");
else if (!_tcsicmp(osid,_T("Win8"))) guid = _T("{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}");
if (guid)
{
@ -113,8 +114,14 @@ string generate(comctl comctl_selection, exec_level exec_level_selection, dpiawa
int soslcount = sosl.getcount();
if (soslcount)
{
char buf[38+1];
xml += "<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\"><application>";
while(soslcount--) xml += "<supportedOS Id=\"", xml += sosl.get(soslcount), xml += "\"/>";
while(soslcount--)
{
xml += "<supportedOS Id=\"";
RawTStrToASCII(sosl.get(soslcount), buf, COUNTOF(buf));
xml += buf, xml += "\"/>";
}
xml += "</application></compatibility>";
}

View file

@ -68,15 +68,15 @@ namespace manifest
}
void addall()
{
append("WinVista");
append("Win7");
append("Win8");
append(_T("WinVista"));
append(_T("Win7"));
append(_T("Win8"));
}
void setdefault()
{
m_list.deleteall();
append("Win7");
append("Win8");
append(_T("Win7"));
append(_T("Win8"));
m_isdefaultlist = true;
}
};

View file

@ -389,7 +389,8 @@ parse_again:
// Added by Ximon Eighteen 5th August 2002
// We didn't recognise this command, could it be the name of a
// function exported from a dll?
if (m_plugins.IsPluginCommand(line.gettoken_str(0)))
// Plugins cannot be called in global scope so there is no need to initialize the list first
if (m_pPlugins && m_pPlugins->IsPluginCommand(line.gettoken_str(0)))
{
np = 0; // parameters are optional
op = -1; // unlimited number of optional parameters
@ -914,7 +915,7 @@ int CEXEBuild::LoadLicenseFile(TCHAR *file, TCHAR** pdata, LineParser &line, BOO
MANAGE_WITH(fp, fclose);
unsigned int beginning=ftell(fp); // (we might be positionned after a BOM)
fseek(fp,0,SEEK_END);
unsigned int datalen=ftell(fp)-beginning; // size of file in bytes! not a number of character
unsigned int datalen=ftell(fp)-beginning; // size of file in bytes! not a number of characters
if (!datalen)
{
ERROR_MSG(_T("%s: empty license file \"%s\"\n"),line.gettoken_str(0),file);
@ -929,16 +930,23 @@ int CEXEBuild::LoadLicenseFile(TCHAR *file, TCHAR** pdata, LineParser &line, BOO
}
*pdata = data; // memory will be released by caller
TCHAR *ldata=data+1;
while (_fgetts(ldata, data+datalen+2-ldata, fp)) // _fgetts translate ANSI/UTF8 characters to TCHAR
while (_fgetts(ldata, data+datalen+2-ldata, fp)) // _fgetts translates ANSI/UTF8 characters to TCHAR //BUGBUG: There is no reason to store ASCII files as TCHAR
ldata += _tcslen(ldata);
if (ferror(fp))
{
ERROR_MSG(_T("%s: can't read file.\n"),line.gettoken_str(0));
return PS_ERROR;
}
bool disallowrichedunicode = false;
#ifdef _UNICODE
if (!build_unicode)
disallowrichedunicode = true; //RichEdit 1.0 does not support unicode
else
*unicode = true; // _fgetts converted to TCHAR
#endif
if (!memcmp(data+1,_T("{\\rtf"),5*sizeof(TCHAR)))
*data = SF_RTF;
else if (*unicode)
else if (*unicode && !disallowrichedunicode)
*data = SF_TEXT|SF_UNICODE;
else
*data = SF_TEXT;
@ -1020,7 +1028,6 @@ int CEXEBuild::process_jump(LineParser &line, int wt, int *offs)
return 0;
}
#define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags_t, flag)/sizeof(int))
#define SECTION_FIELD_GET(field) (FIELD_OFFSET(section, field)/sizeof(int))
#define SECTION_FIELD_SET(field) (-1 - (int)(FIELD_OFFSET(section, field)/sizeof(int)))
@ -1036,7 +1043,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
};
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
build_plugin_table();
if (PS_OK != initialize_default_plugins()) return PS_ERROR;
#endif
multiple_entries_instruction=0;
@ -1820,7 +1827,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
installer_icon = load_icon_file(line.gettoken_str(1));
}
catch (exception& err) {
ERROR_MSG(_T("Error while loading icon from \"%s\": %s\n"), line.gettoken_str(1), CtoTString(err.what()));
ERROR_MSG(_T("Error while loading icon from \"%s\": %s\n"), line.gettoken_str(1), CtoTStrParam(err.what()));
return PS_ERROR;
}
return PS_OK;
@ -1849,7 +1856,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
}
}
catch (exception& err) {
ERROR_MSG(_T("Error while replacing bitmap: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("Error while replacing bitmap: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
return PS_OK;
@ -2316,7 +2323,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
delete [] dlg;
}
catch (exception& err) {
ERROR_MSG(_T("Error setting smooth progress bar: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("Error setting smooth progress bar: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
SCRIPT_MSG(_T("InstProgressFlags: smooth=%d, colored=%d\n"),smooth,
@ -2694,7 +2701,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
SCRIPT_MSG(_T("ChangeUI: %s %s%s\n"), line.gettoken_str(1), line.gettoken_str(2), branding_image_found?_T(" (branding image holder found)"):_T(""));
}
catch (exception& err) {
ERROR_MSG(_T("Error while changing UI: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("Error while changing UI: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
return PS_OK;
@ -2768,7 +2775,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
branding_image_id = IDC_BRANDIMAGE;
}
catch (exception& err) {
ERROR_MSG(_T("Error while adding image branding support: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("Error while adding image branding support: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
return PS_OK;
@ -2840,25 +2847,13 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
#endif// NSIS_CONFIG_VISIBLE_SUPPORT
case TOK_REQEXECLEVEL:
switch (line.gettoken_enum(1,_T("none\0user\0highest\0admin\0")))
{
int k=line.gettoken_enum(1,_T("none\0user\0highest\0admin\0"));
switch (k)
{
case 0:
manifest_exec_level = manifest::exec_level_none;
break;
case 1:
manifest_exec_level = manifest::exec_level_user;
break;
case 2:
manifest_exec_level = manifest::exec_level_highest;
break;
case 3:
manifest_exec_level = manifest::exec_level_admin;
break;
default:
PRINTHELP();
}
case 0: manifest_exec_level = manifest::exec_level_none; break;
case 1: manifest_exec_level = manifest::exec_level_user; break;
case 2: manifest_exec_level = manifest::exec_level_highest; break;
case 3: manifest_exec_level = manifest::exec_level_admin; break;
default: PRINTHELP();
}
return PS_OK;
@ -2887,7 +2882,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
return PS_OK;
}
}
for(int argi=1; argi<line.getnumtokens(); ++argi)
for(int argi = 1; argi < line.getnumtokens(); ++argi)
{
if (!manifest_sosl.append(line.gettoken_str(argi)))
PRINTHELP();
@ -2896,21 +2891,21 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
return PS_OK;
#ifdef _UNICODE
case TOK_TARGETMINIMALOS:
case TOK_TARGETUNICODE:
{
if (build_compressor_set) {
ERROR_MSG(_T("Error: can't change target minimal OS version after data already got compressed or header already changed!\n"));
return PS_ERROR;
}
int major = 0, minor = 0;
if (_stscanf(line.gettoken_str(1), _T("%d.%d"), &major, &minor) == 0)
PRINTHELP()
if (set_target_minimal_OS(major,minor) != PS_OK) // Windows 5.0 or more recent requested? => Unicode support
if (build_compressor_set)
{
ERROR_MSG(_T("Error: error while setting target minimal OS! (adequate stub not found?)\n"));
ERROR_MSG(_T("Error: Can't change target charset after data already got compressed or header already changed!\n"));
return PS_ERROR;
}
int k = line.gettoken_enum(1,_T("false\0true\0"));
if (-1==k) PRINTHELP();
SCRIPT_MSG(_T("Unicode: %s\n"),k?_T("true"):_T("false"));
if (set_target_charset(!!k) != PS_OK)
{
ERROR_MSG(_T("Error: Unable to set target charset (adequate stub not found?)\n"));
return PS_ERROR;
}
SCRIPT_MSG(_T("TargetMinimalOS: %d.%d %s\n"),major,minor,build_unicode?_T("(Unicode installer)"):_T(""));
}
return PS_OK;
#endif
@ -3604,7 +3599,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
uninstaller_icon = load_icon_file(line.gettoken_str(1));
}
catch (exception& err) {
ERROR_MSG(_T("Error while loading icon from \"%s\": %s\n"), line.gettoken_str(1), CtoTString(err.what()));
ERROR_MSG(_T("Error while loading icon from \"%s\": %s\n"), line.gettoken_str(1), CtoTStrParam(err.what()));
return PS_ERROR;
}
return PS_OK;
@ -3964,7 +3959,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
res_editor->FreeResource(dlg);
}
catch (exception& err) {
ERROR_MSG(_T("Error while triming branding text control: %s\n"), CtoTString(err.what()));
ERROR_MSG(_T("Error while triming branding text control: %s\n"), CtoTStrParam(err.what()));
return PS_ERROR;
}
#else
@ -6228,12 +6223,32 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
case TOK_PLUGINDIR:
{
if (line.getnumtokens() == 2)
CEXEBuild::TARGETTYPE tt = m_target_type;
int numtok = line.getnumtokens() - 1;
TCHAR *path = line.gettoken_str(numtok);
if (2 == numtok)
{
SCRIPT_MSG(_T("PluginDir: \"%s\"\n"),line.gettoken_str(1));
TCHAR *path = line.gettoken_str(1);
const TCHAR* arcstr = line.gettoken_str(--numtok);
tt = get_target_type(arcstr+1);
if (_T('/') != arcstr[0] || CEXEBuild::TARGET_UNKNOWN == tt)
{
tstring es = get_commandtoken_name(which_token);
es += _T(": Target parameter must be one of: /");
for(int i = CEXEBuild::TARGETFIRST; i < CEXEBuild::TARGETCOUNT; ++i)
{
tt = (CEXEBuild::TARGETTYPE) i;
if (CEXEBuild::TARGETFIRST != tt) es += _T(", /");
es += get_target_suffix(tt);
}
ERROR_MSG(_T("Error: %s\n"),es.c_str());
return PS_ERROR;
}
}
if (1 == numtok)
{
SCRIPT_MSG(_T("PluginDir: \"%s\"\n"),path);
PATH_CONVERT(path);
m_plugins.FindCommands(path, display_info?true:false);
m_plugins[tt].AddPluginsDir(path, !!display_script);
return PS_OK;
}
}
@ -6241,18 +6256,18 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
case TOK__PLUGINCOMMAND:
{
int ret;
tstring command, dllPath;
if (!m_pPlugins->GetCommandInfo(line.gettoken_str(0), command, dllPath))
{
ERROR_MSG(_T("Plugin command %s conflicts with a plugin in another directory!\n"),command.c_str());
return PS_ERROR;
}
tstring command = m_plugins.NormalizedCommand(line.gettoken_str(0));
#ifdef _UNICODE
if (build_unicode)
command = m_plugins.UseUnicodeVariant(command);
#endif
tstring dllPath = m_plugins.GetPluginPath(command);
tstring dllName = get_file_name(dllPath);
int data_handle = m_plugins.GetPluginHandle(uninstall_mode?true:false, command);
int data_handle = m_pPlugins->GetDllDataHandle(!!uninstall_mode, command);
if (uninstall_mode) uninst_plugin_used = true;
else plugin_used = true;
if (uninstall_mode) uninst_plugin_used = true; else plugin_used = true;
// Initialize $PLUGINSDIR
ent.which=EW_CALL;
@ -6285,7 +6300,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
if (ret != PS_OK) {
return ret;
}
m_plugins.SetDllDataHandle(uninstall_mode?true:false, line.gettoken_str(0), data_handle);
m_pPlugins->SetDllDataHandle(!!uninstall_mode, command, data_handle);
build_overwrite=old_build_overwrite;
build_datesave=old_build_datesave;
// Added by ramon 23 May 2003

View file

@ -101,7 +101,7 @@ int MLStringList::add(const TCHAR *str, WORD codepage /*= CP_ACP*/, bool process
delete[] ansiBuf;
if (len != cbMultiByte)
{ // resize buffers to align future strings on same offsets
len = a+max(len,cbMultiByte);
len = a + STD_MAX(len,cbMultiByte);
m_gr.resize(len*sizeof(TCHAR));
m_grAnsi.resize(len);
}

View file

@ -276,7 +276,6 @@ class SortedStringList
TinyGrowBuf m_gr;
};
#define mymin(x, y) ((x < y) ? x : y)
/**
* This class maintains a list of T types in a GrowBuf sorted by T.name which
@ -394,9 +393,9 @@ class SortedStringListND // no delete - can be placed in GrowBuf
{
unsigned int pCurr_len = _tcslen(pCurr);
if (case_sensitive)
res = _tcsncmp(str, pCurr, mymin((unsigned int) n_chars, pCurr_len));
res = _tcsncmp(str, pCurr, STD_MIN((unsigned int) n_chars, pCurr_len));
else
res = _tcsnicmp(str, pCurr, mymin((unsigned int) n_chars, pCurr_len));
res = _tcsnicmp(str, pCurr, STD_MIN((unsigned int) n_chars, pCurr_len));
// If there is a match and we are looking for a partial match and
// n_chars is NOT the length of the current string, then the

View file

@ -14,21 +14,32 @@
// Jim Park: Only those we use are listed here.
#pragma once
#ifdef _UNICODE
#include <wchar.h>
#ifndef _T
#define __T(x) L ## x
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
#endif
#if defined(_MSC_VER) && (_MSC_VER<=1200)
typedef unsigned short TCHAR;
typedef unsigned short _TUCHAR;
#if !defined(_WIN32) && defined(EXEHEAD)
typedef unsigned short TCHAR, _TUCHAR;
#else
typedef wchar_t TCHAR;
typedef wchar_t _TUCHAR;
// MinGW typedefs TCHAR and _TCHAR inside #ifndef _TCHAR_DEFINED
// MSVC typedefs TCHAR inside #ifndef _TCHAR_DEFINED
// and _TCHAR and _T*CHAR inside #ifndef __TCHAR_DEFINED.
// We don't want to break MSVCs _TSCHAR and _TXCHAR so we don't protect our typedef...
#if (_MSC_VER>1 && (_MSC_VER<1400 || !defined(_NATIVE_WCHAR_T_DEFINED))) || !defined(_WCHAR_T_DEFINED)
// VC6 knows about __wchar_t but does not support it. /Zc:wchar_t is on by default starting with VC8.
// VC7.1 supports __wchar_t but using it causes problems with conversions from WCHAR (unsigned short)?
typedef unsigned short TCHAR, _TUCHAR;
#else
typedef wchar_t TCHAR, _TUCHAR;
#endif
#endif
// program
#define _tmain wmain
@ -39,7 +50,7 @@ typedef wchar_t _TUCHAR;
// printfs
#define _ftprintf fwprintf
#define _sntprintf _snwprintf
#if defined(_MSC_VER) && (_MSC_VER<=1200)
#if (defined(_MSC_VER) && (_MSC_VER<=1310)) || defined(__MINGW32__)
# define _stprintf swprintf
#else
# define _stprintf _swprintf
@ -47,7 +58,7 @@ typedef wchar_t _TUCHAR;
#define _tprintf wprintf
#define _vftprintf vfwprintf
#define _vsntprintf _vsnwprintf
#if defined(_MSC_VER) && (_MSC_VER<=1200)
#if defined(_MSC_VER) && (_MSC_VER<=1310)
# define _vstprintf vswprintf
#else
# define _vstprintf _vswprintf
@ -132,9 +143,11 @@ typedef wchar_t _TUCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif
typedef char TCHAR;
typedef unsigned char _TUCHAR;
// program
#define _tmain main
#define _tWinMain WinMain

View file

@ -218,7 +218,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_STRLEN,_T("StrLen"),2,0,_T("$(user_var: length output) str"),TP_CODE},
{TOK_SUBCAPTION,_T("SubCaption"),2,0,_T("page_number(0-4) new_subcaption"),TP_GLOBAL},
#ifdef _UNICODE
{TOK_TARGETMINIMALOS,_T("TargetMinimalOS"),1,0,_T("windows_version"),TP_GLOBAL},
{TOK_TARGETUNICODE,_T("Unicode"),1,0,_T("true|false"),TP_GLOBAL},
#endif
{TOK_UNINSTALLEXENAME,_T("UninstallExeName"),0,0,_T("no longer supported, use WriteUninstaller from section."),TP_ALL},
{TOK_UNINSTCAPTION,_T("UninstallCaption"),1,0,_T("uninstaller_caption"),TP_GLOBAL},
@ -288,7 +288,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_GETLABELADDR,_T("GetLabelAddress"),2,0,_T("output label"),TP_CODE},
{TOK_GETCURRENTADDR,_T("GetCurrentAddress"),1,0,_T("output"),TP_CODE},
{TOK_PLUGINDIR,_T("!AddPluginDir"),1,0,_T("new_plugin_directory"),TP_ALL},
{TOK_PLUGINDIR,_T("!AddPluginDir"),1,1,_T("[/target] new_plugin_directory"),TP_ALL},
{TOK_INITPLUGINSDIR,_T("InitPluginsDir"),0,0,_T(""),TP_CODE},
// Added by ramon 23 May 2003
{TOK_ALLOWSKIPFILES,_T("AllowSkipFiles"),1,0,_T("(off|on)"),TP_ALL},
@ -301,6 +301,13 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_LOCKWINDOW,_T("LockWindow"),1,0,_T("(on|off)"),TP_CODE},
};
const TCHAR* CEXEBuild::get_commandtoken_name(int tok)
{
for (int x = 0; x < TOK__LAST; ++x)
if (tokenlist[x].id==tok) return tokenlist[x].name;
return 0;
}
void CEXEBuild::print_help(TCHAR *commandname)
{
int x;

View file

@ -74,7 +74,7 @@ enum
TOK_VI_SETPRODUCTVERSION,
TOK_VI_SETFILEVERSION,
#ifdef _UNICODE
TOK_TARGETMINIMALOS,
TOK_TARGETUNICODE,
#endif
TOK_MISCBUTTONTEXT,

View file

@ -18,12 +18,13 @@
#include "validateunicode.h"
#include "util.h"
#include <vector>
#include <stdio.h>
FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode, BOOL* unicode)
{
extern FILE *g_output;
CValidateUnicode::FILE_TYPE ftype = CValidateUnicode::UTF_8; // default file format is UTF-8
if (unicode) *unicode = TRUE;
if (unicode) *unicode = TRUE;
// If we are reading an existing file, check to see what type of file it
// is first.
@ -34,50 +35,50 @@ FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode, BOOL* unicode)
if (fp)
{
MANAGE_WITH(fp, fclose);
MANAGE_WITH(fp, fclose);
fseek(fp, 0, SEEK_END);
size_t fileSize = ftell(fp);
if (fileSize == 0)
{
// Empty files are treated as UTF-8.
ftype = CValidateUnicode::UTF_8;
// Empty files are treated as UTF-8.
ftype = CValidateUnicode::UTF_8;
}
else
{
std::vector<unsigned char> buffer(fileSize);
fseek(fp, 0, SEEK_SET);
fread(&buffer[0], sizeof(unsigned char), fileSize, fp);
std::vector<unsigned char> buffer(fileSize);
fseek(fp, 0, SEEK_SET);
fread(&buffer[0], sizeof(unsigned char), fileSize, fp);
ftype = CValidateUnicode::CheckBOM(&buffer[0], buffer.size());
ftype = CValidateUnicode::CheckBOM(&buffer[0], buffer.size());
switch (ftype)
{
case CValidateUnicode::UTF_8:
case CValidateUnicode::UTF_16LE:
case CValidateUnicode::UTF_16BE:
break;
case CValidateUnicode::UTF_32LE:
case CValidateUnicode::UTF_32BE:
PrintColorFmtMsg_ERR(_T("File '%s' has a BOM marked as %s which is not supported at this time.\n"),
file, CValidateUnicode::TypeToName(ftype));
exit(-1);
break;
case CValidateUnicode::UNKNOWN:
// If unknown, let's see if it's not just UTF_8 without a BOM.
if (CValidateUnicode::ValidateUTF8(&buffer[0], buffer.size()) == 2)
{
// contains UTF-8 characters sequences
_ftprintf(g_output, _T("File '%s' has no BOM but seems to be UTF-8.\n"), file);
ftype = CValidateUnicode::UTF_8;
}
break;
default:
PrintColorFmtMsg_ERR(_T("CValidateUnicode::CheckBOM() for file '%s' returned an unknown return value: %d\n"),
file, ftype);
exit(-1);
break;
}
}
switch (ftype)
{
case CValidateUnicode::UTF_8:
case CValidateUnicode::UTF_16LE:
case CValidateUnicode::UTF_16BE:
break;
case CValidateUnicode::UTF_32LE:
case CValidateUnicode::UTF_32BE:
PrintColorFmtMsg_ERR(_T("File '%s' has a BOM marked as %s which is not supported at this time.\n"),
file, CValidateUnicode::TypeToName(ftype));
exit(-1);
break;
case CValidateUnicode::UNKNOWN:
// If unknown, let's see if it's not just UTF_8 without a BOM.
if (CValidateUnicode::ValidateUTF8(&buffer[0], buffer.size()) == 2)
{
// contains UTF-8 characters sequences
_ftprintf(g_output, _T("File '%s' has no BOM but seems to be UTF-8.\n"), file);
ftype = CValidateUnicode::UTF_8;
}
break;
default:
PrintColorFmtMsg_ERR(_T("CValidateUnicode::CheckBOM() for file '%s' returned an unknown return value: %d\n"),
file, ftype);
exit(-1);
break;
}
}
}
}
@ -93,7 +94,7 @@ FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode, BOOL* unicode)
break;
default:
// Looks like fopen() doesn't support other encodings of Unicode.
if (unicode) *unicode = FALSE;
if (unicode) *unicode = FALSE;
break;
}

View file

@ -45,8 +45,11 @@ typedef std::ifstream tifstream;
#define CtoTString(str) (str)
#define CtoTString2(str,cp) (str)
#define TtoCString(str) (str)
#define CtoTStrParam CtoTString
#else
#define CtoTString2(str,cp) CtoTString(str,cp)
#define CtoTString2(str,cp) CtoTString((str),(cp))
#define CtoTStrParam(str) ( (const TCHAR*) CtoTString((str)) ) // Use this when passing as a vararg parameter
// This is a helpful little function for converting exceptions or
// other system type things that come back ANSI and must be
@ -75,7 +78,8 @@ public:
~CtoTString() { free(m_wStr); m_wStr = 0; }
operator const wchar_t*() { return m_wStr; }
operator const wchar_t*() const { return GetTStr(); }
inline const wchar_t*GetTStr() const { return m_wStr; }
private:
wchar_t* m_wStr;

View file

@ -35,6 +35,14 @@ static EXEHEADWCHAR_T* ExeHeadWStrAlloc(UINT cch)
}
#ifdef _UNICODE
void RawTStrToASCII(const TCHAR*in,char*out,UINT maxcch)
{
const bool empty = !maxcch;
for(; maxcch && *in; --maxcch) *out++ = (char) *in++;
if (!empty) *out = 0;
}
#else // !_UNICODE
EXEHEADTCHAR_T* UTF8ToExeHeadTStrDup(LPCSTR StrU8,UINT Codepage)

View file

@ -28,6 +28,7 @@ typedef unsigned short EXEHEADWCHAR_T;
#ifdef _UNICODE
typedef EXEHEADWCHAR_T EXEHEADTCHAR_T;
void RawTStrToASCII(const TCHAR*in,char*out,UINT maxcch);
#else // !_UNICODE
typedef char EXEHEADTCHAR_T;
@ -39,8 +40,16 @@ inline EXEHEADTCHAR_T* ExeHeadTStrAlloc(UINT cb)
}
extern EXEHEADTCHAR_T* UTF8ToExeHeadTStrDup(LPCSTR StrU8,UINT Codepage);
inline void RawTStrToASCII(const TCHAR*in,char*out,UINT maxcch) { lstrcpyn(out,in,maxcch); }
#endif // ?_UNICODE
template<typename T> T S7ChLwr(T c) { return c>='A' && c<='Z' ? (T)(c|32) : c; }
template<typename T> T S7ChUpr(T c) { return c>='a' && c<='z' ? (T)(c-'a'+'A') : c; }
template<typename T> bool S7IsChEqualI(char ch,T cmp)
{
return cmp==(T)S7ChLwr(ch) || cmp==(T)S7ChUpr(ch);
}
/**
* Tries to peek at the first few bytes in the stream to determine if it is a UTF-8 BOM.

View file

@ -170,8 +170,8 @@ WCHAR *CharNextW(const WCHAR *s) {
}
char *CharNextExA(WORD codepage, const char *s, int flags) {
char buf[1024];
snprintf(buf, 1024, "CP%d", codepage);
char buf[30];
snprintf(buf, 30, "CP%d", codepage);
const char* orglocct = setlocale(LC_CTYPE, buf);
const char* np;

View file

@ -17,6 +17,7 @@
#define _VALIDATEUNICODE_
#include "tchar.h"
#include <stdio.h>
class CValidateUnicode
{