Skip to content

Commit 43d7ff7

Browse files
authored
Merge pull request #8160 from nextcloud/bugfix/msi-allow-other-installdirs
fix(msi): allow custom installation directory
2 parents 9d93050 + 88d62ae commit 43d7ff7

File tree

3 files changed

+62
-9
lines changed

3 files changed

+62
-9
lines changed

admin/win/msi/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ install(FILES
2525
${CMAKE_CURRENT_BINARY_DIR}/OEM.wxi
2626
${CMAKE_CURRENT_BINARY_DIR}/collect-transform.xsl
2727
${CMAKE_CURRENT_BINARY_DIR}/make-msi.bat
28+
EnsureACL.js
2829
Platform.wxi
2930
Nextcloud.wxs
3031
${CMAKE_CURRENT_BINARY_DIR}/RegistryCleanup.vbs

admin/win/msi/EnsureACL.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// writes a message to the MSI logs
2+
function logInfo(message) {
3+
var record = Session.Installer.CreateRecord(0);
4+
record.stringData(0) = message
5+
// 0x40000000 = msiMessageTypeUser -- see https://learn.microsoft.com/en-gb/windows/win32/msi/session-message#parameters
6+
Session.Message(0x04000000, record)
7+
}
8+
9+
function EnsureACL() {
10+
var shell = new ActiveXObject("WScript.Shell");
11+
var fs = new ActiveXObject("Scripting.FileSystemObject");
12+
13+
var programFilesPath = fs.GetAbsolutePathName(shell.ExpandEnvironmentStrings("%PROGRAMFILES%"));
14+
var installPath = fs.GetAbsolutePathName(Session.Property("CustomActionData"));
15+
16+
logInfo("programFilesPath: " + programFilesPath + "\r\n" + "installPath: " + installPath);
17+
18+
if (installPath.toLowerCase().indexOf(programFilesPath.toLowerCase()) == 0) {
19+
// no need to adapt ACLs when installing to C:/Program Files
20+
return 0;
21+
}
22+
23+
// using SIDs here (prefixed by *) to avoid potential issues with non-English installs
24+
// see also: https://learn.microsoft.com/en-us/windows/win32/secauthz/well-known-sids
25+
var grants = [
26+
"*S-1-5-32-544:(OI)(CI)F", // DOMAIN_ALIAS_RID_ADMINS => full access
27+
"*S-1-5-18:(OI)(CI)F", // SECURITY_LOCAL_SYSTEM_RID => full access
28+
"*S-1-5-32-545:(OI)(CI)RX" // DOMAIN_ALIAS_RID_USERS => read, execute
29+
];
30+
var grantsOptions = "";
31+
for (var i = 0; i < grants.length; i++) {
32+
grantsOptions += ' /grant "' + grants[i] + '" ';
33+
}
34+
35+
var icaclsCommand = 'icacls.exe "' + installPath + '" /inheritance:r ' + grantsOptions;
36+
logInfo("Command: " + icaclsCommand);
37+
var retval = shell.Run(icaclsCommand, 0, true);
38+
if (retval != 0) {
39+
logInfo("Return code: " + retval);
40+
return 1603; // fatal error
41+
}
42+
43+
return 0;
44+
}

admin/win/msi/Nextcloud.wxs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@
5757
<!-- Detect legacy NSIS installation -->
5858
<Property Id="NSIS_UNINSTALLEXE">
5959
<RegistrySearch Id="RegistryLegacyUninstallString" Type="file" Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\$(var.AppName)" Name="UninstallString" Win64="no">
60-
<FileSearch Id="LegacyUninstallFileName" Name="Uninstall.exe"/>
61-
</RegistrySearch>
60+
<FileSearch Id="LegacyUninstallFileName" Name="Uninstall.exe"/>
61+
</RegistrySearch>
6262
</Property>
6363

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

74+
<!-- Ensure ACLs -->
75+
<Binary Id="EnsureACL" SourceFile="EnsureACL.js" />
76+
<SetProperty Id="EnsureACL" Before="EnsureACL" Value="[INSTALLDIR]" Sequence="execute" />
77+
<CustomAction Id="EnsureACL" BinaryKey="EnsureACL" JScriptCall="EnsureACL" Return="check" Execute="deferred" Impersonate="no" />
78+
7479
<InstallExecuteSequence>
7580
<!-- Install: Remove previous NSIS installation, if detected -->
7681
<Custom Action="ExecNsisUninstaller" Before="ProcessComponents">NSIS_UNINSTALLEXE AND NOT Installed</Custom>
7782

83+
<!-- Install: Ensure ACLs are set -->
84+
<Custom Action="EnsureACL" After="InstallFiles">NOT Installed</Custom>
85+
7886
<!-- Uninstall: Remove sync folders from Explorer's Navigation Pane, only effective for the current user (home users) -->
7987
<Custom Action="RemoveNavigationPaneEntries" After="RemoveFiles">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
80-
81-
<!-- Uninstall: Cleanup the Registry -->
82-
<Custom Action="RegistryCleanupCustomAction" After="RemoveFiles">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
88+
89+
<!-- Uninstall: Cleanup the Registry -->
90+
<Custom Action="RegistryCleanupCustomAction" After="RemoveFiles">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
8391

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

8896
<!-- "Add or Remove" Programs Entries -->
89-
<Property Id="APPNAME">$(var.AppName)</Property>
97+
<Property Id="APPNAME">$(var.AppName)</Property>
9098
<Property Id="ARPPRODUCTICON">$(var.AppIcon)</Property>
9199
<Property Id="ARPHELPLINK">$(var.AppHelpLink)</Property>
92100
<Property Id="ARPURLINFOABOUT">$(var.AppInfoLink)</Property>
@@ -192,11 +200,11 @@
192200
<RegistryValue Type="integer" Name="skipUpdateCheck" Value="[SKIPAUTOUPDATE]" />
193201
</RegistryKey>
194202
</Component>
195-
<!-- Register URI handler -->
203+
<!-- Register URI handler -->
196204
<Component Id="RegistryUriHandler" Guid="*" Win64="$(var.PlatformWin64)">
197205
<RegistryKey Root="HKLM" Key="Software\Classes\$(var.AppCommandOpenUrlScheme)" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
198206
<RegistryValue Type="string" Value="URL:$(var.AppName) Protocol" />
199-
<RegistryValue Type="string" Name="URL Protocol" Value="" />
207+
<RegistryValue Type="string" Name="URL Protocol" Value="" />
200208
</RegistryKey>
201209
<RegistryKey Root="HKLM" Key="Software\Classes\$(var.AppCommandOpenUrlScheme)\DefaultIcon" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
202210
<RegistryValue Type="string" Value="[INSTALLDIR]$(var.AppExe)" />
@@ -214,7 +222,7 @@
214222

215223
<ComponentRef Id="RegistryVersionInfo" />
216224
<ComponentRef Id="RegistryDefaultSettings" />
217-
<ComponentRef Id="RegistryUriHandler" />
225+
<ComponentRef Id="RegistryUriHandler" />
218226

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

0 commit comments

Comments
 (0)