winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 9171097d6790628cc2226456729026657ed91b60
parent bdb5faac4f1a5cb32baed8103c33ad55ecc8c151
Author: JohnMcPMS <johnmcp@microsoft.com>
Date:   Wed, 12 Mar 2025 16:50:31 -0700

Handle access denied error when setting owner if already owner (#5282)

If we get `ERROR_ACCESS_DENIED` when attempting to set the owner, check
if the owner is already correct. If it is, attempt to set just the DACL.
Diffstat:
Msrc/AppInstallerSharedLib/Filesystem.cpp | 18+++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/AppInstallerSharedLib/Filesystem.cpp b/src/AppInstallerSharedLib/Filesystem.cpp @@ -417,7 +417,23 @@ namespace AppInstaller::Filesystem securityInformation |= OWNER_SECURITY_INFORMATION; } - THROW_IF_WIN32_ERROR(SetNamedSecurityInfoW(&path[0], SE_FILE_OBJECT, securityInformation, ownerSID, nullptr, acl.get(), nullptr)); + DWORD result = SetNamedSecurityInfoW(&path[0], SE_FILE_OBJECT, securityInformation, ownerSID, nullptr, acl.get(), nullptr); + + // We can be denied access attempting to set the owner when the owner is already correct. + // Determine if the owner is correct; if so, try again without attempting to set the owner. + if (result == ERROR_ACCESS_DENIED && ownerSID) + { + wil::unique_hlocal_security_descriptor securityDescriptor; + PSID currentOwnerSID = nullptr; + DWORD getResult = GetNamedSecurityInfoW(&path[0], SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &currentOwnerSID, nullptr, nullptr, nullptr, &securityDescriptor); + + if (SUCCEEDED_WIN32_LOG(getResult) && currentOwnerSID && EqualSid(currentOwnerSID, ownerSID)) + { + result = SetNamedSecurityInfoW(&path[0], SE_FILE_OBJECT, securityInformation & ~OWNER_SECURITY_INFORMATION, nullptr, nullptr, acl.get(), nullptr); + } + } + + THROW_IF_WIN32_ERROR(result); } std::filesystem::path InitializeAndGetPathTo(PathDetails&& details)