mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-21 14:47:03 +01:00
speedo,w32: Allow installation as normal user
* build-aux/speedo/w32/g4wihelp.c (ENV_HK_USER, ENV_REG_USER): New defines. (path_add): Handle is_user_install variable. Don't abort if Path reg key does not exist. Fix crash if Path reg key does not contain a semicolon. (path_remove): Handle is_user_install variable. Fix crash if Path reg key does not exist. * build-aux/speedo/w32/inst.nsi: Remove obsolete HAVE_STARTMENU this was double guarded with WITH_GUI. Add Multiuser plugin and defines for this. Use SHCTX instead of HKLM / HKCU. (PrintNonAdminWarning): Only Warn and don't abort. -- The default is still to install as Adminstrator system wide but the user now has the option to explicitly install GnuPG without Administrator rights. A warning will be shown in that case but a user may continue. A per user install is by default under %LOCALAPPDATA%\GnuPG Related Task: T2971 Signed-off-by: Andre Heinecke <aheinecke@intevation.de>
This commit is contained in:
parent
201f868030
commit
cacfd4bce9
@ -964,10 +964,8 @@ read_w32_registry_string (HKEY root, const char *dir, const char *name)
|
||||
#define ENV_REG "SYSTEM\\CurrentControlSet\\Control\\" \
|
||||
"Session Manager\\Environment"
|
||||
/* The following setting can be used for a per-user setting. */
|
||||
#if 0
|
||||
#define ENV_HK HKEY_CURRENT_USER
|
||||
#define ENV_REG "Environment"
|
||||
#endif
|
||||
#define ENV_HK_USER HKEY_CURRENT_USER
|
||||
#define ENV_REG_USER "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
|
||||
@ -979,12 +977,16 @@ path_add (HWND hwndParent, int string_size, char *variables,
|
||||
stack_t **stacktop, extra_parameters_t *extra)
|
||||
{
|
||||
char dir[PATH_LENGTH_LIMIT];
|
||||
char is_user_install[2];
|
||||
char *path;
|
||||
char *path_new;
|
||||
int path_new_size;
|
||||
char *comp;
|
||||
const char delims[] = ";";
|
||||
int is_user;
|
||||
HKEY key_handle = 0;
|
||||
HKEY root_key;
|
||||
const char *env_reg;
|
||||
|
||||
g_hwndParent = hwndParent;
|
||||
EXDLL_INIT();
|
||||
@ -997,13 +999,26 @@ path_add (HWND hwndParent, int string_size, char *variables,
|
||||
if (popstring (dir, sizeof (dir)))
|
||||
return;
|
||||
|
||||
/* MessageBox (g_hwndParent, "XXX 2", 0, MB_OK); */
|
||||
/* The expected stack layout: HKEY component. */
|
||||
if (popstring (is_user_install, sizeof (is_user_install)))
|
||||
return;
|
||||
|
||||
if (!strcmp(is_user_install, "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, "Path");
|
||||
|
||||
path = read_w32_registry_string (ENV_HK, ENV_REG, "Path");
|
||||
if (! path)
|
||||
{
|
||||
MessageBox (g_hwndParent, "No PATH variable found", 0, MB_OK);
|
||||
return;
|
||||
path = strdup ("");
|
||||
}
|
||||
|
||||
/* MessageBox (g_hwndParent, "XXX 3", 0, MB_OK); */
|
||||
@ -1041,6 +1056,8 @@ path_add (HWND hwndParent, int string_size, char *variables,
|
||||
do
|
||||
{
|
||||
/* MessageBox (g_hwndParent, comp, 0, MB_OK); */
|
||||
if (!comp)
|
||||
break;
|
||||
|
||||
if (!strcmp (comp, dir))
|
||||
{
|
||||
@ -1053,10 +1070,8 @@ path_add (HWND hwndParent, int string_size, char *variables,
|
||||
while (comp);
|
||||
free (path);
|
||||
|
||||
/* MessageBox (g_hwndParent, "XXX 8", 0, MB_OK); */
|
||||
|
||||
/* Set a key for our CLSID. */
|
||||
RegCreateKey (ENV_HK, ENV_REG, &key_handle);
|
||||
/* Update the path key. */
|
||||
RegCreateKey (root_key, env_reg, &key_handle);
|
||||
RegSetValueEx (key_handle, "Path", 0, REG_EXPAND_SZ,
|
||||
path_new, path_new_size);
|
||||
RegCloseKey (key_handle);
|
||||
@ -1074,6 +1089,7 @@ path_remove (HWND hwndParent, int string_size, char *variables,
|
||||
stack_t **stacktop, extra_parameters_t *extra)
|
||||
{
|
||||
char dir[PATH_LENGTH_LIMIT];
|
||||
char is_user_install[2];
|
||||
char *path;
|
||||
char *path_new;
|
||||
int path_new_size;
|
||||
@ -1082,6 +1098,8 @@ path_remove (HWND hwndParent, int string_size, char *variables,
|
||||
HKEY key_handle = 0;
|
||||
int changed = 0;
|
||||
int count = 0;
|
||||
HKEY root_key;
|
||||
const char *env_reg;
|
||||
|
||||
g_hwndParent = hwndParent;
|
||||
EXDLL_INIT();
|
||||
@ -1092,7 +1110,25 @@ path_remove (HWND hwndParent, int string_size, char *variables,
|
||||
if (popstring (dir, sizeof (dir)))
|
||||
return;
|
||||
|
||||
path = read_w32_registry_string (ENV_HK, ENV_REG, "Path");
|
||||
/* The expected stack layout: HKEY component. */
|
||||
if (popstring (is_user_install, sizeof (is_user_install)))
|
||||
return;
|
||||
|
||||
if (!strcmp(is_user_install, "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, "Path");
|
||||
|
||||
if (!path)
|
||||
return;
|
||||
/* Old path plus semicolon plus dir plus terminating nul. */
|
||||
path_new_size = strlen (path) + 1;
|
||||
path_new = malloc (path_new_size);
|
||||
@ -1126,7 +1162,7 @@ path_remove (HWND hwndParent, int string_size, char *variables,
|
||||
return;
|
||||
|
||||
/* Set a key for our CLSID. */
|
||||
RegCreateKey (ENV_HK, ENV_REG, &key_handle);
|
||||
RegCreateKey (root_key, env_reg, &key_handle);
|
||||
RegSetValueEx (key_handle, "Path", 0, REG_EXPAND_SZ,
|
||||
path_new, path_new_size);
|
||||
RegCloseKey (key_handle);
|
||||
|
@ -1,5 +1,6 @@
|
||||
# inst.nsi - Installer for GnuPG on Windows. -*- coding: latin-1; -*-
|
||||
# Copyright (C) 2005, 2014 g10 Code GmbH
|
||||
# 2017 Intevation GmbH
|
||||
#
|
||||
# This file is part of GnuPG.
|
||||
#
|
||||
@ -42,7 +43,7 @@
|
||||
!define PRETTY_PACKAGE "GNU Privacy Guard"
|
||||
!define PRETTY_PACKAGE_SHORT "GnuPG"
|
||||
!define COMPANY "The GnuPG Project"
|
||||
!define COPYRIGHT "Copyright (C) 2015 The GnuPG Project"
|
||||
!define COPYRIGHT "Copyright (C) 2017 The GnuPG Project"
|
||||
!define DESCRIPTION "GnuPG: The GNU Privacy Guard for Windows"
|
||||
|
||||
!define INSTALL_DIR "GnuPG"
|
||||
@ -80,9 +81,6 @@ SetCompressor lzma
|
||||
# SetCompressorDictSize 8
|
||||
!endif
|
||||
|
||||
# Include the generic parts.
|
||||
!define HAVE_STARTMENU
|
||||
|
||||
# We use the modern UI.
|
||||
!include "MUI.nsh"
|
||||
|
||||
@ -90,6 +88,17 @@ SetCompressor lzma
|
||||
!include "LogicLib.nsh"
|
||||
!include "x64.nsh"
|
||||
|
||||
# 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\${PACKAGE_SHORT}"
|
||||
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME ""
|
||||
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "Software\${PACKAGE_SHORT}"
|
||||
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME "Install Directory"
|
||||
!define MULTIUSER_INSTALLMODE_INSTDIR "${PACKAGE_SHORT}"
|
||||
!include "MultiUser.nsh"
|
||||
|
||||
# Set the package name. Note that this name should not be suffixed
|
||||
# with the version because this would get displayed in the start menu.
|
||||
# Given that a slash in the name troubles Windows startmenu creation
|
||||
@ -109,9 +118,6 @@ OutFile "${NAME}-${VERSION}_${BUILD_DATESTR}.exe"
|
||||
!endif
|
||||
InstallDir "$PROGRAMFILES\${INSTALL_DIR}"
|
||||
|
||||
InstallDirRegKey HKLM "Software\${PACKAGE_SHORT}" "Install Directory"
|
||||
|
||||
|
||||
# Add version information to the file properties.
|
||||
VIProductVersion "${PROD_VERSION}"
|
||||
VIAddVersionKey "ProductName" "${PRETTY_PACKAGE_SHORT} (${VERSION})"
|
||||
@ -161,7 +167,7 @@ VIAddVersionKey "FileVersion" "${PROD_VERSION}"
|
||||
|
||||
# We don't have MUI_PAGE_DIRECTORY
|
||||
|
||||
!ifdef HAVE_STARTMENU
|
||||
!ifdef WITH_GUI
|
||||
|
||||
Page custom CustomPageOptions
|
||||
|
||||
@ -169,7 +175,7 @@ Var STARTMENU_FOLDER
|
||||
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE CheckIfStartMenuWanted
|
||||
!define MUI_STARTMENUPAGE_NODISABLE
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\GnuPG"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
|
||||
# We need to set the Startmenu name explicitly because a slash in the
|
||||
@ -354,6 +360,8 @@ FunctionEnd
|
||||
# OS version without the need for an Administrator is in use. Print a
|
||||
# diagnostic if this is not the case and abort installation.
|
||||
Function PrintNonAdminWarning
|
||||
Var /GLOBAL is_user_install
|
||||
StrCpy $is_user_install "0"
|
||||
ClearErrors
|
||||
UserInfo::GetName
|
||||
IfErrors leave
|
||||
@ -361,9 +369,11 @@ Function PrintNonAdminWarning
|
||||
UserInfo::GetAccountType
|
||||
Pop $1
|
||||
StrCmp $1 "Admin" leave +1
|
||||
MessageBox MB_OK "$(T_AdminNeeded)"
|
||||
Quit
|
||||
|
||||
MessageBox MB_YESNO "$(T_AdminWanted)" IDNO exit
|
||||
StrCpy $is_user_install "1"
|
||||
goto leave
|
||||
exit:
|
||||
Quit
|
||||
leave:
|
||||
FunctionEnd
|
||||
|
||||
@ -446,24 +456,30 @@ LangString T_FoundExistingVersion ${LANG_GERMAN} \
|
||||
eine neuere oder dieselbe Version handelt.)"
|
||||
LangString T_FoundExistingVersionB ${LANG_ENGLISH} \
|
||||
"A version of GnuPG has already been installed on the system. \
|
||||
There will be no problem installing and thus overwriting this \
|
||||
Version. $\r$\n\
|
||||
$\r$\n\
|
||||
$\r$\n\
|
||||
Do you want to continue installing GnuPG?"
|
||||
LangString T_FoundExistingVersionB ${LANG_GERMAN} \
|
||||
"Eine Version von GnuPG ist hier bereits installiert. \
|
||||
Es ist problemlos möglich, die Installation fortzuführen. $\r$\n\
|
||||
$\r$\n\
|
||||
$\r$\n\
|
||||
Möchten die die Installation von GnuPG fortführen?"
|
||||
|
||||
|
||||
|
||||
# From Function PrintNonAdminWarning
|
||||
LangString T_AdminNeeded ${LANG_ENGLISH} \
|
||||
"Warning: Administrator permissions required for a successful installation"
|
||||
LangString T_AdminNeeded ${LANG_GERMAN} \
|
||||
"Achtung: Für eine erfolgreiche Installation werden \
|
||||
Administratorrechte benötigt."
|
||||
LangString T_AdminWanted ${LANG_ENGLISH} \
|
||||
"Warning: It is recommended to install GnuPG system-wide with \
|
||||
administrator rights. \
|
||||
$\r$\n\
|
||||
$\r$\n\
|
||||
Do you want to continue installing GnuPG without administrator rights?"
|
||||
LangString T_AdminWanted ${LANG_GERMAN} \
|
||||
"Achtung: Es wird empfohlen GnuPG systemweit mit \
|
||||
Administratorrechten zu installieren. \
|
||||
$\r$\n\
|
||||
$\r$\n\
|
||||
Möchten die die Installation von GnuPG ohne Administratorrechte fortführen?"
|
||||
|
||||
# From Function PrintCloseOtherApps
|
||||
LangString T_CloseOtherApps ${LANG_ENGLISH} \
|
||||
@ -505,7 +521,7 @@ FunctionEnd
|
||||
# Input - head of the stack
|
||||
Function AddToPath
|
||||
Exch $0
|
||||
g4wihelp::path_add "$0"
|
||||
g4wihelp::path_add "$0" $is_user_install
|
||||
StrCmp $R5 "0" add_to_path_done
|
||||
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
|
||||
add_to_path_done:
|
||||
@ -516,8 +532,24 @@ FunctionEnd
|
||||
# RemoveFromPath - Remove a given dir from the path
|
||||
# Input: head of the stack
|
||||
Function un.RemoveFromPath
|
||||
ClearErrors
|
||||
UserInfo::GetName
|
||||
IfErrors remove_admin
|
||||
Pop $0
|
||||
UserInfo::GetAccountType
|
||||
Pop $1
|
||||
StrCmp $1 "Admin" remove_admin remove_user
|
||||
|
||||
remove_admin:
|
||||
Exch $0
|
||||
g4wihelp::path_remove "$0"
|
||||
g4wihelp::path_remove "$0" "0"
|
||||
goto remove_done
|
||||
remove_user:
|
||||
Exch $0
|
||||
g4wihelp::path_remove "$0" "1"
|
||||
goto remove_done
|
||||
|
||||
remove_done:
|
||||
StrCmp $R5 "0" remove_from_path_done
|
||||
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
|
||||
remove_from_path_done:
|
||||
@ -540,7 +572,7 @@ Section "-gnupginst"
|
||||
FileWrite $0 "${VERSION}$\r$\n"
|
||||
FileClose $0
|
||||
|
||||
WriteRegStr HKLM "Software\GnuPG" "Install Directory" $INSTDIR
|
||||
WriteRegStr SHCTX "Software\GnuPG" "Install Directory" $INSTDIR
|
||||
|
||||
# If we are reinstalling, try to kill a possible running gpa using
|
||||
# an already installed gpa.
|
||||
@ -1381,7 +1413,7 @@ Section "-un.gnupginst"
|
||||
RMDir "$INSTDIR"
|
||||
|
||||
# Clean the registry.
|
||||
DeleteRegValue HKLM "Software\GNU\GnuPG" "Install Directory"
|
||||
DeleteRegValue SHCTX "Software\GNU\GnuPG" "Install Directory"
|
||||
SectionEnd
|
||||
|
||||
|
||||
@ -1409,8 +1441,25 @@ Function .onInit
|
||||
!insertmacro MUI_INSTALLOPTIONS_EXTRACT "${W32_SRCDIR}/inst-options.ini"
|
||||
|
||||
#Call CalcDepends
|
||||
|
||||
Var /GLOBAL changed_dir
|
||||
# Check if the install directory was modified on the command line
|
||||
StrCmp "$INSTDIR" "$PROGRAMFILES\${INSTALL_DIR}" unmodified 0
|
||||
# It is modified. Save that value.
|
||||
StrCpy $changed_dir "$INSTDIR"
|
||||
|
||||
# MULITUSER_INIT overwrites directory setting from command line
|
||||
!insertmacro MULTIUSER_INIT
|
||||
StrCpy $INSTDIR "$changed_dir"
|
||||
goto initDone
|
||||
unmodified:
|
||||
!insertmacro MULTIUSER_INIT
|
||||
initDone:
|
||||
FunctionEnd
|
||||
|
||||
Function "un.onInit"
|
||||
!insertmacro MULTIUSER_UNINIT
|
||||
FunctionEnd
|
||||
|
||||
#Function .onInstFailed
|
||||
# Delete $TEMP\gpgspltmp.wav
|
||||
@ -1439,13 +1488,6 @@ FunctionEnd
|
||||
!ifdef WITH_GUI
|
||||
Section "-startmenu"
|
||||
|
||||
!ifdef HAVE_STARTMENU
|
||||
# Make sure that the context of the automatic variables has been set to
|
||||
# the "all users" shell folder. This guarantees that the menu gets written
|
||||
# for all users. We have already checked that we are running as Admin; or
|
||||
# we printed a warning that installation will not succeed.
|
||||
SetShellVarContext all
|
||||
|
||||
# Check if the start menu entries where requested.
|
||||
!insertmacro MUI_INSTALLOPTIONS_READ $R0 "${W32_SRCDIR}/inst-options.ini" \
|
||||
"Field 2" "State"
|
||||
@ -1517,7 +1559,6 @@ no_gpa_quicklaunch:
|
||||
no_quick_launch:
|
||||
|
||||
|
||||
!endif
|
||||
SectionEnd
|
||||
!endif
|
||||
|
||||
@ -1533,30 +1574,23 @@ Section
|
||||
|
||||
# Windows Add/Remove Programs support
|
||||
StrCpy $MYTMP "Software\Microsoft\Windows\CurrentVersion\Uninstall\GnuPG"
|
||||
WriteRegExpandStr HKLM $MYTMP "UninstallString" '"$INSTDIR\gnupg-uninstall.exe"'
|
||||
WriteRegExpandStr HKLM $MYTMP "InstallLocation" "$INSTDIR"
|
||||
WriteRegStr HKLM $MYTMP "DisplayName" "${PRETTY_PACKAGE}"
|
||||
WriteRegExpandStr SHCTX $MYTMP "UninstallString" '"$INSTDIR\gnupg-uninstall.exe"'
|
||||
WriteRegExpandStr SHCTX $MYTMP "InstallLocation" "$INSTDIR"
|
||||
WriteRegStr SHCTX $MYTMP "DisplayName" "${PRETTY_PACKAGE}"
|
||||
!ifdef WITH_GUI
|
||||
WriteRegStr HKLM $MYTMP "DisplayIcon" "$INSTDIR\bin\gpa.exe,0"
|
||||
WriteRegStr SHCTX $MYTMP "DisplayIcon" "$INSTDIR\bin\gpa.exe,0"
|
||||
!else
|
||||
WriteRegStr SHCTX $MYTMP "DisplayIcon" "$INSTDIR\bin\gpg.exe,0"
|
||||
!endif
|
||||
WriteRegStr HKLM $MYTMP "DisplayVersion" "${VERSION}"
|
||||
WriteRegStr HKLM $MYTMP "Publisher" "The GnuPG Project"
|
||||
WriteRegStr HKLM $MYTMP "URLInfoAbout" "https://gnupg.org"
|
||||
WriteRegDWORD HKLM $MYTMP "NoModify" "1"
|
||||
WriteRegDWORD HKLM $MYTMP "NoRepair" "1"
|
||||
WriteRegStr SHCTX $MYTMP "DisplayVersion" "${VERSION}"
|
||||
WriteRegStr SHCTX $MYTMP "Publisher" "The GnuPG Project"
|
||||
WriteRegStr SHCTX $MYTMP "URLInfoAbout" "https://gnupg.org"
|
||||
WriteRegDWORD SHCTX $MYTMP "NoModify" "1"
|
||||
WriteRegDWORD SHCTX $MYTMP "NoRepair" "1"
|
||||
SectionEnd
|
||||
|
||||
|
||||
Section Uninstall
|
||||
|
||||
!ifdef WITH_GUI
|
||||
!ifdef HAVE_STARTMENU
|
||||
# Make sure that the context of the automatic variables has been set to
|
||||
# the "all users" shell folder. This guarantees that the menu gets written
|
||||
# for all users. We have already checked that we are running as Admin; or
|
||||
# we printed a warning that installation will not succeed.
|
||||
SetShellVarContext all
|
||||
|
||||
#---------------------------------------------------
|
||||
# Delete the menu entries and any empty parent menus
|
||||
#---------------------------------------------------
|
||||
@ -1574,7 +1608,7 @@ Section Uninstall
|
||||
StrCmp $MYTMP $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop
|
||||
startMenuDeleteLoopDone:
|
||||
|
||||
DeleteRegValue HKLM "Software\GNU\GnuPG" "Start Menu Folder"
|
||||
DeleteRegValue SHCTX "Software\GNU\GnuPG" "Start Menu Folder"
|
||||
|
||||
# Delete Desktop links.
|
||||
Delete "$DESKTOP\GPA.lnk"
|
||||
@ -1586,15 +1620,14 @@ Section Uninstall
|
||||
Delete "$QUICKLAUNCH\GPA.lnk"
|
||||
no_quick_launch_uninstall:
|
||||
|
||||
!endif
|
||||
!endif
|
||||
|
||||
Delete "$INSTDIR\gnupg-uninstall.exe"
|
||||
RMDir "$INSTDIR"
|
||||
|
||||
# Clean the registry.
|
||||
DeleteRegValue HKLM "Software\GnuPG" "Install Directory"
|
||||
DeleteRegKey /ifempty HKLM "Software\GnuPG"
|
||||
DeleteRegValue SHCTX "Software\GnuPG" "Install Directory"
|
||||
DeleteRegKey /ifempty SHCTX "Software\GnuPG"
|
||||
# Remove Windows Add/Remove Programs support.
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GnuPG"
|
||||
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\GnuPG"
|
||||
SectionEnd
|
||||
|
Loading…
x
Reference in New Issue
Block a user