Skip to content

Commit

Permalink
Make entitlement best effort
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnMcPMS committed Apr 20, 2023
1 parent 4aab7f7 commit ffab94e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 46 deletions.
4 changes: 0 additions & 4 deletions src/AppInstallerCLICore/Resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,6 @@ namespace AppInstaller::CLI::Resource
WINGET_DEFINE_RESOURCE_STRINGID(MsixArgumentDescription);
WINGET_DEFINE_RESOURCE_STRINGID(MsixSignatureHashFailed);
WINGET_DEFINE_RESOURCE_STRINGID(MSStoreAppBlocked);
WINGET_DEFINE_RESOURCE_STRINGID(MSStoreInstallGetEntitlementNetworkError);
WINGET_DEFINE_RESOURCE_STRINGID(MSStoreInstallGetEntitlementNoStoreAccount);
WINGET_DEFINE_RESOURCE_STRINGID(MSStoreInstallGetEntitlementServerError);
WINGET_DEFINE_RESOURCE_STRINGID(MSStoreInstallGetEntitlementSuccess);
WINGET_DEFINE_RESOURCE_STRINGID(MSStoreInstallOrUpdateFailed);
WINGET_DEFINE_RESOURCE_STRINGID(MSStoreInstallTryGetEntitlement);
WINGET_DEFINE_RESOURCE_STRINGID(MSStoreStoreClientBlocked);
Expand Down
75 changes: 45 additions & 30 deletions src/AppInstallerCLICore/Workflows/MSStoreInstallerHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,48 +79,69 @@ namespace AppInstaller::CLI::Workflow
return errorCode;
}

bool GetFreeEntitlement(Execution::Context& context, const std::wstring& productId)
// The type of entitlement we were able to acquire/ensure.
enum class EntitlementType
{
None,
User,
Device,
};

EntitlementType EnsureFreeEntitlement(Execution::Context& context, const std::wstring& productId)
{
AppInstallManager installManager;

AICLI_LOG(CLI, Error, << "Getting entitlement for ProductId: " << Utility::ConvertToUTF8(productId));

// Verifying/Acquiring product ownership
context.Reporter.Info() << Resource::String::MSStoreInstallTryGetEntitlement << std::endl;

GetEntitlementResult result{ nullptr };
GetEntitlementResult entitlementResult{ nullptr };
EntitlementType result = EntitlementType::None;

if (Manifest::ConvertToScopeEnum(context.Args.GetArg(Execution::Args::Type::InstallScope)) == Manifest::ScopeEnum::Machine)
{
AICLI_LOG(CLI, Info, << "Get device entitlement.");
result = installManager.GetFreeDeviceEntitlementAsync(productId, winrt::hstring(), winrt::hstring()).get();
AICLI_LOG(CLI, Info, << "Get device entitlement (machine scope install).");
result = EntitlementType::Device;
entitlementResult = installManager.GetFreeDeviceEntitlementAsync(productId, winrt::hstring(), winrt::hstring()).get();
}
else
{
AICLI_LOG(CLI, Info, << "Get user entitlement.");
result = installManager.GetFreeUserEntitlementAsync(productId, winrt::hstring(), winrt::hstring()).get();
if (result.Status() == GetEntitlementStatus::NoStoreAccount)
result = EntitlementType::User;
entitlementResult = installManager.GetFreeUserEntitlementAsync(productId, winrt::hstring(), winrt::hstring()).get();

if (entitlementResult.Status() == GetEntitlementStatus::NoStoreAccount)
{
AICLI_LOG(CLI, Info, << "Get device entitlement.");
result = installManager.GetFreeDeviceEntitlementAsync(productId, winrt::hstring(), winrt::hstring()).get();
AICLI_LOG(CLI, Info, << "Get device entitlement (no store account).");
result = EntitlementType::Device;
entitlementResult = installManager.GetFreeDeviceEntitlementAsync(productId, winrt::hstring(), winrt::hstring()).get();
}
}

if (result.Status() == GetEntitlementStatus::Succeeded)
if (entitlementResult.Status() == GetEntitlementStatus::Succeeded)
{
context.Reporter.Info() << Resource::String::MSStoreInstallGetEntitlementSuccess << std::endl;
AICLI_LOG(CLI, Info, << "Get entitlement succeeded.");
}
else if (result.Status() == GetEntitlementStatus::NetworkError)
{
context.Reporter.Info() << Resource::String::MSStoreInstallGetEntitlementNetworkError << std::endl;
AICLI_LOG(CLI, Error, << "Get entitlement failed. Network error.");
}
else if (result.Status() == GetEntitlementStatus::ServerError)
else
{
context.Reporter.Info() << Resource::String::MSStoreInstallGetEntitlementServerError << std::endl;
AICLI_LOG(CLI, Error, << "Get entitlement failed Server error. ProductId: " << Utility::ConvertToUTF8(productId));
result = EntitlementType::None;

if (entitlementResult.Status() == GetEntitlementStatus::NetworkError)
{
AICLI_LOG(CLI, Error, << "Get entitlement failed. Network error.");
}
else if (entitlementResult.Status() == GetEntitlementStatus::ServerError)
{
AICLI_LOG(CLI, Error, << "Get entitlement failed. Server error.");
}
else
{
AICLI_LOG(CLI, Error, << "Get entitlement failed. Unknown status: " << static_cast<int32_t>(entitlementResult.Status()));
}
}

return result.Status() == GetEntitlementStatus::Succeeded;
return result;
}
}

Expand All @@ -135,11 +156,8 @@ namespace AppInstaller::CLI::Workflow
{
auto productId = Utility::ConvertToUTF16(context.Get<Execution::Data::Installer>()->ProductId);

// Verifying/Acquiring product ownership
if (!GetFreeEntitlement(context, productId))
{
AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED);
}
// Best effort verifying/acquiring product ownership.
std::ignore = EnsureFreeEntitlement(context, productId);

AppInstallManager installManager;
AppInstallOptions installOptions;
Expand Down Expand Up @@ -184,7 +202,7 @@ namespace AppInstaller::CLI::Workflow
else
{
auto errorCodeString = GetErrorCodeString(errorCode);
context.Reporter.Info() << Resource::String::MSStoreInstallOrUpdateFailed(errorCodeString) << std::endl;
context.Reporter.Error() << Resource::String::MSStoreInstallOrUpdateFailed(errorCodeString) << std::endl;
context.Add<Execution::Data::OperationReturnCode>(errorCode);
AICLI_LOG(CLI, Error, << "MSStore install failed. ProductId: " << Utility::ConvertToUTF8(productId) << " HResult: " << errorCodeString);
AICLI_TERMINATE_CONTEXT(errorCode);
Expand All @@ -195,11 +213,8 @@ namespace AppInstaller::CLI::Workflow
{
auto productId = Utility::ConvertToUTF16(context.Get<Execution::Data::Installer>()->ProductId);

// Verifying/Acquiring product ownership
if (!GetFreeEntitlement(context, productId))
{
AICLI_TERMINATE_CONTEXT(APPINSTALLER_CLI_ERROR_MSSTORE_INSTALL_FAILED);
}
// Best effort verifying/acquiring product ownership.
std::ignore = EnsureFreeEntitlement(context, productId);

AppInstallManager installManager;
AppUpdateOptions updateOptions;
Expand Down
12 changes: 0 additions & 12 deletions src/AppInstallerCLIPackage/Shared/Strings/en-us/winget.resw
Original file line number Diff line number Diff line change
Expand Up @@ -386,18 +386,6 @@ They can be configured through the settings file 'winget settings'.</value>
<value>Failed to install or upgrade Microsoft Store package. Error code: {0}</value>
<comment>{Locked="{0}"} Error message displayed when a Microsoft Store application package fails to install or upgrade. {0} is a placeholder replaced by an error code.</comment>
</data>
<data name="MSStoreInstallGetEntitlementNetworkError" xml:space="preserve">
<value>Verifying/Requesting package acquisition failed: network error</value>
</data>
<data name="MSStoreInstallGetEntitlementNoStoreAccount" xml:space="preserve">
<value>Verifying/Requesting package acquisition failed: no store account found</value>
</data>
<data name="MSStoreInstallGetEntitlementServerError" xml:space="preserve">
<value>Verifying/Requesting package acquisition failed: server error</value>
</data>
<data name="MSStoreInstallGetEntitlementSuccess" xml:space="preserve">
<value>Verifying/Requesting package acquisition success</value>
</data>
<data name="MSStoreStoreClientBlocked" xml:space="preserve">
<value>Failed to install or upgrade Microsoft Store package because Microsoft Store client is blocked by policy</value>
</data>
Expand Down

0 comments on commit ffab94e

Please sign in to comment.