winget-cli

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

Errors.cpp (36469B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #include "pch.h"
      4 #include "Public/AppInstallerErrors.h"
      5 #include "Public/AppInstallerLogging.h"
      6 #include "Public/AppInstallerStrings.h"
      7 #include "Public/winget/Resources.h"
      8 
      9 
     10 namespace AppInstaller
     11 {
     12     namespace
     13     {
     14         // A simple struct to hold the data
     15         struct HResultData
     16         {
     17             HRESULT Value;
     18             std::string_view Symbol;
     19             std::string_view Description;
     20 
     21             bool operator<(const HResultData& other) const
     22             {
     23                 return Value < other.Value;
     24             }
     25         };
     26 
     27         // HRESULT information for our errors
     28         struct WinGetHResultInformation : public Errors::HResultInformation
     29         {
     30             constexpr WinGetHResultInformation(HRESULT value, std::string_view symbol, std::string_view unlocalizedDescription) :
     31                 Errors::HResultInformation(value, symbol), m_unlocalizedDescription(unlocalizedDescription)
     32             {}
     33 
     34             constexpr WinGetHResultInformation(const HResultData& data) :
     35                 Errors::HResultInformation(data.Value, data.Symbol), m_unlocalizedDescription(data.Description)
     36             {}
     37 
     38             Utility::LocIndString GetDescription() const override
     39             {
     40                 auto localizedDescription = StringResource::TryResolveString(Utility::ConvertToUTF16(Symbol()));
     41                 return localizedDescription ?
     42                     std::move(localizedDescription).value() :
     43                     Utility::LocIndString{ m_unlocalizedDescription };
     44             }
     45 
     46         private:
     47             std::string_view m_unlocalizedDescription;
     48         };
     49 
     50         // HRESULT information for our errors, with the unlocalized description only.
     51         struct WinGetHResultInformationUnlocalized : public Errors::HResultInformation
     52         {
     53             constexpr WinGetHResultInformationUnlocalized(HRESULT value, std::string_view symbol, std::string_view unlocalizedDescription) :
     54                 Errors::HResultInformation(value, symbol), m_unlocalizedDescription(unlocalizedDescription)
     55             {}
     56 
     57             constexpr WinGetHResultInformationUnlocalized(const HResultData& data) :
     58                 Errors::HResultInformation(data.Value, data.Symbol), m_unlocalizedDescription(data.Description)
     59             {}
     60 
     61             Utility::LocIndString GetDescription() const override
     62             {
     63                 return Utility::LocIndString{ m_unlocalizedDescription };
     64             }
     65 
     66         private:
     67             std::string_view m_unlocalizedDescription;
     68         };
     69 
     70         // The information entry for an HRESULT not in the list (someone probably forgot to add an entry)
     71         struct UnknownHResultInformation : public Errors::HResultInformation
     72         {
     73             constexpr UnknownHResultInformation(HRESULT value) :
     74                 Errors::HResultInformation(value)
     75             {}
     76 
     77             Utility::LocIndString GetDescription() const override
     78             {
     79                 auto localizedDescription = StringResource::TryResolveString(StringResource::String::UnknownErrorCode);
     80                 return localizedDescription ?
     81                     std::move(localizedDescription).value() :
     82                     Utility::LocIndString{ "Unknown error code"sv };
     83             }
     84         };
     85 
     86 #define WINGET_HRESULT_INFO(_name_,_description_) HResultData{ _name_, #_name_, _description_ }
     87 
     88         constexpr const HResultData s_wingetHResultData[] =
     89         {
     90             // Changes to any of these errors require the corresponding resource string in winget.resw to be updated.
     91             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INTERNAL_ERROR, "Internal Error"),
     92             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_CL_ARGUMENTS, "Invalid command line arguments"),
     93             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_COMMAND_FAILED, "Executing command failed"),
     94             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MANIFEST_FAILED, "Opening manifest failed"),
     95             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CTRL_SIGNAL_RECEIVED, "Cancellation signal received"),
     96             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SHELLEXEC_INSTALL_FAILED, "Running ShellExecute failed"),
     97             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UNSUPPORTED_MANIFESTVERSION, "Cannot process manifest. The manifest version is higher than supported. Please update the client."),
     98             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DOWNLOAD_FAILED, "Downloading installer failed"),
     99             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CANNOT_WRITE_TO_UPLEVEL_INDEX, "Cannot write to index; it is a higher schema version"),
    100             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INDEX_INTEGRITY_COMPROMISED, "The index is corrupt"),
    101             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCES_INVALID, "The configured source information is corrupt"),
    102             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_NAME_ALREADY_EXISTS, "The source name is already configured"),
    103             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_SOURCE_TYPE, "The source type is invalid"),
    104             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PACKAGE_IS_BUNDLE, "The MSIX file is a bundle, not a package"),
    105             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_DATA_MISSING, "Data required by the source is missing"),
    106             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_INSTALLER, "None of the installers are applicable for the current system"),
    107             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALLER_HASH_MISMATCH, "The installer file's hash does not match the manifest"),
    108             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_NAME_DOES_NOT_EXIST, "The source name does not exist"),
    109             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_ARG_ALREADY_EXISTS, "The source location is already configured under another name"),
    110             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_APPLICATIONS_FOUND, "No packages found"),
    111             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_SOURCES_DEFINED, "No sources are configured"),
    112             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MULTIPLE_APPLICATIONS_FOUND, "Multiple packages found matching the criteria"),
    113             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_MANIFEST_FOUND, "No manifest found matching the criteria"),
    114             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_EXTENSION_PUBLIC_FAILED, "Failed to get Public folder from source package"),
    115             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_COMMAND_REQUIRES_ADMIN, "Command requires administrator privileges to run"),
    116             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_NOT_SECURE, "The source location is not secure"),
    117             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MSSTORE_BLOCKED_BY_POLICY, "The Microsoft Store client is blocked by policy"),
    118             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MSSTORE_APP_BLOCKED_BY_POLICY, "The Microsoft Store app is blocked by policy"),
    119             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_EXPERIMENTAL_FEATURE_DISABLED, "The feature is currently under development. It can be enabled using winget settings."),
    120             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED, "Failed to install the Microsoft Store app"),
    121             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_COMPLETE_INPUT_BAD, "Failed to perform auto complete"),
    122             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_INIT_FAILED, "Failed to initialize YAML parser"),
    123             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_INVALID_MAPPING_KEY, "Encountered an invalid YAML key"),
    124             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_DUPLICATE_MAPPING_KEY, "Encountered a duplicate YAML key"),
    125             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_INVALID_OPERATION, "Invalid YAML operation"),
    126             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_DOC_BUILD_FAILED, "Failed to build YAML doc"),
    127             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_INVALID_EMITTER_STATE, "Invalid YAML emitter state"),
    128             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_YAML_INVALID_DATA, "Invalid YAML data"),
    129             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_LIBYAML_ERROR, "LibYAML error"),
    130             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_WARNING, "Manifest validation succeeded with warning"),
    131             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MANIFEST_VALIDATION_FAILURE, "Manifest validation failed"),
    132             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_MANIFEST, "Manifest is invalid"),
    133             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UPDATE_NOT_APPLICABLE, "No applicable update found"),
    134             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UPDATE_ALL_HAS_FAILURE, "winget upgrade --all completed with failures"),
    135             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALLER_SECURITY_CHECK_FAILED, "Installer failed security check"),
    136             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DOWNLOAD_SIZE_MISMATCH, "Download size does not match expected content length"),
    137             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_UNINSTALL_INFO_FOUND, "Uninstall command not found"),
    138             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_EXEC_UNINSTALL_COMMAND_FAILED, "Running uninstall command failed"),
    139             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ICU_BREAK_ITERATOR_ERROR, "ICU break iterator error"),
    140             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ICU_CASEMAP_ERROR, "ICU casemap error"),
    141             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ICU_REGEX_ERROR, "ICU regex error"),
    142             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_IMPORT_INSTALL_FAILED, "Failed to install one or more imported packages"),
    143             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NOT_ALL_PACKAGES_FOUND, "Could not find one or more requested packages"),
    144             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, "Json file is invalid"),
    145             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_NOT_REMOTE, "The source location is not remote"),
    146             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UNSUPPORTED_RESTSOURCE, "The configured rest source is not supported"),
    147             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_DATA, "Invalid data returned by rest source"),
    148             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY, "Operation is blocked by Group Policy"),
    149             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTAPI_INTERNAL_ERROR, "Rest API internal error"),
    150             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_URL, "Invalid rest source url"),
    151             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTAPI_UNSUPPORTED_MIME_TYPE, "Unsupported MIME type returned by rest API"),
    152             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTSOURCE_INVALID_VERSION, "Invalid rest source contract version"),
    153             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_DATA_INTEGRITY_FAILURE, "The source data is corrupted or tampered"),
    154             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_STREAM_READ_FAILURE, "Error reading from the stream"),
    155             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PACKAGE_AGREEMENTS_NOT_ACCEPTED, "Package agreements were not agreed to"),
    156             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PROMPT_INPUT_ERROR, "Error reading input in prompt"),
    157             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UNSUPPORTED_SOURCE_REQUEST, "The search request is not supported by one or more sources"),
    158             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESTAPI_ENDPOINT_NOT_FOUND, "The rest API endpoint is not found."),
    159             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED, "Failed to open the source."),
    160             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SOURCE_AGREEMENTS_NOT_ACCEPTED, "Source agreements were not agreed to"),
    161             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CUSTOMHEADER_EXCEEDS_MAXLENGTH, "Header size exceeds the allowable limit of 1024 characters. Please reduce the size and try again."),
    162             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MISSING_RESOURCE_FILE, "Missing resource file"),
    163             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MSI_INSTALL_FAILED, "Running MSI install failed"),
    164             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_MSIEXEC_ARGUMENT, "Arguments for msiexec are invalid"),
    165             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_FAILED_TO_OPEN_ALL_SOURCES, "Failed to open one or more sources"),
    166             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DEPENDENCIES_VALIDATION_FAILED, "Failed to validate dependencies"),
    167             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MISSING_PACKAGE, "One or more package is missing"),
    168             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_TABLE_COLUMN, "Invalid table column"),
    169             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_NOT_NEWER, "The upgrade version is not newer than the installed version"),
    170             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UPGRADE_VERSION_UNKNOWN, "Upgrade version is unknown and override is not specified"),
    171             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ICU_CONVERSION_ERROR, "ICU conversion error"),
    172             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PORTABLE_INSTALL_FAILED, "Failed to install portable package"),
    173             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PORTABLE_REPARSE_POINT_NOT_SUPPORTED, "Volume does not support reparse points"),
    174             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PORTABLE_PACKAGE_ALREADY_EXISTS, "Portable package from a different source already exists."),
    175             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PORTABLE_SYMLINK_PATH_IS_DIRECTORY, "Unable to create symlink, path points to a directory."),
    176             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALLER_PROHIBITS_ELEVATION, "The installer cannot be run from an administrator context."),
    177             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PORTABLE_UNINSTALL_FAILED, "Failed to uninstall portable package"),
    178             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ARP_VERSION_VALIDATION_FAILED, "Failed to validate DisplayVersion values against index."),
    179             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_UNSUPPORTED_ARGUMENT, "One or more arguments are not supported."),
    180             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_BIND_WITH_EMBEDDED_NULL, "Embedded null characters are disallowed for SQLite"),
    181             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_NOT_FOUND, "Failed to find the nested installer in the archive."),
    182             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_EXTRACT_ARCHIVE_FAILED, "Failed to extract archive."),
    183             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NESTEDINSTALLER_INVALID_PATH, "Invalid relative file path to nested installer provided."),
    184             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH, "The server certificate did not match any of the expected values."),
    185             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_LOCATION_REQUIRED, "Install location must be provided."),
    186             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_ARCHIVE_SCAN_FAILED, "Archive malware scan failed."),
    187             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PACKAGE_ALREADY_INSTALLED, "Found at least one version of the package installed."),
    188             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PIN_ALREADY_EXISTS, "A pin already exists for the package."),
    189             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PIN_DOES_NOT_EXIST, "There is no pin for the package."),
    190             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CANNOT_OPEN_PINNING_INDEX, "Unable to open the pin database."),
    191             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MULTIPLE_INSTALL_FAILED, "One or more applications failed to install"),
    192             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_MULTIPLE_UNINSTALL_FAILED, "One or more applications failed to uninstall"),
    193             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NOT_ALL_QUERIES_FOUND_SINGLE, "One or more queries did not return exactly one match"),
    194             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PACKAGE_IS_PINNED, "The package has a pin that prevents upgrade."),
    195             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB, "The package currently installed is the stub package"),
    196             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_APPTERMINATION_RECEIVED, "Application shutdown signal received"),
    197             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DOWNLOAD_DEPENDENCIES, "Failed to download package dependencies."),
    198             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DOWNLOAD_COMMAND_PROHIBITED, "Failed to download package. Download for offline installation is prohibited."),
    199             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SERVICE_UNAVAILABLE, "A required service is busy or unavailable. Try again later."),
    200             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESUME_ID_NOT_FOUND, "The guid provided does not correspond to a valid resume state."),
    201             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CLIENT_VERSION_MISMATCH, "The current client version did not match the client version of the saved state."),
    202             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_RESUME_STATE, "The resume state data is invalid."),
    203             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_CANNOT_OPEN_CHECKPOINT_INDEX, "Unable to open the checkpoint database."),
    204             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_RESUME_LIMIT_EXCEEDED, "Exceeded max resume limit."),
    205             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INVALID_AUTHENTICATION_INFO, "Invalid authentication info."),
    206             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_AUTHENTICATION_TYPE_NOT_SUPPORTED, "Authentication method not supported."),
    207             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_AUTHENTICATION_FAILED, "Authentication failed."),
    208             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_AUTHENTICATION_INTERACTIVE_REQUIRED, "Authentication failed. Interactive authentication required."),
    209             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_AUTHENTICATION_CANCELLED_BY_USER, "Authentication failed. User cancelled."),
    210             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_AUTHENTICATION_INCORRECT_ACCOUNT, "Authentication failed. Authenticated account is not the desired account."),
    211             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_REPAIR_INFO_FOUND, "Repair command not found."),
    212             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_REPAIR_NOT_APPLICABLE, "Repair operation is not applicable."),
    213             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_EXEC_REPAIR_FAILED, "Repair operation failed."),
    214             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_REPAIR_NOT_SUPPORTED, "The installer technology in use doesn't support repair."),
    215             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."),
    216             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SQLITE_CONNECTION_TERMINATED, "The SQLite connection was terminated to prevent corruption."),
    217             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_DISPLAYCATALOG_API_FAILED, "Failed to get Microsoft Store package catalog."),
    218             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_DISPLAYCATALOG_PACKAGE, "No applicable Microsoft Store package found from Microsoft Store package catalog."),
    219             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED, "Failed to get Microsoft Store package download information."),
    220             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_NO_APPLICABLE_SFSCLIENT_PACKAGE, "No applicable Microsoft Store package download information found."),
    221             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED, "Failed to retrieve Microsoft Store package license."),
    222             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_SFSCLIENT_PACKAGE_NOT_SUPPORTED, "The Microsoft Store package does not support download."),
    223             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_LICENSING_API_FAILED_FORBIDDEN, "Failed to retrieve Microsoft Store package license. The Microsoft Entra Id account does not have the required privilege."),
    224             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALLER_ZERO_BYTE_FILE, "Downloaded zero byte installer; ensure that your network connection is working properly."),
    225 
    226             // Install errors.
    227             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE, "Application is currently running. Exit the application then try again."),
    228             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_INSTALL_IN_PROGRESS, "Another installation is already in progress. Try again later."),
    229             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_FILE_IN_USE, "One or more file is being used. Exit the application then try again."),
    230             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_MISSING_DEPENDENCY, "This package has a dependency missing from your system."),
    231             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_DISK_FULL, "There's no more space on your PC. Make space, then try again."),
    232             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_INSUFFICIENT_MEMORY, "There's not enough memory available to install. Close other applications then try again."),
    233             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_NO_NETWORK, "This application requires internet connectivity. Connect to a network then try again."),
    234             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_CONTACT_SUPPORT, "This application encountered an error during installation. Contact support."),
    235             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_TO_FINISH, "Restart your PC to finish installation."),
    236             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_REQUIRED_FOR_INSTALL, "Installation failed. Restart your PC then try again."),
    237             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_REBOOT_INITIATED, "Your PC will restart to finish installation."),
    238             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_CANCELLED_BY_USER, "You cancelled the installation."),
    239             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_ALREADY_INSTALLED, "Another version of this application is already installed."),
    240             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_DOWNGRADE, "A higher version of this application is already installed."),
    241             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_BLOCKED_BY_POLICY, "Organization policies are preventing installation. Contact your admin."),
    242             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_DEPENDENCIES, "Failed to install package dependencies."),
    243             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_PACKAGE_IN_USE_BY_APPLICATION, "Application is currently in use by another application."),
    244             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_INVALID_PARAMETER, "Invalid parameter."),
    245             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_SYSTEM_NOT_SUPPORTED, "Package not supported by the system."),
    246             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_UPGRADE_NOT_SUPPORTED, "The installer does not support upgrading an existing package."),
    247             WINGET_HRESULT_INFO(APPINSTALLER_CLI_ERROR_INSTALL_CUSTOM_ERROR, "Installation failed with a custom installer error."),
    248 
    249             // Status values for check package installed status results.
    250             // Partial success has the success bit(first bit) set to 0.
    251             WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_ARP_ENTRY_NOT_FOUND, "The Apps and Features Entry for the package could not be found."),
    252             WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_FOUND, "The install location could not be found."),
    253             WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_FILE_HASH_MISMATCH, "The hash of the existing file did not match."),
    254             WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_FILE_NOT_FOUND, "File not found."),
    255             WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_FILE_ACCESS_ERROR, "The file could not be accessed."),
    256 
    257             // Configuration Errors
    258             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_INVALID_CONFIGURATION_FILE, "The configuration file is invalid."),
    259             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_INVALID_YAML, "The YAML syntax is invalid."),
    260             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_INVALID_FIELD_TYPE, "A configuration field has an invalid type."),
    261             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNKNOWN_CONFIGURATION_FILE_VERSION, "The configuration has an unknown version."),
    262             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_SET_APPLY_FAILED, "An error occurred while applying the configuration."),
    263             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_DUPLICATE_IDENTIFIER, "The configuration contains a duplicate identifier."),
    264             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_MISSING_DEPENDENCY, "The configuration is missing a dependency."),
    265             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_DEPENDENCY_UNSATISFIED, "The configuration has an unsatisfied dependency."),
    266             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_ASSERTION_FAILED, "An assertion for the configuration unit failed."),
    267             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_MANUALLY_SKIPPED, "The configuration was manually skipped."),
    268             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_WARNING_NOT_ACCEPTED, "The user declined to continue execution."),
    269             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_SET_DEPENDENCY_CYCLE, "The dependency graph contains a cycle which cannot be resolved."),
    270             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_INVALID_FIELD_VALUE, "The configuration has an invalid field value."),
    271             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_MISSING_FIELD, "The configuration is missing a field."),
    272             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_TEST_FAILED, "Some of the configuration units failed while testing their state."),
    273             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_TEST_NOT_RUN, "Configuration state was not tested."),
    274             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_GET_FAILED, "The configuration unit failed getting its properties."),
    275             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_HISTORY_ITEM_NOT_FOUND, "The specified configuration could not be found."),
    276             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_PARAMETER_INTEGRITY_BOUNDARY, "Parameter cannot be passed across integrity boundary."),
    277 
    278             // Configuration Processor Errors
    279             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_NOT_INSTALLED, "The configuration unit was not installed."),
    280             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_NOT_FOUND_REPOSITORY, "The configuration unit could not be found."),
    281             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_MULTIPLE_MATCHES, "Multiple matches were found for the configuration unit; specify the module to select the correct one."),
    282             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_INVOKE_GET, "The configuration unit failed while attempting to get the current system state."),
    283             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_INVOKE_TEST, "The configuration unit failed while attempting to test the current system state."),
    284             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_INVOKE_SET, "The configuration unit failed while attempting to apply the desired state."),
    285             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_MODULE_CONFLICT, "The module for the configuration unit is available in multiple locations with the same version."),
    286             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE, "Loading the module for the configuration unit failed."),
    287             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_INVOKE_INVALID_RESULT, "The configuration unit returned an unexpected result during execution."),
    288             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_SETTING_CONFIG_ROOT, "A unit contains a setting that requires the config root."),
    289             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_UNIT_IMPORT_MODULE_ADMIN, "Loading the module for the configuration unit failed because it requires administrator privileges to run."),
    290             WINGET_HRESULT_INFO(WINGET_CONFIG_ERROR_NOT_SUPPORTED_BY_PROCESSOR, "Operation is not supported by the configuration processor."),
    291 
    292             // Errors without the error bit set
    293             WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_INSTALL_LOCATION_NOT_APPLICABLE, "The install location is not applicable."),
    294             WINGET_HRESULT_INFO(WINGET_INSTALLED_STATUS_FILE_FOUND_WITHOUT_HASH_CHECK, "The file was found but the hash was not checked."),
    295         };
    296 
    297         // Map externally defined HRESULTs to error messages we want to use here
    298         constexpr const HResultData s_externalHResultData[] =
    299         {
    300             // Changes to any of these errors require the corresponding resource string in winget.resw to be updated.
    301             HResultData{ static_cast<HRESULT>(0x803FB103), "StoreInstall_PackageNotAvailableForCurrentSystem", "The package is not compatible with the current Windows version or platform." },
    302             HResultData{ static_cast<HRESULT>(0x803FB104), "StoreInstall_PackageNotAvailableForCurrentSystem", "The package is not compatible with the current Windows version or platform." },
    303             HResultData{ static_cast<HRESULT>(0x803FB106), "StoreInstall_PackageNotAvailableForCurrentSystem", "The package is not compatible with the current Windows version or platform." },
    304         };
    305 
    306         template <size_t ArraySize>
    307         const HResultData* FindHResultData(HRESULT value, const HResultData (&dataArray)[ArraySize])
    308         {
    309             auto itr = std::lower_bound(std::cbegin(dataArray), std::cend(dataArray), HResultData{ value });
    310 
    311             if (itr != std::cend(dataArray) && itr->Value == value)
    312             {
    313                 return itr;
    314             }
    315 
    316             return nullptr;
    317         }
    318 
    319         const HResultData* FindWinGetHResultData(HRESULT value)
    320         {
    321             return FindHResultData(value, s_wingetHResultData);
    322         }
    323 
    324         const HResultData* FindExternalHResultData(HRESULT value)
    325         {
    326             return FindHResultData(value, s_externalHResultData);
    327         }
    328 
    329         Utility::LocIndString GetMessageForAppInstallerHR(HRESULT hr)
    330         {
    331             const HResultData* data = FindWinGetHResultData(hr);
    332             return data ?
    333                 WinGetHResultInformation(*data).GetDescription() :
    334                 UnknownHResultInformation(hr).GetDescription();
    335         }
    336 
    337         void GetUserPresentableMessageForHR(std::ostringstream& strstr, HRESULT hr)
    338         {
    339             strstr << "0x" << Logging::SetHRFormat << hr << " : ";
    340 
    341             if (HRESULT_FACILITY(hr) == APPINSTALLER_CLI_ERROR_FACILITY)
    342             {
    343                 strstr << GetMessageForAppInstallerHR(hr);
    344             }
    345             else
    346             {
    347                 const HResultData* data = FindExternalHResultData(hr);
    348 
    349                 if (data)
    350                 {
    351                     strstr << WinGetHResultInformation(*data).GetDescription();
    352                 }
    353                 else
    354                 {
    355                     strstr << std::system_category().message(hr);
    356                 }
    357             }
    358         }
    359     }
    360 
    361     std::string GetUserPresentableMessage(const wil::ResultException& re)
    362     {
    363         const auto& info = re.GetFailureInfo();
    364 
    365         std::ostringstream strstr;
    366 
    367         // We assume that if the exception has a message, that message is relevant to show to the user.
    368         if (info.pszMessage)
    369         {
    370             strstr << Utility::ConvertToUTF8(info.pszMessage) << std::endl;
    371         }
    372 
    373         GetUserPresentableMessageForHR(strstr, re.GetErrorCode());
    374 
    375         return strstr.str();
    376     }
    377 
    378     std::string GetUserPresentableMessage(const std::exception& e)
    379     {
    380         return e.what();
    381     }
    382 
    383     std::string GetUserPresentableMessage(HRESULT hr)
    384     {
    385         std::ostringstream strstr;
    386         GetUserPresentableMessageForHR(strstr, hr);
    387         return strstr.str();
    388     }
    389 
    390 #ifndef WINGET_DISABLE_FOR_FUZZING
    391     std::string GetUserPresentableMessage(const winrt::hresult_error& hre)
    392     {
    393         std::ostringstream strstr;
    394         GetUserPresentableMessageForHR(strstr, hre.code());
    395         return strstr.str();
    396     }
    397 #endif
    398 
    399     namespace Errors
    400     {
    401         constexpr HResultInformation::HResultInformation(HRESULT value) :
    402             m_value(value) {}
    403 
    404         constexpr HResultInformation::HResultInformation(HRESULT value, std::string_view symbol) :
    405             m_value(value), m_symbol(symbol) {}
    406 
    407         HRESULT HResultInformation::Value() const
    408         {
    409             return m_value;
    410         }
    411 
    412         bool HResultInformation::operator<(const HResultInformation& other) const
    413         {
    414             return m_value < other.m_value;
    415         }
    416 
    417         Utility::LocIndView HResultInformation::Symbol() const
    418         {
    419             return Utility::LocIndView{ m_symbol };
    420         }
    421 
    422         Utility::LocIndString HResultInformation::GetDescription() const
    423         {
    424             if (HRESULT_FACILITY(m_value) == APPINSTALLER_CLI_ERROR_FACILITY)
    425             {
    426                 // In case external code attempts to construct HResultInformation directly
    427                 return GetMessageForAppInstallerHR(m_value);
    428             }
    429             else
    430             {
    431                 return Utility::LocIndString{ std::system_category().message(m_value) };
    432             }
    433         }
    434 
    435         std::unique_ptr<HResultInformation> HResultInformation::Find(HRESULT value)
    436         {
    437             if (HRESULT_FACILITY(value) == APPINSTALLER_CLI_ERROR_FACILITY)
    438             {
    439                 const HResultData* data = FindWinGetHResultData(value);
    440 
    441                 if (data)
    442                 {
    443                     return std::make_unique<WinGetHResultInformation>(*data);
    444                 }
    445                 else
    446                 {
    447                     return std::make_unique<UnknownHResultInformation>(value);
    448                 }
    449             }
    450             else
    451             {
    452                 return std::make_unique<HResultInformation>(value);
    453             }
    454         }
    455 
    456         std::vector<std::unique_ptr<HResultInformation>> HResultInformation::Find(std::string_view value)
    457         {
    458             std::vector<std::unique_ptr<HResultInformation>> result;
    459 
    460             auto addToResultIf = [&](auto predicate)
    461             {
    462                 for (const HResultData& data : s_wingetHResultData)
    463                 {
    464                     if (predicate(data) &&
    465                         std::none_of(result.begin(), result.end(), [&](const std::unique_ptr<HResultInformation>& info) { return info->Value() == data.Value; }))
    466                     {
    467                         result.emplace_back(std::make_unique<WinGetHResultInformation>(data));
    468                     }
    469                 }
    470             };
    471 
    472             addToResultIf([&](const HResultData& data) { return Utility::CaseInsensitiveEquals(data.Symbol, value); });
    473             addToResultIf([&](const HResultData& data) { return Utility::CaseInsensitiveContainsSubstring(data.Symbol, value); });
    474             addToResultIf([&](const HResultData& data) { return Utility::CaseInsensitiveContainsSubstring(data.Description, value); });
    475 
    476             return result;
    477         }
    478 
    479         std::vector<std::unique_ptr<HResultInformation>> GetWinGetErrors()
    480         {
    481             std::vector<std::unique_ptr<HResultInformation>> result;
    482             result.reserve(ARRAYSIZE(s_wingetHResultData));
    483 
    484             for (const HResultData& data : s_wingetHResultData)
    485             {
    486                 result.emplace_back(std::make_unique<WinGetHResultInformationUnlocalized>(data));
    487             }
    488 
    489             return result;
    490         }
    491     }
    492 }