Commit 719085f1 authored by Ludovic Fauvet's avatar Ludovic Fauvet

nsis: compile the nsProcess plugin

The plugin is a NSIS helper used to find and kill a running process. It
is licensed under the same terms as NSIS (zlib/libpng).
parent 537acc94
!define nsProcess::FindProcess `!insertmacro nsProcess::FindProcess`
!macro nsProcess::FindProcess _FILE _ERR
nsProcess::_FindProcess /NOUNLOAD `${_FILE}`
Pop ${_ERR}
!macroend
!define nsProcess::KillProcess `!insertmacro nsProcess::KillProcess`
!macro nsProcess::KillProcess _FILE _ERR
nsProcess::_KillProcess /NOUNLOAD `${_FILE}`
Pop ${_ERR}
!macroend
!define nsProcess::CloseProcess `!insertmacro nsProcess::CloseProcess`
!macro nsProcess::CloseProcess _FILE _ERR
nsProcess::_CloseProcess /NOUNLOAD `${_FILE}`
Pop ${_ERR}
!macroend
!define nsProcess::Unload `!insertmacro nsProcess::Unload`
!macro nsProcess::Unload
nsProcess::_Unload
!macroend
/*
* apih
*
* This file is a part of NSIS.
*
* Copyright (C) 1999-2008 Nullsoft and Contributors
*
* Licensed under the zlib/libpng license (the "License");
* you may not use this file except in compliance with the License.
*
* Licence details can be found in the file COPYING.
*
* This software is provided 'as-is', without any express or implied
* warranty.
*/
#ifndef _NSIS_EXEHEAD_API_H_
#define _NSIS_EXEHEAD_API_H_
// Starting with NSIS 2.42, you can check the version of the plugin API in exec_flags->plugin_api_version
// The format is 0xXXXXYYYY where X is the major version and Y is the minor version (MAKELONG(y,x))
// When doing version checks, always remember to use >=, ex: if (pX->exec_flags->plugin_api_version >= NSISPIAPIVER_1_0) {}
#define NSISPIAPIVER_1_0 0x00010000
#define NSISPIAPIVER_CURR NSISPIAPIVER_1_0
// NSIS Plug-In Callback Messages
enum NSPIM
{
NSPIM_UNLOAD, // This is the last message a plugin gets, do final cleanup
NSPIM_GUIUNLOAD, // Called after .onGUIEnd
};
// Prototype for callbacks registered with extra_parameters->RegisterPluginCallback()
// Return NULL for unknown messages
// Should always be __cdecl for future expansion possibilities
typedef UINT_PTR (*NSISPLUGINCALLBACK)(enum NSPIM);
// extra_parameters data structures containing other interesting stuff
// but the stack, variables and HWND passed on to plug-ins.
typedef struct
{
int autoclose;
int all_user_var;
int exec_error;
int abort;
int exec_reboot; // NSIS_SUPPORT_REBOOT
int reboot_called; // NSIS_SUPPORT_REBOOT
int XXX_cur_insttype; // depreacted
int plugin_api_version; // see NSISPIAPIVER_CURR
// used to be XXX_insttype_changed
int silent; // NSIS_CONFIG_SILENT_SUPPORT
int instdir_error;
int rtl;
int errlvl;
int alter_reg_view;
int status_update;
} exec_flags_t;
#ifndef NSISCALL
# define NSISCALL __stdcall
#endif
typedef struct {
exec_flags_t *exec_flags;
int (NSISCALL *ExecuteCodeSegment)(int, HWND);
void (NSISCALL *validate_filename)(TCHAR *);
BOOL (NSISCALL *RegisterPluginCallback)(HMODULE, NSISPLUGINCALLBACK);
} extra_parameters;
// Definitions for page showing plug-ins
// See Ui.c to understand better how they're used
// sent to the outer window to tell it to go to the next inner window
#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
// custom pages should send this message to let NSIS know they're ready
#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
// sent as wParam with WM_NOTIFY_OUTER_NEXT when user cancels - heed its warning
#define NOTIFY_BYE_BYE 'x'
#endif /* _PLUGIN_H_ */
/*********************************************************************
* nsProcess NSIS plugin v1.5 *
* *
* 2006 Shengalts Aleksander aka Instructor (Shengalts@mail.ru) *
* *
* Licensed under the zlib/libpng license (the "License"); *
* you may not use this file except in compliance with the License. *
* *
* Licence details can be found in the file COPYING. *
* *
* This software is provided 'as-is', without any express or implied *
* warranty. *
* *
* Source function FIND_PROC_BY_NAME based *
* upon the Ravi Kochhar (kochhar@physiology.wisc.edu) code *
* Thanks iceman_k (FindProcDLL plugin) and *
* DITMan (KillProcDLL plugin) for point me up *
*********************************************************************/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tlhelp32.h>
#include "pluginapi.h"
/* Defines */
#define NSIS_MAX_STRLEN 1024
#define SystemProcessInformation 5
#define STATUS_SUCCESS 0x00000000L
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004L
typedef struct _SYSTEM_THREAD_INFO {
FILETIME ftCreationTime;
DWORD dwUnknown1;
DWORD dwStartAddress;
DWORD dwOwningPID;
DWORD dwThreadID;
DWORD dwCurrentPriority;
DWORD dwBasePriority;
DWORD dwContextSwitches;
DWORD dwThreadState;
DWORD dwUnknown2;
DWORD dwUnknown3;
DWORD dwUnknown4;
DWORD dwUnknown5;
DWORD dwUnknown6;
DWORD dwUnknown7;
} SYSTEM_THREAD_INFO;
typedef struct _SYSTEM_PROCESS_INFO {
DWORD dwOffset;
DWORD dwThreadCount;
DWORD dwUnkown1[6];
FILETIME ftCreationTime;
DWORD dwUnkown2;
DWORD dwUnkown3;
DWORD dwUnkown4;
DWORD dwUnkown5;
DWORD dwUnkown6;
WCHAR *pszProcessName;
DWORD dwBasePriority;
DWORD dwProcessID;
DWORD dwParentProcessID;
DWORD dwHandleCount;
DWORD dwUnkown7;
DWORD dwUnkown8;
DWORD dwVirtualBytesPeak;
DWORD dwVirtualBytes;
DWORD dwPageFaults;
DWORD dwWorkingSetPeak;
DWORD dwWorkingSet;
DWORD dwUnkown9;
DWORD dwPagedPool;
DWORD dwUnkown10;
DWORD dwNonPagedPool;
DWORD dwPageFileBytesPeak;
DWORD dwPageFileBytes;
DWORD dwPrivateBytes;
DWORD dwUnkown11;
DWORD dwUnkown12;
DWORD dwUnkown13;
DWORD dwUnkown14;
SYSTEM_THREAD_INFO ati[ANYSIZE_ARRAY];
} SYSTEM_PROCESS_INFO;
/* Include conversion functions */
//#define xatoi
//#define xitoa
/* Global variables */
TCHAR szBuf[NSIS_MAX_STRLEN];
/* Funtions prototypes and macros */
int FIND_PROC_BY_NAME(TCHAR *szProcessName, BOOL bTerminate, BOOL bClose);
/* NSIS functions code */
void __declspec(dllexport) _FindProcess(HWND hwndParent, int string_size,
TCHAR *variables, stack_t **stacktop, extra_parameters *extra)
{
EXDLL_INIT();
{
int nError;
popstringn(szBuf, NSIS_MAX_STRLEN);
nError=FIND_PROC_BY_NAME(szBuf, FALSE, FALSE);
pushint(nError);
}
}
void __declspec(dllexport) _KillProcess(HWND hwndParent, int string_size,
TCHAR *variables, stack_t **stacktop, extra_parameters *extra)
{
EXDLL_INIT();
{
int nError=0;
popstringn(szBuf, NSIS_MAX_STRLEN);
nError=FIND_PROC_BY_NAME(szBuf, TRUE, FALSE);
pushint(nError);
}
}
void __declspec(dllexport) _CloseProcess(HWND hwndParent, int string_size,
TCHAR *variables, stack_t **stacktop, extra_parameters *extra)
{
EXDLL_INIT();
{
int nError=0;
popstringn(szBuf, NSIS_MAX_STRLEN);
nError=FIND_PROC_BY_NAME(szBuf, TRUE, TRUE);
pushint(nError);
}
}
void __declspec(dllexport) _Unload(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)
{
return TRUE;
}
BOOL CALLBACK EnumWindowsProc( HWND hwnd,
LPARAM lParam
)
{
HANDLE *data = lParam;
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);
if (pid == data[0])
{
PostMessage(data[1], WM_CLOSE, 0, 0);
data[1] = hwnd;
}
return TRUE;
}
void NiceTerminate(DWORD id, BOOL bClose, BOOL *bSuccess, BOOL *bFailed)
{
HANDLE hProc;
HANDLE data[2];
DWORD ec;
BOOL bDone = FALSE;
if (hProc=OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, id))
{
data[0] = id;
data[1] = NULL;
if (bClose)
EnumWindows(EnumWindowsProc, data);
if (data[1] != NULL)
{
if (GetExitCodeProcess(hProc,&ec) && ec == STILL_ACTIVE)
if (WaitForSingleObject(hProc, 3000) == WAIT_OBJECT_0)
{
*bSuccess = bDone = TRUE;
}
else;
else
{
*bSuccess = bDone = TRUE;
}
}
if (!bDone)
{
// Open for termination
if (TerminateProcess(hProc, 0))
*bSuccess=TRUE;
else
*bFailed=TRUE;
}
CloseHandle(hProc);
}
}
int FIND_PROC_BY_NAME(TCHAR *szProcessName, BOOL bTerminate, BOOL bClose)
// Find the process "szProcessName" if it is currently running.
// This works for Win95/98/ME and also WinNT/2000/XP.
// The process name is case-insensitive, i.e. "notepad.exe" and "NOTEPAD.EXE"
// will both work. If bTerminate is TRUE, then process will be terminated.
//
// Return codes are as follows:
// 0 = Success
// 601 = No permission to terminate process
// 602 = Not all processes terminated successfully
// 603 = Process was not currently running
// 604 = Unable to identify system type
// 605 = Unsupported OS
// 606 = Unable to load NTDLL.DLL
// 607 = Unable to get procedure address from NTDLL.DLL
// 608 = NtQuerySystemInformation failed
// 609 = Unable to load KERNEL32.DLL
// 610 = Unable to get procedure address from KERNEL32.DLL
// 611 = CreateToolhelp32Snapshot failed
//
// Change history:
// created 06/23/2000 - Ravi Kochhar (kochhar@physiology.wisc.edu)
// http://www.neurophys.wisc.edu/ravi/software/
// modified 03/08/2002 - Ravi Kochhar (kochhar@physiology.wisc.edu)
// - Borland-C compatible if BORLANDC is defined as
// suggested by Bob Christensen
// modified 03/10/2002 - Ravi Kochhar (kochhar@physiology.wisc.edu)
// - Removed memory leaks as suggested by
// Jonathan Richard-Brochu (handles to Proc and Snapshot
// were not getting closed properly in some cases)
// modified 14/11/2005 - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
// - Combine functions FIND_PROC_BY_NAME and KILL_PROC_BY_NAME
// - Code has been optimized
// - Now kill all processes with specified name (not only one)
// - Cosmetic improvements
// - Removed error 632 (Invalid process name)
// - Changed error 602 (Unable to terminate process for some other reason)
// - BORLANDC define not needed
// modified 04/01/2006 - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
// - Removed CRT dependency
// modified 21/04/2006 - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
// - Removed memory leak as suggested by {_trueparuex^}
// (handle to hSnapShot was not getting closed properly in some cases)
// modified 21/04/2006 - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
// - Removed memory leak as suggested by {_trueparuex^}
// (handle to hSnapShot was not getting closed properly in some cases)
// modified 19/07/2006 - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
// - Code for WinNT/2000/XP has been rewritten
// - Changed error codes
// modified 31/08/2006 - Shengalts Aleksander aka Instructor (Shengalts@mail.ru):
// - Removed memory leak as suggested by Daniel Vanesse
{
TCHAR szName[MAX_PATH];
OSVERSIONINFO osvi;
HMODULE hLib;
HANDLE hProc;
ULONG uError;
BOOL bFound=FALSE;
BOOL bSuccess=FALSE;
BOOL bFailed=FALSE;
// First check what version of Windows we're in
osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if (!GetVersionEx(&osvi)) return 604;
if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT &&
osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
return 605;
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
// WinNT/2000/XP
SYSTEM_PROCESS_INFO *spi;
SYSTEM_PROCESS_INFO *spiCount;
DWORD dwSize=0x4000;
DWORD dwData;
ULONG (WINAPI *NtQuerySystemInformationPtr)(ULONG, PVOID, LONG, PULONG);
if (hLib=LoadLibraryW(L"NTDLL.DLL"))
{
NtQuerySystemInformationPtr=(ULONG(WINAPI *)(ULONG, PVOID, LONG, PULONG))GetProcAddress(hLib, "NtQuerySystemInformation");
if (NtQuerySystemInformationPtr)
{
while (1)
{
if (spi=LocalAlloc(LMEM_FIXED, dwSize))
{
uError=(*NtQuerySystemInformationPtr)(SystemProcessInformation, spi, dwSize, &dwData);
if (uError == STATUS_SUCCESS) break;
LocalFree(spi);
if (uError != STATUS_INFO_LENGTH_MISMATCH)
{
uError=608;
break;
}
}
else
{
uError=608;
break;
}
dwSize*=2;
}
}
else uError=607;
FreeLibrary(hLib);
}
else uError=606;
if (uError != STATUS_SUCCESS) return uError;
spiCount=spi;
while (1)
{
if (spiCount->pszProcessName)
{
#ifdef UNICODE
lstrcpyn(szName, spiCount->pszProcessName, MAX_PATH);
#else
WideCharToMultiByte(CP_ACP, 0, spiCount->pszProcessName, -1, szName, MAX_PATH, NULL, NULL);
#endif
if (!lstrcmpi(szName, szProcessName))
{
// Process found
bFound=TRUE;
if (bTerminate == TRUE)
{
NiceTerminate(spiCount->dwProcessID, bClose, &bSuccess, &bFailed);
}
else break;
}
}
if (spiCount->dwOffset == 0) break;
spiCount=(SYSTEM_PROCESS_INFO *)((char *)spiCount + spiCount->dwOffset);
}
LocalFree(spi);
}
else
{
// Win95/98/ME
PROCESSENTRY32 pe;
char *pName;
HANDLE hSnapShot;
BOOL bResult;
HANDLE (WINAPI *CreateToolhelp32SnapshotPtr)(DWORD, DWORD);
BOOL (WINAPI *Process32FirstPtr)(HANDLE, LPPROCESSENTRY32);
BOOL (WINAPI *Process32NextPtr)(HANDLE, LPPROCESSENTRY32);
if (hLib=LoadLibraryA("KERNEL32.DLL"))
{
CreateToolhelp32SnapshotPtr=(HANDLE(WINAPI *)(DWORD, DWORD)) GetProcAddress(hLib, "CreateToolhelp32Snapshot");
Process32FirstPtr=(BOOL(WINAPI *)(HANDLE, LPPROCESSENTRY32)) GetProcAddress(hLib, "Process32First");
Process32NextPtr=(BOOL(WINAPI *)(HANDLE, LPPROCESSENTRY32)) GetProcAddress(hLib, "Process32Next");
if (CreateToolhelp32SnapshotPtr && Process32NextPtr && Process32FirstPtr)
{
// Get a handle to a Toolhelp snapshot of all the systems processes.
if ((hSnapShot=(*CreateToolhelp32SnapshotPtr)(TH32CS_SNAPPROCESS, 0)) != INVALID_HANDLE_VALUE)
{
// Get the first process' information.
pe.dwSize=sizeof(PROCESSENTRY32);
bResult=(*Process32FirstPtr)(hSnapShot, &pe);
// While there are processes, keep looping and checking.
while (bResult)
{
//Get file name
for (pName=pe.szExeFile + lstrlen(pe.szExeFile) - 1; *pName != '\\' && *pName != '\0'; --pName);
++pName;
#ifdef UNICODE
MultiByteToWideChar(CP_ACP, 0, pName, lstrlenA(pName)+1, szName, MAX_PATH);
#else
lstrcpyn(szName, pName, MAX_PATH);
#endif
if (!lstrcmpi(szName, szProcessName))
{
// Process found
bFound=TRUE;
if (bTerminate == TRUE)
{
// Open for termination
NiceTerminate(pe.th32ProcessID, bClose, &bSuccess, &bFailed);
}
else break;
}
//Keep looking
bResult=(*Process32NextPtr)(hSnapShot, &pe);
}
CloseHandle(hSnapShot);
}
else uError=611;
}
else uError=610;
FreeLibrary(hLib);
}
else uError=609;
}
if (bFound == FALSE) return 603;
if (bTerminate == TRUE)
{
if (bSuccess == FALSE) return 601;
if (bFailed == TRUE) return 602;
}
return 0;
}
/*
* nsis_tchar.h
*
* This file is a part of NSIS.
*
* Copyright (C) 1999-2007 Nullsoft and Contributors
*
* This software is provided 'as-is', without any express or implied
* warranty.
*
* For Unicode support by Jim Park -- 08/30/2007
*/
// Jim Park: Only those we use are listed here.
#pragma once
#ifdef _UNICODE
#ifndef _T
#define __T(x) L ## x
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
#endif
typedef wchar_t TCHAR;
typedef wchar_t _TUCHAR;
// program
#define _tmain wmain
#define _tWinMain wWinMain
#define _tenviron _wenviron
#define __targv __wargv
// printfs
#define _ftprintf fwprintf
#define _sntprintf _snwprintf
#define _stprintf _swprintf
#define _tprintf wprintf
#define _vftprintf vfwprintf
#define _vsntprintf _vsnwprintf
#define _vstprintf _vswprintf
// scanfs
#define _tscanf wscanf
#define _stscanf swscanf
// string manipulations
#define _tcscat wcscat
#define _tcschr wcschr
#define _tcsclen wcslen
#define _tcscpy wcscpy
#define _tcsdup _wcsdup
#define _tcslen wcslen
#define _tcsnccpy wcsncpy
#define _tcsncpy wcsncpy
#define _tcsrchr wcsrchr
#define _tcsstr wcsstr
#define _tcstok wcstok
// string comparisons
#define _tcscmp wcscmp
#define _tcsicmp _wcsicmp
#define _tcsncicmp _wcsnicmp
#define _tcsncmp wcsncmp
#define _tcsnicmp _wcsnicmp
// upper / lower
#define _tcslwr _wcslwr
#define _tcsupr _wcsupr
#define _totlower towlower
#define _totupper towupper
// conversions to numbers
#define _tcstoi64 _wcstoi64
#define _tcstol wcstol
#define _tcstoul wcstoul
#define _tstof _wtof
#define _tstoi _wtoi
#define _tstoi64 _wtoi64
#define _ttoi _wtoi
#define _ttoi64 _wtoi64
#define _ttol _wtol
// conversion from numbers to strings
#define _itot _itow
#define _ltot _ltow
#define _i64tot _i64tow
#define _ui64tot _ui64tow
// file manipulations
#define _tfopen _wfopen
#define _topen _wopen
#define _tremove _wremove
#define _tunlink _wunlink
// reading and writing to i/o
#define _fgettc fgetwc
#define _fgetts fgetws
#define _fputts fputws
#define _gettchar getwchar
// directory
#define _tchdir _wchdir
// environment
#define _tgetenv _wgetenv
#define _tsystem _wsystem
// time
#define _tcsftime wcsftime
#else // ANSI
#ifndef _T
#define _T(x) x
#define _TEXT(x) x
#endif
typedef char TCHAR;
typedef unsigned char _TUCHAR;
// program
#define _tmain main
#define _tWinMain WinMain
#define _tenviron environ
#define __targv __argv
// printfs
#define _ftprintf fprintf
#define _sntprintf _snprintf
#define _stprintf sprintf
#define _tprintf printf
#define _vftprintf vfprintf
#define _vsntprintf _vsnprintf
#define _vstprintf vsprintf
// scanfs
#define _tscanf scanf
#define _stscanf sscanf
// string manipulations
#define _tcscat strcat
#define _tcschr strchr
#define _tcsclen strlen
#define _tcscnlen strnlen
#define _tcscpy strcpy
#define _tcsdup _strdup
#define _tcslen strlen
#define _tcsnccpy strncpy
#define _tcsrchr strrchr
#define _tcsstr strstr
#define _tcstok strtok
// string comparisons
#define _tcscmp strcmp
#define _tcsicmp _stricmp
#define _tcsncmp strncmp
#define _tcsncicmp _strnicmp
#define _tcsnicmp _strnicmp
// upper / lower
#define _tcslwr _strlwr
#define _tcsupr _strupr
#define _totupper toupper
#define _totlower tolower
// conversions to numbers
#define _tcstol strtol
#define _tcstoul strtoul
#define _tstof atof
#define _tstoi atoi
#define _tstoi64 _atoi64
#define _tstoi64 _atoi64
#define _ttoi atoi
#define _ttoi64 _atoi64
#define _ttol atol
// conversion from numbers to strings
#define _i64tot _i64toa
#define _itot _itoa
#define _ltot _ltoa
#define _ui64tot _ui64toa
// file manipulations
#define _tfopen fopen
#define _topen _open
#define _tremove remove
#define _tunlink _unlink
// reading and writing to i/o
#define _fgettc fgetc
#define _fgetts fgets
#define _fputts fputs
#define _gettchar getchar
// directory
#define _tchdir _chdir
// environment
#define _tgetenv getenv
#define _tsystem system
// time
#define _tcsftime strftime
#endif
// is functions (the same in Unicode / ANSI)
#define _istgraph isgraph
#define _istascii __isascii
#define __TFILE__ _T(__FILE__)
#define __TDATE__ _T(__DATE__)
#define __TTIME__ _T(__TIME__)
#include <windows.h>
#include "pluginapi.h"
unsigned int g_stringsize;
stack_t **g_stacktop;
TCHAR *g_variables;
// utility functions (not required but often useful)
int NSISCALL popstring(TCHAR *str)
{
stack_t *th;
if (!g_stacktop || !*g_stacktop) return 1;
th=(*g_stacktop);
lstrcpy(str,th->text);
*g_stacktop = th->next;
GlobalFree((HGLOBAL)th);
return 0;
}
int NSISCALL popstringn(TCHAR *str, int maxlen)
{
stack_t *th;
if (!g_stacktop || !*g_stacktop) return 1;
th=(*g_stacktop);
if (str) lstrcpyn(str,th->text,maxlen?maxlen:g_stringsize);
*g_stacktop = th->next;
GlobalFree((HGLOBAL)th);
return 0;
}
void NSISCALL pushstring(const TCHAR *str)
{
stack_t *th;
if (!g_stacktop) return;
th=(stack_t*)GlobalAlloc(GPTR,(sizeof(stack_t)+(g_stringsize)*sizeof(TCHAR)));
lstrcpyn(th->text,str,g_stringsize);
th->next=*g_stacktop;
*g_stacktop=th;
}
TCHAR * NSISCALL getuservariable(const int varnum)
{
if (varnum < 0 || varnum >= __INST_LAST) return NULL;
return g_variables+varnum*g_stringsize;
}
void NSISCALL setuservariable(const int varnum, const TCHAR *var)
{
if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
lstrcpy(g_variables + varnum*g_stringsize, var);
}
#ifdef _UNICODE
int NSISCALL PopStringA(char* ansiStr)
{
wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t));
int rval = popstring(wideStr);
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
GlobalFree((HGLOBAL)wideStr);
return rval;
}
int NSISCALL PopStringNA(char* ansiStr, int maxlen)
{
int realLen = maxlen ? maxlen : g_stringsize;
wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, realLen*sizeof(wchar_t));
int rval = popstringn(wideStr, realLen);
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, realLen, NULL, NULL);
GlobalFree((HGLOBAL)wideStr);
return rval;
}
void NSISCALL PushStringA(const char* ansiStr)
{
wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t));
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
pushstring(wideStr);
GlobalFree((HGLOBAL)wideStr);
return;
}
void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr)
{
lstrcpyW(wideStr, getuservariable(varnum));
}
void NSISCALL GetUserVariableA(const int varnum, char* ansiStr)
{
wchar_t* wideStr = getuservariable(varnum);
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
}
void NSISCALL SetUserVariableA(const int varnum, const char* ansiStr)
{
if (ansiStr != NULL && varnum >= 0 && varnum < __INST_LAST)
{
wchar_t* wideStr = g_variables + varnum * g_stringsize;
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
}
}
#else
// ANSI defs
int NSISCALL PopStringW(wchar_t* wideStr)
{
char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize);
int rval = popstring(ansiStr);
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
GlobalFree((HGLOBAL)ansiStr);
return rval;
}
int NSISCALL PopStringNW(wchar_t* wideStr, int maxlen)
{
int realLen = maxlen ? maxlen : g_stringsize;
char* ansiStr = (char*) GlobalAlloc(GPTR, realLen);
int rval = popstringn(ansiStr, realLen);
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, realLen);
GlobalFree((HGLOBAL)ansiStr);
return rval;
}
void NSISCALL PushStringW(wchar_t* wideStr)
{
char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize);
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
pushstring(ansiStr);
GlobalFree((HGLOBAL)ansiStr);
}
void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr)
{
char* ansiStr = getuservariable(varnum);
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
}
void NSISCALL GetUserVariableA(const int varnum, char* ansiStr)
{
lstrcpyA(ansiStr, getuservariable(varnum));
}
void NSISCALL SetUserVariableW(const int varnum, const wchar_t* wideStr)
{
if (wideStr != NULL && varnum >= 0 && varnum < __INST_LAST)
{
char* ansiStr = g_variables + varnum * g_stringsize;
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
}
}
#endif
// playing with integers
int NSISCALL myatoi(const TCHAR *s)
{
int v=0;
if (*s == _T('0') && (s[1] == _T('x') || s[1] == _T('X')))
{
s++;
for (;;)
{
int c=*(++s);
if (c >= _T('0') && c <= _T('9')) c-=_T('0');
else if (c >= _T('a') && c <= _T('f')) c-=_T('a')-10;
else if (c >= _T('A') && c <= _T('F')) c-=_T('A')-10;
else break;
v<<=4;
v+=c;
}
}
else if (*s == _T('0') && s[1] <= _T('7') && s[1] >= _T('0'))
{
for (;;)
{
int c=*(++s);
if (c >= _T('0') && c <= _T('7')) c-=_T('0');
else break;
v<<=3;
v+=c;
}
}
else
{
int sign=0;
if (*s == _T('-')) sign++; else s--;
for (;;)
{
int c=*(++s) - _T('0');
if (c < 0 || c > 9) break;
v*=10;
v+=c;
}
if (sign) v = -v;
}
return v;
}
unsigned NSISCALL myatou(const TCHAR *s)
{
unsigned int v=0;
for (;;)
{
unsigned int c=*s++;
if (c >= _T('0') && c <= _T('9')) c-=_T('0');
else break;
v*=10;
v+=c;
}
return v;
}
int NSISCALL myatoi_or(const TCHAR *s)
{
int v=0;
if (*s == _T('0') && (s[1] == _T('x') || s[1] == _T('X')))
{
s++;
for (;;)
{
int c=*(++s);
if (c >= _T('0') && c <= _T('9')) c-=_T('0');
else if (c >= _T('a') && c <= _T('f')) c-=_T('a')-10;
else if (c >= _T('A') && c <= _T('F')) c-=_T('A')-10;
else break;
v<<=4;
v+=c;
}
}
else if (*s == _T('0') && s[1] <= _T('7') && s[1] >= _T('0'))
{
for (;;)
{
int c=*(++s);
if (c >= _T('0') && c <= _T('7')) c-=_T('0');
else break;
v<<=3;
v+=c;
}
}
else
{
int sign=0;
if (*s == _T('-')) sign++; else s--;
for (;;)
{
int c=*(++s) - _T('0');
if (c < 0 || c > 9) break;
v*=10;
v+=c;
}
if (sign) v = -v;
}
// Support for simple ORed expressions
if (*s == _T('|'))
{
v |= myatoi_or(s+1);
}
return v;
}
int NSISCALL popint()
{
TCHAR buf[128];
if (popstringn(buf,sizeof(buf)/sizeof(TCHAR)))
return 0;
return myatoi(buf);
}
int NSISCALL popint_or()
{
TCHAR buf[128];
if (popstringn(buf,sizeof(buf)/sizeof(TCHAR)))
return 0;
return myatoi_or(buf);
}
void NSISCALL pushint(int value)
{
TCHAR buffer[1024];
wsprintf(buffer, _T("%d"), value);
pushstring(buffer);
}
#ifndef ___NSIS_PLUGIN__H___
#define ___NSIS_PLUGIN__H___
#ifdef __cplusplus
extern "C" {
#endif
#include "api.h"
#include "nsis_tchar.h"
#ifndef NSISCALL
# define NSISCALL __stdcall
#endif
#define EXDLL_INIT() { \
g_stringsize=string_size; \
g_stacktop=stacktop; \
g_variables=variables; }
typedef struct _stack_t {
struct _stack_t *next;
TCHAR text[1]; // this should be the length of string_size
} stack_t;
enum
{
INST_0, // $0
INST_1, // $1
INST_2, // $2
INST_3, // $3
INST_4, // $4
INST_5, // $5
INST_6, // $6
INST_7, // $7
INST_8, // $8
INST_9, // $9
INST_R0, // $R0
INST_R1, // $R1
INST_R2, // $R2
INST_R3, // $R3
INST_R4, // $R4
INST_R5, // $R5
INST_R6, // $R6
INST_R7, // $R7
INST_R8, // $R8
INST_R9, // $R9
INST_CMDLINE, // $CMDLINE
INST_INSTDIR, // $INSTDIR
INST_OUTDIR, // $OUTDIR
INST_EXEDIR, // $EXEDIR
INST_LANG, // $LANGUAGE
__INST_LAST
};
extern unsigned int g_stringsize;
extern stack_t **g_stacktop;
extern TCHAR *g_variables;
int NSISCALL popstring(TCHAR *str); // 0 on success, 1 on empty stack
int NSISCALL popstringn(TCHAR *str, int maxlen); // with length limit, pass 0 for g_stringsize
int NSISCALL popint(); // pops an integer
int NSISCALL popint_or(); // with support for or'ing (2|4|8)
int NSISCALL myatoi(const TCHAR *s); // converts a string to an integer
unsigned NSISCALL myatou(const TCHAR *s); // converts a string to an unsigned integer, decimal only
int NSISCALL myatoi_or(const TCHAR *s); // with support for or'ing (2|4|8)
void NSISCALL pushstring(const TCHAR *str);
void NSISCALL pushint(int value);
TCHAR * NSISCALL getuservariable(const int varnum);
void NSISCALL setuservariable(const int varnum, const TCHAR *var);
#ifdef _UNICODE
#define PopStringW(x) popstring(x)
#define PushStringW(x) pushstring(x)
#define SetUserVariableW(x,y) setuservariable(x,y)
int NSISCALL PopStringA(char* ansiStr);
void NSISCALL PushStringA(const char* ansiStr);
void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr);
void NSISCALL GetUserVariableA(const int varnum, char* ansiStr);
void NSISCALL SetUserVariableA(const int varnum, const char* ansiStr);
#else
// ANSI defs
#define PopStringA(x) popstring(x)
#define PushStringA(x) pushstring(x)
#define SetUserVariableA(x,y) setuservariable(x,y)
int NSISCALL PopStringW(wchar_t* wideStr);
void NSISCALL PushStringW(wchar_t* wideStr);
void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr);
void NSISCALL GetUserVariableA(const int varnum, char* ansiStr);
void NSISCALL SetUserVariableW(const int varnum, const wchar_t* wideStr);
#endif
#ifdef __cplusplus
}
#endif
#endif//!___NSIS_PLUGIN__H___
......@@ -132,9 +132,18 @@ else
$(CXX) $^ -D_WIN32_IE=0x0601 -D__forceinline=inline -shared -o $@ -lole32 -static-libstdc++ -static-libgcc
$(STRIP) $@
endif
$(win32_destdir)/NSIS/nsProcess.dll: extras/package/win32/NSIS/nsProcess/nsProcess.c extras/package/win32/NSIS/nsProcess/pluginapi.c
mkdir -p "$(win32_destdir)/NSIS/"
if HAVE_WIN64
i686-w64-mingw32-gcc $^ -shared -o $@ -lole32 -static-libgcc
i686-w64-mingw32-strip $@
else
$(CC) $^ -D_WIN32_IE=0x0601 -shared -o $@ -lole32 -static-libgcc
$(STRIP) $@
endif
package-win32-exe: package-win-strip $(win32_destdir)/NSIS/UAC.dll
package-win32-exe: package-win-strip $(win32_destdir)/NSIS/UAC.dll $(win32_destdir)/NSIS/nsProcess.dll
# Script installer
cp $(top_builddir)/extras/package/win32/NSIS/vlc.win32.nsi "$(win32_destdir)/"
cp $(top_builddir)/extras/package/win32/NSIS/spad.nsi "$(win32_destdir)/"
......@@ -142,6 +151,7 @@ package-win32-exe: package-win-strip $(win32_destdir)/NSIS/UAC.dll
cp -r $(srcdir)/extras/package/win32/NSIS/helpers "$(win32_destdir)/"
mkdir -p "$(win32_destdir)/NSIS/"
cp "$(top_srcdir)/extras/package/win32/NSIS/UAC.nsh" "$(win32_destdir)/NSIS/"
cp "$(top_srcdir)/extras/package/win32/NSIS/nsProcess.nsh" "$(win32_destdir)/NSIS/"
# Create package
if makensis -VERSION >/dev/null 2>&1; then \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment