Bug 39711964: WinAppSDK: DeploymentManager doesn't handle ERROR_INSUFFICIENT_BUFFER (#2548)

* Bug 39711964: WinAppSDK: DeploymentManager doesn't handle ERROR_INSUFFICIENT_BUFFER

* Forgot to remove the original (bugged) line

* Fix Breakaway support

* Remove PROC_THREAD_ATTRIBUTE_HANDLE_LIST. The code was derived from AppLifecycleAgent but UpdateProcThread(PROC_THREAD_ATTRIBUTE_HANDLE_LIST, size=0, list=null) error'd. We don't actually need a list of handles (unlike AppLifecycleAgent was passing a list) so we can remove this attribute
This commit is contained in:
Howard Kapustein 2022-05-24 14:42:28 -07:00 коммит произвёл GitHub
Родитель d74db76e55
Коммит 091d8fd5ae
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 16 добавлений и 22 удалений

Просмотреть файл

@ -300,7 +300,7 @@ namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implem
CATCH_RETURN()
std::wstring DeploymentManager::GenerateDeploymentAgentPath()
std::wstring DeploymentManager::GenerateDeploymentAgentPath()
{
// Calculate the path to the restart agent as being in the same directory as the current module.
wil::unique_hmodule module;
@ -310,7 +310,8 @@ namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implem
return modulePath.parent_path() / c_deploymentAgentFilename;
}
HRESULT DeploymentManager::AddPackageInBreakAwayProcess(const std::filesystem::path& packagePath, const bool forceDeployment) try
/// @warning This function is ONLY for processes with package identity. It's the caller's responsibility to ensure this.
HRESULT DeploymentManager::AddPackageInBreakAwayProcess(const std::filesystem::path& packagePath, const bool forceDeployment) try
{
auto exePath{ GenerateDeploymentAgentPath() };
auto activityId{ winrt::to_hstring(*::WindowsAppRuntime::Deployment::Activity::Context::Get().GetActivity().Id()) };
@ -321,28 +322,21 @@ namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implem
SIZE_T attributeListSize{};
auto attributeCount{ 1 };
if (AppModel::Identity::IsPackagedProcess())
{
// Packaged scenarios have an additional attribute.
attributeCount++;
}
THROW_IF_WIN32_BOOL_FALSE(InitializeProcThreadAttributeList(nullptr, attributeCount, 0, &attributeListSize));
PPROC_THREAD_ATTRIBUTE_LIST attributeList = reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(new BYTE[attributeListSize]);
// attributeCount is always >0 so we need to allocate a buffer. Call InitializeProcThreadAttributeList()
// to determine the size needed so we always expect ERROR_INSUFFICIENT_BUFFER.
THROW_HR_IF(E_UNEXPECTED, !!InitializeProcThreadAttributeList(nullptr, attributeCount, 0, &attributeListSize));
const auto lastError{ GetLastError() };
THROW_HR_IF(HRESULT_FROM_WIN32(lastError), lastError != ERROR_INSUFFICIENT_BUFFER);
wistd::unique_ptr<BYTE[]> attributeListBuffer{ new BYTE[attributeListSize] };
auto attributeList{ reinterpret_cast<PPROC_THREAD_ATTRIBUTE_LIST>(attributeListBuffer.get()) };
THROW_IF_WIN32_BOOL_FALSE(InitializeProcThreadAttributeList(attributeList, attributeCount, 0, &attributeListSize));
auto freeAttributeList{ wil::scope_exit([&] { DeleteProcThreadAttributeList(attributeList); }) };
// Launch the deployment agent
THROW_IF_WIN32_BOOL_FALSE(UpdateProcThreadAttribute(attributeList, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, nullptr, 0, nullptr, nullptr));
if (AppModel::Identity::IsPackagedProcess())
{
// Desktop Bridge applications by default have their child processes break away from the parent process. In order to recreate the calling process'
// environment correctly, this code must prevent child breakaway semantics when calling the agent. Additionally the agent must do the same when
// restarting the caller.
DWORD policy{ PROCESS_CREATION_DESKTOP_APP_BREAKAWAY_OVERRIDE };
THROW_IF_WIN32_BOOL_FALSE(UpdateProcThreadAttribute(attributeList, 0, PROC_THREAD_ATTRIBUTE_DESKTOP_APP_POLICY, &policy, sizeof(policy), nullptr, nullptr));
}
// Desktop Bridge applications by default have their child processes break away from the parent process.
// In order to recreate the calling process' environment correctly, we must prevent child breakaway semantics
// when calling the agent. Additionally the agent must do the same when restarting the caller.
DWORD policy{ PROCESS_CREATION_DESKTOP_APP_BREAKAWAY_OVERRIDE };
THROW_IF_WIN32_BOOL_FALSE(UpdateProcThreadAttribute(attributeList, 0, PROC_THREAD_ATTRIBUTE_DESKTOP_APP_POLICY, &policy, sizeof(policy), nullptr, nullptr));
STARTUPINFOEX info{};
info.StartupInfo.cb = sizeof(info);
@ -366,7 +360,7 @@ namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implem
return S_OK;
}
CATCH_RETURN()
// Deploys all of the packages carried by the specified framework.
HRESULT DeploymentManager::Deploy(const std::wstring& frameworkPackageFullName, const bool forceDeployment) try
{