Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34102810
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
48 KB
Subscribers
None
View Options
diff --git a/src/exdll.c b/src/exdll.c
index 1f1839d7..7815523a 100644
--- a/src/exdll.c
+++ b/src/exdll.c
@@ -1,286 +1,286 @@
#include "exdll.h"
unsigned int g_stringsize;
stack_t **g_stacktop;
LPTSTR g_variables;
// utility functions (not required but often useful)
int NSISCALL popstring(LPTSTR str)
{
stack_t *th;
if (!g_stacktop || !*g_stacktop) return 1;
th=(*g_stacktop);
if (str) lstrcpy(str,th->text);
*g_stacktop = th->next;
GlobalFree((HGLOBAL)th);
return 0;
}
int NSISCALL popstringn(LPTSTR 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(LPCTSTR str)
{
stack_t *th;
if (!g_stacktop) return;
th=(stack_t*)GlobalAlloc(GPTR,(sizeof(stack_t)+(g_stringsize)*sizeof(*str)));
lstrcpyn(th->text,str,g_stringsize);
th->next=*g_stacktop;
*g_stacktop=th;
}
LPTSTR NSISCALL getuservariable(const int varnum)
{
if (!isvalidnsisvarindex(varnum)) return NULL;
- return (LPWSTR)((char*)g_variables+varnum*g_stringsize);
+ return (LPWSTR)((wchar_t*)g_variables+varnum*g_stringsize);
}
void NSISCALL setuservariable(const int varnum, LPCTSTR var)
{
if (var && isvalidnsisvarindex(varnum))
- lstrcpy((LPWSTR)((char*)g_variables + varnum*g_stringsize), var);
+ lstrcpy((LPWSTR)((wchar_t*)g_variables + varnum*g_stringsize), var);
}
#ifdef UNICODE
int NSISCALL PopStringA(LPSTR ansiStr)
{
LPWSTR wideStr = (LPWSTR) GlobalAlloc(GPTR, g_stringsize*sizeof(WCHAR));
int rval = popstring(wideStr);
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
GlobalFree((HGLOBAL)wideStr);
return rval;
}
int NSISCALL PopStringNA(LPSTR ansiStr, int maxlen)
{
int realLen = maxlen ? maxlen : g_stringsize;
LPWSTR wideStr = (LPWSTR) GlobalAlloc(GPTR, realLen*sizeof(WCHAR));
int rval = popstringn(wideStr, realLen);
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, realLen, NULL, NULL);
GlobalFree((HGLOBAL)wideStr);
return rval;
}
void NSISCALL PushStringA(LPCSTR ansiStr)
{
LPWSTR wideStr = (LPWSTR) GlobalAlloc(GPTR, g_stringsize*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
pushstring(wideStr);
GlobalFree((HGLOBAL)wideStr);
return;
}
void NSISCALL GetUserVariableW(const int varnum, LPWSTR wideStr)
{
lstrcpyW(wideStr, getuservariable(varnum));
}
void NSISCALL GetUserVariableA(const int varnum, LPSTR ansiStr)
{
LPWSTR wideStr = getuservariable(varnum);
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
}
void NSISCALL SetUserVariableA(const int varnum, LPCSTR ansiStr)
{
if (ansiStr && isvalidnsisvarindex(varnum))
{
LPWSTR wideStr = (LPWSTR)((char*)g_variables + varnum * g_stringsize);
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
}
}
#else
// ANSI defs
int NSISCALL PopStringW(LPWSTR wideStr)
{
LPSTR ansiStr = (LPSTR) 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(LPWSTR wideStr, int maxlen)
{
int realLen = maxlen ? maxlen : g_stringsize;
LPSTR ansiStr = (LPSTR) GlobalAlloc(GPTR, realLen);
int rval = popstringn(ansiStr, realLen);
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, realLen);
GlobalFree((HGLOBAL)ansiStr);
return rval;
}
void NSISCALL PushStringW(LPWSTR wideStr)
{
LPSTR ansiStr = (LPSTR) 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, LPWSTR wideStr)
{
LPSTR ansiStr = getuservariable(varnum);
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
}
void NSISCALL GetUserVariableA(const int varnum, LPSTR ansiStr)
{
lstrcpyA(ansiStr, getuservariable(varnum));
}
void NSISCALL SetUserVariableW(const int varnum, LPCWSTR wideStr)
{
if (wideStr && isvalidnsisvarindex(varnum))
{
LPSTR ansiStr = (char*)g_variables + varnum * g_stringsize;
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
}
}
#endif
// playing with integers
INT_PTR NSISCALL nsishelper_str_to_ptr(LPCTSTR s)
{
INT_PTR 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 int NSISCALL myatou(LPCTSTR 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(LPCTSTR 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_PTR NSISCALL popintptr()
{
TCHAR buf[128];
if (popstringn(buf,COUNTOF(buf)))
return 0;
return nsishelper_str_to_ptr(buf);
}
int NSISCALL popint_or()
{
TCHAR buf[128];
if (popstringn(buf,COUNTOF(buf)))
return 0;
return myatoi_or(buf);
}
void NSISCALL pushintptr(INT_PTR value)
{
TCHAR buffer[30];
wsprintf(buffer, sizeof(void*) > 4 ? _T("%Id") : _T("%d"), value);
pushstring(buffer);
}
diff --git a/src/g4wihelp.c b/src/g4wihelp.c
index b83ab4a2..bae4b837 100644
--- a/src/g4wihelp.c
+++ b/src/g4wihelp.c
@@ -1,1284 +1,1323 @@
-/* g4wihelp.c - NSIS Helper DLL used with gpg4win. -*- coding: latin-1; -*-
+/* g4wihelp.c - NSIS Helper DLL used with gpg4win.
* Copyright (C) 2005, 2023 g10 Code GmbH
* Copyright (C) 2001 Justin Frankel
* Copyright (C) 2016, 2017 Intevation GmbH
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must
* not claim that you wrote the original software. If you use this
* software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must
* not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
************************************************************
* The code for the splash screen has been taken from the Splash
* plugin of the NSIS 2.04 distribution. That code comes without
* explicit copyright notices in tyhe source files or author names, it
* seems that it has been written by Justin Frankel; not sure about
* the year, though. [wk 2005-11-28]
*
* Fixed some compiler warnings. [wk 2014-02-24].
* Merged code from GnuPG version. [wk 2023-04-24].
*
* Compile time macros:
* ENABLE_SLIDE_SHOW :: Define for Gpg4win.
*/
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <psapi.h>
#include <stdio.h>
#include <string.h>
#include "exdll.h"
/* We keep some code here for documentation reasons. That code has not
* yet been converted to the Unicode NSIS plugin API. */
/* #define ENABLE_SOUND_GADGET 1 */
/* #define ENABLE_SPLASH_GADGET 1 */
/* #define ENABLE_SERVICE_MANAGEMENT 1 */
static HINSTANCE g_hInstance; /* Our Instance. */
static HWND g_hwndParent; /* Handle of parent window or NULL. */
static HBITMAP g_hbm; /* Handle of the splash image. */
static int sleepint; /* Milliseconds to show the spals image. */
#ifdef ENABLE_SLIDE_SHOW
void
slide_stop(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop);
#endif
/* Standard entry point for DLLs. */
int WINAPI
DllMain (HANDLE hinst, DWORD reason, LPVOID reserved)
{
if (reason == DLL_PROCESS_ATTACH)
g_hInstance = hinst;
else if (reason == DLL_PROCESS_DETACH)
{
#ifdef ENABLE_SLIDE_SHOW
slide_stop (NULL, 0, NULL, NULL);
#endif
}
return TRUE;
}
/* Dummy function for testing. */
void __declspec(dllexport)
dummy (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra)
{
g_hwndParent = hwndParent;
EXDLL_INIT();
// note if you want parameters from the stack, pop them off in order.
// i.e. if you are called via exdll::myFunction file.dat poop.dat
// calling popstring() the first time would give you file.dat,
// and the second time would give you poop.dat.
// you should empty the stack of your parameters, and ONLY your
// parameters.
- // do your stuff here
+ /* Let's dump the variables. */
+ {
+ char line[512];
+ char *p;
+ const unsigned char *s = (void*)g_variables;
+ int i,j;
+
+ for (i=0; i < string_size* __INST_LAST; i+=32, s += 32)
+ {
+ for (j=0; j < 32; j++)
+ if (s[j])
+ break;
+ if (j != 32)
+ {
+ p = line;
+ *p = 0;
+ snprintf (p, 10, "%05x: ", i);
+ p += strlen (p);
+ for (j=0; j < 32; j++)
+ {
+ snprintf (p, 10, "%02x", s[j]);
+ p += strlen (p);
+ }
+ strcat (p, " |");
+ p += strlen (p);
+ for (j=0; j < 32; j++)
+ {
+ if (s[j] >= 32 && s[j] < 127)
+ *p = s[j];
+ else
+ *p = '.';
+ p++;
+ }
+ strcat (p, "|");
+ OutputDebugStringA (line);
+ }
+ }
+ }
+
+
{
wchar_t buf[1024];
swprintf(buf, 1024,
L"stringsize=%d\r\n$0=%s\r\n$1=%s\r\n$R0=%s\r\n$R1=%s\r\n",
string_size,
getuservariable(INST_0),
getuservariable(INST_1),
getuservariable(INST_R0),
getuservariable(INST_R1));
MessageBoxW(g_hwndParent,buf,0,MB_OK);
swprintf (buf, 1024,
L"autoclose =%d\r\n"
"all_user_var =%d\r\n"
"exec_error =%d\r\n"
"abort =%d\r\n"
"exec_reboot =%d\r\n"
"reboot_called=%d\r\n"
"api_version =%d\r\n"
"silent =%d\r\n"
"instdir_error=%d\r\n"
"rtl =%d\r\n"
"errlvl =%d\r\n",
extra->exec_flags->autoclose,
extra->exec_flags->all_user_var,
extra->exec_flags->exec_error,
extra->exec_flags->abort,
extra->exec_flags->exec_reboot,
extra->exec_flags->reboot_called,
extra->exec_flags->plugin_api_version,
extra->exec_flags->silent,
extra->exec_flags->instdir_error,
extra->exec_flags->rtl,
extra->exec_flags->errlvl);
MessageBoxW(g_hwndParent,buf,0,MB_OK);
}
}
void __declspec(dllexport)
runonce (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra)
{
LPCWSTR result;
g_hwndParent = hwndParent;
EXDLL_INIT();
CreateMutexW (NULL, 0, getuservariable(INST_R0));
result = GetLastError ()? L"1" : L"0";
setuservariable (INST_R0, result);
}
#ifdef ENABLE_SOUND_GADGET
void __declspec(dllexport)
playsound (HWND hwndParent, int string_size, char *variables,
stack_t **stacktop, extra_parameters_t *extra)
{
char fname[MAX_PATH];
g_hwndParent = hwndParent;
EXDLL_INIT();
if (popstring(fname, sizeof fname))
return;
PlaySound (fname, NULL, SND_ASYNC|SND_FILENAME|SND_NODEFAULT);
}
void __declspec(dllexport)
stopsound (HWND hwndParent, int string_size, char *variables,
stack_t **stacktop, extra_parameters_t *extra)
{
g_hwndParent = hwndParent;
EXDLL_INIT();
PlaySound (NULL, NULL, 0);
}
#endif /*ENABLE_SOUND_GADGET*/
#ifdef ENABLE_SPLASH_GADGET
/* Windows procedure to control the splashimage. This one pauses the
execution until the sleep time is over or the user closes this
windows. */
static LRESULT CALLBACK
splash_wndproc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT result = 0;
switch (uMsg)
{
case WM_CREATE:
{
BITMAP bm;
RECT vp;
GetObject(g_hbm, sizeof(bm), (LPSTR)&bm);
SystemParametersInfo(SPI_GETWORKAREA, 0, &vp, 0);
SetWindowLong(hwnd,GWL_STYLE,0);
SetWindowPos(hwnd,NULL,
vp.left+(vp.right-vp.left-bm.bmWidth)/2,
vp.top+(vp.bottom-vp.top-bm.bmHeight)/2,
bm.bmWidth,bm.bmHeight,
SWP_NOZORDER);
ShowWindow(hwnd,SW_SHOW);
SetTimer(hwnd,1,sleepint,NULL);
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT r;
HDC curdc=BeginPaint(hwnd,&ps);
HDC hdc=CreateCompatibleDC(curdc);
HBITMAP oldbm;
GetClientRect(hwnd,&r);
oldbm=(HBITMAP)SelectObject(hdc,g_hbm);
BitBlt(curdc,r.left,r.top,r.right-r.left,r.bottom-r.top,
hdc,0,0,SRCCOPY);
SelectObject(hdc,oldbm);
DeleteDC(hdc);
EndPaint(hwnd,&ps);
}
break;
case WM_CLOSE:
break;
case WM_TIMER:
case WM_LBUTTONDOWN:
DestroyWindow(hwnd);
/*(fall through)*/
default:
result = DefWindowProc (hwnd, uMsg, wParam, lParam);
}
return result;
}
/* Display a splash screen. Call as
g4wihelp::showsplash SLEEP FNAME
With SLEEP being the time in milliseconds to show the splashscreen
and FNAME the complete filename of the image. As of now only BMP
is supported.
*/
void __declspec(dllexport)
showsplash (HWND hwndParent, int string_size, char *variables,
stack_t **stacktop, extra_parameters_t *extra)
{
static WNDCLASS wc;
char sleepstr[30];
char fname[MAX_PATH];
int err = 0;
char *p;
char classname[] = "_sp";
g_hwndParent = hwndParent;
EXDLL_INIT();
if (popstring(sleepstr, sizeof sleepstr))
err = 1;
if (popstring(fname, sizeof fname))
err = 1;
if (err)
return;
if (!*fname)
return; /* Nothing to do. */
for (sleepint=0, p=sleepstr; *p >= '0' && *p <= '9'; p++)
{
sleepint *= 10;
sleepint += *p - '0';
}
if (sleepint <= 0)
return; /* Nothing to do. */
wc.lpfnWndProc = splash_wndproc;
wc.hInstance = g_hInstance;
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.lpszClassName = classname;
if (!RegisterClass(&wc))
return; /* Error. */
g_hbm = LoadImage (NULL, fname, IMAGE_BITMAP,
0, 0 , LR_CREATEDIBSECTION|LR_LOADFROMFILE);
if (g_hbm)
{
MSG msg;
HWND hwnd;
hwnd = CreateWindowEx (WS_EX_TOOLWINDOW, classname, classname,
0, 0, 0, 0, 0, (HWND)hwndParent, NULL,
g_hInstance, NULL);
while (IsWindow(hwnd) && GetMessage ( &msg, hwnd, 0, 0))
{
DispatchMessage (&msg);
}
DeleteObject (g_hbm);
g_hbm = NULL;
}
UnregisterClass (classname, g_hInstance);
}
#endif /*ENABLE_SPLASH_GADGET*/
#ifdef ENABLE_SERVICE_MANAGEMENT
/* Use this to report unexpected errors. FIXME: This is really not
very descriptive. */
void
service_error (const char *str)
{
char buf[1024];
snprintf (buf, sizeof (buf), "error: %s: ec=%d\r\n", str,
GetLastError ());
MessageBox(g_hwndParent, buf, 0, MB_OK);
setuservariable (INST_R0, "1");
}
void __declspec(dllexport)
service_create (HWND hwndParent, int string_size, char *variables,
stack_t **stacktop, extra_parameters_t *extra)
{
SC_HANDLE sc;
SC_HANDLE service;
const char *result = NULL;
char service_name[256];
char display_name[256];
char program[256];
int err = 0;
g_hwndParent = hwndParent;
EXDLL_INIT();
/* The expected stack layout: service_name, display_name, program. */
if (popstring (service_name, sizeof (service_name)))
err = 1;
if (!err && popstring (display_name, sizeof (display_name)))
err = 1;
if (!err && popstring (program, sizeof (program)))
err = 1;
if (err)
{
setuservariable (INST_R0, "1");
return;
}
sc = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (sc == NULL)
{
service_error ("OpenSCManager");
return;
}
service = CreateService (sc, service_name, display_name,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
/* Use SERVICE_DEMAND_START for testing.
FIXME: Currently not configurable by caller. */
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL, program,
NULL, NULL, NULL,
/* FIXME: Currently not configurable by caller. */
/* FIXME: LocalService or NetworkService
don't work for dirmngr right now. NOTE!
If you change it here, you also should
adjust make-msi.pl for the msi
installer. In the future, this should
be an argument to the function and then
the make-msi.pl script can extract it
from the invocation. */
NULL /* "NT AUTHORITY\\LocalService" */,
NULL);
if (service == NULL)
{
service_error ("CreateService");
CloseServiceHandle (sc);
return;
}
CloseServiceHandle (service);
result = GetLastError () ? "1":"0";
setuservariable (INST_R0, result);
return;
}
/* Requires g_hwndParent to be set! */
SC_HANDLE
service_lookup (char *service_name)
{
SC_HANDLE sc;
SC_HANDLE service;
sc = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (sc == NULL)
{
service_error ("OpenSCManager");
return NULL;
}
service = OpenService (sc, service_name, SC_MANAGER_ALL_ACCESS);
if (service == NULL)
{
/* Fail silently here. */
CloseServiceHandle (sc);
return NULL;
}
CloseServiceHandle (sc);
return service;
}
/* Returns status. */
void __declspec(dllexport)
service_query (HWND hwndParent, int string_size, char *variables,
stack_t **stacktop, extra_parameters_t *extra)
{
SC_HANDLE service;
const char *result = NULL;
char service_name[256];
int err = 0;
SERVICE_STATUS status;
g_hwndParent = hwndParent;
EXDLL_INIT();
/* The expected stack layout: service_name argc [argv]. */
if (popstring (service_name, sizeof (service_name)))
err = 1;
if (err)
{
setuservariable (INST_R0, "ERROR");
return;
}
service = service_lookup (service_name);
if (service == NULL)
if (err == 0)
{
setuservariable (INST_R0, "MISSING");
return;
}
err = QueryServiceStatus (service, &status);
if (err == 0)
{
setuservariable (INST_R0, "ERROR");
CloseServiceHandle (service);
return;
}
CloseServiceHandle (service);
switch (status.dwCurrentState)
{
case SERVICE_START_PENDING:
result = "START_PENDING";
break;
case SERVICE_RUNNING:
result = "RUNNING";
break;
case SERVICE_PAUSE_PENDING:
result = "PAUSE_PENDING";
break;
case SERVICE_PAUSED:
result = "PAUSED";
break;
case SERVICE_CONTINUE_PENDING:
result = "CONTINUE_PENDING";
break;
case SERVICE_STOP_PENDING:
result = "STOP_PENDING";
break;
case SERVICE_STOPPED:
result = "STOPPED";
break;
default:
result = "UNKNOWN";
}
setuservariable (INST_R0, result);
return;
}
void __declspec(dllexport)
service_start (HWND hwndParent, int string_size, char *variables,
stack_t **stacktop, extra_parameters_t *extra)
{
SC_HANDLE service;
const char *result = NULL;
char service_name[256];
char argc_str[256];
#define NR_ARGS 10
#define ARG_MAX 256
char argv_str[NR_ARGS][ARG_MAX];
const char *argv[NR_ARGS + 1];
int argc;
int i;
int err = 0;
g_hwndParent = hwndParent;
EXDLL_INIT();
/* The expected stack layout: service_name argc [argv]. */
if (popstring (service_name, sizeof (service_name)))
err = 1;
if (!err && popstring (argc_str, sizeof (argc_str)))
err = 1;
if (!err)
{
argc = atoi (argc_str);
for (i = 0; i < argc; i++)
{
if (popstring (argv_str[i], ARG_MAX))
{
err = 1;
break;
}
argv[i] = argv_str[i];
}
argv[i] = NULL;
}
if (err)
{
setuservariable (INST_R0, "1");
return;
}
service = service_lookup (service_name);
if (service == NULL)
return;
err = StartService (service, argc, argc == 0 ? NULL : argv);
if (err == 0)
{
service_error ("StartService");
CloseServiceHandle (service);
return;
}
CloseServiceHandle (service);
setuservariable (INST_R0, "0");
return;
}
void __declspec(dllexport)
service_stop (HWND hwndParent, int string_size, char *variables,
stack_t **stacktop, extra_parameters_t *extra)
{
SC_HANDLE service;
const char *result = NULL;
char service_name[256];
int err = 0;
SERVICE_STATUS status;
DWORD timeout = 10000; /* 10 seconds. */
DWORD start_time;
g_hwndParent = hwndParent;
EXDLL_INIT();
/* The expected stack layout: service_name argc [argv]. */
if (popstring (service_name, sizeof (service_name)))
err = 1;
if (err)
{
setuservariable (INST_R0, "1");
return;
}
service = service_lookup (service_name);
if (service == NULL)
return;
err = QueryServiceStatus (service, &status);
if (err == 0)
{
service_error ("QueryService");
CloseServiceHandle (service);
return;
}
if (status.dwCurrentState != SERVICE_STOPPED
&& status.dwCurrentState != SERVICE_STOP_PENDING)
{
err = ControlService (service, SERVICE_CONTROL_STOP, &status);
if (err == 0)
{
service_error ("ControlService");
CloseServiceHandle (service);
return;
}
}
start_time = GetTickCount ();
while (status.dwCurrentState != SERVICE_STOPPED)
{
Sleep (1000); /* One second. */
if (!QueryServiceStatus (service, &status))
{
service_error ("QueryService");
CloseServiceHandle (service);
return;
}
if (status.dwCurrentState == SERVICE_STOPPED)
break;
if (GetTickCount () - start_time > timeout)
{
char buf[1024];
snprintf (buf, sizeof (buf),
"time out waiting for service %s to stop\r\n",
service_name);
MessageBox (g_hwndParent, buf, 0, MB_OK);
setuservariable (INST_R0, "1");
return;
}
}
CloseServiceHandle (service);
setuservariable (INST_R0, "0");
return;
}
void __declspec(dllexport)
service_delete (HWND hwndParent, int string_size, char *variables,
stack_t **stacktop, extra_parameters_t *extra)
{
SC_HANDLE service;
const char *result = NULL;
char service_name[256];
int err = 0;
g_hwndParent = hwndParent;
EXDLL_INIT();
/* The expected stack layout: service_name argc [argv]. */
if (popstring (service_name, sizeof (service_name)))
err = 1;
if (err)
{
setuservariable (INST_R0, "1");
return;
}
service = service_lookup (service_name);
if (service == NULL)
return;
err = DeleteService (service);
if (err == 0)
{
service_error ("DeleteService");
CloseServiceHandle (service);
return;
}
CloseServiceHandle (service);
setuservariable (INST_R0, "0");
return;
}
#endif /*ENABLE_SERVICE_MANAGEMENT*/
/* Extract config file parameters. FIXME: Not particularly robust.
We expect some reasonable formatting. The parser below is very
limited. It expects a command line option /c=FILE or /C=FILE,
where FILE must be enclosed in double-quotes if it contains spaces.
That file should contain a single section [gpg4win] and KEY=VALUE
pairs for each additional configuration file to install. Comments
are supported only on lines by themselves. VALUE can be quoted in
double-quotes, but does not need to be, unless it has whitespace at
the beginning or end. KEY can, for example, be "gpg.conf" (without
the quotes). */
void
config_init (char **keys, char **values, int max)
{
/* First, parse the command line. */
LPCWSTR wcmdline;
char *cmdline;
char *begin = NULL;
char *end = NULL;
char mark;
char *fname;
char *ptr;
FILE *conf;
*keys = NULL;
*values = NULL;
cmdline = malloc (4096);
if (!cmdline)
return;
wcmdline = getuservariable (INST_CMDLINE);
*cmdline = 0;
WideCharToMultiByte(CP_ACP, 0, wcmdline, -1, cmdline, 4095, NULL, NULL);
if (!*cmdline)
return;
mark = (*cmdline == '"') ? (cmdline++, '"') : ' ';
while (*cmdline && *cmdline != mark)
cmdline++;
if (mark == '"' && *cmdline)
cmdline++;
while (*cmdline && *cmdline == ' ')
cmdline++;
while (*cmdline)
{
/* We are at the beginning of a new argument. */
if (cmdline[0] == '/' && (cmdline[1] == 'C' || cmdline[1] == 'c')
&& cmdline[2] == '=')
{
cmdline += 3;
begin = cmdline;
}
while (*cmdline && *cmdline != ' ')
{
/* Skip over quoted parts. */
if (*cmdline == '"')
{
cmdline++;
while (*cmdline && *cmdline != '"')
cmdline++;
if (*cmdline)
cmdline++;
}
else
cmdline++;
}
if (begin && !end)
{
end = cmdline - 1;
break;
}
while (*cmdline && *cmdline == ' ')
cmdline++;
}
if (!begin || begin > end)
return;
/* Strip quotes. */
if (*begin == '"' && *end == '"')
{
begin++;
end--;
}
if (begin > end)
return;
fname = malloc (end - begin + 2);
if (!fname)
return;
ptr = fname;
while (begin <= end)
*(ptr++) = *(begin++);
*ptr = '\0';
conf = fopen (fname, "r");
free (fname);
free (cmdline);
if (!conf)
return;
while (max - 1 > 0)
{
char line[256];
char *ptr2;
if (fgets (line, sizeof (line), conf) == NULL)
break;
ptr = &line[strlen (line)];
while (ptr > line && (ptr[-1] == '\n' || ptr[-1] == '\r'
|| ptr[-1] == ' ' || ptr[-1] == '\t'))
ptr--;
*ptr = '\0';
ptr = line;
while (*ptr && (*ptr == ' ' || *ptr == '\t'))
ptr++;
/* Ignore comment lines. */
/* FIXME: Ignore section markers. */
if (*ptr == '\0' || *ptr == ';' || *ptr == '[')
continue;
begin = ptr;
while (*ptr && *ptr != '=' && *ptr != ' ' && *ptr != '\t')
ptr++;
end = ptr - 1;
while (*ptr && (*ptr == ' ' || *ptr == '\t'))
ptr++;
if (*ptr != '=')
continue;
ptr++;
if (begin > end)
continue;
/* We found a key. */
*keys = malloc (end - begin + 2);
if (!keys)
return;
ptr2 = *keys;
while (begin <= end)
*(ptr2++) = *(begin++);
*ptr2 = '\0';
*values = NULL;
while (*ptr && (*ptr == ' ' || *ptr == '\t'))
ptr++;
begin = ptr;
/* In this case, end points to the byte after the value, which
is OK because that is '\0'. */
end = &line[strlen (line)];
if (begin > end)
begin = end;
/* Strip quotes. */
if (*begin == '"' && end[-1] == '"')
{
begin++;
end--;
*end = '\0';
}
if (begin > end)
return;
*values = malloc (end - begin + 1);
ptr2 = *values;
while (begin <= end)
*(ptr2++) = *(begin++);
keys++;
values++;
max--;
}
fclose (conf);
*keys = NULL;
*values = NULL;
}
char *
config_lookup (char *key)
{
#define MAX_KEYS 128
static int initialised = 0;
static char *keys[MAX_KEYS];
static char *values[MAX_KEYS];
int i;
if (initialised == 0)
{
initialised = 1;
config_init (keys, values, MAX_KEYS);
#if 0
MessageBox(g_hwndParent, "Configuration File:", 0, MB_OK);
i = 0;
while (keys[i])
{
char buf[256];
sprintf (buf, "%s=%s\r\n", keys[i], values[i]);
MessageBox (g_hwndParent, buf, 0, MB_OK);
i++;
}
#endif
}
i = 0;
while (keys[i])
{
if (!strcmp (keys[i], key))
return values[i];
i++;
}
return NULL;
}
void __declspec(dllexport)
config_fetch (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra)
{
char key[256];
int err = 0;
char *value;
g_hwndParent = hwndParent;
EXDLL_INIT();
/* The expected stack layout: key. */
if (PopStringNA (key, sizeof (key)))
err = 1;
if (err)
{
setuservariable (INST_R0, L"");
return;
}
value = config_lookup (key);
SetUserVariableA (INST_R0, value == NULL ? "" : value);
return;
}
void __declspec(dllexport)
config_fetch_bool (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra)
{
char key[256];
int err = 0;
char *value;
int result;
g_hwndParent = hwndParent;
EXDLL_INIT();
/* The expected stack layout: key. */
if (PopStringNA (key, sizeof (key)))
err = 1;
if (err)
{
setuservariable (INST_R0, L"");
return;
}
value = config_lookup (key);
if (value == NULL || *value == '\0')
{
setuservariable (INST_R0, L"");
return;
}
result = 0;
if (!strcasecmp (value, "true")
|| !strcasecmp (value, "yes")
|| atoi (value) != 0)
result = 1;
SetUserVariableA (INST_R0, result == 0 ? "0" : "1");
return;
}
/* Return a string from the Win32 Registry or NULL in case of error.
Caller must release the return value. A NULL for root is an alias
for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. */
static wchar_t *
read_w32_registry_string (HKEY root, const wchar_t *dir, const wchar_t *name)
{
HKEY root_key;
HKEY key_handle;
DWORD n1, nbytes, type;
wchar_t *result = NULL;
root_key = root;
if (!root_key)
root_key = HKEY_CURRENT_USER;
if (RegOpenKeyExW (root_key, dir, 0, KEY_READ, &key_handle))
{
if (root)
return NULL; /* no need for a RegClose, so return direct */
/* It seems to be common practise to fall back to HKLM. */
if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle))
return NULL; /* still no need for a RegClose, so return direct */
}
nbytes = 1;
if (RegQueryValueExW (key_handle, name, 0, NULL, NULL, &nbytes))
{
if (root)
goto leave;
/* Try to fallback to HKLM also for a missing value. */
RegCloseKey (key_handle);
if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle))
return NULL; /* Nope. */
if (RegQueryValueExW (key_handle, name, 0, NULL, NULL, &nbytes))
goto leave;
}
result = calloc ((n1=nbytes+1), sizeof *result);
if (!result)
goto leave;
if (RegQueryValueExW (key_handle, name, 0, &type,
(unsigned char *)result, &n1))
{
free (result);
result = NULL;
goto leave;
}
result[nbytes] = 0; /* Make sure it is really a string */
leave:
RegCloseKey (key_handle);
return result;
}
/* Registry keys for PATH for HKLM and HKCU. */
#define ENV_HK HKEY_LOCAL_MACHINE
#define ENV_REG L"SYSTEM\\CurrentControlSet\\Control\\" \
"Session Manager\\Environment"
#define ENV_HK_USER HKEY_CURRENT_USER
#define ENV_REG_USER L"Environment"
/* Due to a bug in Windows7 (kb 2685893) we better put a lower limit
* than 8191 on the maximum length of the PATH variable. Note, that
* depending on the used toolchain we used to had a 259 byte limit in
* the past.
* [wk 2023-04-24]: Can this be lifted now that we use the wchar_t API?
*/
#define PATH_LENGTH_LIMIT 2047
void __declspec(dllexport)
path_add (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra)
{
wchar_t dir[PATH_LENGTH_LIMIT];
wchar_t is_user_install[2];
wchar_t *path;
wchar_t *path_new;
size_t path_new_size;
wchar_t *comp;
const wchar_t delims[] = L";";
int is_user;
HKEY key_handle = 0;
HKEY root_key;
const wchar_t *env_reg;
/* wchar_t *tokctx; Context var for wcstok - not yet needed. */
g_hwndParent = hwndParent;
EXDLL_INIT();
setuservariable (INST_R0, L"0"); /* Default return value. */
/* The expected stack layout: path component. */
if (popstringn (dir, COUNTOF (dir)))
return;
dir[COUNTOF(dir)-1] = 0;
/* The expected stack layout: HKEY component. */
if (popstringn (is_user_install, COUNTOF (is_user_install)))
return;
is_user_install[COUNTOF(is_user_install)-1] = 0;
if (!wcscmp (is_user_install, L"1"))
{
root_key = ENV_HK_USER;
env_reg = ENV_REG_USER;
}
else
{
root_key = ENV_HK;
env_reg = ENV_REG;
}
path = read_w32_registry_string (root_key, env_reg, L"Path");
if (!path)
{
path = wcsdup (L"");
}
/* Old path plus semicolon plus dir plus terminating nul. */
path_new_size = wcslen (path) + 1 + wcslen (dir) + 1;
if (path_new_size > PATH_LENGTH_LIMIT)
{
MessageBox (g_hwndParent, L"PATH env variable too big", 0, MB_OK);
free (path);
return;
}
path_new = calloc (path_new_size, sizeof *path_new);
if (!path_new)
{
free (path);
return;
}
wcscpy (path_new, path);
wcscat (path_new, L";");
wcscat (path_new, dir);
/* Check if the directory already exists in the path. */
comp = wcstok (path, delims/*, &tokctx*/);
do
{
/* MessageBox (g_hwndParent, comp, 0, MB_OK); */
if (!comp)
break;
if (!wcscmp (comp, dir))
{
free (path);
free (path_new);
return;
}
comp = wcstok (NULL, delims/*, &tokctx*/);
}
while (comp);
free (path);
/* Update the path key. */
RegCreateKeyW (root_key, env_reg, &key_handle);
RegSetValueEx (key_handle, L"Path", 0, REG_EXPAND_SZ,
(unsigned char*)path_new,
wcslen (path_new) * sizeof *path_new);
RegCloseKey (key_handle);
SetEnvironmentVariableW(L"PATH", path_new);
free (path_new);
/* MessageBox (g_hwndParent, "XXX 9", 0, MB_OK); */
setuservariable (INST_R0, L"1"); /* success. */
}
void __declspec(dllexport)
path_remove (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra)
{
wchar_t dir[PATH_LENGTH_LIMIT];
wchar_t is_user_install[2];
wchar_t *path;
wchar_t *path_new;
size_t path_new_size;
wchar_t *comp;
const wchar_t delims[] = L";";
HKEY key_handle = 0;
int changed = 0;
int count = 0;
HKEY root_key;
const wchar_t *env_reg;
/* wchar_t *tokctx; Context var for wcstok - not yet needed. */
g_hwndParent = hwndParent;
EXDLL_INIT();
setuservariable (INST_R0, L"0");
/* The expected stack layout: path component. */
if (popstringn (dir, COUNTOF (dir)))
return;
dir[COUNTOF(dir)-1] = 0;
/* The expected stack layout: HKEY component. */
if (popstringn (is_user_install, COUNTOF (is_user_install)))
return;
is_user_install[COUNTOF(is_user_install)-1] = 0;
if (!wcscmp (is_user_install, L"1"))
{
root_key = ENV_HK_USER;
env_reg = ENV_REG_USER;
}
else
{
root_key = ENV_HK;
env_reg = ENV_REG;
}
path = read_w32_registry_string (root_key, env_reg, L"Path");
if (!path)
return;
/* Old path plus semicolon plus dir plus terminating nul. */
path_new_size = wcslen (path) + 1;
path_new = calloc (path_new_size, sizeof *path_new);
if (!path_new)
{
free (path);
return;
}
/* Compose the new path. */
comp = wcstok (path, delims/*, &tokctx*/);
do
{
if (wcscmp (comp, dir))
{
if (count)
wcscat (path_new, L";");
wcscat (path_new, comp);
count++;
}
else
changed = 1;
}
while ((comp = wcstok (NULL, delims/*, &tokctx*/)));
free (path);
if (!changed)
{
free (path_new);
return;
}
/* Set a key for our CLSID. */
RegCreateKeyW (root_key, env_reg, &key_handle);
RegSetValueEx (key_handle, L"Path", 0, REG_EXPAND_SZ,
(unsigned char*)path_new,
wcslen (path_new) * sizeof *path_new);
RegCloseKey (key_handle);
free (path_new);
setuservariable (INST_R0, L"1"); /* success */
}
/** @brief Kill processes with the name name.
*
* This function tries to kill a process using ExitProcess.
*
* If it does not work it does not work. No return values.
* The intention is to make an effort to kill something during
* installation / uninstallation.
*
* The function signature is explained by NSIS.
*/
void __declspec(dllexport) __cdecl KillProc(HWND hwndParent,
int string_size,
char *variables,
stack_t **stacktop)
{
HANDLE h;
PROCESSENTRY32 pe32;
if (!stacktop || !*stacktop || !(*stacktop)->text)
{
ERRORPRINTF ("Invalid call to KillProc.");
return;
}
h = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
if (h == INVALID_HANDLE_VALUE)
{
ERRORPRINTF ("Failed to create Toolhelp snapshot");
return;
}
pe32.dwSize = sizeof (PROCESSENTRY32);
if (!Process32First (h, &pe32))
{
ERRORPRINTF ("Failed to get first process");
CloseHandle (h);
return;
}
do
{
if (!wcscmp ((*stacktop)->text, pe32.szExeFile))
{
HANDLE hProc = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
pe32.th32ProcessID);
if (!hProc)
{
ERRORPRINTF ("Failed to open process handle.");
continue;
}
if (!TerminateProcess (hProc, 1))
{
ERRORPRINTF ("Failed to terminate process.");
}
CloseHandle (hProc);
}
}
while (Process32Next (h, &pe32));
CloseHandle (h);
}
diff --git a/src/gpg4win-src.nsi b/src/gpg4win-src.nsi
index ca41c1c9..b5069618 100644
--- a/src/gpg4win-src.nsi
+++ b/src/gpg4win-src.nsi
@@ -1,111 +1,113 @@
-# gpg4win-src.nsi - Installer for GPG4Win sources. -*- coding: latin-1; -*-
+# gpg4win-src.nsi - Installer for GPG4Win sources.
# Copyright (C) 2005, 2007 g10 Code GmbH
#
# This file is part of Gpg4win.
#
# Gpg4win is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Gpg4win is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+Unicode true
+
!cd "${BUILD_DIR}"
!addincludedir "${TOP_SRCDIR}"
!addincludedir "${TOP_SRCDIR}/po"
!addincludedir "${SRCDIR}"
!addplugindir "${BUILD_DIR}"
!include "config.nsi"
# We need StrRep.
!include "StrFunc.nsh"
# The package name and version. PRETTY_PACKAGE is a user visible name
# only while PACKAGE is useful for filenames etc. PROD_VERSION is the
# product version and needs to be in the format "MAJ.MIN.MIC.BUILDNR".
# NOTE: Please keep the capitalization of PRETTY_PACKAGE_SHORT as it is
# used as registry key.
!define PACKAGE "${_PACKAGE}-src"
!define PRETTY_PACKAGE "Gpg4win Sources"
!define PRETTY_PACKAGE_SHORT "GPG4WinSrc"
!define VERSION "${_VERSION}"
!define PROD_VERSION "${_BUILD_FILEVERSION}"
!define COMPANY "g10 Code GmbH"
!define COPYRIGHT "Copyright (C) 2007 g10 Code GmbH"
!define DESCRIPTION "Gpg4win: The GNU Privacy Guard and tools for Windows (Source Files)"
!define INSTALL_DIR "GnuPG\Source"
!define WELCOME_TITLE_STR "$(T_WelcomeTitleGpg4winSrc)"
!define ABOUT_STR "$(T_AboutGpg4winSrc) \
$\r$\n$\r$\n$_CLICK $\r$\n$\r$\n$\r$\n$\r$\n$\r$\n \
$(T_AboutGpg4winSrcVersion) $\r$\n \
$(T_AboutGpg4winSrcFileVersion) $\r$\n$\r$\n \
$(T_AboutGpg4winSrcReleaseDate)"
# The copyright license of the package. Define only one of these.
!define LICENSE_GPL
# !define LICENSE_LGPL
# Sections
!include "Sections.nsh"
# We use Memento to remember past installation choices.
!include Memento.nsh
!define MEMENTO_REGISTRY_ROOT SHCTX
!define MEMENTO_REGISTRY_KEY \
Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRETTY_PACKAGE_SHORT}
# We need to know wether we are installing to 64 bit.
!include "x64.nsh"
# The installation directory.
!define ipdir "playground/install/pkgs"
!define exipdir "playground/install-ex/pkgs"
!define bpdir "playground/build"
# For source packages we use the standard zip method because it takes
# ages to compress a large archive of already packed sources.
SetCompressor zlib
# Now include all the sections.
!define SOURCES
!include "inst-sections.nsi"
# Now include the generic parts.
!include "installer.nsi"
# The WelcomeTitle is displayed on the first page.
LangString T_WelcomeTitleGpg4winSrc ${LANG_ENGLISH} \
"Welcome to the installation of the Gpg4win sources"
# The About string as displayed on the first page.
LangString T_AboutGpg4winSrc ${LANG_ENGLISH} \
"Gpg4win is an installer package for Windows for EMail and \
file encryption using the core component GnuPG for Windows. \
Both relevant cryptography standards are supported, OpenPGP \
and S/MIME. Gpg4win and the software included with Gpg4win \
are Free Software."
LangString T_AboutGpg4winSrcVersion ${LANG_ENGLISH} \
"This is Gpg4win version ${VERSION}"
LangString T_AboutGpg4winSrcFileVersion ${LANG_ENGLISH} \
"file version ${PROD_VERSION}"
LangString T_AboutGpg4winSrcReleaseDate ${LANG_ENGLISH} \
"release date ${_BUILD_ISODATE}"
# At long last, include all the translations.
!include "../po/catalogs.nsi"
# Now include the generic parts to end the installation.
!include "installer-finish.nsi"
diff --git a/src/gpg4win.nsi b/src/gpg4win.nsi
index 281f7a42..ca27b4a4 100644
--- a/src/gpg4win.nsi
+++ b/src/gpg4win.nsi
@@ -1,134 +1,136 @@
-# gpg4win.nsi - Installer for GnuPG 4 Windows. -*- coding: latin-1; -*-
+# gpg4win.nsi - Installer for GnuPG 4 Windows.
# Copyright (C) 2005, 2007, 2008 g10 Code GmbH
#
# This file is part of GPG4Win.
#
# GPG4Win is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# GPG4Win is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+Unicode true
+
!cd "${BUILD_DIR}"
!addincludedir "${TOP_SRCDIR}"
!addincludedir "${TOP_SRCDIR}/po"
!addincludedir "${SRCDIR}"
!addplugindir "${BUILD_DIR}"
!include "config.nsi"
# Define this early automatically it is only defined after
# MUI_LANGUAGE has been called.
!define LANG_ENGLISH 1033
# The package name and version. PRETTY_PACKAGE is a user visible name
# only while PACKAGE is useful for filenames etc. PROD_VERSION is the
# product version and needs to be in the format "MAJ.MIN.MIC.BUILDNR".
# NOTE: Please keep the capitalization of PRETTY_PACKAGE_SHORT as it is
# used as registry key.
!define PACKAGE "${_PACKAGE}"
!define PRETTY_PACKAGE "Gpg4win"
!define PRETTY_PACKAGE_SHORT "Gpg4win"
!define VERSION "${_VERSION}"
!define PROD_VERSION "${_BUILD_FILEVERSION}"
!define COMPANY "Intevation GmbH"
!define COPYRIGHT "Copyright (C) 2020 Intevation GmbH"
!define DESCRIPTION "Gpg4win: The GNU Privacy Guard and Tools for Windows"
!define INSTALL_DIR "Gpg4win"
!define WELCOME_TITLE_STR "$(T_WelcomeTitleGpg4win)"
!define ABOUT_STR "$(T_AboutGpg4win) \
$\r$\n$\r$\n$\r$\n$_CLICK $\r$\n$\r$\n$\r$\n$\r$\n$\r$\n\
$(T_AboutGpg4winVersion) $\r$\n$(T_AboutGpg4winReleaseDate)"
# The copyright license of the package. Define only one of these.
!define LICENSE_GPL
# Select the best compression algorithm available. The dictionary
# size is the default (8 MB).
!ifndef DISABLE_LZMA
!ifndef SOURCES
SetCompressor /SOLID lzma
# SetCompressorDictSize 8
!endif
!endif
# We support user mode installation but prefer system wide
!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_MUI
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "Software\${PRETTY_PACKAGE_SHORT}"
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME ""
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "Software\${PRETTY_PACKAGE_SHORT}"
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME "Install Directory"
!define MULTIUSER_INSTALLMODE_INSTDIR "${PRETTY_PACKAGE_SHORT}"
!include "MultiUser.nsh"
!ifdef DEBUG
!undef DEBUG
!endif
# The installation directory.
!define ipdir "playground/install/pkgs"
!define exipdir "playground/install-ex/pkgs"
!define bpdir "playground/build"
# Variables
VAR is_minimal
VAR with_browser
VAR is_update
# Sections
!include "Sections.nsh"
# We use Memento to remember past installation choices.
!include Memento.nsh
!define MEMENTO_REGISTRY_ROOT SHCTX
!define MEMENTO_REGISTRY_KEY \
Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRETTY_PACKAGE_SHORT}
# We need to know wether we are installing to 64 bit.
!include "x64.nsh"
# Now include the sections.
!define BINARIES
!include "inst-sections.nsi"
# Now include the generic parts.
!define HAVE_STARTMENU
!include "installer.nsi"
# The WelcomeTitle is displayed on the first page.
LangString T_WelcomeTitleGpg4win ${LANG_ENGLISH} \
"Welcome to the installation of Gpg4win"
# The About string as displayed on the first page.
LangString T_AboutGpg4win ${LANG_ENGLISH} \
"Gpg4win is an installer package for Windows for EMail and \
file encryption using the core component GnuPG for Windows. \
Both relevant cryptography standards are supported, OpenPGP \
and S/MIME. Gpg4win and the software included with Gpg4win \
is Free Software."
LangString T_AboutGpg4winVersion ${LANG_ENGLISH} \
"This is Gpg4win version ${VERSION}"
LangString T_AboutGpg4winFileVersion ${LANG_ENGLISH} \
"file version ${PROD_VERSION}"
LangString T_AboutGpg4winReleaseDate ${LANG_ENGLISH} \
"Release date ${_BUILD_ISODATE}"
# At long last, include all the translations.
!include "../po/catalogs.nsi"
# Now include the generic parts to end the installation.
!include "installer-finish.nsi"
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Dec 4, 2:14 PM (1 d, 8 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
b7/8e/c64ecdec698a24fc5982a672fe62
Attached To
rW Gpg4win
Event Timeline
Log In to Comment