Skip to content

Commit

Permalink
DynamicDependencies: Use Win11 APIs if available (microsoft#3704)
Browse files Browse the repository at this point in the history
DynamicDependencies: Use Win11 APIs if available

Leverage the Win11 Dynamic Dependency API if available, otherwise use WinAppSDK's implementation (aka polyfill). The WinAppSDK DynDep C API handles this, thus benefiting all callers of WinAppSDK's C and WinRT DynDep API (e.g. C# via projections).

This happens on Win11 >= 22H2 (aka SV2).

NOTE: This makes the DDLM irrelevant on Win11 22H2+ (>SV2). A future (separate) PR will change the intaller to not install the DDLM packages on these systems.

*NOTE:* Persisted definitions aren't imported into the OS after OSupgrade to Win11 22H2+. If you create a persisted definition (LifetimeKind=FilePath|RegistryKey) on older you'll need to re-create them after the OS upgrades.

*NOTE:* MddGetResolvedPackageFullNameForPackageDependency()'s behavior differed from GetResolvedPackageFullNameForPackageDependency(). Both return null vs package full name when the PackageDependencyId is not resolved vs resolved but the HRESULT return value differed

|PackageDependencyId|WinAppSDK                         |OS API|
|-------------------|----------------------------------|------|
|unknown            |HRESULT_FROM_WIN32(ERROR_NO_MATCH)|S_OK  |
|not resolved       |S_OK                              |S_OK  |
|resolved           |S_OK                              |S_OK  |

MddGetResolvedPackageFullNameForPackageDependency() has been changed to match the OS API. A new OS API will be needed to distinguish between a known valid PackageDependencyId that's not been resolved yet vs an invalid/unknown PackageDependencyId.

NOTE: This change is compatible with the documented behavior. It'll be noted in the release notes.

NOTE: As a byproduct of return MddGetResolvedPackageFullNameForPackageDependency() error handling the WinRT APIs `PackageDependency.GetFromId()` and `PackageDependency.GetFromIdForSystem()` no longer fail for an unknown/invalid id e.g. `PackageDependency.GetFromId("not a valid id")`. Inappropriate later use will fail e.g.

```
var pd = PackageDependency.GetFromId("not a valid id");
var context = pd.Add();
// Add() fails and throws an exception
```

NOTE: A new OS API is needed to determine if a `PackageDependencyId` is a valid (known) value. WinAppSDK will be updated to use that when available.

https://task.ms/47326537

NOTE: Did the work to support Win11 21H2 but the OS may not fully support it. Left IsSupported() unchanged (Win11 >=22H2) for now while I investigate further

P.S. Increase test timeout to 120m
  • Loading branch information
DrusTheAxe authored Nov 30, 2023
1 parent 202c9ef commit f0d6f3b
Show file tree
Hide file tree
Showing 54 changed files with 1,050 additions and 1,202 deletions.
18 changes: 0 additions & 18 deletions WindowsAppRuntime.sln
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Process.Environme
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ChangeTracker", "dev\EnvironmentManager\ChangeTracker\ChangeTracker.vcxitems", "{E15C3465-9D45-495D-92CE-B91EF45E8623}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WindowsAppRuntime_MSIXInstallFromPath", "dev\WindowsAppRuntime_MSIXInstallFromPath\WindowsAppRuntime_MSIXInstallFromPath.vcxproj", "{D45D4170-E055-4926-8B03-04DAA5F02C6C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Framework.Widgets", "test\DynamicDependency\data\Framework.Widgets\Framework.Widgets.vcxproj", "{09DDAE21-397F-4263-8561-7F2FF28127CF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DynamicDependencyLifetimeManagerShadow", "dev\DynamicDependency\DynamicDependencyLifetimeManagerShadow\DynamicDependencyLifetimeManagerShadow.vcxproj", "{6539E9E1-BF36-40E5-86BC-070E99DB7B7B}"
Expand Down Expand Up @@ -1315,20 +1313,6 @@ Global
{0B01DB78-F115-4C90-B28F-7819071303C6}.Release|x64.Build.0 = Release|x64
{0B01DB78-F115-4C90-B28F-7819071303C6}.Release|x86.ActiveCfg = Release|Win32
{0B01DB78-F115-4C90-B28F-7819071303C6}.Release|x86.Build.0 = Release|Win32
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Debug|Any CPU.ActiveCfg = Debug|Win32
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Debug|ARM64.ActiveCfg = Debug|ARM64
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Debug|ARM64.Build.0 = Debug|ARM64
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Debug|x64.ActiveCfg = Debug|x64
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Debug|x64.Build.0 = Debug|x64
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Debug|x86.ActiveCfg = Debug|Win32
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Debug|x86.Build.0 = Debug|Win32
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Release|Any CPU.ActiveCfg = Release|Win32
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Release|ARM64.ActiveCfg = Release|ARM64
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Release|ARM64.Build.0 = Release|ARM64
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Release|x64.ActiveCfg = Release|x64
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Release|x64.Build.0 = Release|x64
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Release|x86.ActiveCfg = Release|Win32
{D45D4170-E055-4926-8B03-04DAA5F02C6C}.Release|x86.Build.0 = Release|Win32
{09DDAE21-397F-4263-8561-7F2FF28127CF}.Debug|Any CPU.ActiveCfg = Debug|Win32
{09DDAE21-397F-4263-8561-7F2FF28127CF}.Debug|ARM64.ActiveCfg = Debug|ARM64
{09DDAE21-397F-4263-8561-7F2FF28127CF}.Debug|ARM64.Build.0 = Debug|ARM64
Expand Down Expand Up @@ -2470,7 +2454,6 @@ Global
{6967798A-AC07-4994-8FE9-DC9442F88E97} = {B4196B13-AB24-492E-9147-03CC7F2CAE59}
{2F3FAD1B-D3DF-4866-A3A3-C2C777D55638} = {8ABB3637-75DB-4DC3-BFB1-0933FFA4269B}
{E15C3465-9D45-495D-92CE-B91EF45E8623} = {6967798A-AC07-4994-8FE9-DC9442F88E97}
{D45D4170-E055-4926-8B03-04DAA5F02C6C} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A}
{09DDAE21-397F-4263-8561-7F2FF28127CF} = {0C534F12-B076-47E5-A05B-2A711233AC6F}
{6539E9E1-BF36-40E5-86BC-070E99DB7B7B} = {6CD01EF6-D4A4-4801-ADCF-344CF87FF942}
{4B30C685-8490-440F-9879-A75D45DAA361} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440}
Expand Down Expand Up @@ -2634,7 +2617,6 @@ Global
dev\DynamicDependency\API\DynamicDependency.vcxitems*{bf055a59-0919-4e34-9b76-dd055495cc5a}*SharedItemsImports = 9
test\inc\inc.vcxitems*{c62688a1-16a0-4729-b6ed-842f4faa29f3}*SharedItemsImports = 4
dev\AccessControl\AccessControl.vcxitems*{c91bcb93-9ed1-4acd-85f3-26f9f6ac52e3}*SharedItemsImports = 9
dev\Common\Common.vcxitems*{d45d4170-e055-4926-8b03-04daa5f02c6c}*SharedItemsImports = 4
test\inc\inc.vcxitems*{d5667df6-a151-4081-abc7-b93e8e5604ce}*SharedItemsImports = 4
dev\Deployment\Deployment.vcxitems*{db38fb4d-d04f-4c1d-93e0-f8ae259c5fd6}*SharedItemsImports = 9
dev\EnvironmentManager\ChangeTracker\ChangeTracker.vcxitems*{e15c3465-9d45-495d-92ce-b91ef45e8623}*SharedItemsImports = 9
Expand Down
4 changes: 0 additions & 4 deletions build/CopyFilesToStagingDir.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,6 @@ PublishFile $FullBuildOutput\WindowsAppRuntime_BootstrapDLL\Microsoft.WindowsApp
PublishFile $FullBuildOutput\WindowsAppRuntime_BootstrapDLL\Microsoft.WindowsAppRuntime.Bootstrap.dll $NugetDir\runtimes\win-$Platform\native
PublishFile $FullBuildOutput\WindowsAppRuntime_BootstrapDLL\Microsoft.WindowsAppRuntime.Bootstrap.pdb $NugetDir\runtimes\win10-$Platform\native
#
# Tools
PublishFile $FullBuildOutput\WindowsAppRuntime_MSIXInstallFromPath\WindowsAppRuntime_MSIXInstallFromPath.exe $NugetDir\tools\$Platform
PublishFile $FullBuildOutput\WindowsAppRuntime_MSIXInstallFromPath\WindowsAppRuntime_MSIXInstallFromPath.pdb $NugetDir\tools\$Platform
#
# WinMD for UWP apps
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.ApplicationModel.DynamicDependency.winmd $NugetDir\lib\uap10.0
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.ApplicationModel.WindowsAppRuntime.winmd $NugetDir\lib\uap10.0
Expand Down
21 changes: 16 additions & 5 deletions dev/Common/WindowsAppRuntime.VersionInfo.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

#include "pch.h"
Expand All @@ -7,6 +7,8 @@

#include "WindowsAppRuntime.VersionInfo.h"

#include "MddWin11.h"

// Function prototype of the function exported by the resource DLL
// (defined later in the build pipeline so we can't #include a header from there)
STDAPI_(const void*) WindowsAppRuntime_GetVersionInfo();
Expand Down Expand Up @@ -115,11 +117,20 @@ STDAPI WindowsAppRuntime_VersionInfo_TestInitialize(
PCWSTR frameworkPackageFamilyName,
PCWSTR mainPackageFamilyName) noexcept try
{
// Both or neither must be valued
// Verify parameters
const bool frameworkPackageFamilyNameIsEmpty{ !frameworkPackageFamilyName || (*frameworkPackageFamilyName == L'0') };
const bool mainPackageFamilyNameIsEmpty{ !mainPackageFamilyName || (*mainPackageFamilyName == L'0') };
FAIL_FAST_HR_IF(E_UNEXPECTED, frameworkPackageFamilyNameIsEmpty && !mainPackageFamilyNameIsEmpty);
FAIL_FAST_HR_IF(E_UNEXPECTED, !frameworkPackageFamilyNameIsEmpty && mainPackageFamilyNameIsEmpty);
if (MddCore::Win11::IsSupported())
{
// Framework is optional but Main is never specified
FAIL_FAST_HR_IF(E_UNEXPECTED, !mainPackageFamilyNameIsEmpty);
}
else
{
// Both or neither must be valued
FAIL_FAST_HR_IF(E_UNEXPECTED, frameworkPackageFamilyNameIsEmpty && !mainPackageFamilyNameIsEmpty);
FAIL_FAST_HR_IF(E_UNEXPECTED, !frameworkPackageFamilyNameIsEmpty && mainPackageFamilyNameIsEmpty);
}

// Update our state
if (frameworkPackageFamilyNameIsEmpty)
Expand All @@ -132,7 +143,7 @@ STDAPI WindowsAppRuntime_VersionInfo_TestInitialize(
{
// Initialize test support
g_test_frameworkPackageFamilyName = frameworkPackageFamilyName;
g_test_mainPackageFamilyName = mainPackageFamilyName;
g_test_mainPackageFamilyName = (!mainPackageFamilyName ? L"" : mainPackageFamilyName);
}
return S_OK;
}
Expand Down
14 changes: 13 additions & 1 deletion dev/Common/WindowsAppRuntime.VersionInfo.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

#ifndef __MICROSFT_WINDOWSAPPRUNTIME_VERSIONINFO_H
Expand Down Expand Up @@ -68,6 +68,18 @@ inline void TestInitialize(
THROW_IF_FAILED(WindowsAppRuntime_VersionInfo_TestInitialize(frameworkPackageFamilyName, mainPackageFamilyName));
}

/// Initialize VersionInfo's test support. This will constrain package enumeration
/// and matching for test purposes.
///
/// @param frameworkPackageFamilyName only match framework packages with this family name
///
/// @note Not for product use. This is for test purposes only to verify the implementation.
inline void TestInitialize(
_In_ PCWSTR frameworkPackageFamilyName)
{
THROW_IF_FAILED(WindowsAppRuntime_VersionInfo_TestInitialize(frameworkPackageFamilyName, nullptr));
}

/// Shutdown VersionInfo's test support.
///
/// @note Not for product use. This is for test purposes only to verify the implementation.
Expand Down
1 change: 0 additions & 1 deletion dev/DynamicDependency/API/DynamicDependency.vcxitems
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
<ClCompile Include="$(MSBuildThisFileDirectory)M.AM.DD.PackageDependencyRank.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)MddDetourPackageGraph.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)MddLifetimeManagement.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)MddWin11.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)MddWinRT.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)MsixDynamicDependency.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)PackageDependency.cpp" />
Expand Down
3 changes: 0 additions & 3 deletions dev/DynamicDependency/API/DynamicDependency.vcxitems.filters
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@
<ClCompile Include="$(MSBuildThisFileDirectory)DataStore.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)MddWin11.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)MddWinRT.cpp">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down
34 changes: 26 additions & 8 deletions dev/DynamicDependency/API/M.AM.DD.PackageDependency.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

#include "pch.h"
Expand All @@ -16,6 +16,8 @@

#include <M.AM.Converters.h>

#include "MddWin11.h"

namespace winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::implementation
{
PackageDependency::PackageDependency(hstring const& id) :
Expand All @@ -25,21 +27,37 @@ namespace winrt::Microsoft::Windows::ApplicationModel::DynamicDependency::implem

winrt::PackageDependency PackageDependency::GetFromId(hstring const& id)
{
auto tokenUser{ wil::get_token_information<TOKEN_USER>(GetCurrentThreadEffectiveToken()) };
auto exists{ MddCore::PackageDependencyManager::ExistsPackageDependency(tokenUser->User.Sid, id.c_str()) };
if (!exists)
// Use the Win11 APIs if available (instead of Detour'ing to our own implementation)
if (MddCore::Win11::IsSupported())
{
//TODO:47775758 GetResolved2 GetPackageDependencyInfo2(userSid, id.c_str(), &packageDependencyInfo)
}
else
{
return nullptr;
auto tokenUser{ wil::get_token_information<TOKEN_USER>(GetCurrentThreadEffectiveToken()) };
auto exists{ MddCore::PackageDependencyManager::ExistsPackageDependency(tokenUser->User.Sid, id.c_str()) };
if (!exists)
{
return nullptr;
}
}
return winrt::make<implementation::PackageDependency>(id);
}

winrt::PackageDependency PackageDependency::GetFromIdForSystem(hstring const& id)
{
auto exists{ MddCore::PackageDependencyManager::ExistsPackageDependency(nullptr, id.c_str()) };
if (!exists)
// Use the Win11 APIs if available (instead of Detour'ing to our own implementation)
if (MddCore::Win11::IsSupported())
{
//TODO:47775758 GetResolved2 GetPackageDependencyInfo2(userSid, id.c_str(), &packageDependencyInfo)
}
else
{
return nullptr;
auto exists{ MddCore::PackageDependencyManager::ExistsPackageDependency(nullptr, id.c_str()) };
if (!exists)
{
return nullptr;
}
}
return winrt::make<implementation::PackageDependency>(id);
}
Expand Down
18 changes: 17 additions & 1 deletion dev/DynamicDependency/API/MddDetourPackageGraph.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation and Contributors.
// Copyright (c) Microsoft Corporation and Contributors.
// Licensed under the MIT License.

#include "pch.h"
Expand All @@ -9,6 +9,8 @@

#include "PackageGraphManager.h"

#include "MddWin11.h"

#include <../Detours/detours.h>

// Windows provides HRESULT_FROM_WIN32() but not the reverse. We need that for compat reasons.
Expand Down Expand Up @@ -110,6 +112,13 @@ typedef UINT32 (WINAPI* GetPackageGraphRevisionIdFunction)();

HRESULT WINAPI MddDetourPackageGraphInitialize() noexcept
{
// Use the Win11 APIs if available (instead of Detour'ing to our own implementation)
if (MddCore::Win11::IsSupported())
{
RETURN_IF_FAILED(MddWin11Initialize());
return S_OK;
}

// Detour package graph APIs to our implementation
FAIL_FAST_IF_WIN32_ERROR(DetourUpdateThread(GetCurrentThread()));
FAIL_FAST_IF_WIN32_ERROR(DetourAttach(&(PVOID&)TrueGetCurrentPackageInfo, DynamicGetCurrentPackageInfo));
Expand Down Expand Up @@ -160,6 +169,13 @@ HRESULT WINAPI MddDetourPackageGraphInitialize() noexcept

HRESULT _MddDetourPackageGraphShutdown() noexcept
{
// Use the Win11 APIs if available (instead of Detour'ing to our own implementation)
if (MddCore::Win11::IsSupported())
{
MddWin11Shutdown();
return S_OK;
}

// Stop Detour'ing package graph APIs to our implementation (undo in reverse order we started Detour'ing APIs)
if (TrueGetPackageGraphRevisionId)
{
Expand Down
Loading

0 comments on commit f0d6f3b

Please sign in to comment.