1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

speedo: Update NSIS helper DLL from Gpg4win

* build-aux/speedo/w32/inst.nsi: Re-enable run-once check.
* build-aux/speedo/w32/exdll.c: New.
* build-aux/speedo.mk (g4wihelp.dll): Change build commands.
--

GnuPG-bug-id: 6448
This commit is contained in:
Werner Koch 2023-04-24 18:48:54 +02:00
parent c4a456e5ff
commit 7359665add
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
6 changed files with 717 additions and 254 deletions

View File

@ -55,6 +55,7 @@ EXTRA_DIST = build-aux/config.rpath build-aux/potomo autogen.sh autogen.rc \
build-aux/speedo/w32/pango.modules \ build-aux/speedo/w32/pango.modules \
build-aux/speedo/w32/gdk-pixbuf-loaders.cache \ build-aux/speedo/w32/gdk-pixbuf-loaders.cache \
build-aux/speedo/w32/exdll.h \ build-aux/speedo/w32/exdll.h \
build-aux/speedo/w32/exdll.c \
build-aux/speedo/w32/README.txt \ build-aux/speedo/w32/README.txt \
build-aux/speedo/w32/gnupg-logo-150x57.bmp \ build-aux/speedo/w32/gnupg-logo-150x57.bmp \
build-aux/speedo/w32/gnupg-logo-164x314.bmp \ build-aux/speedo/w32/gnupg-logo-164x314.bmp \

View File

@ -1340,10 +1340,14 @@ $(bdir)/README.txt: $(bdir)/NEWS.tmp $(topsrc)/README $(w32src)/README.txt \
| sed -e '/^#/d' \ | sed -e '/^#/d' \
| awk '{printf "%s\r\n", $$0}' >$(bdir)/README.txt | awk '{printf "%s\r\n", $$0}' >$(bdir)/README.txt
$(bdir)/g4wihelp.dll: $(w32src)/g4wihelp.c $(w32src)/exdll.h $(bdir)/g4wihelp.dll: $(w32src)/g4wihelp.c $(w32src)/exdll.h $(w32src)/exdll.c
(set -e; cd $(bdir); \ (set -e; cd $(bdir); \
$(W32CC) -I. -shared -O2 -o g4wihelp.dll $(w32src)/g4wihelp.c \ $(W32CC) -DUNICODE -static-libgcc -I . -O2 -c \
-lwinmm -lgdi32; \ -o exdll.o $(w32src)/exdll.c; \
$(W32CC) -DUNICODE -static-libgcc -I. -shared -O2 \
-o g4wihelp.dll $(w32src)/g4wihelp.c exdll.o \
-lwinmm -lgdi32 -luserenv \
-lshell32 -loleaut32 -lshlwapi -lmsimg32; \
$(STRIP) g4wihelp.dll) $(STRIP) g4wihelp.dll)
w32_insthelpers: $(bdir)/g4wihelp.dll w32_insthelpers: $(bdir)/g4wihelp.dll

View File

@ -0,0 +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)((wchar_t*)g_variables+varnum*g_stringsize);
}
void NSISCALL setuservariable(const int varnum, LPCTSTR var)
{
if (var && isvalidnsisvarindex(varnum))
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);
}

View File

@ -1,60 +1,71 @@
/* exdll.h for use with gpg4win #include <windows.h>
* Copyright (C) 1999-2005 Nullsoft, Inc. #ifndef ___NSIS_PLUGIN__H___
* #define ___NSIS_PLUGIN__H___
* This license applies to everything in the NSIS package, except
* where otherwise noted.
*
* 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.
************************************************************
* 2005-11-14 wk Applied license text to original exdll.h file from
* NSIS 2.0.4 and did some formatting changes.
*/
#ifndef _EXDLL_H_ #ifdef __cplusplus
#define _EXDLL_H_ extern "C" {
#endif
/* only include this file from one place in your DLL. (it is all #ifndef NSISCALL
static, if you use it in two places it will fail) */ # define NSISCALL __stdcall
#endif
#if !defined(_WIN32) && !defined(LPTSTR)
# define LPTSTR TCHAR*
#endif
#ifndef NSISCALL
# define NSISCALL WINAPI
#endif
#define EXDLL_INIT() { \ #define EXDLL_INIT() { \
g_stringsize=string_size; \ g_stringsize=string_size; \
g_stacktop=stacktop; \ g_stacktop=stacktop; \
g_variables=variables; } g_variables=variables; }
/* For page showing plug-ins */
#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8) enum NSPIM
#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd) {
#define NOTIFY_BYE_BYE 'x' NSPIM_UNLOAD,
NSPIM_GUIUNLOAD
};
typedef UINT_PTR (*NSISPLUGINCALLBACK)(enum NSPIM);
typedef struct _stack_t { typedef struct _stack_t {
struct _stack_t *next; struct _stack_t *next;
char text[1]; /* This should be the length of string_size. */ #ifdef UNICODE
WCHAR text[1]; // this should be the length of g_stringsize when allocating
#else
char text[1];
#endif
} stack_t; } stack_t;
typedef struct {
int autoclose;
int all_user_var;
int exec_error;
int abort;
int exec_reboot;
int reboot_called;
int XXX_cur_insttype; /* deprecated */
int plugin_api_version; /* Used to be insttype_changed */
int silent;
int instdir_error;
int rtl;
int errlvl;
int alter_reg_view;
int status_update;
} exec_flags_t;
static unsigned int g_stringsize; typedef struct {
static stack_t **g_stacktop; exec_flags_t *exec_flags;
static char *g_variables; int (__stdcall *ExecuteCodeSegment)(int, HWND);
void (__stdcall *validate_filename)(LPTSTR);
int (__stdcall *RegisterPluginCallback)(HMODULE, NSISPLUGINCALLBACK);
} extra_parameters_t;
static int __stdcall popstring(char *str, size_t maxlen); /* 0 on success, 1 on empty stack */
static void __stdcall pushstring(const char *str);
enum enum
{ {
@ -86,66 +97,80 @@ enum
__INST_LAST __INST_LAST
}; };
typedef struct { extern unsigned int g_stringsize;
int autoclose; extern stack_t **g_stacktop;
int all_user_var; extern LPTSTR g_variables;
int exec_error;
int abort;
int exec_reboot;
int reboot_called;
int XXX_cur_insttype; /* deprecated */
int XXX_insttype_changed; /* deprecated */
int silent;
int instdir_error;
int rtl;
int errlvl;
} exec_flags_t;
typedef struct { void NSISCALL pushstring(LPCTSTR str);
exec_flags_t *exec_flags; void NSISCALL pushintptr(INT_PTR value);
int (__stdcall *ExecuteCodeSegment)(int, HWND); #define pushint(v) pushintptr((INT_PTR)(v))
} extra_parameters_t; int NSISCALL popstring(LPTSTR str); // 0 on success, 1 on empty stack
int NSISCALL popstringn(LPTSTR str, int maxlen); // with length limit, pass 0 for g_stringsize
INT_PTR NSISCALL popintptr();
#define popint() ( (int) popintptr() )
int NSISCALL popint_or(); // with support for or'ing (2|4|8)
INT_PTR NSISCALL nsishelper_str_to_ptr(LPCTSTR s);
#define myatoi(s) ( (int) nsishelper_str_to_ptr(s) ) // converts a string to an integer
unsigned int NSISCALL myatou(LPCTSTR s); // converts a string to an unsigned integer, decimal only
int NSISCALL myatoi_or(LPCTSTR s); // with support for or'ing (2|4|8)
LPTSTR NSISCALL getuservariable(const int varnum);
void NSISCALL setuservariable(const int varnum, LPCTSTR var);
#ifdef UNICODE
#define PopStringW(x) popstring(x)
#define PushStringW(x) pushstring(x)
#define SetUserVariableW(x,y) setuservariable(x,y)
/* Utility functions (not required but often useful). */ int NSISCALL PopStringA(LPSTR ansiStr);
static int __stdcall int NSISCALL PopStringNA(LPSTR ansiStr, int maxlen);
popstring(char *str, size_t maxlen) void NSISCALL PushStringA(LPCSTR ansiStr);
{ void NSISCALL GetUserVariableW(const int varnum, LPWSTR wideStr);
stack_t *th; void NSISCALL GetUserVariableA(const int varnum, LPSTR ansiStr);
if (!g_stacktop || !*g_stacktop) void NSISCALL SetUserVariableA(const int varnum, LPCSTR ansiStr);
return 1;
th=(*g_stacktop); #else
lstrcpyn (str, th->text, maxlen); // ANSI defs
*g_stacktop = th->next;
GlobalFree((HGLOBAL)th); #define PopStringA(x) popstring(x)
return 0; #define PushStringA(x) pushstring(x)
#define SetUserVariableA(x,y) setuservariable(x,y)
int NSISCALL PopStringW(LPWSTR wideStr);
void NSISCALL PushStringW(LPWSTR wideStr);
void NSISCALL GetUserVariableW(const int varnum, LPWSTR wideStr);
void NSISCALL GetUserVariableA(const int varnum, LPSTR ansiStr);
void NSISCALL SetUserVariableW(const int varnum, LPCWSTR wideStr);
#endif
#ifdef __cplusplus
} }
#endif
static void __stdcall #endif//!___NSIS_PLUGIN__H___
pushstring(const char *str)
{ #ifndef COUNTOF
stack_t *th; #define COUNTOF(a) (sizeof(a)/sizeof(a[0]))
if (!g_stacktop) return; #endif
th=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t)+g_stringsize);
lstrcpyn(th->text,str,g_stringsize); // minimal tchar.h emulation
th->next=*g_stacktop; #ifndef _T
*g_stacktop=th; # define _T TEXT
#endif
#if !defined(TCHAR) && !defined(_TCHAR_DEFINED)
# ifdef UNICODE
# define TCHAR WCHAR
# else
# define TCHAR char
# endif
#endif
#define isvalidnsisvarindex(varnum) ( ((unsigned int)(varnum)) < (__INST_LAST) )
#define ERRORPRINTF(fmt, ...) \
{ \
char buf[512]; \
snprintf(buf, 511, "ERROR: " fmt, ##__VA_ARGS__); \
buf[511] = '\0'; \
OutputDebugStringA(buf); \
} }
static char * __stdcall
getuservariable(const int varnum)
{
if (varnum < 0 || varnum >= __INST_LAST) return NULL;
return g_variables+varnum*g_stringsize;
}
static void __stdcall
setuservariable(const int varnum, const char *var)
{
if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
lstrcpy(g_variables + varnum*g_stringsize, var);
}
#endif/*_EXDLL_H_*/

View File

@ -1,6 +1,7 @@
/* g4wihelp.c - NSIS Helper DLL used with gpg4win. -*- coding: latin-1; -*- /* g4wihelp.c - NSIS Helper DLL used with gpg4win.
* Copyright (C) 2005 g10 Code GmbH * Copyright (C) 2005, 2023 g10 Code GmbH
* Copyright (C) 2001 Justin Frankel * Copyright (C) 2001 Justin Frankel
* Copyright (C) 2016, 2017 Intevation GmbH
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any * warranty. In no event will the authors be held liable for any
@ -23,22 +24,41 @@
************************************************************ ************************************************************
* The code for the splash screen has been taken from the Splash * The code for the splash screen has been taken from the Splash
* plugin of the NSIS 2.04 distribution. That code comes without * plugin of the NSIS 2.04 distribution. That code comes without
* explicit copyright notices in the source files or author names, it * explicit copyright notices in tyhe source files or author names, it
* seems that it has been written by Justin Frankel; not sure about * seems that it has been written by Justin Frankel; not sure about
* the year, though. [wk 2005-11-28] * the year, though. [wk 2005-11-28]
* *
* Fixed some compiler warnings. [wk 2014-02-24]. * 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 <stdio.h>
#include <windows.h> #include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <psapi.h>
#include <stdio.h>
#include <string.h>
#include "exdll.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 HINSTANCE g_hInstance; /* Our Instance. */
static HWND g_hwndParent; /* Handle of parent window or NULL. */ static HWND g_hwndParent; /* Handle of parent window or NULL. */
static HBITMAP g_hbm; /* Handle of the splash image. */ static HBITMAP g_hbm; /* Handle of the splash image. */
static int sleepint; /* Milliseconds to show the spals 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. */ /* Standard entry point for DLLs. */
int WINAPI int WINAPI
@ -46,6 +66,12 @@ DllMain (HANDLE hinst, DWORD reason, LPVOID reserved)
{ {
if (reason == DLL_PROCESS_ATTACH) if (reason == DLL_PROCESS_ATTACH)
g_hInstance = hinst; g_hInstance = hinst;
else if (reason == DLL_PROCESS_DETACH)
{
#ifdef ENABLE_SLIDE_SHOW
slide_stop (NULL, 0, NULL, NULL);
#endif
}
return TRUE; return TRUE;
} }
@ -53,7 +79,7 @@ DllMain (HANDLE hinst, DWORD reason, LPVOID reserved)
/* Dummy function for testing. */ /* Dummy function for testing. */
void __declspec(dllexport) void __declspec(dllexport)
dummy (HWND hwndParent, int string_size, char *variables, dummy (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra) stack_t **stacktop, extra_parameters_t *extra)
{ {
g_hwndParent = hwndParent; g_hwndParent = hwndParent;
@ -67,21 +93,66 @@ dummy (HWND hwndParent, int string_size, char *variables,
// you should empty the stack of your parameters, and ONLY your // you should empty the stack of your parameters, and ONLY your
// parameters. // parameters.
// do your stuff here /* Let's dump the variables. */
{ {
char buf[1024]; char line[512];
snprintf (buf, sizeof buf, "$R0=%s\r\n$R1=%s\r\n", 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_R0),
getuservariable(INST_R1)); getuservariable(INST_R1));
MessageBox (g_hwndParent,buf,0,MB_OK); MessageBoxW(g_hwndParent,buf,0,MB_OK);
snprintf (buf, sizeof buf, swprintf (buf, 1024,
"autoclose =%d\r\n" L"autoclose =%d\r\n"
"all_user_var =%d\r\n" "all_user_var =%d\r\n"
"exec_error =%d\r\n" "exec_error =%d\r\n"
"abort =%d\r\n" "abort =%d\r\n"
"exec_reboot =%d\r\n" "exec_reboot =%d\r\n"
"reboot_called=%d\r\n" "reboot_called=%d\r\n"
"api_version =%d\r\n"
"silent =%d\r\n" "silent =%d\r\n"
"instdir_error=%d\r\n" "instdir_error=%d\r\n"
"rtl =%d\r\n" "rtl =%d\r\n"
@ -92,30 +163,34 @@ dummy (HWND hwndParent, int string_size, char *variables,
extra->exec_flags->abort, extra->exec_flags->abort,
extra->exec_flags->exec_reboot, extra->exec_flags->exec_reboot,
extra->exec_flags->reboot_called, extra->exec_flags->reboot_called,
extra->exec_flags->plugin_api_version,
extra->exec_flags->silent, extra->exec_flags->silent,
extra->exec_flags->instdir_error, extra->exec_flags->instdir_error,
extra->exec_flags->rtl, extra->exec_flags->rtl,
extra->exec_flags->errlvl); extra->exec_flags->errlvl);
MessageBox(g_hwndParent,buf,0,MB_OK); MessageBoxW(g_hwndParent,buf,0,MB_OK);
} }
} }
void __declspec(dllexport) void __declspec(dllexport)
runonce (HWND hwndParent, int string_size, char *variables, runonce (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra) stack_t **stacktop, extra_parameters_t *extra)
{ {
const char *result; LPCWSTR result;
g_hwndParent = hwndParent; g_hwndParent = hwndParent;
EXDLL_INIT(); EXDLL_INIT();
CreateMutexA (NULL, 0, getuservariable(INST_R0)); CreateMutexW (NULL, 0, getuservariable(INST_R0));
result = GetLastError ()? "1":"0"; result = GetLastError ()? L"1" : L"0";
setuservariable (INST_R0, result); setuservariable (INST_R0, result);
} }
#ifdef ENABLE_SOUND_GADGET
void __declspec(dllexport) void __declspec(dllexport)
playsound (HWND hwndParent, int string_size, char *variables, playsound (HWND hwndParent, int string_size, char *variables,
stack_t **stacktop, extra_parameters_t *extra) stack_t **stacktop, extra_parameters_t *extra)
@ -139,8 +214,10 @@ stopsound (HWND hwndParent, int string_size, char *variables,
EXDLL_INIT(); EXDLL_INIT();
PlaySound (NULL, NULL, 0); PlaySound (NULL, NULL, 0);
} }
#endif /*ENABLE_SOUND_GADGET*/
#ifdef ENABLE_SPLASH_GADGET
/* Windows procedure to control the splashimage. This one pauses the /* Windows procedure to control the splashimage. This one pauses the
execution until the sleep time is over or the user closes this execution until the sleep time is over or the user closes this
windows. */ windows. */
@ -268,10 +345,10 @@ showsplash (HWND hwndParent, int string_size, char *variables,
} }
UnregisterClass (classname, g_hInstance); UnregisterClass (classname, g_hInstance);
} }
#endif /*ENABLE_SPLASH_GADGET*/
/* Service Management. */
#ifdef ENABLE_SERVICE_MANAGEMENT
/* Use this to report unexpected errors. FIXME: This is really not /* Use this to report unexpected errors. FIXME: This is really not
very descriptive. */ very descriptive. */
void void
@ -626,9 +703,8 @@ service_delete (HWND hwndParent, int string_size, char *variables,
setuservariable (INST_R0, "0"); setuservariable (INST_R0, "0");
return; return;
} }
#endif /*ENABLE_SERVICE_MANAGEMENT*/
#include <stdio.h>
/* Extract config file parameters. FIXME: Not particularly robust. /* Extract config file parameters. FIXME: Not particularly robust.
We expect some reasonable formatting. The parser below is very We expect some reasonable formatting. The parser below is very
@ -644,6 +720,7 @@ void
config_init (char **keys, char **values, int max) config_init (char **keys, char **values, int max)
{ {
/* First, parse the command line. */ /* First, parse the command line. */
LPCWSTR wcmdline;
char *cmdline; char *cmdline;
char *begin = NULL; char *begin = NULL;
char *end = NULL; char *end = NULL;
@ -655,7 +732,15 @@ config_init (char **keys, char **values, int max)
*keys = NULL; *keys = NULL;
*values = NULL; *values = NULL;
cmdline = getuservariable (INST_CMDLINE); 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++, '"') : ' '; mark = (*cmdline == '"') ? (cmdline++, '"') : ' ';
while (*cmdline && *cmdline != mark) while (*cmdline && *cmdline != mark)
@ -721,6 +806,7 @@ config_init (char **keys, char **values, int max)
conf = fopen (fname, "r"); conf = fopen (fname, "r");
free (fname); free (fname);
free (cmdline);
if (!conf) if (!conf)
return; return;
@ -843,7 +929,7 @@ config_lookup (char *key)
void __declspec(dllexport) void __declspec(dllexport)
config_fetch (HWND hwndParent, int string_size, char *variables, config_fetch (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra) stack_t **stacktop, extra_parameters_t *extra)
{ {
char key[256]; char key[256];
@ -854,23 +940,23 @@ config_fetch (HWND hwndParent, int string_size, char *variables,
EXDLL_INIT(); EXDLL_INIT();
/* The expected stack layout: key. */ /* The expected stack layout: key. */
if (popstring (key, sizeof (key))) if (PopStringNA (key, sizeof (key)))
err = 1; err = 1;
if (err) if (err)
{ {
setuservariable (INST_R0, ""); setuservariable (INST_R0, L"");
return; return;
} }
value = config_lookup (key); value = config_lookup (key);
setuservariable (INST_R0, value == NULL ? "" : value); SetUserVariableA (INST_R0, value == NULL ? "" : value);
return; return;
} }
void __declspec(dllexport) void __declspec(dllexport)
config_fetch_bool (HWND hwndParent, int string_size, char *variables, config_fetch_bool (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra) stack_t **stacktop, extra_parameters_t *extra)
{ {
char key[256]; char key[256];
@ -882,18 +968,18 @@ config_fetch_bool (HWND hwndParent, int string_size, char *variables,
EXDLL_INIT(); EXDLL_INIT();
/* The expected stack layout: key. */ /* The expected stack layout: key. */
if (popstring (key, sizeof (key))) if (PopStringNA (key, sizeof (key)))
err = 1; err = 1;
if (err) if (err)
{ {
setuservariable (INST_R0, ""); setuservariable (INST_R0, L"");
return; return;
} }
value = config_lookup (key); value = config_lookup (key);
if (value == NULL || *value == '\0') if (value == NULL || *value == '\0')
{ {
setuservariable (INST_R0, ""); setuservariable (INST_R0, L"");
return; return;
} }
@ -903,7 +989,7 @@ config_fetch_bool (HWND hwndParent, int string_size, char *variables,
|| atoi (value) != 0) || atoi (value) != 0)
result = 1; result = 1;
setuservariable (INST_R0, result == 0 ? "0" : "1"); SetUserVariableA (INST_R0, result == 0 ? "0" : "1");
return; return;
} }
@ -911,48 +997,52 @@ config_fetch_bool (HWND hwndParent, int string_size, char *variables,
/* Return a string from the Win32 Registry or NULL in case of error. /* 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 Caller must release the return value. A NULL for root is an alias
for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. */ for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. */
char * static wchar_t *
read_w32_registry_string (HKEY root, const char *dir, const char *name) read_w32_registry_string (HKEY root, const wchar_t *dir, const wchar_t *name)
{ {
HKEY root_key; HKEY root_key;
HKEY key_handle; HKEY key_handle;
DWORD n1, nbytes, type; DWORD n1, nbytes, type;
char *result = NULL; wchar_t *result = NULL;
root_key = root; root_key = root;
if (!root_key) if (!root_key)
root_key = HKEY_CURRENT_USER; root_key = HKEY_CURRENT_USER;
if( RegOpenKeyEx( root_key, dir, 0, KEY_READ, &key_handle ) ) if (RegOpenKeyExW (root_key, dir, 0, KEY_READ, &key_handle))
{ {
if (root) if (root)
return NULL; /* no need for a RegClose, so return direct */ return NULL; /* no need for a RegClose, so return direct */
/* It seems to be common practise to fall back to HKLM. */ /* It seems to be common practise to fall back to HKLM. */
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) ) if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle))
return NULL; /* still no need for a RegClose, so return direct */ return NULL; /* still no need for a RegClose, so return direct */
} }
nbytes = 1; nbytes = 1;
if( RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) ) { if (RegQueryValueExW (key_handle, name, 0, NULL, NULL, &nbytes))
{
if (root) if (root)
goto leave; goto leave;
/* Try to fallback to HKLM also vor a missing value. */ /* Try to fallback to HKLM also for a missing value. */
RegCloseKey (key_handle); RegCloseKey (key_handle);
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) ) if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle))
return NULL; /* Nope. */ return NULL; /* Nope. */
if (RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes)) if (RegQueryValueExW (key_handle, name, 0, NULL, NULL, &nbytes))
goto leave; goto leave;
} }
result = malloc( (n1=nbytes+1) ); result = calloc ((n1=nbytes+1), sizeof *result);
if (!result) if (!result)
goto leave; goto leave;
if( RegQueryValueEx( key_handle, name, 0, &type, result, &n1 ) ) {
free(result); result = NULL; if (RegQueryValueExW (key_handle, name, 0, &type,
(unsigned char *)result, &n1))
{
free (result);
result = NULL;
goto leave; goto leave;
} }
result[nbytes] = 0; /* make sure it is really a string */ result[nbytes] = 0; /* Make sure it is really a string */
leave: leave:
RegCloseKey (key_handle); RegCloseKey (key_handle);
@ -960,50 +1050,54 @@ read_w32_registry_string (HKEY root, const char *dir, const char *name)
} }
/* Registry keys for PATH for HKLM and HKCU. */
#define ENV_HK HKEY_LOCAL_MACHINE #define ENV_HK HKEY_LOCAL_MACHINE
#define ENV_REG "SYSTEM\\CurrentControlSet\\Control\\" \ #define ENV_REG L"SYSTEM\\CurrentControlSet\\Control\\" \
"Session Manager\\Environment" "Session Manager\\Environment"
/* The following setting can be used for a per-user setting. */
#define ENV_HK_USER HKEY_CURRENT_USER #define ENV_HK_USER HKEY_CURRENT_USER
#define ENV_REG_USER "Environment" #define ENV_REG_USER L"Environment"
/* Due to a bug in Windows7 (kb 2685893) we better put a lower limit /* 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 * 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 * depending on the used toolchain we used to had a 259 byte limit in
the past. */ * the past.
* [wk 2023-04-24]: Can this be lifted now that we use the wchar_t API?
*/
#define PATH_LENGTH_LIMIT 2047 #define PATH_LENGTH_LIMIT 2047
void __declspec(dllexport) void __declspec(dllexport)
path_add (HWND hwndParent, int string_size, char *variables, path_add (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra) stack_t **stacktop, extra_parameters_t *extra)
{ {
char dir[PATH_LENGTH_LIMIT]; wchar_t dir[PATH_LENGTH_LIMIT];
char is_user_install[2]; wchar_t is_user_install[2];
char *path; wchar_t *path;
char *path_new; wchar_t *path_new;
int path_new_size; size_t path_new_size;
char *comp; wchar_t *comp;
const char delims[] = ";"; const wchar_t delims[] = L";";
int is_user; int is_user;
HKEY key_handle = 0; HKEY key_handle = 0;
HKEY root_key; HKEY root_key;
const char *env_reg; const wchar_t *env_reg;
/* wchar_t *tokctx; Context var for wcstok - not yet needed. */
g_hwndParent = hwndParent; g_hwndParent = hwndParent;
EXDLL_INIT(); EXDLL_INIT();
setuservariable (INST_R0, "0"); setuservariable (INST_R0, L"0"); /* Default return value. */
/* MessageBox (g_hwndParent, "XXX 1", 0, MB_OK); */
/* The expected stack layout: path component. */ /* The expected stack layout: path component. */
if (popstring (dir, sizeof (dir))) if (popstringn (dir, COUNTOF (dir)))
return; return;
dir[COUNTOF(dir)-1] = 0;
/* The expected stack layout: HKEY component. */ /* The expected stack layout: HKEY component. */
if (popstring (is_user_install, sizeof (is_user_install))) if (popstringn (is_user_install, COUNTOF (is_user_install)))
return; return;
is_user_install[COUNTOF(is_user_install)-1] = 0;
if (!strcmp(is_user_install, "1")) if (!wcscmp (is_user_install, L"1"))
{ {
root_key = ENV_HK_USER; root_key = ENV_HK_USER;
env_reg = ENV_REG_USER; env_reg = ENV_REG_USER;
@ -1014,107 +1108,100 @@ path_add (HWND hwndParent, int string_size, char *variables,
env_reg = ENV_REG; env_reg = ENV_REG;
} }
path = read_w32_registry_string (root_key, env_reg, "Path"); path = read_w32_registry_string (root_key, env_reg, L"Path");
if (!path) if (!path)
{ {
path = strdup (""); path = wcsdup (L"");
} }
/* MessageBox (g_hwndParent, "XXX 3", 0, MB_OK); */
/* Old path plus semicolon plus dir plus terminating nul. */ /* Old path plus semicolon plus dir plus terminating nul. */
path_new_size = strlen (path) + 1 + strlen (dir) + 1; path_new_size = wcslen (path) + 1 + wcslen (dir) + 1;
if (path_new_size > PATH_LENGTH_LIMIT) if (path_new_size > PATH_LENGTH_LIMIT)
{ {
MessageBox (g_hwndParent, "PATH env variable too big", 0, MB_OK); MessageBox (g_hwndParent, L"PATH env variable too big", 0, MB_OK);
free (path); free (path);
return; return;
} }
/* MessageBox (g_hwndParent, "XXX 4", 0, MB_OK); */ path_new = calloc (path_new_size, sizeof *path_new);
path_new = malloc (path_new_size);
if (!path_new) if (!path_new)
{ {
free (path); free (path);
return; return;
} }
/* MessageBox (g_hwndParent, "XXX 5", 0, MB_OK); */ wcscpy (path_new, path);
wcscat (path_new, L";");
strcpy (path_new, path); wcscat (path_new, dir);
strcat (path_new, ";");
strcat (path_new, dir);
/* MessageBox (g_hwndParent, "XXX 6", 0, MB_OK); */
/* MessageBox (g_hwndParent, dir, 0, MB_OK); */
/* MessageBox (g_hwndParent, "XXX 7", 0, MB_OK); */
/* Check if the directory already exists in the path. */ /* Check if the directory already exists in the path. */
comp = strtok (path, delims); comp = wcstok (path, delims/*, &tokctx*/);
do do
{ {
/* MessageBox (g_hwndParent, comp, 0, MB_OK); */ /* MessageBox (g_hwndParent, comp, 0, MB_OK); */
if (!comp) if (!comp)
break; break;
if (!strcmp (comp, dir)) if (!wcscmp (comp, dir))
{ {
free (path); free (path);
free (path_new); free (path_new);
return; return;
} }
comp = strtok (NULL, delims); comp = wcstok (NULL, delims/*, &tokctx*/);
} }
while (comp); while (comp);
free (path); free (path);
/* Update the path key. */ /* Update the path key. */
RegCreateKey (root_key, env_reg, &key_handle); RegCreateKeyW (root_key, env_reg, &key_handle);
RegSetValueEx (key_handle, "Path", 0, REG_EXPAND_SZ, RegSetValueEx (key_handle, L"Path", 0, REG_EXPAND_SZ,
path_new, path_new_size); (unsigned char*)path_new,
wcslen (path_new) * sizeof *path_new);
RegCloseKey (key_handle); RegCloseKey (key_handle);
SetEnvironmentVariable("PATH", path_new); SetEnvironmentVariableW(L"PATH", path_new);
free (path_new); free (path_new);
/* MessageBox (g_hwndParent, "XXX 9", 0, MB_OK); */ /* MessageBox (g_hwndParent, "XXX 9", 0, MB_OK); */
setuservariable (INST_R0, "1"); setuservariable (INST_R0, L"1"); /* success. */
} }
void __declspec(dllexport) void __declspec(dllexport)
path_remove (HWND hwndParent, int string_size, char *variables, path_remove (HWND hwndParent, int string_size, LPTSTR variables,
stack_t **stacktop, extra_parameters_t *extra) stack_t **stacktop, extra_parameters_t *extra)
{ {
char dir[PATH_LENGTH_LIMIT]; wchar_t dir[PATH_LENGTH_LIMIT];
char is_user_install[2]; wchar_t is_user_install[2];
char *path; wchar_t *path;
char *path_new; wchar_t *path_new;
int path_new_size; size_t path_new_size;
char *comp; wchar_t *comp;
const char delims[] = ";"; const wchar_t delims[] = L";";
HKEY key_handle = 0; HKEY key_handle = 0;
int changed = 0; int changed = 0;
int count = 0; int count = 0;
HKEY root_key; HKEY root_key;
const char *env_reg; const wchar_t *env_reg;
/* wchar_t *tokctx; Context var for wcstok - not yet needed. */
g_hwndParent = hwndParent; g_hwndParent = hwndParent;
EXDLL_INIT(); EXDLL_INIT();
setuservariable (INST_R0, "0"); setuservariable (INST_R0, L"0");
/* The expected stack layout: path component. */ /* The expected stack layout: path component. */
if (popstring (dir, sizeof (dir))) if (popstringn (dir, COUNTOF (dir)))
return; return;
dir[COUNTOF(dir)-1] = 0;
/* The expected stack layout: HKEY component. */ /* The expected stack layout: HKEY component. */
if (popstring (is_user_install, sizeof (is_user_install))) if (popstringn (is_user_install, COUNTOF (is_user_install)))
return; return;
is_user_install[COUNTOF(is_user_install)-1] = 0;
if (!strcmp(is_user_install, "1")) if (!wcscmp (is_user_install, L"1"))
{ {
root_key = ENV_HK_USER; root_key = ENV_HK_USER;
env_reg = ENV_REG_USER; env_reg = ENV_REG_USER;
@ -1125,37 +1212,34 @@ path_remove (HWND hwndParent, int string_size, char *variables,
env_reg = ENV_REG; env_reg = ENV_REG;
} }
path = read_w32_registry_string (root_key, env_reg, "Path"); path = read_w32_registry_string (root_key, env_reg, L"Path");
if (!path) if (!path)
return; return;
/* Old path plus semicolon plus dir plus terminating nul. */ /* Old path plus semicolon plus dir plus terminating nul. */
path_new_size = strlen (path) + 1; path_new_size = wcslen (path) + 1;
path_new = malloc (path_new_size); path_new = calloc (path_new_size, sizeof *path_new);
if (!path_new) if (!path_new)
{ {
free (path); free (path);
return; return;
} }
path_new[0] = '\0';
/* Compose the new path. */ /* Compose the new path. */
comp = strtok (path, delims); comp = wcstok (path, delims/*, &tokctx*/);
do do
{ {
if (strcmp (comp, dir)) if (wcscmp (comp, dir))
{ {
if (count != 0) if (count)
strcat (path_new, ";"); wcscat (path_new, L";");
strcat (path_new, comp); wcscat (path_new, comp);
count++; count++;
} }
else else
changed = 1; changed = 1;
comp = strtok (NULL, delims);
} }
while (comp); while ((comp = wcstok (NULL, delims/*, &tokctx*/)));
free (path); free (path);
if (!changed) if (!changed)
@ -1165,11 +1249,75 @@ path_remove (HWND hwndParent, int string_size, char *variables,
} }
/* Set a key for our CLSID. */ /* Set a key for our CLSID. */
RegCreateKey (root_key, env_reg, &key_handle); RegCreateKeyW (root_key, env_reg, &key_handle);
RegSetValueEx (key_handle, "Path", 0, REG_EXPAND_SZ, RegSetValueEx (key_handle, L"Path", 0, REG_EXPAND_SZ,
path_new, path_new_size); (unsigned char*)path_new,
wcslen (path_new) * sizeof *path_new);
RegCloseKey (key_handle); RegCloseKey (key_handle);
free (path_new); free (path_new);
setuservariable (INST_R0, "1"); 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);
} }

View File

@ -1462,8 +1462,7 @@ Function .onInit
;;!define MUI_LANGDLL_ALWAYSSHOW ;;!define MUI_LANGDLL_ALWAYSSHOW
!insertmacro MUI_LANGDLL_DISPLAY !insertmacro MUI_LANGDLL_DISPLAY
# Temporay disabled until we have fixed the DLL issue (wk 2023-04-05) Call G4wRunOnce
# Call G4wRunOnce
SetOutPath $TEMP SetOutPath $TEMP
#!ifdef SOURCES #!ifdef SOURCES