Permalink
Browse files

BUILD: Make Windows installer run unprivileged for non-admin users

  • Loading branch information...
csnover authored and lotharsm committed Dec 9, 2017
1 parent c2f3532 commit 0fccd88bd9ebc4fd8655fe2e9072520912699183
Showing with 137 additions and 6 deletions.
  1. +137 −6 dists/win32/ScummVM.iss
@@ -1,18 +1,20 @@
#define AppName "ScummVM"

[Setup]
AppCopyright=2018
AppName=ScummVM
AppVerName=ScummVM Git
AppName={#AppName}
AppVerName={#AppName} Git
AppPublisher=The ScummVM Team
AppPublisherURL=http://www.scummvm.org/
AppSupportURL=http://www.scummvm.org/
AppUpdatesURL=http://www.scummvm.org/
DefaultDirName={pf}\ScummVM
DefaultGroupName=ScummVM
DefaultDirName={pf}\{#AppName}
DefaultGroupName={#AppName}
AllowNoIcons=true
AlwaysUsePersonalGroup=false
EnableDirDoesntExistWarning=false
Compression=lzma
OutputDir=C:\ScummVM
OutputDir=C:\{#AppName}
OutputBaseFilename=scummvm-win32
DisableStartupPrompt=true
AppendDefaultDirName=false
@@ -22,7 +24,136 @@ SetupIconFile=graphics\scummvm-install.ico
WizardImageFile=graphics\left.bmp
ShowLanguageDialog=yes
LanguageDetectionMethod=uilanguage
PrivilegesRequired=lowest
PrivilegesRequired=none

; This privilege escalation code comes from
; https://stackoverflow.com/a/35435534/252087

#define InnoSetupReg \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\" + AppName + "_is1"
#define InnoSetupAppPathReg "Inno Setup: App Path"

[Code]
function IsWinVista: Boolean;
begin
Result := (GetWindowsVersion >= $06000000);
end;

function IsElevated: Boolean;
begin
Result := IsAdminLoggedOn or IsPowerUserLoggedOn;
end;

function HaveWriteAccessToApp: Boolean;
var
FileName: string;
begin
FileName := AddBackslash(WizardDirValue) + 'writetest.tmp';
Result := SaveStringToFile(FileName, 'test', False);
if Result then
begin
Log(Format(
'Have write access to the last installation path [%s]', [WizardDirValue]));
DeleteFile(FileName);
end
else
begin
Log(Format('Does not have write access to the last installation path [%s]', [
WizardDirValue]));
end;
end;

procedure ExitProcess(uExitCode: UINT);
external 'ExitProcess@kernel32.dll stdcall';
function ShellExecute(hwnd: HWND; lpOperation: string; lpFile: string;
lpParameters: string; lpDirectory: string; nShowCmd: Integer): THandle;
external 'ShellExecuteW@shell32.dll stdcall';

function Elevate: Boolean;
var
I: Integer;
RetVal: Integer;
Params: string;
S: string;
begin
{ Collect current instance parameters }
for I := 1 to ParamCount do
begin
S := ParamStr(I);
{ Unique log file name for the elevated instance }
if CompareText(Copy(S, 1, 5), '/LOG=') = 0 then
begin
S := S + '-elevated';
end;
{ Do not pass our /SL5 switch }
if CompareText(Copy(S, 1, 5), '/SL5=') <> 0 then
begin
Params := Params + AddQuotes(S) + ' ';
end;
end;

{ ... and add selected language }
Params := Params + '/LANG=' + ActiveLanguage;

Log(Format('Elevating setup with parameters [%s]', [Params]));
RetVal := ShellExecute(0, 'runas', ExpandConstant('{srcexe}'), Params, '', SW_SHOW);
Log(Format('Running elevated setup returned [%d]', [RetVal]));
Result := (RetVal > 32);
{ if elevated executing of this setup succeeded, then... }
if Result then
begin
Log('Elevation succeeded');
{ exit this non-elevated setup instance }
ExitProcess(0);
end
else
begin
Log(Format('Elevation failed [%s]', [SysErrorMessage(RetVal)]));
end;
end;

procedure InitializeWizard;
var
S: string;
Upgrade: Boolean;
begin
Upgrade :=
RegQueryStringValue(HKLM, '{#InnoSetupReg}', '{#InnoSetupAppPathReg}', S) or
RegQueryStringValue(HKCU, '{#InnoSetupReg}', '{#InnoSetupAppPathReg}', S);

{ elevate }

if not IsWinVista then
begin
Log(Format('This version of Windows [%x] does not support elevation', [
GetWindowsVersion]));
end
else
if IsElevated then
begin
Log('Running elevated');
end
else
begin
Log('Running non-elevated');
if Upgrade then
begin
if not HaveWriteAccessToApp then
begin
Elevate;
end;
end
else
begin
if not Elevate then
begin
WizardForm.DirEdit.Text := ExpandConstant('{localappdata}\{#AppName}');
Log(Format('Falling back to local application user folder [%s]', [
WizardForm.DirEdit.Text]));
end;
end;
end;
end;

[Languages]
Name: en; MessagesFile: compiler:Default.isl

0 comments on commit 0fccd88

Please sign in to comment.