168 lines
6.2 KiB
Plaintext
168 lines
6.2 KiB
Plaintext
#ifndef Payload
|
|
#error Payload is required
|
|
#endif
|
|
#ifndef Output
|
|
#error Output is required
|
|
#endif
|
|
[Setup]
|
|
AppId={{65B3E62C-937C-4FAA-B1F0-2F1C3D2B9955}
|
|
AppName=Monitor
|
|
AppVersion=1.003.1
|
|
DefaultDirName={autopf}\Monitor
|
|
DefaultGroupName=Monitor
|
|
OutputDir={#Output}
|
|
OutputBaseFilename=Monitor-Setup-x64
|
|
ArchitecturesAllowed=x64compatible
|
|
ArchitecturesInstallIn64BitMode=x64compatible
|
|
MinVersion=10.0
|
|
PrivilegesRequired=admin
|
|
Compression=zip/7
|
|
SolidCompression=no
|
|
WizardStyle=modern
|
|
UninstallDisplayIcon={app}\Monitor.exe
|
|
CloseApplications=no
|
|
RestartApplications=no
|
|
|
|
[Files]
|
|
Source: "{#Payload}\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
|
|
|
[Dirs]
|
|
Name: "{commonappdata}\Monitor"
|
|
|
|
[Icons]
|
|
Name: "{autodesktop}\Monitor"; Filename: "{app}\Monitor.exe"; WorkingDir: "{app}"
|
|
Name: "{group}\Monitor"; Filename: "{app}\Monitor.exe"; WorkingDir: "{app}"
|
|
|
|
[Run]
|
|
Filename: "{app}\Monitor.exe"; Description: "Start Monitor"; Flags: nowait postinstall skipifsilent runasoriginaluser
|
|
|
|
[Code]
|
|
var OwnerPage: TInputQueryWizardPage;
|
|
|
|
procedure InitializeWizard();
|
|
begin
|
|
OwnerPage := CreateInputQueryPage(wpSelectDir, 'Monitor Windows account',
|
|
'Choose the Windows account that will run Monitor',
|
|
'Only this account, Administrators and SYSTEM can access the database and keys. Use DOMAIN\username or COMPUTER\username.');
|
|
OwnerPage.Add('Runtime account:', False);
|
|
OwnerPage.Values[0] := GetPreviousData('MonitorOwner', GetEnv('USERDOMAIN') + '\' + GetUserNameString);
|
|
end;
|
|
|
|
procedure RegisterPreviousData(PreviousDataKey: Integer);
|
|
begin
|
|
SetPreviousData(PreviousDataKey, 'MonitorOwner', OwnerPage.Values[0]);
|
|
end;
|
|
|
|
procedure ConfigureDataAcl();
|
|
var Code: Integer; UserName: String;
|
|
begin
|
|
UserName := Trim(OwnerPage.Values[0]);
|
|
if UserName = '' then RaiseException('A runtime Windows account is required');
|
|
if Pos('"', UserName) > 0 then RaiseException('Unsupported Windows user name');
|
|
if not Exec(ExpandConstant('{sys}\icacls.exe'),
|
|
'"' + ExpandConstant('{commonappdata}\Monitor') + '" /inheritance:r /grant:r "' +
|
|
UserName + ':(OI)(CI)M" "*S-1-5-18:(OI)(CI)F" "*S-1-5-32-544:(OI)(CI)F"',
|
|
'', SW_HIDE, ewWaitUntilTerminated, Code) or (Code <> 0) then
|
|
RaiseException('Unable to restrict Monitor data directory permissions');
|
|
end;
|
|
|
|
procedure AddFirewallRule(Arguments: String);
|
|
var Code: Integer;
|
|
begin
|
|
if not Exec(ExpandConstant('{sys}\netsh.exe'), Arguments, '', SW_HIDE, ewWaitUntilTerminated, Code) or (Code <> 0) then
|
|
RaiseException('Unable to configure Monitor firewall rules. Check Windows Firewall and the installation log.');
|
|
end;
|
|
|
|
procedure Firewall(AddRules: Boolean);
|
|
var Code: Integer; ExePath: String;
|
|
begin
|
|
Exec(ExpandConstant('{sys}\netsh.exe'),'advfirewall firewall delete rule name="Monitor Web SIP"','',SW_HIDE,ewWaitUntilTerminated,Code);
|
|
Exec(ExpandConstant('{sys}\netsh.exe'),'advfirewall firewall delete rule name="Monitor ZLM TCP"','',SW_HIDE,ewWaitUntilTerminated,Code);
|
|
Exec(ExpandConstant('{sys}\netsh.exe'),'advfirewall firewall delete rule name="Monitor ZLM UDP"','',SW_HIDE,ewWaitUntilTerminated,Code);
|
|
if not AddRules then Exit;
|
|
ExePath := ExpandConstant('{app}\Monitor.exe');
|
|
AddFirewallRule(
|
|
'advfirewall firewall add rule name="Monitor Web SIP" dir=in action=allow program="' + ExePath +
|
|
'" protocol=TCP localport=10001,15060 profile=private,domain remoteip=localsubnet');
|
|
AddFirewallRule(
|
|
'advfirewall firewall add rule name="Monitor Web SIP" dir=in action=allow program="' + ExePath +
|
|
'" protocol=UDP localport=15060 profile=private,domain remoteip=localsubnet');
|
|
ExePath := ExpandConstant('{app}\_internal\zlm\monitor_zlm.exe');
|
|
AddFirewallRule(
|
|
'advfirewall firewall add rule name="Monitor ZLM TCP" dir=in action=allow program="' + ExePath +
|
|
'" protocol=TCP localport=10002,10554,10935,20002-40000 profile=private,domain remoteip=localsubnet');
|
|
AddFirewallRule(
|
|
'advfirewall firewall add rule name="Monitor ZLM UDP" dir=in action=allow program="' + ExePath +
|
|
'" protocol=UDP localport=20002-40000 profile=private,domain remoteip=localsubnet');
|
|
end;
|
|
|
|
function BackupRuntimeData(): String;
|
|
var Root, Backup, Base: String; Files: TArrayOfString; I, Counter: Integer;
|
|
begin
|
|
Result := '';
|
|
Root := ExpandConstant('{commonappdata}\Monitor');
|
|
if not DirExists(Root) then Exit;
|
|
if not FileExists(Root + '\monitor.sqlite3') then Exit;
|
|
Base := Root + '\backups\installer-' + GetDateTimeString('yyyymmdd-hhnnss', '-', ':');
|
|
Backup := Base;
|
|
Counter := 0;
|
|
while DirExists(Backup) do begin
|
|
Counter := Counter + 1;
|
|
Backup := Base + '-' + IntToStr(Counter);
|
|
end;
|
|
if not ForceDirectories(Backup) then begin
|
|
Result := 'Cannot create the pre-upgrade data backup directory.';
|
|
Exit;
|
|
end;
|
|
SetArrayLength(Files, 11);
|
|
Files[0] := 'monitor.sqlite3';
|
|
Files[1] := 'monitor.sqlite3-wal';
|
|
Files[2] := 'monitor.sqlite3-shm';
|
|
Files[3] := 'config.json';
|
|
Files[4] := 'settings.json';
|
|
Files[5] := 'network.json';
|
|
Files[6] := '.runtime-secrets.json';
|
|
Files[7] := '.trusted-models.json';
|
|
Files[8] := 'license.json';
|
|
Files[9] := 'license-clock.json';
|
|
Files[10] := 'zlm-template.ini';
|
|
for I := 0 to GetArrayLength(Files)-1 do
|
|
if FileExists(Root + '\' + Files[I]) then
|
|
if not CopyFile(Root + '\' + Files[I], Backup + '\' + Files[I], True) then begin
|
|
Result := 'Pre-upgrade backup failed for ' + Files[I] + '. Installation stopped to protect existing data.';
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
function PrepareToInstall(var NeedsRestart: Boolean): String;
|
|
var Code: Integer;
|
|
begin
|
|
Result := '';
|
|
if FileExists(ExpandConstant('{app}\Monitor.exe')) then begin
|
|
if not Exec(ExpandConstant('{app}\Monitor.exe'),'--stop','',SW_HIDE,ewWaitUntilTerminated,Code) or (Code <> 0) then begin
|
|
Result := 'Please exit Monitor before upgrading.';
|
|
Exit;
|
|
end;
|
|
end;
|
|
Result := BackupRuntimeData();
|
|
end;
|
|
|
|
procedure CurStepChanged(CurStep: TSetupStep);
|
|
begin
|
|
if CurStep = ssPostInstall then begin
|
|
ConfigureDataAcl();
|
|
Firewall(True);
|
|
end;
|
|
end;
|
|
|
|
function InitializeUninstall(): Boolean;
|
|
var Code: Integer;
|
|
begin
|
|
Result := Exec(ExpandConstant('{app}\Monitor.exe'),'--stop','',SW_HIDE,ewWaitUntilTerminated,Code) and (Code = 0);
|
|
end;
|
|
|
|
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
|
|
begin
|
|
if CurUninstallStep = usUninstall then Firewall(False);
|
|
end;
|