Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions admin/win/msi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ install(FILES
${CMAKE_CURRENT_BINARY_DIR}/OEM.wxi
${CMAKE_CURRENT_BINARY_DIR}/collect-transform.xsl
${CMAKE_CURRENT_BINARY_DIR}/make-msi.bat
EnsureACL.js
Platform.wxi
Nextcloud.wxs
${CMAKE_CURRENT_BINARY_DIR}/RegistryCleanup.vbs
Expand Down
44 changes: 44 additions & 0 deletions admin/win/msi/EnsureACL.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// writes a message to the MSI logs
function logInfo(message) {
var record = Session.Installer.CreateRecord(0);
record.stringData(0) = message
// 0x40000000 = msiMessageTypeUser -- see https://learn.microsoft.com/en-gb/windows/win32/msi/session-message#parameters
Session.Message(0x04000000, record)
}

function EnsureACL() {
var shell = new ActiveXObject("WScript.Shell");
var fs = new ActiveXObject("Scripting.FileSystemObject");

var programFilesPath = fs.GetAbsolutePathName(shell.ExpandEnvironmentStrings("%PROGRAMFILES%"));
var installPath = fs.GetAbsolutePathName(Session.Property("CustomActionData"));

logInfo("programFilesPath: " + programFilesPath + "\r\n" + "installPath: " + installPath);

if (installPath.toLowerCase().indexOf(programFilesPath.toLowerCase()) == 0) {
// no need to adapt ACLs when installing to C:/Program Files
return 0;
}

// using SIDs here (prefixed by *) to avoid potential issues with non-English installs
// see also: https://learn.microsoft.com/en-us/windows/win32/secauthz/well-known-sids
var grants = [
"*S-1-5-32-544:(OI)(CI)F", // DOMAIN_ALIAS_RID_ADMINS => full access
"*S-1-5-18:(OI)(CI)F", // SECURITY_LOCAL_SYSTEM_RID => full access
"*S-1-5-32-545:(OI)(CI)RX" // DOMAIN_ALIAS_RID_USERS => read, execute
];
var grantsOptions = "";
for (var i = 0; i < grants.length; i++) {
grantsOptions += ' /grant "' + grants[i] + '" ';
}

var icaclsCommand = 'icacls.exe "' + installPath + '" /inheritance:r ' + grantsOptions;
logInfo("Command: " + icaclsCommand);
var retval = shell.Run(icaclsCommand, 0, true);
if (retval != 0) {
logInfo("Return code: " + retval);
return 1603; // fatal error
}

return 0;
}
26 changes: 17 additions & 9 deletions admin/win/msi/Nextcloud.wxs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@
<!-- Detect legacy NSIS installation -->
<Property Id="NSIS_UNINSTALLEXE">
<RegistrySearch Id="RegistryLegacyUninstallString" Type="file" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\$(var.AppName)" Name="UninstallString" Win64="no">
<FileSearch Id="LegacyUninstallFileName" Name="Uninstall.exe"/>
</RegistrySearch>
<FileSearch Id="LegacyUninstallFileName" Name="Uninstall.exe"/>
</RegistrySearch>
</Property>

<!-- Property to disable update checks -->
Expand All @@ -71,22 +71,30 @@
<SetProperty Id="ExecNsisUninstaller" Value="&quot;$(var.AppShortName)&quot; &quot;[NSIS_UNINSTALLEXE]&quot;" Before="ExecNsisUninstaller" Sequence="execute" />
<SetProperty Id="RemoveNavigationPaneEntries" Value="&quot;$(var.AppName)&quot;" Before="RemoveNavigationPaneEntries" Sequence="execute" />

<!-- Ensure ACLs -->
<Binary Id="EnsureACL" SourceFile="EnsureACL.js" />
<SetProperty Id="EnsureACL" Before="EnsureACL" Value="[INSTALLDIR]" Sequence="execute" />
<CustomAction Id="EnsureACL" BinaryKey="EnsureACL" JScriptCall="EnsureACL" Return="check" Execute="deferred" Impersonate="no" />

<InstallExecuteSequence>
<!-- Install: Remove previous NSIS installation, if detected -->
<Custom Action="ExecNsisUninstaller" Before="ProcessComponents">NSIS_UNINSTALLEXE AND NOT Installed</Custom>

<!-- Install: Ensure ACLs are set -->
<Custom Action="EnsureACL" After="InstallFiles">NOT Installed</Custom>

<!-- Uninstall: Remove sync folders from Explorer's Navigation Pane, only effective for the current user (home users) -->
<Custom Action="RemoveNavigationPaneEntries" After="RemoveFiles">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
<!-- Uninstall: Cleanup the Registry -->
<Custom Action="RegistryCleanupCustomAction" After="RemoveFiles">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>

<!-- Uninstall: Cleanup the Registry -->
<Custom Action="RegistryCleanupCustomAction" After="RemoveFiles">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>

<!-- Schedule Reboot for the Shell Extensions (in silent installation mode only, or if SCHEDULE_REBOOT argument is set-->
<ScheduleReboot After="InstallFinalize">(SCHEDULE_REBOOT=1) OR NOT (UILevel=2)</ScheduleReboot>
</InstallExecuteSequence>

<!-- "Add or Remove" Programs Entries -->
<Property Id="APPNAME">$(var.AppName)</Property>
<Property Id="APPNAME">$(var.AppName)</Property>
<Property Id="ARPPRODUCTICON">$(var.AppIcon)</Property>
<Property Id="ARPHELPLINK">$(var.AppHelpLink)</Property>
<Property Id="ARPURLINFOABOUT">$(var.AppInfoLink)</Property>
Expand Down Expand Up @@ -192,11 +200,11 @@
<RegistryValue Type="integer" Name="skipUpdateCheck" Value="[SKIPAUTOUPDATE]" />
</RegistryKey>
</Component>
<!-- Register URI handler -->
<!-- Register URI handler -->
<Component Id="RegistryUriHandler" Guid="*" Win64="$(var.PlatformWin64)">
<RegistryKey Root="HKLM" Key="Software\Classes\$(var.AppCommandOpenUrlScheme)" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
<RegistryValue Type="string" Value="URL:$(var.AppName) Protocol" />
<RegistryValue Type="string" Name="URL Protocol" Value="" />
<RegistryValue Type="string" Name="URL Protocol" Value="" />
</RegistryKey>
<RegistryKey Root="HKLM" Key="Software\Classes\$(var.AppCommandOpenUrlScheme)\DefaultIcon" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
<RegistryValue Type="string" Value="[INSTALLDIR]$(var.AppExe)" />
Expand All @@ -214,7 +222,7 @@

<ComponentRef Id="RegistryVersionInfo" />
<ComponentRef Id="RegistryDefaultSettings" />
<ComponentRef Id="RegistryUriHandler" />
<ComponentRef Id="RegistryUriHandler" />

<Feature Id="ShellExtensions" Title="Integration for Windows Explorer"
Description="This feature requires a reboot." >
Expand Down