Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion doc/windows/package-manager/winget/returnCodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ ms.localizationpriority: low
| 0x8A15007A | -1978335110 | APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE | Repair operation is not applicable. |
| 0x8A15007B | -1978335109 | APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED | Repair operation failed. |
| 0x8A15007C | -1978335108 | APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED | The installer technology in use doesn't support repair. |
| 0x8A15007D | -1978335107 | APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED | Repair operations involving administrator privileges are not permitted on packages installed within the user scope. |
| 0x8A15007D | -1978335107 | APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED | The requested operation is not permitted from an administrator context on packages installed within the user scope. |
| 0x8A15007E | -1978335106 | APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED | The SQLite connection was terminated to prevent corruption. |
| 0x8A15007F | -1978335105 | APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED | Failed to get Microsoft Store package catalog. |
| 0x8A150080 | -1978335104 | APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE | No applicable Microsoft Store package found from Microsoft Store package catalog. |
Expand Down
1 change: 1 addition & 0 deletions src/AppInstallerCLICore/Resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ namespace AppInstaller::CLI::Resource
WINGET_DEFINE_RESOURCE_STRINGID(NestedInstallerNotSpecified);
WINGET_DEFINE_RESOURCE_STRINGID(NestedInstallerNotSupported);
WINGET_DEFINE_RESOURCE_STRINGID(NoAdminRepairForUserScopePackage);
WINGET_DEFINE_RESOURCE_STRINGID(NoAdminUninstallForUserScopePackage);
WINGET_DEFINE_RESOURCE_STRINGID(NoApplicableInstallers);
WINGET_DEFINE_RESOURCE_STRINGID(NoExperimentalFeaturesMessage);
WINGET_DEFINE_RESOURCE_STRINGID(NoInstalledFontFound);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ namespace AppInstaller::CLI::Workflow
if (scopeEnum == ScopeEnum::User)
{
context.Reporter.Error() << Resource::String::NoAdminRepairForUserScopePackage << std::endl;
AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED);
AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED);
}
}

Expand Down
38 changes: 32 additions & 6 deletions src/AppInstallerCLICore/Workflows/UninstallFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@ namespace AppInstaller::CLI::Workflow

std::vector<Item> Items;
};

bool AdminExecutionShouldBlockUserScopePackages(InstallerTypeEnum installerType)
{
switch (installerType)
{
case InstallerTypeEnum::Exe:
case InstallerTypeEnum::Burn:
case InstallerTypeEnum::Inno:
case InstallerTypeEnum::Nullsoft:
case InstallerTypeEnum::Portable:
return true;
default:
return false;
}
}
}

void UninstallSinglePackage(Execution::Context& context)
Expand Down Expand Up @@ -214,16 +229,27 @@ namespace AppInstaller::CLI::Workflow
return;
}

const std::string installedTypeString = installedPackageVersion->GetMetadata()[PackageVersionMetadata::InstalledType];
switch (ConvertToInstallerTypeEnum(installedTypeString))
auto packageMetadata = installedPackageVersion->GetMetadata();
auto installedType = ConvertToInstallerTypeEnum(packageMetadata[PackageVersionMetadata::InstalledType]);

// When running as admin, block attempt to uninstall user scope package to prevent elevation of privilege paths.
if (AdminExecutionShouldBlockUserScopePackages(installedType) && Runtime::IsRunningAsAdmin())
{
auto scopeEnum = ConvertToScopeEnum(packageMetadata[PackageVersionMetadata::InstalledScope]);
if (scopeEnum == ScopeEnum::User)
{
context.Reporter.Error() << Resource::String::NoAdminUninstallForUserScopePackage << std::endl;
AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED);
}
}

switch (installedType)
{
case InstallerTypeEnum::Exe:
case InstallerTypeEnum::Burn:
case InstallerTypeEnum::Inno:
case InstallerTypeEnum::Nullsoft:
{
IPackageVersion::Metadata packageMetadata = installedPackageVersion->GetMetadata();

// Default to silent unless it is not present or interactivity is requested
auto uninstallCommandItr = packageMetadata.find(PackageVersionMetadata::SilentUninstallCommand);
if (uninstallCommandItr == packageMetadata.end() || context.Args.Contains(Execution::Args::Type::Interactive))
Expand Down Expand Up @@ -281,8 +307,8 @@ namespace AppInstaller::CLI::Workflow
AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND);
}

const std::string installedScope = context.Get<Execution::Data::InstalledPackageVersion>()->GetMetadata()[Repository::PackageVersionMetadata::InstalledScope];
const std::string installedArch = context.Get<Execution::Data::InstalledPackageVersion>()->GetMetadata()[Repository::PackageVersionMetadata::InstalledArchitecture];
const std::string installedScope = packageMetadata[Repository::PackageVersionMetadata::InstalledScope];
const std::string installedArch = packageMetadata[Repository::PackageVersionMetadata::InstalledArchitecture];

PortableInstaller portableInstaller = PortableInstaller(
Manifest::ConvertToScopeEnum(installedScope),
Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerCLIE2ETests/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ public class ErrorCode

public const int ERROR_NO_REPAIR_INFO_FOUND = unchecked((int)0x8A150079);
public const int ERROR_REPAIR_NOT_SUPPORTED = unchecked((int)0x8A15007C);
public const int ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED = unchecked((int)0x8A15007D);
public const int ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED = unchecked((int)0x8A15007D);

public const int ERROR_INSTALLER_ZERO_BYTE_FILE = unchecked((int)0x8A150086);
public const int ERROR_FONT_INSTALL_FAILED = unchecked((int)0x8A150087);
Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerCLIE2ETests/Interop/RepairInterop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public async Task RepairBurnInstallerInAdminContextWithUserScopeInstall()
var repairOptions = this.TestFactory.CreateRepairOptions();
repairOptions.PackageRepairMode = PackageRepairMode.Silent;

await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, repairOptions, RepairResultStatus.RepairError, Constants.ErrorCode.ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED);
await this.RepairPackageAndValidateStatus(searchResult.CatalogPackage, repairOptions, RepairResultStatus.RepairError, Constants.ErrorCode.ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED);

// Cleanup
TestCommon.CleanupTestExeAndDirectory(this.installDir);
Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerCLIE2ETests/RepairCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void RepairBurnInstallerInAdminContextWithUserScopeInstall()
Assert.True(result.StdOut.Contains("Successfully installed"));

result = TestCommon.RunAICLICommand("repair", "AppInstallerTest.TestUserScopeInstallRepairInAdminContext");
Assert.AreEqual(Constants.ErrorCode.ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED, result.ExitCode);
Assert.AreEqual(Constants.ErrorCode.ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED, result.ExitCode);
Assert.True(result.StdOut.Contains("The package installed for user scope cannot be repaired when running with administrator privileges."));
TestCommon.CleanupTestExeAndDirectory(installDir);
}
Expand Down
7 changes: 5 additions & 2 deletions src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw
Original file line number Diff line number Diff line change
Expand Up @@ -2890,8 +2890,8 @@ Please specify one of them using the --source option to proceed.</value>
<data name="NoAdminRepairForUserScopePackage" xml:space="preserve">
<value>The package installed for user scope cannot be repaired when running with administrator privileges.</value>
</data>
<data name="APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED" xml:space="preserve">
<value>Repair operations involving administrator privileges are not permitted on packages installed within the user scope.</value>
<data name="APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED" xml:space="preserve">
<value>The requested operation is not permitted from an administrator context on packages installed within the user scope.</value>
</data>
<data name="RepairFailedWithCode" xml:space="preserve">
<value>Repair failed with exit code: {0}</value>
Expand Down Expand Up @@ -3649,4 +3649,7 @@ An unlocalized JSON fragment will follow on another line.</comment>
<data name="WINGET_CONFIG_ERROR_PROCESSOR_HASH_MISMATCH" xml:space="preserve">
<value>The DSC processor hash provided does not match hash of the target file.</value>
</data>
<data name="NoAdminUninstallForUserScopePackage" xml:space="preserve">
<value>The package installed for user scope cannot be uninstalled when running with administrator privileges.</value>
</data>
</root>
2 changes: 1 addition & 1 deletion src/AppInstallerSharedLib/Errors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ namespace AppInstaller
WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE, "Repair operation is not applicable."),
WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED, "Repair operation failed."),
WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED, "The installer technology in use doesn't support repair."),
WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED, "Repair operations involving administrator privileges are not permitted on packages installed within the user scope."),
WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED, "The requested operation is not permitted from an administrator context on packages installed within the user scope."),
WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED, "The SQLite connection was terminated to prevent corruption."),
WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED, "Failed to get Microsoft Store package catalog."),
WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE, "No applicable Microsoft Store package found from Microsoft Store package catalog."),
Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerSharedLib/Public/AppInstallerErrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
#define APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE ((HRESULT)0x8A15007A)
#define APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED ((HRESULT)0x8A15007B)
#define APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED ((HRESULT)0x8A15007C)
#define APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED ((HRESULT)0x8A15007D)
#define APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED ((HRESULT)0x8A15007D)
#define APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED ((HRESULT)0x8A15007E)
#define APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED ((HRESULT)0x8A15007F)
#define APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE ((HRESULT)0x8A150080)
Expand Down
4 changes: 3 additions & 1 deletion src/Microsoft.Management.Deployment/Converters.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,11 @@ namespace winrt::Microsoft::Management::Deployment::implementation
case APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE:
case APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED:
case APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED:
case APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED:
WINGET_GET_OPERATION_RESULT_STATUS(InternalError, InternalError, InternalError, RepairError);
break;
case APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED:
WINGET_GET_OPERATION_RESULT_STATUS(InternalError, UninstallError, InternalError, RepairError);
break;
case APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED:
WINGET_GET_OPERATION_RESULT_STATUS(PackageAgreementsNotAccepted, InternalError, PackageAgreementsNotAccepted, PackageAgreementsNotAccepted);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ internal static class ErrorCode
public const int RepairNotSupported = unchecked((int)0x8A15007C);

/// <summary>
/// Error code for APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_REPAIR_PROHIBITED.
/// Error code for APPINSTALLER_CLI_ERROR_ADMIN_CONTEXT_ACTION_PROHIBITED.
/// </summary>
public const int AdminContextRepairProhibited = unchecked((int)0x8A15007D);
public const int AdminContextActionProhibited = unchecked((int)0x8A15007D);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private static string GetMessage(int hresult, uint repairerExitCode = 0)
return Resources.RepairOperationNotSupported;
case ErrorCode.RepairNotApplicable:
return Resources.RepairDifferentInstallTechnology;
case ErrorCode.AdminContextRepairProhibited:
case ErrorCode.AdminContextActionProhibited:
return Resources.NoAdminRepairForUserScopePackage;
default:
return string.Format(Resources.UnknownRepairFailure, hresult);
Expand Down
Loading