diff --git a/BuildAll.ps1 b/BuildAll.ps1
index 2549f2467b..a883e697b5 100644
--- a/BuildAll.ps1
+++ b/BuildAll.ps1
@@ -277,14 +277,19 @@ Try {
Copy-Item -Path "$nuSpecsPath\WindowsAppSDK-Nuget-Native.props" -Destination "$BasePath\build\native\Microsoft.WindowsAppSDK.Foundation.props"
Copy-Item -Path "$nuSpecsPath\WindowsAppSDK-Nuget-Native.C.props" -Destination "$BasePath\build\native"
Copy-Item -Path "$nuSpecsPath\WindowsAppSDK-Nuget-Native.WinRt.props" -Destination "$BasePath\build\native"
+ Copy-Item -Path "$nuSpecsPath\WindowsAppSDK-Nuget-Native.AutoInitializer.targets" -Destination "$BasePath\build\native"
Copy-Item -Path "$nuSpecsPath\WindowsAppSDK-Nuget-Native.Bootstrap.targets" -Destination "$BasePath\build\native"
+ Copy-Item -Path "$nuSpecsPath\WindowsAppSDK-Nuget-Native.CompatibilitySetter.targets" -Destination "$BasePath\build\native"
Copy-Item -Path "$nuSpecsPath\WindowsAppSDK-Nuget-Native.DeploymentManager.targets" -Destination "$BasePath\build\native"
Copy-Item -Path "$nuSpecsPath\WindowsAppSDK-Nuget-Native.UndockedRegFreeWinRT.targets" -Destination "$BasePath\build\native"
Copy-Item -Path "$nuSpecsPath\Microsoft.WindowsAppSDK.Foundation.targets" -Destination "$BasePath\build"
Copy-Item -Path "$nuSpecsPath\Microsoft.WindowsAppSDK.Foundation.props" -Destination "$BasePath\build"
+ Copy-Item -Path "$nuSpecsPath\Microsoft.WindowsAppSDK.AutoInitializer.CS.targets" -Destination "$BasePath\build"
+ Copy-Item -Path "$nuSpecsPath\Microsoft.WindowsAppSDK.AutoInitializerCommon.targets" -Destination "$BasePath\build"
Copy-Item -Path "$nuSpecsPath\Microsoft.WindowsAppSDK.Bootstrap.CS.targets" -Destination "$BasePath\build"
Copy-Item -Path "$nuSpecsPath\Microsoft.WindowsAppSDK.BootstrapCommon.targets" -Destination "$BasePath\build"
+ Copy-Item -Path "$nuSpecsPath\Microsoft.WindowsAppSDK.CompatibilitySetter.CS.targets" -Destination "$BasePath\build"
Copy-Item -Path "$nuSpecsPath\Microsoft.WindowsAppSDK.DeploymentManager.CS.targets" -Destination "$BasePath\build"
Copy-Item -Path "$nuSpecsPath\Microsoft.WindowsAppSDK.DeploymentManagerCommon.targets" -Destination "$BasePath\build"
Copy-Item -Path "$nuSpecsPath\Microsoft.WindowsAppSDK.UndockedRegFreeWinRT.CS.targets" -Destination "$BasePath\build"
diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln
index 7fe4f2a978..cd77601b04 100644
--- a/WindowsAppRuntime.sln
+++ b/WindowsAppRuntime.sln
@@ -566,6 +566,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IXP", "IXP", "{7B323048-439
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IXP.TransportPackage.PackageReference", "eng\PackageReference\IXP\IXP.TransportPackage.PackageReference.csproj", "{A949149D-29CA-4AA7-B1ED-0E571B4AD9BB}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BackgroundTaskTests", "test\BackgroundTaskTests\BackgroundTaskTests.vcxproj", "{69FC8020-7E15-46EA-BE4A-767AAFC9C715}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B73AD907-6164-4294-88FB-F3C9C10DA1F1} = {B73AD907-6164-4294-88FB-F3C9C10DA1F1}
+ EndProjectSection
+EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Notifications", "Notifications", "{43FE6980-3E16-4EF9-A3DE-29B402FB4FAB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BaseNotifications", "BaseNotifications", "{586EA218-74C8-420B-B47E-0B307AA4B82D}"
@@ -577,10 +582,34 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BaseNotifications", "dev\Notifications\BaseNotifications\BaseNotifications.vcxitems", "{2BD7A1BB-D3D8-484F-9180-409D781DCCF9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.BadgeNotifications.Projection", "dev\Projections\CS\Microsoft.Windows.BadgeNotifications.Projection\Microsoft.Windows.BadgeNotifications.Projection.csproj", "{A243A58D-ABD7-4520-8C71-F492247B7B92}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CompatibilityOptions", "dev\CompatibilityOptions\CompatibilityOptions.vcxitems", "{1F7B9E9F-9987-490B-9E6E-093C7F63FEC4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CompatibilityOptions", "CompatibilityOptions", "{35972D8A-F47E-4875-A341-E8C25DB7A098}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CompatibilityTests", "test\Compatibility\CompatibilityTests\CompatibilityTests.vcxproj", "{040BB64B-012E-4E4F-BB02-E85EF46D3475}"
+ ProjectSection(ProjectDependencies) = postProject
+ {F76B776E-86F5-48C5-8FC7-D2795ECC9746} = {F76B776E-86F5-48C5-8FC7-D2795ECC9746}
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Compatibility", "Compatibility", "{423E7BAC-0125-46F4-944D-E8F138B3C654}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test_CompatibilitySetter_CPP", "test\Compatibility\Test_CompatibilitySetter_CPP\Test_CompatibilitySetter_CPP.vcxproj", "{7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test_CompatibilitySetter_CS", "test\Compatibility\Test_CompatibilitySetter_CS\Test_CompatibilitySetter_CS.csproj", "{42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OAuthTestApp", "test\TestApps\OAuthTestApp\OAuthTestApp.vcxproj", "{4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}"
+EndProject
+Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "OAuthTestAppPackage", "test\TestApps\OAuthTestAppPackage\OAuthTestAppPackage.wapproj", "{455C01F8-0A3E-42C4-9F22-13992EB909EC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OAuth2ManagerTests", "test\OAuth2ManagerTests\OAuth2ManagerTests.vcxproj", "{0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.Storage.Pickers.Projection", "dev\Projections\CS\Microsoft.Windows.Storage.Pickers.Projection\Microsoft.Windows.Storage.Pickers.Projection.csproj", "{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "dev\Interop\StoragePickers\StoragePickers.vcxitems", "{A39E7B2F-5F67-47DD-8443-531D095CA7F3}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickersTests", "test\StoragePickersTests\StoragePickersTests.vcxproj", "{85C86306-46D1-4563-8303-0A79DF923586}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -2017,6 +2046,22 @@ Global
{A949149D-29CA-4AA7-B1ED-0E571B4AD9BB}.Release|x64.Build.0 = Release|x64
{A949149D-29CA-4AA7-B1ED-0E571B4AD9BB}.Release|x86.ActiveCfg = Release|x86
{A949149D-29CA-4AA7-B1ED-0E571B4AD9BB}.Release|x86.Build.0 = Release|x86
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Debug|Any CPU.Build.0 = Debug|x64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Debug|ARM64.Build.0 = Debug|ARM64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Debug|x64.ActiveCfg = Debug|x64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Debug|x64.Build.0 = Debug|x64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Debug|x86.ActiveCfg = Debug|Win32
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Debug|x86.Build.0 = Debug|Win32
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Release|Any CPU.ActiveCfg = Release|x64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Release|Any CPU.Build.0 = Release|x64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Release|ARM64.ActiveCfg = Release|ARM64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Release|ARM64.Build.0 = Release|ARM64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Release|x64.ActiveCfg = Release|x64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Release|x64.Build.0 = Release|x64
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Release|x86.ActiveCfg = Release|Win32
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}.Release|x86.Build.0 = Release|Win32
{A243A58D-ABD7-4520-8C71-F492247B7B92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A243A58D-ABD7-4520-8C71-F492247B7B92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A243A58D-ABD7-4520-8C71-F492247B7B92}.Debug|ARM64.ActiveCfg = Debug|Any CPU
@@ -2033,6 +2078,110 @@ Global
{A243A58D-ABD7-4520-8C71-F492247B7B92}.Release|x64.Build.0 = Release|Any CPU
{A243A58D-ABD7-4520-8C71-F492247B7B92}.Release|x86.ActiveCfg = Release|Any CPU
{A243A58D-ABD7-4520-8C71-F492247B7B92}.Release|x86.Build.0 = Release|Any CPU
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|Any CPU.Build.0 = Debug|x64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|ARM64.Build.0 = Debug|ARM64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x64.ActiveCfg = Debug|x64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x64.Build.0 = Debug|x64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x86.ActiveCfg = Debug|Win32
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x86.Build.0 = Debug|Win32
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|Any CPU.ActiveCfg = Release|x64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|Any CPU.Build.0 = Release|x64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|ARM64.ActiveCfg = Release|ARM64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|ARM64.Build.0 = Release|ARM64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x64.ActiveCfg = Release|x64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x64.Build.0 = Release|x64
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x86.ActiveCfg = Release|Win32
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x86.Build.0 = Release|Win32
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|Any CPU.Build.0 = Debug|x64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|ARM64.Build.0 = Debug|ARM64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x64.ActiveCfg = Debug|x64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x64.Build.0 = Debug|x64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x86.ActiveCfg = Debug|Win32
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x86.Build.0 = Debug|Win32
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|Any CPU.ActiveCfg = Release|x64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|Any CPU.Build.0 = Release|x64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|ARM64.ActiveCfg = Release|ARM64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|ARM64.Build.0 = Release|ARM64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x64.ActiveCfg = Release|x64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x64.Build.0 = Release|x64
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x86.ActiveCfg = Release|Win32
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x86.Build.0 = Release|Win32
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|ARM64.Build.0 = Debug|ARM64
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x64.ActiveCfg = Debug|x64
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x64.Build.0 = Debug|x64
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x86.ActiveCfg = Debug|x86
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x86.Build.0 = Debug|x86
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|ARM64.ActiveCfg = Release|ARM64
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|ARM64.Build.0 = Release|ARM64
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x64.ActiveCfg = Release|x64
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x64.Build.0 = Release|x64
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x86.ActiveCfg = Release|x86
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x86.Build.0 = Release|x86
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Debug|Any CPU.Build.0 = Debug|x64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Debug|ARM64.ActiveCfg = Debug|x64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Debug|ARM64.Build.0 = Debug|x64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Debug|x64.ActiveCfg = Debug|x64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Debug|x64.Build.0 = Debug|x64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Debug|x86.ActiveCfg = Debug|Win32
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Debug|x86.Build.0 = Debug|Win32
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Release|Any CPU.ActiveCfg = Release|x64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Release|Any CPU.Build.0 = Release|x64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Release|ARM64.ActiveCfg = Release|ARM64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Release|ARM64.Build.0 = Release|ARM64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Release|x64.ActiveCfg = Release|x64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Release|x64.Build.0 = Release|x64
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Release|x86.ActiveCfg = Release|Win32
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Release|x86.Build.0 = Release|Win32
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|ARM64.Build.0 = Debug|ARM64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|x64.ActiveCfg = Debug|x64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|x64.Build.0 = Debug|x64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|x64.Deploy.0 = Debug|x64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|x86.ActiveCfg = Debug|x86
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|x86.Build.0 = Debug|x86
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Debug|x86.Deploy.0 = Debug|x86
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|ARM64.ActiveCfg = Release|ARM64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|ARM64.Build.0 = Release|ARM64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|ARM64.Deploy.0 = Release|ARM64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|x64.ActiveCfg = Release|x64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|x64.Build.0 = Release|x64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|x64.Deploy.0 = Release|x64
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|x86.ActiveCfg = Release|x86
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|x86.Build.0 = Release|x86
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC}.Release|x86.Deploy.0 = Release|x86
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Debug|Any CPU.Build.0 = Debug|x64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Debug|ARM64.ActiveCfg = Debug|x64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Debug|ARM64.Build.0 = Debug|x64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Debug|x64.ActiveCfg = Debug|x64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Debug|x64.Build.0 = Debug|x64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Debug|x86.ActiveCfg = Debug|Win32
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Debug|x86.Build.0 = Debug|Win32
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Release|Any CPU.ActiveCfg = Release|x64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Release|Any CPU.Build.0 = Release|x64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Release|ARM64.ActiveCfg = Release|ARM64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Release|ARM64.Build.0 = Release|ARM64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Release|x64.ActiveCfg = Release|x64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Release|x64.Build.0 = Release|x64
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Release|x86.ActiveCfg = Release|Win32
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Release|x86.Build.0 = Release|Win32
{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|Any CPU.ActiveCfg = Debug|x64
{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|Any CPU.Build.0 = Debug|x64
{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|ARM64.ActiveCfg = Debug|arm64
@@ -2049,6 +2198,22 @@ Global
{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x64.Build.0 = Release|x64
{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x86.ActiveCfg = Release|x86
{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x86.Build.0 = Release|x86
+ {85C86306-46D1-4563-8303-0A79DF923586}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Debug|Any CPU.Build.0 = Debug|x64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Debug|ARM64.Build.0 = Debug|ARM64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x64.ActiveCfg = Debug|x64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x64.Build.0 = Debug|x64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x86.ActiveCfg = Debug|Win32
+ {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x86.Build.0 = Debug|Win32
+ {85C86306-46D1-4563-8303-0A79DF923586}.Release|Any CPU.ActiveCfg = Release|x64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Release|Any CPU.Build.0 = Release|x64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Release|ARM64.ActiveCfg = Release|ARM64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Release|ARM64.Build.0 = Release|ARM64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Release|x64.ActiveCfg = Release|x64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Release|x64.Build.0 = Release|x64
+ {85C86306-46D1-4563-8303-0A79DF923586}.Release|x86.ActiveCfg = Release|Win32
+ {85C86306-46D1-4563-8303-0A79DF923586}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2228,21 +2393,34 @@ Global
{D5958784-4518-44F1-A518-80514B380ED5} = {E24C263A-DE3E-4844-BA50-842DA5AD7A49}
{7B323048-439F-47E9-A3D4-7342C5ADE2A5} = {5C88AE1D-AC20-4A41-9299-1EEA15B80724}
{A949149D-29CA-4AA7-B1ED-0E571B4AD9BB} = {7B323048-439F-47E9-A3D4-7342C5ADE2A5}
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
{43FE6980-3E16-4EF9-A3DE-29B402FB4FAB} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A}
{586EA218-74C8-420B-B47E-0B307AA4B82D} = {43FE6980-3E16-4EF9-A3DE-29B402FB4FAB}
{50205ED9-0E08-4878-B124-9AC0EBA138D6} = {43FE6980-3E16-4EF9-A3DE-29B402FB4FAB}
{85D111C7-B720-4E19-A56D-03C87B953983} = {50205ED9-0E08-4878-B124-9AC0EBA138D6}
{2BD7A1BB-D3D8-484F-9180-409D781DCCF9} = {586EA218-74C8-420B-B47E-0B307AA4B82D}
{A243A58D-ABD7-4520-8C71-F492247B7B92} = {716C26A0-E6B0-4981-8412-D14A4D410531}
+ {1F7B9E9F-9987-490B-9E6E-093C7F63FEC4} = {35972D8A-F47E-4875-A341-E8C25DB7A098}
+ {35972D8A-F47E-4875-A341-E8C25DB7A098} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A}
+ {040BB64B-012E-4E4F-BB02-E85EF46D3475} = {423E7BAC-0125-46F4-944D-E8F138B3C654}
+ {423E7BAC-0125-46F4-944D-E8F138B3C654} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
+ {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA} = {423E7BAC-0125-46F4-944D-E8F138B3C654}
+ {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9} = {423E7BAC-0125-46F4-944D-E8F138B3C654}
+ {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440}
+ {455C01F8-0A3E-42C4-9F22-13992EB909EC} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440}
+ {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
{8E01AA4F-A16A-4E3F-A59F-6D49422B4410} = {716C26A0-E6B0-4981-8412-D14A4D410531}
{A39E7B2F-5F67-47DD-8443-531D095CA7F3} = {3B706C5C-55E0-4B76-BF59-89E20FE46795}
+ {85C86306-46D1-4563-8303-0A79DF923586} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
test\inc\inc.vcxitems*{08bc78e0-63c6-49a7-81b3-6afc3deac4de}*SharedItemsImports = 4
+ test\inc\inc.vcxitems*{0ff6a68f-6c7f-4e66-8cb8-c0b9501060ca}*SharedItemsImports = 4
dev\PushNotifications\PushNotifications.vcxitems*{103c0c23-7ba8-4d44-a63c-83488e2e3a81}*SharedItemsImports = 9
+ dev\CompatibilityOptions\CompatibilityOptions.vcxitems*{1f7b9e9f-9987-490b-9e6e-093c7f63fec4}*SharedItemsImports = 9
dev\Notifications\BaseNotifications\BaseNotifications.vcxitems*{2bd7a1bb-d3d8-484f-9180-409d781dccf9}*SharedItemsImports = 9
dev\EnvironmentManager\API\Microsoft.Process.Environment.vcxitems*{2f3fad1b-d3df-4866-a3a3-c2c777d55638}*SharedItemsImports = 9
dev\OAuth\OAuth.vcxitems*{3e7fd510-8b66-40e7-a80b-780cb8972f83}*SharedItemsImports = 9
@@ -2266,6 +2444,7 @@ Global
dev\ApplicationData\ApplicationData.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
dev\BackgroundTask\BackgroundTaskBuilder\BackgroundTaskBuilder.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
dev\Common\Common.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
+ dev\CompatibilityOptions\CompatibilityOptions.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
dev\DynamicDependency\API\DynamicDependency.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
dev\Licensing\Licensing.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
dev\PackageManager\API\PackageManager.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4
diff --git a/build/AzurePipelinesTemplates/WindowsAppSDK-SetupBuildEnvironment-Steps.yml b/build/AzurePipelinesTemplates/WindowsAppSDK-SetupBuildEnvironment-Steps.yml
index 12f9ef0e1c..f085304fc5 100644
--- a/build/AzurePipelinesTemplates/WindowsAppSDK-SetupBuildEnvironment-Steps.yml
+++ b/build/AzurePipelinesTemplates/WindowsAppSDK-SetupBuildEnvironment-Steps.yml
@@ -195,6 +195,14 @@ steps:
arguments: -Path $(Build.SourcesDirectory)\dev\common\TerminalVelocityFeatures-OAuth.xml -Channel $(channel) -Language C++ -Namespace Microsoft.Security.Authentication.OAuth -Output $(Build.SourcesDirectory)\dev\common\TerminalVelocityFeatures-OAuth.h
workingDirectory: '$(Build.SourcesDirectory)'
+- task: powershell@2
+ displayName: 'Create CompatibilityOptions TerminalVelocity features'
+ inputs:
+ targetType: filePath
+ filePath: tools\TerminalVelocity\Generate-TerminalVelocityFeatures.ps1
+ arguments: -Path $(Build.SourcesDirectory)\dev\common\TerminalVelocityFeatures-CompatibilityOptions.xml -Channel $(channel) -Language C++ -Namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime -Output $(Build.SourcesDirectory)\dev\common\TerminalVelocityFeatures-CompatibilityOptions.h
+ workingDirectory: '$(Build.SourcesDirectory)'
+
- task: powershell@2
name: UpdateTraceloggingConfig
inputs:
diff --git a/build/CopyFilesToStagingDir.ps1 b/build/CopyFilesToStagingDir.ps1
index 0ba84a2ba8..ff06bddcd2 100644
--- a/build/CopyFilesToStagingDir.ps1
+++ b/build/CopyFilesToStagingDir.ps1
@@ -216,6 +216,10 @@ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windo
PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.System.winmd $NugetDir\lib\uap10.0
PublishFile $FullBuildOutput\WindowsAppRuntime_UniversalBGTaskDLL\Microsoft.Windows.ApplicationModel.Background.UniversalBGTask.winmd $NugetDir\lib\uap10.0
#
+# Common Auto-Initializer Files
+PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\WindowsAppRuntimeAutoInitializer.cpp $NugetDir\include
+PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\WindowsAppRuntimeAutoInitializer.cs $NugetDir\include
+#
# Bootstrap Auto-Initializer Files
PublishFile $FullBuildOutput\WindowsAppRuntime_BootstrapDLL\MddBootstrapAutoInitializer.cpp $NugetDir\include
PublishFile $FullBuildOutput\WindowsAppRuntime_BootstrapDLL\MddBootstrapAutoInitializer.cs $NugetDir\include
diff --git a/build/NuSpecs/AppxManifest.xml b/build/NuSpecs/AppxManifest.xml
index b2d7d2621e..7e2fc37af6 100644
--- a/build/NuSpecs/AppxManifest.xml
+++ b/build/NuSpecs/AppxManifest.xml
@@ -115,6 +115,9 @@
+
+
+
diff --git a/build/NuSpecs/Microsoft.WindowsAppSDK.AutoInitializer.CS.targets b/build/NuSpecs/Microsoft.WindowsAppSDK.AutoInitializer.CS.targets
new file mode 100644
index 0000000000..309ac6058e
--- /dev/null
+++ b/build/NuSpecs/Microsoft.WindowsAppSDK.AutoInitializer.CS.targets
@@ -0,0 +1,19 @@
+
+
+
+
+
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_BOOTSTRAP
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_DEPLOYMENTMANAGER
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_UNDOCKEDREGFREEWINRT
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_COMPATIBILITY
+
+
+
+
+
+
+
+
+
+
diff --git a/build/NuSpecs/Microsoft.WindowsAppSDK.AutoInitializerCommon.targets b/build/NuSpecs/Microsoft.WindowsAppSDK.AutoInitializerCommon.targets
new file mode 100644
index 0000000000..287befbad2
--- /dev/null
+++ b/build/NuSpecs/Microsoft.WindowsAppSDK.AutoInitializerCommon.targets
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+ true
+
+
+
diff --git a/build/NuSpecs/Microsoft.WindowsAppSDK.CompatibilitySetter.CS.targets b/build/NuSpecs/Microsoft.WindowsAppSDK.CompatibilitySetter.CS.targets
new file mode 100644
index 0000000000..6c2924fc3b
--- /dev/null
+++ b/build/NuSpecs/Microsoft.WindowsAppSDK.CompatibilitySetter.CS.targets
@@ -0,0 +1,64 @@
+
+
+
+
+
+ true
+
+
+
+
+ $(GeneratedFilesDir)\WindowsAppSDK\
+ $([MSBuild]::NormalizeDirectory('$(MSBuildProjectDirectory)', '$(IntermediateOutputPath)', 'Generated Files', 'WindowsAppSDK'))
+
+ $(WindowsAppSDKGeneratedFilesDir)WindowsAppSDKCompatibilitySetter.cs
+
+ compatibilityOptions.PatchMode1 = new WindowsAppRuntimeVersion($(WindowsAppSDKRuntimePatchMode.Replace(".", ",")))%3B
+
+
+ compatibilityOptions.PatchMode2 = new WindowsAppRuntimeVersion($(WindowsAppSDKRuntimePatchMode2.Replace(".", ",")))%3B
+
+
+ $([System.Text.RegularExpressions.Regex]::Replace($(WindowsAppSDKDisabledChanges), "\s+", ""))
+
+ var disabledChangesArray = new CompatibilityChange[] { CompatibilityChange.$([System.Text.RegularExpressions.Regex]::Replace($(WindowsAppSDKCompatibilityDisabledChangesNoSpaces), ",([A-Za-z])", ", CompatibilityChange.$1")) }%3B
+ foreach (var changeId in disabledChangesArray)
+ {
+ compatibilityOptions.DisabledChanges.Add(changeId)%3B
+ }
+
+
+
+using Microsoft.Windows.ApplicationModel.WindowsAppRuntime%3B
+
+// This file is generated by the build based on project properties.
+namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime.Compatibility
+{
+ class AutoInitialize
+ {
+ // Called by WindowsAppRuntimeAutoInitializer.cs
+ internal static void ConfigureCompatibility()
+ {
+ var compatibilityOptions = new CompatibilityOptions()%3B
+$(WindowsAppSDKCompatibilityPatchMode1Lines)
+$(WindowsAppSDKCompatibilityPatchMode2Lines)
+$(WindowsAppSDKCompatibilityDisabledChangesLines)
+ compatibilityOptions.Apply()%3B
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/NuSpecs/Microsoft.WindowsAppSDK.Foundation.targets b/build/NuSpecs/Microsoft.WindowsAppSDK.Foundation.targets
index 73434d043d..3a98933c31 100644
--- a/build/NuSpecs/Microsoft.WindowsAppSDK.Foundation.targets
+++ b/build/NuSpecs/Microsoft.WindowsAppSDK.Foundation.targets
@@ -13,6 +13,11 @@
+
+
+
+
+
diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.AutoInitializer.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.AutoInitializer.targets
new file mode 100644
index 0000000000..ae3313a43a
--- /dev/null
+++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.AutoInitializer.targets
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ NotUsing
+ MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_BOOTSTRAP;%(PreprocessorDefinitions)
+ MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_DEPLOYMENTMANAGER;%(PreprocessorDefinitions)
+ MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_UNDOCKEDREGFREEWINRT;%(PreprocessorDefinitions)
+ MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_COMPATIBILITY;%(PreprocessorDefinitions)
+
+
+
+
+
+
+ $(BeforeClCompileTargets); WindowsAppRuntimeAutoInitializer;
+
+
+
+
diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets
index 573c99e2b1..c5b72d705f 100644
--- a/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets
+++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets
@@ -1,6 +1,6 @@
-
+
NotUsing
@@ -15,4 +15,10 @@
+
+
+ $(BeforeClCompileTargets); GenerateBootstrapCpp;
+
+
+
diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.CompatibilitySetter.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.CompatibilitySetter.targets
new file mode 100644
index 0000000000..845d3b2ff5
--- /dev/null
+++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.CompatibilitySetter.targets
@@ -0,0 +1,73 @@
+
+
+
+
+
+ true
+
+
+
+
+ $(GeneratedFilesDir)WindowsAppSDKCompatibilitySetter.cpp
+
+ compatibilityOptions.PatchMode1({$(WindowsAppSDKRuntimePatchMode.Replace(".", ","))})%3B
+
+
+ compatibilityOptions.PatchMode2({$(WindowsAppSDKRuntimePatchMode2.Replace(".", ","))})%3B
+
+ $([System.Text.RegularExpressions.Regex]::Replace($(WindowsAppSDKDisabledChanges), "\s+", ""))
+
+ CompatibilityChange disabledChangesArray[] = { CompatibilityChange::$([System.Text.RegularExpressions.Regex]::Replace($(WindowsAppSDKCompatibilityDisabledChangesNoSpaces), ",([A-Za-z])", ", CompatibilityChange::$1")) }%3B
+ for (auto changeId : disabledChangesArray)
+ {
+ compatibilityOptions.DisabledChanges().Append(changeId)%3B
+ }
+
+
+
+// This file is generated by the build based on project properties.
+#include <winrt/Windows.Foundation.h>
+#include <winrt/Windows.Foundation.Collections.h>
+
+#include <winrt/Microsoft.Windows.ApplicationModel.WindowsAppRuntime.h>
+
+using namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime%3B
+
+namespace Microsoft::Windows::ApplicationModel::WindowsAppRuntime::Compatibility
+{
+ namespace AutoInitialize
+ {
+ // Called by WindowsAppRuntimeAutoInitializer.cpp
+ void Initialize()
+ {
+ CompatibilityOptions compatibilityOptions%3B
+$(WindowsAppSDKCompatibilityPatchMode1Lines)
+$(WindowsAppSDKCompatibilityPatchMode2Lines)
+$(WindowsAppSDKCompatibilityDisabledChangesLines)
+ compatibilityOptions.Apply()%3B
+ }
+ }
+}
+
+
+
+
+
+
+
+ NotUsing
+
+
+
+
+
+
+ $(BeforeClCompileTargets); WindowsAppSDKCompatibilitySetterTarget;
+
+
+
+
diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.DeploymentManager.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.DeploymentManager.targets
index 159bd5a781..cfbd8687c4 100644
--- a/build/NuSpecs/WindowsAppSDK-Nuget-Native.DeploymentManager.targets
+++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.DeploymentManager.targets
@@ -1,6 +1,6 @@
-
+
NotUsing
@@ -11,4 +11,10 @@
+
+
+ $(BeforeClCompileTargets); GenerateDeploymentManagerCpp;
+
+
+
diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.UndockedRegFreeWinRT.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.UndockedRegFreeWinRT.targets
index 7e899ca1fb..10db792396 100644
--- a/build/NuSpecs/WindowsAppSDK-Nuget-Native.UndockedRegFreeWinRT.targets
+++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.UndockedRegFreeWinRT.targets
@@ -1,11 +1,16 @@
-
+
MICROSOFT_WINDOWSAPPSDK_UNDOCKEDREGFREEWINRT_AUTO_INITIALIZE;%(PreprocessorDefinitions)
MICROSOFT_WINDOWSAPPSDK_UNDOCKEDREGFREEWINRT_AUTO_INITIALIZE_LOADLIBRARY;%(PreprocessorDefinitions)
+
+
+
+
+
NotUsing
MICROSOFT_WINDOWSAPPSDK_UNDOCKEDREGFREEWINRT_AUTO_INITIALIZE;%(PreprocessorDefinitions)
@@ -14,4 +19,10 @@
+
+
+ $(BeforeClCompileTargets); GenerateUndockedRegFreeWinRTCpp;
+
+
+
diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets
index bf9cc3639e..ae295ae46f 100644
--- a/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets
+++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets
@@ -160,4 +160,9 @@
+
+
+
+
+
diff --git a/build/VersionInfo/AssemblyInfo.h b/build/VersionInfo/AssemblyInfo.h
new file mode 100644
index 0000000000..abc67be25e
--- /dev/null
+++ b/build/VersionInfo/AssemblyInfo.h
@@ -0,0 +1,14 @@
+// WARNING: the values in the AssemblyInfo file are defaults for use in dev-loop.
+// This file is meant to be overwritten by GenerateVersionInfo.ps1
+// Please modify the generation script in GenerateVersionInfo.ps1 to change any fields or values.
+
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#ifndef WINDOWSAPPSDK_RELEASE_MAJOR
+#define WINDOWSAPPSDK_RELEASE_MAJOR 1
+#endif
+
+#ifndef WINDOWSAPPSDK_RELEASE_MINOR
+#define WINDOWSAPPSDK_RELEASE_MINOR 7
+#endif
diff --git a/build/VersionInfo/GenerateVersionInfo.ps1 b/build/VersionInfo/GenerateVersionInfo.ps1
index 31bbadf45b..e2e8ec583f 100644
--- a/build/VersionInfo/GenerateVersionInfo.ps1
+++ b/build/VersionInfo/GenerateVersionInfo.ps1
@@ -1,7 +1,7 @@
# Copyright (c) Microsoft Corporation and Contributors.
# Licensed under the MIT License.
-# This scripts overrides AssemblyInfo.cs and AssemblyInfo.ver in eng/common/VersionInfo.
+# This script overrides AssemblyInfo.cs, AssemblyInfo.ver, and AssemblyInfo.h in build/VersionInfo.
# The parameters ProductMajor and ProductMinor version will be used in the overwrite
# for the ProductVersion field
@@ -137,3 +137,23 @@ Write-Verbose $assemblyInfoVer
$assemblyInfoVerPath = "$scriptFullPath/AssemblyInfo.ver"
Write-Verbose "Writing $assemblyInfoVerPath..."
[System.IO.File]::WriteAllLines($assemblyInfoVerPath, $assemblyInfoVer, $utf8NoBomEncoding)
+
+# Generating AssemblyInfo.h override
+$assemblyInfoH = @"
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#ifndef WINDOWSAPPSDK_RELEASE_MAJOR
+#define WINDOWSAPPSDK_RELEASE_MAJOR $ProductMajor
+#endif
+
+#ifndef WINDOWSAPPSDK_RELEASE_MINOR
+#define WINDOWSAPPSDK_RELEASE_MINOR $ProductMinor
+#endif
+"@
+
+Write-Verbose $assemblyInfoH
+$assemblyInfoHPath = "$scriptFullPath/AssemblyInfo.h"
+Write-Verbose "Writing $assemblyInfoHPath..."
+[System.IO.File]::WriteAllLines($assemblyInfoHPath, $assemblyInfoH, $utf8NoBomEncoding)
+
diff --git a/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.cpp b/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.cpp
index cbcebc8f91..b606a7b7fb 100644
--- a/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.cpp
+++ b/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.cpp
@@ -24,6 +24,16 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Background::implementatio
m_name = name;
}
+ void BackgroundTaskBuilder::TaskGroup(winrt::BackgroundTaskRegistrationGroup TaskGroup)
+ {
+ m_builder.TaskGroup(TaskGroup);
+ }
+
+ winrt::BackgroundTaskRegistrationGroup BackgroundTaskBuilder::TaskGroup()
+ {
+ return m_builder.TaskGroup();
+ }
+
void BackgroundTaskBuilder::SetTrigger(winrt::IBackgroundTrigger trigger)
{
m_builder.SetTrigger(trigger);
diff --git a/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.h b/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.h
index ca0e55e19f..090ebdb6cc 100644
--- a/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.h
+++ b/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.h
@@ -29,6 +29,9 @@ namespace winrt::Microsoft::Windows::ApplicationModel::Background::implementatio
void Name(winrt::hstring Name);
winrt::hstring Name() { return m_name; }
+ void TaskGroup(winrt::Windows::ApplicationModel::Background::BackgroundTaskRegistrationGroup TaskGroup);
+ winrt::Windows::ApplicationModel::Background::BackgroundTaskRegistrationGroup TaskGroup();
+
winrt::Windows::ApplicationModel::Background::BackgroundTaskRegistration Register();
winrt::Windows::ApplicationModel::Background::BackgroundTaskRegistration Register(winrt::hstring taskName);
diff --git a/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.idl b/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.idl
index d1b34aa0d6..6d8449c01a 100644
--- a/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.idl
+++ b/dev/BackgroundTask/BackgroundTaskBuilder/BackgroundTaskBuilder.idl
@@ -24,6 +24,7 @@ namespace Microsoft.Windows.ApplicationModel.Background
);
String Name{ set; get; };
+ Windows.ApplicationModel.Background.BackgroundTaskRegistrationGroup TaskGroup{ set; get; };
[return_name("task")]
Windows.ApplicationModel.Background.BackgroundTaskRegistration Register();
diff --git a/dev/Common/Common.vcxitems b/dev/Common/Common.vcxitems
index 9fe4e51244..6b554ac6f2 100644
--- a/dev/Common/Common.vcxitems
+++ b/dev/Common/Common.vcxitems
@@ -32,4 +32,8 @@
-
\ No newline at end of file
+
+
+
+
+
diff --git a/dev/Common/TerminalVelocityFeatures-CompatibilityOptions.h b/dev/Common/TerminalVelocityFeatures-CompatibilityOptions.h
new file mode 100644
index 0000000000..a2c4f72cac
--- /dev/null
+++ b/dev/Common/TerminalVelocityFeatures-CompatibilityOptions.h
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+// THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT IT
+
+// INPUT FILE: .\dev\common\TerminalVelocityFeatures-CompatibilityOptions.xml
+// OPTIONS: -Channel Experimental -Language C++ -Namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime -Path .\dev\common\TerminalVelocityFeatures-CompatibilityOptions.xml -Output dev\common\TerminalVelocityFeatures-CompatibilityOptions.h
+
+#if defined(__midlrt)
+namespace features
+{
+ feature_name Feature_CompatibilityOptions = { DisabledByDefault, FALSE };
+}
+#endif // defined(__midlrt)
+
+// Feature constants
+#define WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_APPLICATIONMODEL_WINDOWSAPPRUNTIME_FEATURE_COMPATIBILITYOPTIONS_ENABLED 1
+
+#if defined(__cplusplus)
+
+namespace Microsoft::Windows::ApplicationModel::WindowsAppRuntime
+{
+
+__pragma(detect_mismatch("ODR_violation_WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_APPLICATIONMODEL_WINDOWSAPPRUNTIME_FEATURE_COMPATIBILITYOPTIONS_ENABLED_mismatch", "AlwaysEnabled"))
+struct Feature_CompatibilityOptions
+{
+ static constexpr bool IsEnabled() { return WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_APPLICATIONMODEL_WINDOWSAPPRUNTIME_FEATURE_COMPATIBILITYOPTIONS_ENABLED == 1; }
+};
+
+} // namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime
+
+#endif // defined(__cplusplus)
diff --git a/dev/Common/TerminalVelocityFeatures-CompatibilityOptions.xml b/dev/Common/TerminalVelocityFeatures-CompatibilityOptions.xml
new file mode 100644
index 0000000000..7df32a6942
--- /dev/null
+++ b/dev/Common/TerminalVelocityFeatures-CompatibilityOptions.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+ Feature_CompatibilityOptions
+ CompatibilityOptions for the WindowsAppRuntime
+ AlwaysEnabled
+
+
diff --git a/dev/Common/TerminalVelocityFeatures-StoragePickers.h b/dev/Common/TerminalVelocityFeatures-StoragePickers.h
new file mode 100644
index 0000000000..2b7b2f1b95
--- /dev/null
+++ b/dev/Common/TerminalVelocityFeatures-StoragePickers.h
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+// THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT IT
+
+// INPUT FILE: .\dev\Common\TerminalVelocityFeatures-StoragePickers.xml
+// OPTIONS: -Channel Experimental -Language C++ -Path .\dev\Common\TerminalVelocityFeatures-StoragePickers.xml
+
+#if defined(__midlrt)
+namespace features
+{
+ feature_name Feature_StoragePickers = { DisabledByDefault, FALSE };
+}
+#endif // defined(__midlrt)
+
+// Feature constants
+#define WINDOWSAPPRUNTIME_FEATURE_STORAGEPICKERS_ENABLED 1
+
+#if defined(__cplusplus)
+
+__pragma(detect_mismatch("ODR_violation_WINDOWSAPPRUNTIME_FEATURE_STORAGEPICKERS_ENABLED_mismatch", "AlwaysEnabled"))
+struct Feature_StoragePickers
+{
+ static constexpr bool IsEnabled() { return WINDOWSAPPRUNTIME_FEATURE_STORAGEPICKERS_ENABLED == 1; }
+};
+
+#endif // defined(__cplusplus)
\ No newline at end of file
diff --git a/dev/Common/TerminalVelocityFeatures-StoragePickers.xml b/dev/Common/TerminalVelocityFeatures-StoragePickers.xml
new file mode 100644
index 0000000000..123cf78ecb
--- /dev/null
+++ b/dev/Common/TerminalVelocityFeatures-StoragePickers.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+ Feature_StoragePickers
+ StoragePickers for the WindowsAppRuntime
+ AlwaysEnabled
+
+ Preview
+ Stable
+
+
+
diff --git a/dev/Common/WindowsAppRuntimeAutoInitializer.cpp b/dev/Common/WindowsAppRuntimeAutoInitializer.cpp
new file mode 100644
index 0000000000..7596fb1e3b
--- /dev/null
+++ b/dev/Common/WindowsAppRuntimeAutoInitializer.cpp
@@ -0,0 +1,59 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+// Forward-declare the various AutoInitialize functions
+namespace Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap
+{
+ namespace AutoInitialize { void Initialize(); void Shutdown(); };
+}
+namespace Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentManager
+{
+ namespace AutoInitialize { void Initialize(); };
+}
+namespace Microsoft::Windows::Foundation::UndockedRegFreeWinRT
+{
+ namespace AutoInitialize { void Initialize(); };
+}
+namespace Microsoft::Windows::ApplicationModel::WindowsAppRuntime::Compatibility
+{
+ namespace AutoInitialize { void Initialize(); };
+}
+
+// The common AutoInitialize struct that calls the various AutoInitialize functions
+namespace Microsoft::Windows::ApplicationModel::WindowsAppRuntime::Common
+{
+ struct AutoInitialize
+ {
+ AutoInitialize()
+ {
+ Initialize();
+ }
+
+ ~AutoInitialize()
+ {
+#if MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_BOOTSTRAP
+ Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap::AutoInitialize::Shutdown();
+#endif
+ }
+
+ static void Initialize()
+ {
+ // Call the AutoInitialize functions, as needed, starting with those initializing the WindowsAppRuntime
+#if MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_BOOTSTRAP
+ Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap::AutoInitialize::Initialize();
+#endif
+#if MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_DEPLOYMENTMANAGER
+ Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentManager::AutoInitialize::Initialize();
+#endif
+#if MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_UNDOCKEDREGFREEWINRT
+ Microsoft::Windows::Foundation::UndockedRegFreeWinRT::AutoInitialize::Initialize();
+#endif
+
+ // Compatibility happens just after initializing WindowsAppRuntime
+#if MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_COMPATIBILITY
+ Microsoft::Windows::ApplicationModel::WindowsAppRuntime::Compatibility::AutoInitialize::Initialize();
+#endif
+ }
+ };
+ static AutoInitialize g_autoInitialize;
+}
diff --git a/dev/Common/WindowsAppRuntimeAutoInitializer.cs b/dev/Common/WindowsAppRuntimeAutoInitializer.cs
new file mode 100644
index 0000000000..e947953fc4
--- /dev/null
+++ b/dev/Common/WindowsAppRuntimeAutoInitializer.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+//
+// Exclude this file from StyleCop analysis. This file isn't generated but is added to projects.
+// DO NOT MODIFY. Changes to this file may cause incorrect behavior and will be lost on updates.
+//
+
+
+namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime.Common
+{
+ class AutoInitialize
+ {
+ [global::System.Runtime.CompilerServices.ModuleInitializer]
+ internal static void InitializeWindowsAppSDK()
+ {
+ // Call the AutoInitialize functions, as needed, starting with those initializing the WindowsAppRuntime
+#if MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_BOOTSTRAP
+ Microsoft.Windows.ApplicationModel.DynamicDependency.BootstrapCS.AutoInitialize.AccessWindowsAppSDK();
+#endif
+#if MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_DEPLOYMENTMANAGER
+ Microsoft.Windows.ApplicationModel.WindowsAppRuntime.DeploymentManagerCS.AutoInitialize.AccessWindowsAppSDK();
+#endif
+#if MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_UNDOCKEDREGFREEWINRT
+ Microsoft.Windows.Foundation.UndockedRegFreeWinRTCS.AutoInitialize.AccessWindowsAppSDK();
+#endif
+
+ // Compatibility happens just after initializing WindowsAppRuntime
+#if MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_COMPATIBILITY
+ Microsoft.Windows.ApplicationModel.WindowsAppRuntime.Compatibility.AutoInitialize.ConfigureCompatibility();
+#endif
+ }
+ }
+}
+
diff --git a/dev/CompatibilityOptions/CompatibilityOptions.cpp b/dev/CompatibilityOptions/CompatibilityOptions.cpp
new file mode 100644
index 0000000000..8f41e0d586
--- /dev/null
+++ b/dev/CompatibilityOptions/CompatibilityOptions.cpp
@@ -0,0 +1,64 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "CompatibilityOptions.h"
+#include "Microsoft.Windows.ApplicationModel.WindowsAppRuntime.CompatibilityOptions.g.cpp"
+#include "AssemblyInfo.h"
+#include
+
+namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implementation
+{
+ winrt::Windows::Foundation::Collections::IVector CompatibilityOptions::DisabledChanges()
+ {
+ return m_disabledChanges;
+ }
+
+ void CompatibilityOptions::Apply()
+ {
+ WinAppSdk::Containment::WinAppSDKRuntimeConfiguration config;
+
+ // If both patch modes are set to the same major.minor version, error out if the patch versions are different.
+ if (m_patchMode1.Major == m_patchMode2.Major && m_patchMode1.Minor == m_patchMode2.Minor &&
+ m_patchMode1.Major != 0)
+ {
+ if (m_patchMode1.Patch != m_patchMode2.Patch)
+ {
+ throw hresult_invalid_argument(L"Patch modes should target different Major.Minor versions or match Patch version.");
+ }
+ }
+
+ // Apply the patch mode which applies to the major.minor version, if any.
+ if (m_patchMode1.Major == WINDOWSAPPSDK_RELEASE_MAJOR && m_patchMode1.Minor == WINDOWSAPPSDK_RELEASE_MINOR)
+ {
+ // Apply patch mode 1
+ config.patchVersion = (WinAppSDKPatchVersion)WinAppSDKPatchVersionFromValues(m_patchMode1.Major, m_patchMode1.Minor, m_patchMode1.Patch);
+ }
+ else if (m_patchMode2.Major == WINDOWSAPPSDK_RELEASE_MAJOR && m_patchMode2.Minor == WINDOWSAPPSDK_RELEASE_MINOR)
+ {
+ // Apply patch mode 2
+ config.patchVersion = (WinAppSDKPatchVersion)WinAppSDKPatchVersionFromValues(m_patchMode2.Major, m_patchMode2.Minor, m_patchMode2.Patch);
+ }
+
+ // Add the set of disabled changes
+ std::vector disabledChanges;
+ for (auto changeId : m_disabledChanges)
+ {
+ // TODO: Telemetry! Log the changeId that was disabled.
+ // UINT32 is used internally for the changeId, so cast from the enum's Int32 to that.
+ disabledChanges.push_back(static_cast(changeId));
+ }
+ config.disabledChanges = disabledChanges.data();
+ config.disabledChangesCount = static_cast(disabledChanges.size());
+
+ HRESULT hr = WinAppSdk::Containment::SetConfiguration(&config);
+ if (FAILED(hr))
+ {
+ if (hr == E_ILLEGAL_STATE_CHANGE)
+ {
+ throw winrt::hresult_illegal_state_change(L"Configuration already set or locked.");
+ }
+ winrt::throw_hresult(hr);
+ }
+ }
+}
diff --git a/dev/CompatibilityOptions/CompatibilityOptions.h b/dev/CompatibilityOptions/CompatibilityOptions.h
new file mode 100644
index 0000000000..5bfb25c69d
--- /dev/null
+++ b/dev/CompatibilityOptions/CompatibilityOptions.h
@@ -0,0 +1,34 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#pragma once
+
+#include "Microsoft.Windows.ApplicationModel.WindowsAppRuntime.CompatibilityOptions.g.h"
+
+namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implementation
+{
+ struct CompatibilityOptions : CompatibilityOptionsT
+ {
+ CompatibilityOptions() = default;
+
+ WindowsAppRuntimeVersion PatchMode1() { return m_patchMode1; }
+ void PatchMode1(WindowsAppRuntimeVersion const& value) { m_patchMode1 = value; }
+ WindowsAppRuntimeVersion PatchMode2() { return m_patchMode2; }
+ void PatchMode2(WindowsAppRuntimeVersion const& value) { m_patchMode2 = value; }
+ winrt::Windows::Foundation::Collections::IVector DisabledChanges();
+
+ void Apply();
+
+ private:
+ WindowsAppRuntimeVersion m_patchMode1{ 0, 0, 0 };
+ WindowsAppRuntimeVersion m_patchMode2{ 0, 0, 0 };
+ winrt::Windows::Foundation::Collections::IVector m_disabledChanges{ winrt::single_threaded_vector() };
+ };
+}
+
+namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::factory_implementation
+{
+ struct CompatibilityOptions : CompatibilityOptionsT
+ {
+ };
+}
diff --git a/dev/CompatibilityOptions/CompatibilityOptions.idl b/dev/CompatibilityOptions/CompatibilityOptions.idl
new file mode 100644
index 0000000000..42554cecf2
--- /dev/null
+++ b/dev/CompatibilityOptions/CompatibilityOptions.idl
@@ -0,0 +1,53 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+#include
+
+namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime
+{
+ /// The set of servicing changes that can be disabled.
+ enum CompatibilityChange
+ {
+ None = 0, /// do not use this value
+
+ // Add real changes here:
+
+ // 1.7.1
+ // ...
+ };
+
+ [contractversion(1)]
+ apicontract CompatibilityContract {};
+
+ /// Represents a version of the Windows App Runtime.
+ [contract(CompatibilityContract, 1), feature(Feature_CompatibilityOptions)]
+ struct WindowsAppRuntimeVersion
+ {
+ UInt32 Major;
+ UInt32 Minor;
+ UInt32 Patch;
+ };
+
+ /// This object is used by the app to configure any desired compatibility options
+ /// for Windows App Runtime behavior of changes added in servicing updates. This
+ /// object is only used to set the runtime behavior and can't be used to query the
+ /// applied options.
+ // TODO: Get agreement and add a generic Feature_Experimental
+ [contract(CompatibilityContract, 1), feature(Feature_CompatibilityOptions)]
+ runtimeclass CompatibilityOptions
+ {
+ CompatibilityOptions();
+
+ /// An optional patch mode to use if the runtime version matches the major.minor version.
+ WindowsAppRuntimeVersion PatchMode1 { get; set; };
+
+ /// An optional patch mode to use if the runtime version matches the major.minor version.
+ WindowsAppRuntimeVersion PatchMode2 { get; set; };
+
+ /// An optional list of specific servicing changes to disable.
+ IVector DisabledChanges{ get; };
+
+ /// Apply the compatibility options to the runtime.
+ void Apply();
+ }
+}
diff --git a/dev/CompatibilityOptions/CompatibilityOptions.vcxitems b/dev/CompatibilityOptions/CompatibilityOptions.vcxitems
new file mode 100644
index 0000000000..85891246c9
--- /dev/null
+++ b/dev/CompatibilityOptions/CompatibilityOptions.vcxitems
@@ -0,0 +1,32 @@
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ true
+ {1f7b9e9f-9987-490b-9e6e-093c7f63fec4}
+
+
+
+ %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)
+
+
+
+
+
+
+
+
+
+
+ $(RepoRoot)\build\VersionInfo;%(AdditionalIncludeDirectories)
+ $(RepoRoot)\build\VersionInfo;%(AdditionalIncludeDirectories)
+ $(RepoRoot)\build\VersionInfo;%(AdditionalIncludeDirectories)
+ $(RepoRoot)\build\VersionInfo;%(AdditionalIncludeDirectories)
+ $(RepoRoot)\build\VersionInfo;%(AdditionalIncludeDirectories)
+ $(RepoRoot)\build\VersionInfo;%(AdditionalIncludeDirectories)
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dev/Deployment/DeploymentManagerAutoInitializer.cpp b/dev/Deployment/DeploymentManagerAutoInitializer.cpp
index f48b7be070..07a3bcaf7e 100644
--- a/dev/Deployment/DeploymentManagerAutoInitializer.cpp
+++ b/dev/Deployment/DeploymentManagerAutoInitializer.cpp
@@ -24,15 +24,8 @@
namespace Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentManager
{
- struct AutoInitialize
+ namespace AutoInitialize
{
- AutoInitialize()
- {
- Initialize();
- }
-
- ~AutoInitialize() = default;
-
static ::winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentInitializeOptions Options()
{
::winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentInitializeOptions options;
@@ -50,7 +43,8 @@ namespace Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentMan
return options;
}
- static void Initialize()
+ // Called by WindowsAppRuntimeAutoInitializer.cpp
+ void Initialize()
{
auto options{ Options() };
auto deploymentResult{ ::winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentManager::Initialize(options) };
@@ -61,5 +55,4 @@ namespace Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentMan
}
}
};
- static AutoInitialize g_autoInitialize;
}
diff --git a/dev/Deployment/DeploymentManagerAutoInitializer.cs b/dev/Deployment/DeploymentManagerAutoInitializer.cs
index 3031f8012c..f31259f157 100644
--- a/dev/Deployment/DeploymentManagerAutoInitializer.cs
+++ b/dev/Deployment/DeploymentManagerAutoInitializer.cs
@@ -24,7 +24,7 @@ namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime.DeploymentManager
{
class AutoInitialize
{
- [global::System.Runtime.CompilerServices.ModuleInitializer]
+ // Called by WindowsAppRuntimeAutoInitializer.cs
internal static void AccessWindowsAppSDK()
{
var options = Options;
diff --git a/dev/OAuth/AuthRequestAsyncOperation.cpp b/dev/OAuth/AuthRequestAsyncOperation.cpp
index 60571a97e7..f98bd21ba4 100644
--- a/dev/OAuth/AuthRequestAsyncOperation.cpp
+++ b/dev/OAuth/AuthRequestAsyncOperation.cpp
@@ -13,58 +13,6 @@ using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Windows::Security::Cryptography;
-AuthRequestAsyncOperation::AuthRequestAsyncOperation(winrt::hstring& state)
-{
- try
- {
- if (state.empty())
- {
- while (true)
- {
- state = random_base64urlencoded_string(32);
- if (try_create_pipe(state))
- {
- break;
- }
-
- // 'FILE_FLAG_FIRST_PIPE_INSTANCE' is documented as failing with 'ERROR_ACCESS_DENIED' if a pipe
- // with the same name has already been created.
- if (auto err = ::GetLastError(); err != ERROR_ACCESS_DENIED)
- {
- throw winrt::hresult_error(HRESULT_FROM_WIN32(err),
- L"Generation of a unique state value unexpectedly failed");
- }
- }
- }
- else if (!try_create_pipe(state))
- {
- auto err = ::GetLastError();
- auto msg =
- (err == ERROR_ACCESS_DENIED) ? L"Provided state value is not unique" : L"Failed to create named pipe";
- throw winrt::hresult_error(HRESULT_FROM_WIN32(err), msg);
- }
-
- m_overlapped.hEvent = ::CreateEventW(nullptr, true, false, nullptr);
- if (!m_overlapped.hEvent)
- {
- throw winrt::hresult_error(HRESULT_FROM_WIN32(::GetLastError()), L"Failed to create an event");
- }
-
- m_ptp.reset(::CreateThreadpoolWait(async_callback, this, nullptr)); // Use reset() to initialize
- if (!m_ptp)
- {
- throw winrt::hresult_error(HRESULT_FROM_WIN32(::GetLastError()), L"Failed to create threadpool wait");
- }
- connect_to_new_client();
- }
- catch (...)
- {
- // Throwing in a constructor will cause the destructor not to run...
- destroy();
- throw;
- }
-}
-
AuthRequestAsyncOperation::AuthRequestAsyncOperation(implementation::AuthRequestParams* params) :
m_params(params->get_strong())
{
diff --git a/dev/OAuth/AuthRequestAsyncOperation.h b/dev/OAuth/AuthRequestAsyncOperation.h
index 07fa7f2ecf..b16a326697 100644
--- a/dev/OAuth/AuthRequestAsyncOperation.h
+++ b/dev/OAuth/AuthRequestAsyncOperation.h
@@ -9,7 +9,6 @@ struct AuthRequestAsyncOperation :
winrt::implements,
foundation::IAsyncInfo>
{
- AuthRequestAsyncOperation(winrt::hstring& state);
AuthRequestAsyncOperation(oauth::implementation::AuthRequestParams* params);
~AuthRequestAsyncOperation();
diff --git a/dev/OAuth/OAuth.idl b/dev/OAuth/OAuth.idl
index c73522b7c4..7b7a2a28ba 100644
--- a/dev/OAuth/OAuth.idl
+++ b/dev/OAuth/OAuth.idl
@@ -29,21 +29,6 @@ namespace Microsoft.Security.Authentication.OAuth
[contract(OAuthContract, 1), feature(Feature_OAuth)]
static runtimeclass OAuth2Manager
{
- // Initiates an authorization request in the user's default browser as described by RFC 6749 section 3.1. The
- // returned 'IAsyncOperation' will remain in the 'Started' state until it is either cancelled or completed by a
- // call to 'CompleteAuthRequest'. This performs authorization of response_type="token".
- static Windows.Foundation.IAsyncOperation RequestAuthAsync(
- Microsoft.UI.WindowId parentWindowId,
- Windows.Foundation.Uri completeAuthEndpoint,
- Windows.Foundation.Uri redirectUri);
-
- // Initiates an authorization request in the user's default browser as described by RFC 6749 section 3.1. The
- // returned 'IAsyncOperation' will remain in the 'Started' state until it is either cancelled or completed by a
- // call to 'CompleteAuthRequest'.This performs authorization of response_type="token".
- static Windows.Foundation.IAsyncOperation RequestAuthAsync(
- Microsoft.UI.WindowId parentWindowId,
- Windows.Foundation.Uri completeAuthEndpoint);
-
// Initiates an authorization request in the user's default browser as described by RFC 6749 section 3.1. The
// returned 'IAsyncOperation' will remain in the 'Started' state until it is either cancelled or completed by a
// call to 'CompleteAuthRequest'.
@@ -98,16 +83,8 @@ namespace Microsoft.Security.Authentication.OAuth
// parameters as well as a redirect URI, which is frequently specified.
static AuthRequestParams CreateForAuthorizationCodeRequest(String clientId, Windows.Foundation.Uri redirectUri);
- // Helper method to create for an implicit grant request ("token" response type) with required parameters, per
- // RFC 6749 section 4.2.1.
- static AuthRequestParams CreateForImplicitRequest(String clientId);
- // Helper method to create for an implicit grant request ("token" response type) with required parameters as
- // well as a redirect URI, which is frequently specified.
- static AuthRequestParams CreateForImplicitRequest(String clientId, Windows.Foundation.Uri redirectUri);
-
// Specifies the required "response_type" parameter of the authorization request. This property is initialized
- // by the creation function used ("code" for 'CreateForAuthorizationCodeRequest' and "token" for
- // 'CreateForImplicitRequest').
+ // by the creation function used ("code" for 'CreateForAuthorizationCodeRequest').
//
// Defined by RFC 6749: The OAuth 2.0 Authorization Framework, sections 4.1.1 and 4.2.1
// https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
@@ -157,9 +134,7 @@ namespace Microsoft.Security.Authentication.OAuth
String CodeChallenge{ get; set; };
// Specifies the optional "code_challenge_method" parameter of the authorization request. For authorization code
- // requests, this value defaults to 'S256'. For implicit requests, this value defaults to 'None' and cannot be
- // changed.
- //
+ // requests, this value defaults to 'S256'.
// Defined by RFC 7636: Proof Key for Code Exchange by OAuth Public Clients, section 4.3
// https://www.rfc-editor.org/rfc/rfc7636#section-4.3
CodeChallengeMethodKind CodeChallengeMethod { get; set; };
@@ -186,30 +161,22 @@ namespace Microsoft.Security.Authentication.OAuth
// https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2
String Code { get; };
- // From the "access_token" parameter of the authorization response. Set only if the request was an implicit
- // request.
- //
+ // From the "access_token" parameter of the authorization response.
// Defined by RFC 6749: The OAuth 2.0 Authorization Framework, section 4.2.2
// https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2
String AccessToken { get; };
- // From the "token_type" parameter of the authorization response. Set only if the request was an implicit
- // request.
- //
+ // From the "token_type" parameter of the authorization response.
// Defined by RFC 6749: The OAuth 2.0 Authorization Framework, section 4.2.2
// https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2
String TokenType { get; };
- // From the "expires_in" parameter of the authorization response. An optional parameter that may be set only if
- // the request was an implicit request.
- //
+ // From the "expires_in" parameter of the authorization response.
// Defined by RFC 6749: The OAuth 2.0 Authorization Framework, section 4.2.2
// https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2
String ExpiresIn { get; }; // TODO: DateTime?
- // From the "scope" parameter of the authorization response. An optional parameter that may be set only if the
- // request was an implicit request.
- //
+ // From the "scope" parameter of the authorization response.
// Defined by RFC 6749: The OAuth 2.0 Authorization Framework, section 4.2.2
// https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2
String Scope { get; };
@@ -281,10 +248,6 @@ namespace Microsoft.Security.Authentication.OAuth
// 4.1.3.
static TokenRequestParams CreateForAuthorizationCodeRequest(AuthResponse authResponse);
- // Helper method to create for a resource owner password credentials grant request ("password" grant type),
- // initialized with the required parameters, per RFC 6749 section 4.3.2.
- static TokenRequestParams CreateForResourceOwnerPasswordCredentials(String username, String password);
-
// Helper method to create for a client credentials grant request ("client_credentials" grant type), initialized
// with the required parameters, per RFC 6749 section 4.4.2.
static TokenRequestParams CreateForClientCredentials();
diff --git a/dev/OAuth/OAuth2Manager.cpp b/dev/OAuth/OAuth2Manager.cpp
index 4ae3e16018..601f1ee967 100644
--- a/dev/OAuth/OAuth2Manager.cpp
+++ b/dev/OAuth/OAuth2Manager.cpp
@@ -23,74 +23,6 @@ using namespace winrt::Windows::Web::Http;
namespace winrt::Microsoft::Security::Authentication::OAuth::factory_implementation
{
- IAsyncOperation OAuth2Manager::RequestAuthAsync(winrt::Microsoft::UI::WindowId const& parentWindowId,
- const Uri& completeAuthEndpoint,
- const Uri& redirectUri)
- {
- THROW_HR_IF(E_NOTIMPL, !::Microsoft::Security::Authentication::OAuth::Feature_OAuth::IsEnabled());
-
- bool isAppPackaged = m_telemetryHelper.IsPackagedApp();
- PCWSTR appName = m_telemetryHelper.GetAppName().c_str();
- OAuth2ManagerTelemetry::RequestAuthAsyncTriggered(isAppPackaged, appName, true);
-
- winrt::hstring state;
- auto asyncOp = winrt::make_self(state);
-
- {
- std::lock_guard guard{ m_mutex };
- m_pendingAuthRequests.push_back(AuthRequestState{ state, asyncOp });
- }
-
- try
- {
- // Pipe server has been successfully set up. Initiate the launch
- auto url = create_implicit_url(completeAuthEndpoint, state, redirectUri);
-
- // Launch browser
- execute_shell(parentWindowId, url);
- }
- catch (...)
- {
- try_remove(asyncOp.get());
- throw;
- }
-
- return *asyncOp;
- }
-
- IAsyncOperation OAuth2Manager::RequestAuthAsync(winrt::Microsoft::UI::WindowId const& parentWindowId,
- const Uri& completeAuthEndpoint)
- {
- THROW_HR_IF(E_NOTIMPL, !::Microsoft::Security::Authentication::OAuth::Feature_OAuth::IsEnabled());
-
-
- bool isAppPackaged = m_telemetryHelper.IsPackagedApp();
- PCWSTR appName = m_telemetryHelper.GetAppName().c_str();
- OAuth2ManagerTelemetry::RequestAuthAsyncTriggered(isAppPackaged, appName, false);
-
- winrt::hstring state;
- auto asyncOp = winrt::make_self(state);
-
- {
- std::lock_guard guard{ m_mutex };
- m_pendingAuthRequests.push_back(AuthRequestState{ state, asyncOp });
- }
-
- try
- {
- // Pipe server has been successfully set up. Initiate the launch
- auto url = create_implicit_url(completeAuthEndpoint, state, nullptr);
-
- // Launch browser
- execute_shell(parentWindowId, url);
- }
- catch (...)
- {
- try_remove(asyncOp.get());
- throw;
- }
- return *asyncOp;
- }
IAsyncOperation OAuth2Manager::RequestAuthWithParamsAsync(winrt::Microsoft::UI::WindowId const& parentWindowId,
const Uri& authEndpoint,
@@ -408,30 +340,6 @@ namespace winrt::Microsoft::Security::Authentication::OAuth::factory_implementat
return result;
}
- std::wstring OAuth2Manager::create_implicit_url(const foundation::Uri& completeAuthEndpoint, const winrt::hstring& state, const foundation::Uri& redirectUri)
- {
- std::lock_guard guard{ m_mutex };
- // Per RFC 6749 section 3.1, the auth endpoint URI *MAY* contain a query string, which must be retained
- std::wstring result{ completeAuthEndpoint.RawUri() };
- if (completeAuthEndpoint.Query().empty())
- {
- result += L"?state=";
- }
- else
- {
- result += L"&state=";
- }
- result += Uri::EscapeComponent(state);
- result += L"&response_type=token";
-
- if (redirectUri)
- {
- result += L"&redirect_uri=";
- result += Uri::EscapeComponent(redirectUri.RawUri());
- }
- return result;
- }
-
void OAuth2Manager::execute_shell(winrt::Microsoft::UI::WindowId const& parentWindowId, const std::wstring& url)
{
// Convert parentWindowId to HWND
diff --git a/dev/OAuth/OAuth2Manager.h b/dev/OAuth/OAuth2Manager.h
index fc1f7012ac..352a4cba58 100644
--- a/dev/OAuth/OAuth2Manager.h
+++ b/dev/OAuth/OAuth2Manager.h
@@ -21,10 +21,6 @@ namespace winrt::Microsoft::Security::Authentication::OAuth::factory_implementat
struct OAuth2Manager : OAuth2ManagerT
{
- foundation::IAsyncOperation RequestAuthAsync(
- winrt::Microsoft::UI::WindowId const& parentWindowId, const foundation::Uri& completeAuthEndpoint, const foundation::Uri& redirectUri);
- foundation::IAsyncOperation RequestAuthAsync(
- winrt::Microsoft::UI::WindowId const& parentWindowId, const foundation::Uri& completeAuthEndpoint);
foundation::IAsyncOperation RequestAuthWithParamsAsync(
winrt::Microsoft::UI::WindowId const& parentWindowId, const foundation::Uri& authEndpoint, const oauth::AuthRequestParams& params);
bool CompleteAuthRequest(const foundation::Uri& responseUri);
@@ -41,7 +37,6 @@ namespace winrt::Microsoft::Security::Authentication::OAuth::factory_implementat
private:
AuthRequestState try_remove(AuthRequestAsyncOperation* op);
- std::wstring create_implicit_url(const foundation::Uri& completeAuthEndpoint, const winrt::hstring& state, const foundation::Uri& redirectUri);
void execute_shell(winrt::Microsoft::UI::WindowId const& parentWindowId, const std::wstring& url);
std::shared_mutex m_mutex;
TelemetryHelper m_telemetryHelper;
@@ -53,22 +48,6 @@ namespace winrt::Microsoft::Security::Authentication::OAuth::implementation
{
struct OAuth2Manager
{
- static foundation::IAsyncOperation RequestAuthAsync(
- winrt::Microsoft::UI::WindowId const& parentWindowId,
- foundation::Uri completeAuthEndpoint, foundation::Uri redirectUri)
- {
- return winrt::make_self()->RequestAuthAsync(parentWindowId,
- completeAuthEndpoint,
- redirectUri);
- }
-
- static foundation::IAsyncOperation RequestAuthAsync(
- winrt::Microsoft::UI::WindowId const& parentWindowId,
- foundation::Uri completeAuthEndpoint)
- {
- return winrt::make_self()->RequestAuthAsync(parentWindowId,
- completeAuthEndpoint);
- }
static foundation::IAsyncOperation RequestAuthWithParamsAsync(
winrt::Microsoft::UI::WindowId const& parentWindowId,
diff --git a/dev/OAuth/OAuth2ManagerTelemetry.h b/dev/OAuth/OAuth2ManagerTelemetry.h
index b2e3d3a5cc..afb710c153 100644
--- a/dev/OAuth/OAuth2ManagerTelemetry.h
+++ b/dev/OAuth/OAuth2ManagerTelemetry.h
@@ -10,8 +10,6 @@ class OAuth2ManagerTelemetry : public wil::TraceLoggingProvider
(0x27d8ee3f, 0xd704, 0x45d6, 0xb6, 0x6c, 0x1d, 0xad, 0x95, 0x79, 0x5c, 0xe5));
//{27d8ee3f-d704-45d6-b66c-1dad95795ce5}
public:
- DEFINE_COMPLIANT_MEASURES_EVENT_PARAM3(RequestAuthAsyncTriggered, PDT_ProductAndServicePerformance,
- bool, IsAppPackaged, PCWSTR, AppName, bool, IsRedirectURIPassed);
DEFINE_COMPLIANT_MEASURES_EVENT_PARAM3(RequestAuthWithParamsAsyncTriggered, PDT_ProductAndServicePerformance,
bool, IsAppPackaged, PCWSTR, AppName, PCWSTR, ResponseType);
diff --git a/dev/OAuth/TokenRequestParams.cpp b/dev/OAuth/TokenRequestParams.cpp
index bfb7682f94..ba3844e599 100644
--- a/dev/OAuth/TokenRequestParams.cpp
+++ b/dev/OAuth/TokenRequestParams.cpp
@@ -45,16 +45,6 @@ namespace winrt::Microsoft::Security::Authentication::OAuth::implementation
return *result;
}
- oauth::TokenRequestParams TokenRequestParams::CreateForResourceOwnerPasswordCredentials(
- const winrt::hstring& username, const winrt::hstring& password)
- {
- auto result = winrt::make_self(L"password");
- result->m_username = username;
- result->m_password = password;
-
- return *result;
- }
-
oauth::TokenRequestParams TokenRequestParams::CreateForClientCredentials()
{
return winrt::make(L"client_credentials");
diff --git a/dev/OAuth/TokenRequestParams.h b/dev/OAuth/TokenRequestParams.h
index a8b434b9c0..d805606d2c 100644
--- a/dev/OAuth/TokenRequestParams.h
+++ b/dev/OAuth/TokenRequestParams.h
@@ -15,8 +15,6 @@ namespace winrt::Microsoft::Security::Authentication::OAuth::implementation
TokenRequestParams(const winrt::hstring& grantType);
static oauth::TokenRequestParams CreateForAuthorizationCodeRequest(const oauth::AuthResponse& authResponse);
- static oauth::TokenRequestParams CreateForResourceOwnerPasswordCredentials(const winrt::hstring& username,
- const winrt::hstring& password);
static oauth::TokenRequestParams CreateForClientCredentials();
static oauth::TokenRequestParams CreateForExtension(const foundation::Uri& extensionUri);
static oauth::TokenRequestParams CreateForRefreshToken(const winrt::hstring& refreshToken);
diff --git a/dev/UndockedRegFreeWinRT/UndockedRegFreeWinRT-AutoInitializer.cpp b/dev/UndockedRegFreeWinRT/UndockedRegFreeWinRT-AutoInitializer.cpp
index e22415b6c3..2ca590db64 100644
--- a/dev/UndockedRegFreeWinRT/UndockedRegFreeWinRT-AutoInitializer.cpp
+++ b/dev/UndockedRegFreeWinRT/UndockedRegFreeWinRT-AutoInitializer.cpp
@@ -12,9 +12,10 @@ STDAPI WindowsAppRuntime_EnsureIsLoaded();
namespace Microsoft::Windows::Foundation::UndockedRegFreeWinRT
{
- struct AutoInitialize
+ namespace AutoInitialize
{
- AutoInitialize()
+ // Called by WindowsAppRuntimeAutoInitializer.cpp
+ void Initialize()
{
// Load the Windows App SDK runtime DLL. The only reason this could fail
// is if the loading application using WinAppSDK/SelfContained has a
@@ -38,5 +39,4 @@ namespace Microsoft::Windows::Foundation::UndockedRegFreeWinRT
#endif
}
};
- static AutoInitialize g_autoInitialize;
}
diff --git a/dev/UndockedRegFreeWinRT/UndockedRegFreeWinRT-AutoInitializer.cs b/dev/UndockedRegFreeWinRT/UndockedRegFreeWinRT-AutoInitializer.cs
index e9a29c56f1..2e07c542df 100644
--- a/dev/UndockedRegFreeWinRT/UndockedRegFreeWinRT-AutoInitializer.cs
+++ b/dev/UndockedRegFreeWinRT/UndockedRegFreeWinRT-AutoInitializer.cs
@@ -20,7 +20,7 @@ internal static class NativeMethods
class AutoInitialize
{
- [global::System.Runtime.CompilerServices.ModuleInitializer]
+ // Called by WindowsAppRuntimeAutoInitializer.cs
internal static void AccessWindowsAppSDK()
{
// Set base directory env var for PublishSingleFile support (referenced by SxS redirection)
diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp
index 777a696e84..f2aa32d42a 100644
--- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp
+++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cpp
@@ -24,14 +24,10 @@
namespace Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap
{
- struct AutoInitialize
+ namespace AutoInitialize
{
- AutoInitialize()
- {
- Initialize();
- }
-
- ~AutoInitialize()
+ // Called by WindowsAppRuntimeAutoInitializer.cpp
+ void Shutdown()
{
::MddBootstrapShutdown();
}
@@ -66,7 +62,8 @@ namespace Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap
#endif
}
- static void Initialize()
+ // Called by WindowsAppRuntimeAutoInitializer.cpp
+ void Initialize()
{
const UINT32 c_majorMinorVersion{ WINDOWSAPPSDK_RELEASE_MAJORMINOR };
PCWSTR c_versionTag{ WINDOWSAPPSDK_RELEASE_VERSION_TAG_W };
@@ -79,5 +76,4 @@ namespace Microsoft::Windows::ApplicationModel::DynamicDependency::Bootstrap
}
}
};
- static AutoInitialize g_autoInitialize;
}
diff --git a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs
index bbd9503bdc..19b7ec350e 100644
--- a/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs
+++ b/dev/WindowsAppRuntime_BootstrapDLL/MddBootstrapAutoInitializer.cs
@@ -28,7 +28,7 @@ namespace Microsoft.Windows.ApplicationModel.DynamicDependency.BootstrapCS
{
class AutoInitialize
{
- [global::System.Runtime.CompilerServices.ModuleInitializer]
+ // Called by WindowsAppRuntimeAutoInitializer.cs
internal static void AccessWindowsAppSDK()
{
uint majorMinorVersion = global::Microsoft.WindowsAppSDK.Release.MajorMinor;
diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj
index a7a1d9c4b2..2963b01c9d 100644
--- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj
+++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj
@@ -104,6 +104,7 @@
+
diff --git a/docs/Coding-Guidelines/GettingStarted.md b/docs/Coding-Guidelines/GettingStarted.md
index b5b5aa15cf..e66de020fe 100644
--- a/docs/Coding-Guidelines/GettingStarted.md
+++ b/docs/Coding-Guidelines/GettingStarted.md
@@ -83,10 +83,12 @@ harmless if your configuration is current with no changes needed.
# Tada!
-Now you're ready to load `WindowsAppSDK.sln` and start development!
+Now you're ready to load `WindowsAppRuntime.sln` and start development!
Some tips:
+* If VS starts in a configuration of `Any CPU`, switch to a specific architecture like `x64`
+ to successfully build.
* Build everything in VS via the Build menu's `Build Solution` or `Rebuild Solution`
* Right-click on individual projects in Solution Explorer to only build select projects.
Dependencies and Build Order should be defined to build prerequisites (if necessary) for the
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 43229f960c..310a8054c3 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -27,7 +27,7 @@
-->
-
+
https://dev.azure.com/microsoft/LiftedIXP/_git/DCPP
57cc118841f9386543f7eb6f16d25dacddc8d07d
@@ -35,7 +35,7 @@
https://dev.azure.com/microsoft/ProjectReunion/_git/WindowsAppSDKClosed
f52676312ebf1d66ef59731feb4fad29a713a897
-
+
https://dev.azure.com/microsoft/LiftedIXP/_git/DCPP
57cc118841f9386543f7eb6f16d25dacddc8d07d
diff --git a/specs/BackgroundTask/BackgroundTaskBuilder.md b/specs/BackgroundTask/BackgroundTaskBuilder.md
index 9dfd9ca329..e28cffa7b3 100644
--- a/specs/BackgroundTask/BackgroundTaskBuilder.md
+++ b/specs/BackgroundTask/BackgroundTaskBuilder.md
@@ -105,6 +105,7 @@ namespace Microsoft.Windows.ApplicationModel.Background
);
String Name{ set; get; };
+ Windows.ApplicationModel.Background.BackgroundTaskRegistrationGroup TaskGroup { set; get; };
Windows.ApplicationModel.Background.BackgroundTaskRegistration Register(
);
diff --git a/specs/OAuth/OAuth2Manager.md b/specs/OAuth/OAuth2Manager.md
index 05283e477d..395b22df76 100644
--- a/specs/OAuth/OAuth2Manager.md
+++ b/specs/OAuth/OAuth2Manager.md
@@ -4,7 +4,9 @@ OAuth2Manager API
This is the spec for proposal: [Issue #441](https://github.com/microsoft/WindowsAppSDK/issues/441)
This spec details the API of a new `OAuth2Manager` in WinAppSDK,
-enabling desktop applications such as WinUI3 to seamlessly perform OAuth functionality across diverse Windows platforms.
+enabling desktop applications such as WinUI3 to seamlessly perform OAuth functionality across diverse Windows platforms.
+OAuth2Manager API intentionally does not provide API for the implicit request & resource owner password credential because of the security concerns that follow it. It is recommended to use the
+authorization code grant type using Proof Key for Code Exchange (PKCE).
@@ -39,47 +41,6 @@ and OAuth 2.0 for Native Apps [RFC 8252](https://tools.ietf.org/html/rfc8252).
## Perform OAuth 2.0 (c++)
- Performing an Implicit Request with redirect URI(grant type/'response_type' = "token")
-
- ```c++
- // Get the WindowId for the application window
- Microsoft::UI::WindowId parentWindowId = this->AppWindow().Id();
-
-AuthRequestResult authRequestResult = co_await OAuth2Manager::RequestAuthAsync(parentWindowId,
- Uri(L"https://my.server.com/oauth/authorize?client_id=&scope="), Uri(L"my-app:/oauth-callback/"));
-if (AuthResponse authResponse = authRequestResult.Response())
-{
- //To obtain the access token
- authResponse.AccessToken();
-}
-else
-{
- AuthFailure authFailure = authRequestResult.Failure();
- NotifyFailure(authFailure.Error(), authFailure.ErrorDescription());
-}
-```
-
-Performing an Implicit Request without redirect URI(grant type/'response_type' = "token")
-
- ```c++
- // Get the WindowId for the application window
- Microsoft::UI::WindowId parentWindowId = this->AppWindow().Id();
-
-AuthRequestResult authRequestResult = co_await OAuth2Manager::RequestAuthAsync(parentWindowId,
- Uri(L"https://my.server.com/oauth/authorize?client_id=&scope="));
-if (AuthResponse authResponse = authRequestResult.Response())
-{
- //To obtain the access token
- authResponse.AccessToken();
-}
-else
-{
- AuthFailure authFailure = authRequestResult.Failure();
- NotifyFailure(authFailure.Error(), authFailure.ErrorDescription());
-}
-```
-
-
Performing an Authorization Code Request (grant type/'response_type' = "code")
```c++
@@ -190,37 +151,6 @@ else
}
```
-Performing an Implicit Request for a token (grant type/'response_type' = "token")
-
- ```c++
- // Get the WindowId for the application window
-Microsoft::UI::WindowId parentWindowId = this->AppWindow().Id();
-
-AuthRequestParams authRequestParams = AuthRequestParams::CreateForImplicitRequest(L"my_client_id",
- Uri(L"my-app:/oauth-callback/"));
-authRequestParams.Scope(L"user:email user:birthday");
-
-AuthRequestResult authRequestResult = co_await OAuth2Manager::RequestAuthWithParamsAsync(parentWindowId,
- Uri(L"https://my.server.com/oauth/authorize"), authRequestParams);
-if (AuthResponse authResponse = authRequestResult.Response())
-{
- //To obtain the access token
- String accessToken = tokenResponse.AccessToken();
-
- String tokenType = tokenResponse.TokenType();
-
- // Use the access token for resources
- DoRequestWithToken(accessToken, tokenType);
-}
-else
-{
- AuthFailure authFailure = authRequestResult.Failure();
- NotifyFailure(authFailure.Error(), authFailure.ErrorDescription());
-}
-```
-
-> Note: The authorization server MUST NOT issue a refresh token for implicit request.
-
Completing an Authorization Request from a Protocol Activation
```c++
@@ -255,8 +185,6 @@ complete an authorization request, and request an access token for a user throug
| Name | Description | Parameters | Returns |
|-|-|-|-|
-| RequestAuthAsync(Microsoft.UI.WindowId, Windows.Foundation.Uri, Windows.Foundation.Uri) | Initiates an authorization request in the user's default browser. This performs an access token request of implicit grant type. | Microsoft.UI.WindowId `parentWindowId`, Windows.Foundation.Uri `authEndPoint` , Windows.Foundation.Uri `redirectUri` | Windows.Foundation.IAsyncOperation< AuthRequestResult > |
-| RequestAuthAsync(Microsoft.UI.WindowId, Windows.Foundation.Uri) | Initiates an authorization request in the user's default browser. This performs an access token request of implicit grant type. | Microsoft.UI.WindowId `parentWindowId`, Windows.Foundation.Uri `authEndPoint` | Windows.Foundation.IAsyncOperation< AuthRequestResult > |
| RequestAuthWithParamsAsync(Microsoft.UI.WindowId, Windows.Foundation.Uri, AuthRequestParams) | Intiates auth request for a user in the user's default browser through a client.| Microsoft.UI.WindowId `parentWindowId`, Windows.Foundation.Uri `authEndPoint` , AuthRequestParams `params` | Windows.Foundation.IAsyncOperation< AuthRequestResult > |
| CompleteAuthRequest(Windows.Foundation.Uri) | Completes an auth request through a redirect URI. | Windows.Foundation.Uri `responseUri` | Boolean |
| RequestTokenAsync(Windows.Foundation.Uri, TokenRequestParams) | Initiates an access token request. | Windows.Foundation.Uri `tokenEndPoint` , TokenRequestParams `params` | Windows.Foundation.IAsyncOperation< TokenRequestResult > |
@@ -322,8 +250,6 @@ response_type is described in section 3.1.1 of [RFC 6749](https://www.rfc-editor
|-|-|-|-|
| CreateForAuthorizationCodeRequest(String) | Helper method to create for an authorization code grant request ("code" response type) with required parameters. | String `clientId` | AuthRequestParams |
| CreateForAuthorizationCodeRequest(String, Windows.Foundation.Uri) | Helper method to create for an authorization code grant request ("code" response type) with required parameters. | String `clientId` , Windows.Foundation.Uri `redirectUri` | AuthRequestParams |
-| CreateForImplicitRequest(String) | Helper method to create for an implicit grant request ("token" response type) with required parameters. | String `clientId` | AuthRequestParams |
-| CreateForImplicitRequest(String, Windows.Foundation.Uri) | Helper method to create for an implicit grant request ("token" response type) with required parameters. | String `clientId` , Windows.Foundation.Uri `redirectUri` | AuthRequestParams |
## AuthRequestParams Properties
@@ -400,7 +326,6 @@ It's a class that provides methods to create a token request parameter object. T
| Name | Description | Parameters | Returns |
|-|-|-|-|
| CreateForAuthorizationCodeRequest(AuthResponse) | Helper method to create for an authorization code grant request ("authorization_code" grant type) with required parameters extracted from the authorization response. | AuthResponse `authResponse` | TokenRequestParams |
-| CreateForResourceOwnerPasswordCredentials(String, String) | Helper method to create for a resource owner password credentials grant request ("password" grant type) with required parameters. | String `username` , String `password` | TokenRequestParams |
| CreateForClientCredentials() | Helper method to create for a client credentials grant request ("client_credentials" grant type) with required parameters. | None | TokenRequestParams |
| CreateForExtension(Windows.Foundation.Uri) | Helper method to create for an extension grant request, using the provided URI for the grant type. | Windows.Foundation.Uri `extensionUri` | TokenRequestParams |
| CreateForRefreshToken(String) | Helper method to create for an access token refresh request ("refresh_token" grant type) with required parameters. | String `refreshToken` | TokenRequestParams |
@@ -505,18 +430,6 @@ namespace Microsoft.Security.Authentication.OAuth
[contract(OAuthContract, 1)]
static runtimeclass OAuth2Manager
{
- // Initiates an authorization request in the user's default browser as described by RFC 6749 section 3.1. The
- // returned 'IAsyncOperation' will remain in the 'Started' state until it is either cancelled or completed by a
- // call to 'CompleteAuthRequest'. This performs authorization of response_type="token".
- static Windows.Foundation.IAsyncOperation RequestAuthAsync(Microsoft.UI.WindowId parentWindowId,
- Windows.Foundation.Uri completeAuthEndpoint,
- Windows.Foundation.Uri redirectUri);
-
- // Initiates an authorization request in the user's default browser as described by RFC 6749 section 3.1. The
- // returned 'IAsyncOperation' will remain in the 'Started' state until it is either cancelled or completed by a
- // call to 'CompleteAuthRequest'.This performs authorization of response_type="token".
- static Windows.Foundation.IAsyncOperation RequestAuthAsync(Microsoft.UI.WindowId parentWindowId,
- Windows.Foundation.Uri completeAuthEndpoint);
// Initiates an authorization request in the user's default browser as described by RFC 6749 section 3.1. The
// returned 'IAsyncOperation' will remain in the 'Started' state until it is either cancelled or completed by a
@@ -572,17 +485,8 @@ namespace Microsoft.Security.Authentication.OAuth
// parameters as well as a redirect URI, which is frequently specified.
static AuthRequestParams CreateForAuthorizationCodeRequest(String clientId, Windows.Foundation.Uri redirectUri);
- // Helper method to create for an implicit grant request ("token" response type) with required parameters, per
- // RFC 6749 section 4.2.1.
- static AuthRequestParams CreateForImplicitRequest(String clientId);
-
- // Helper method to create for an implicit grant request ("token" response type) with required parameters as
- // well as a redirect URI, which is frequently specified.
- static AuthRequestParams CreateForImplicitRequest(String clientId, Windows.Foundation.Uri redirectUri);
-
// Specifies the required "response_type" parameter of the authorization request. This property is initialized
- // by the creation function used ("code" for 'CreateForAuthorizationCodeRequest' and "token" for
- // 'CreateForImplicitRequest').
+ // by the creation function used ("code" for 'CreateForAuthorizationCodeRequest').
//
// Defined by RFC 6749: The OAuth 2.0 Authorization Framework, sections 4.1.1 and 4.2.1
// https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
@@ -632,9 +536,7 @@ namespace Microsoft.Security.Authentication.OAuth
String CodeChallenge { get; set; };
// Specifies the optional "code_challenge_method" parameter of the authorization request. For authorization code
- // requests, this value defaults to 'S256'. For implicit requests, this value defaults to 'None' and cannot be
- // changed.
- //
+ // requests, this value defaults to 'S256'.
// Defined by RFC 7636: Proof Key for Code Exchange by OAuth Public Clients, section 4.3
// https://www.rfc-editor.org/rfc/rfc7636#section-4.3
CodeChallengeMethodKind CodeChallengeMethod { get; set; };
@@ -661,30 +563,22 @@ namespace Microsoft.Security.Authentication.OAuth
// https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2
String Code { get; };
- // From the "access_token" parameter of the authorization response. Set only if the request was an implicit
- // request.
- //
+ // From the "access_token" parameter of the authorization response.
// Defined by RFC 6749: The OAuth 2.0 Authorization Framework, section 4.2.2
// https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2
String AccessToken { get; };
- // From the "token_type" parameter of the authorization response. Set only if the request was an implicit
- // request.
- //
+ // From the "token_type" parameter of the authorization response.
// Defined by RFC 6749: The OAuth 2.0 Authorization Framework, section 4.2.2
// https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2
String TokenType { get; };
- // From the "expires_in" parameter of the authorization response. An optional parameter that may be set only if
- // the request was an implicit request.
- //
+ // From the "expires_in" parameter of the authorization response.
// Defined by RFC 6749: The OAuth 2.0 Authorization Framework, section 4.2.2
// https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2
String ExpiresIn { get; }; // TODO: DateTime?
- // From the "scope" parameter of the authorization response. An optional parameter that may be set only if the
- // request was an implicit request.
- //
+ // From the "scope" parameter of the authorization response.
// Defined by RFC 6749: The OAuth 2.0 Authorization Framework, section 4.2.2
// https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2
String Scope { get; };
@@ -756,10 +650,6 @@ namespace Microsoft.Security.Authentication.OAuth
// 4.1.3.
static TokenRequestParams CreateForAuthorizationCodeRequest(AuthResponse authResponse);
- // Helper method to create for a resource owner password credentials grant request ("password" grant type),
- // initialized with the required parameters, per RFC 6749 section 4.3.2.
- static TokenRequestParams CreateForResourceOwnerPasswordCredentials(String username, String password);
-
// Helper method to create for a client credentials grant request ("client_credentials" grant type), initialized
// with the required parameters, per RFC 6749 section 4.4.2.
static TokenRequestParams CreateForClientCredentials();
diff --git a/test/BackgroundTaskTests/BackgroundTaskBuilder-AppxManifest.xml b/test/BackgroundTaskTests/BackgroundTaskBuilder-AppxManifest.xml
new file mode 100644
index 0000000000..1cfb23ff29
--- /dev/null
+++ b/test/BackgroundTaskTests/BackgroundTaskBuilder-AppxManifest.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+ WindowsAppRuntime.Test.BackgroundTaskBuilder for tests
+ Windows APP SDK
+ taef.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Microsoft.Windows.ApplicationModel.Background.UniversalBGTask.dll
+
+
+
+
+
+
+
+
diff --git a/test/BackgroundTaskTests/BackgroundTaskBuilderTests.cpp b/test/BackgroundTaskTests/BackgroundTaskBuilderTests.cpp
new file mode 100644
index 0000000000..ab050d2307
--- /dev/null
+++ b/test/BackgroundTaskTests/BackgroundTaskBuilderTests.cpp
@@ -0,0 +1,88 @@
+// Copyright (c) Microsoft Corporation and Contributors. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+#include "pch.h"
+
+#include
+#include
+#include
+#include
+
+using namespace WEX::Common;
+using namespace WEX::Logging;
+using namespace WEX::TestExecution;
+using namespace winrt::Windows::ApplicationModel::Background;
+using namespace winrt::Windows::Storage;
+
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+
+namespace BackgroundTaskTests
+{
+ class BackgroundTaskBuilderTests
+ {
+ public:
+ BEGIN_TEST_CLASS(BackgroundTaskBuilderTests)
+ TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA")
+ TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"RestrictedUser")
+ TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
+ TEST_CLASS_PROPERTY(L"UAP:AppxManifest", L"BackgroundTaskBuilder-AppxManifest.xml")
+ END_TEST_CLASS()
+
+ TEST_CLASS_SETUP(BackgroundTaskBuilderTestsClassInit)
+ {
+ ::Test::Bootstrap::SetupPackages();
+ return true;
+ }
+
+ TEST_CLASS_CLEANUP(BackgroundTaskBuilderTestsClassUninit)
+ {
+ ::Test::Bootstrap::CleanupPackages();
+ return true;
+ }
+
+ TEST_METHOD_SETUP(BackgroundTaskBuilderTestsMethodInit)
+ {
+ VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework());
+ return true;
+ }
+
+ TEST_METHOD_CLEANUP(BackgroundTaskBuilderTestsMethodUninit)
+ {
+ VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework());
+ return true;
+ }
+
+ TEST_METHOD(TestBackgroundTaskRegistration)
+ {
+ if (!::Microsoft::Windows::ApplicationModel::Background::Feature_BackgroundTask::IsEnabled())
+ {
+ Log::Result(TestResults::Skipped, L"BackgroundTaskBuilder API Features are not enabled.");
+ return;
+ }
+ winrt::Microsoft::Windows::ApplicationModel::Background::BackgroundTaskBuilder builder;
+ auto trigger = SystemTrigger(SystemTriggerType::TimeZoneChange, false);
+ builder.SetTrigger(trigger);
+ winrt::guid clsId{ 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
+ builder.SetTaskEntryPointClsid(clsId);
+ builder.AddCondition(SystemCondition(SystemConditionType::InternetAvailable));
+ builder.Name(L"TestName");
+ BackgroundTaskRegistration taskReg = builder.Register();
+ // Verifying that BackgroundTask Registration is successful
+ VERIFY_IS_NOT_NULL(taskReg);
+ VERIFY_ARE_EQUAL(taskReg.Name(), L"TestName");
+ VERIFY_IS_TRUE(taskReg.AllTasks().Size() > 0);
+
+ winrt::hstring lookupStr = winrt::to_hstring(taskReg.TaskId());
+ ApplicationDataContainer localSettings = ApplicationData::Current().LocalSettings();
+ auto values = localSettings.Values();
+ auto lookupobj = values.Lookup(lookupStr);
+ winrt::guid comClsId = winrt::unbox_value(lookupobj);
+
+ // Verifying that the CLSID is stored in the local settings
+ VERIFY_IS_NOT_NULL(lookupobj);
+ VERIFY_IS_TRUE(clsId == comClsId);
+ taskReg.Unregister(true);
+ }
+ };
+}
diff --git a/test/BackgroundTaskTests/BackgroundTaskTests.vcxproj b/test/BackgroundTaskTests/BackgroundTaskTests.vcxproj
new file mode 100644
index 0000000000..46e0974bd2
--- /dev/null
+++ b/test/BackgroundTaskTests/BackgroundTaskTests.vcxproj
@@ -0,0 +1,266 @@
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Release
+ ARM64
+
+
+ Debug
+ ARM64
+
+
+
+ 17.0
+ {69FC8020-7E15-46EA-BE4A-767AAFC9C715}
+ Win32Proj
+ BackgroundTaskTests
+ 10.0
+ NativeUnitTestProject
+ true
+
+
+
+ DynamicLibrary
+ true
+ v143
+ Unicode
+ false
+
+
+ DynamicLibrary
+ false
+ v143
+ true
+ Unicode
+ false
+
+
+ DynamicLibrary
+ true
+ v143
+ Unicode
+ false
+
+
+ DynamicLibrary
+ false
+ v143
+ true
+ Unicode
+ false
+
+
+ DynamicLibrary
+ true
+ v143
+ Unicode
+ false
+
+
+ DynamicLibrary
+ false
+ v143
+ true
+ Unicode
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ Use
+ Level3
+ true
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common
+ WIN32;_DEBUG;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Windows
+ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)
+
+
+
+
+ Use
+ Level3
+ true
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common
+ _DEBUG;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Windows
+ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)
+
+
+
+
+ Use
+ Level3
+ true
+ true
+ true
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common
+ WIN32;NDEBUG;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Windows
+ true
+ true
+ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)
+
+
+
+
+ Use
+ Level3
+ true
+ true
+ true
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common
+ NDEBUG;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Windows
+ true
+ true
+ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)
+
+
+
+
+ Use
+ Level3
+ true
+ true
+ true
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common
+ NDEBUG;%(PreprocessorDefinitions)
+ true
+ pch.h
+
+
+ Windows
+ true
+ true
+ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)
+
+
+
+
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
+
+
+
+ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.ApplicationModel.Background.winmd
+ true
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+ {f76b776e-86f5-48c5-8fc7-d2795ecc9746}
+
+
+ {0c4405e6-029e-4363-8273-a9e1fcf057de}
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
\ No newline at end of file
diff --git a/test/BackgroundTaskTests/BackgroundTaskTests.vcxproj.filters b/test/BackgroundTaskTests/BackgroundTaskTests.vcxproj.filters
new file mode 100644
index 0000000000..8e7b15efa5
--- /dev/null
+++ b/test/BackgroundTaskTests/BackgroundTaskTests.vcxproj.filters
@@ -0,0 +1,39 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/BackgroundTaskTests/packages.config b/test/BackgroundTaskTests/packages.config
new file mode 100644
index 0000000000..d5bdb8bcfc
--- /dev/null
+++ b/test/BackgroundTaskTests/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/test/BackgroundTaskTests/pch.cpp b/test/BackgroundTaskTests/pch.cpp
new file mode 100644
index 0000000000..e0bf786609
--- /dev/null
+++ b/test/BackgroundTaskTests/pch.cpp
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft Corporation and Contributors. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
diff --git a/test/BackgroundTaskTests/pch.h b/test/BackgroundTaskTests/pch.h
new file mode 100644
index 0000000000..4d5f0da07c
--- /dev/null
+++ b/test/BackgroundTaskTests/pch.h
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+// pch.h: This is a precompiled header file.
+// Files listed below are compiled only once, improving build performance for future builds.
+// This also affects IntelliSense performance, including code completion and many code browsing features.
+// However, files listed here are ALL re-compiled if any one of them is updated between builds.
+// Do not add files here that you will be updating frequently as this negates the performance advantage.
+
+#ifndef PCH_H
+#define PCH_H
+
+// add headers that you want to pre-compile here
+
+#ifndef INLINE_TEST_METHOD_MARKUP
+#define INLINE_TEST_METHOD_MARKUP
+#endif
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#include
+
+#include "WexTestClass.h"
+#include
+#include
+
+#include
+#endif //PCH_H
diff --git a/test/CameraCaptureUITests/PickersAPITests.cpp b/test/CameraCaptureUITests/PickersAPITests.cpp
new file mode 100644
index 0000000000..1ac27691ed
--- /dev/null
+++ b/test/CameraCaptureUITests/PickersAPITests.cpp
@@ -0,0 +1,147 @@
+#include "pch.h"
+#include "winrt\Microsoft.Windows.Storage.Pickers.h"
+#include "winrt\Microsoft.Windows.Media.Capture.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include "winrt\Microsoft.Windows.Media.Capture.h"
+#include
+
+using namespace std::chrono_literals;
+using namespace WEX::Common;
+using namespace WEX::Logging;
+using namespace WEX::TestExecution;
+using namespace winrt::Windows::Storage;
+
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+
+namespace CameraCaptureUITests
+{
+ // Timeout in milliseconds
+ class PickersAPITests
+ {
+ public:
+ BEGIN_TEST_CLASS(PickersAPITests)
+ TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA")
+ TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"RestrictedUser")
+ //TEST_CLASS_PROPERTY(L"RunAs", L"Restricted")
+ TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
+ TEST_CLASS_PROPERTY(L"UAP:AppxManifest", L"CameraCaptureUI-AppxManifest.xml")
+ END_TEST_CLASS()
+
+ TEST_CLASS_SETUP(ClassInit)
+ {
+ ::Test::Bootstrap::SetupPackages();
+ return true;
+ }
+
+ TEST_CLASS_CLEANUP(ClassUninit)
+ {
+ ::Test::Bootstrap::CleanupPackages();
+ return true;
+ }
+
+ TEST_METHOD_SETUP(MethodInit)
+ {
+ VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework());
+ return true;
+ }
+
+ TEST_METHOD_CLEANUP(MethodUninit)
+ {
+ VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework());
+ return true;
+ }
+
+ // The unit tests will be updated,first test might is there for testing purpose locally.
+ // Focusing solely on functional tests for now.
+ TEST_METHOD(CapturePhoto_ShouldReturnFile_Desktop)
+ {
+ if (!::Microsoft::Windows::Media::Capture::Feature_CameraCaptureUI::IsEnabled())
+ {
+ Log::Result(TestResults::Skipped, L"CameraCaptureUI API Features are not enabled.");
+ return;
+ }
+ try
+ {
+ auto parentWindow = ::GetForegroundWindow();
+ winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) };
+ winrt::Microsoft::Windows::Media::Capture::CameraCaptureUI cameraUI(windowId);
+ return;
+ // Configure Photo Settings
+ cameraUI.PhotoSettings().Format(winrt::Microsoft::Windows::Media::Capture::CameraCaptureUIPhotoFormat::Png);
+ cameraUI.PhotoSettings().AllowCropping(false);
+ // Act
+ auto photoOperation = cameraUI.CaptureFileAsync(winrt::Microsoft::Windows::Media::Capture::CameraCaptureUIMode::Photo);
+ auto photo = photoOperation.get();
+
+ // Assert
+ if (photo != nullptr)
+ {
+ Log::Comment(L"Photo capture was successful.");
+ VERIFY_IS_TRUE(photo.Name().c_str() != nullptr);
+ }
+ else
+ {
+ Log::Error(L"Photo capture failed or was canceled.");
+ VERIFY_FAIL(L"Photo capture returned null.");
+ }
+ }
+ catch (const winrt::hresult_error& ex)
+ {
+ Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str());
+ VERIFY_FAIL(L"Exception occurred during photo capture.");
+ }
+ catch (const std::exception& ex)
+ {
+ Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str());
+ VERIFY_FAIL(L"Standard exception occurred during photo capture.");
+ }
+ }
+
+ TEST_METHOD(FileSavePicker_ShouldCreateNewFile)
+ {
+ try
+ {
+ auto parentWindow = ::GetForegroundWindow();
+ winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) };
+ //{
+ // winrt::Microsoft::Windows::Media::Capture::CameraCaptureUI cameraUI(windowId);
+ //}
+ winrt::Microsoft::Windows::Storage::Pickers::FileSavePicker savePicker(windowId);
+ //savePicker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary);
+ savePicker.FileTypeChoices().Insert(L"Plain Text", winrt::single_threaded_vector({ L".txt" }));
+ savePicker.SuggestedFileName(L"test.txt");
+ // Act
+ auto fileOperation = savePicker.PickSaveFileAsync();
+ auto file = fileOperation.get();
+
+ // Assert
+ if (file != nullptr)
+ {
+ Log::Comment(L"File save was successful.");
+ VERIFY_IS_TRUE(file.Name().c_str() != nullptr);
+ }
+ else
+ {
+ Log::Error(L"Photo capture failed or was canceled.");
+ VERIFY_FAIL(L"File save returned null.");
+ }
+ }
+ catch (const winrt::hresult_error& ex)
+ {
+ Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str());
+ VERIFY_FAIL(L"Exception occurred during photo capture.");
+ }
+ catch (const std::exception& ex)
+ {
+ Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str());
+ VERIFY_FAIL(L"Standard exception occurred during photo capture.");
+ }
+ }
+ };
+}
diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp
new file mode 100644
index 0000000000..8bbe369856
--- /dev/null
+++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp
@@ -0,0 +1,142 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "AssemblyInfo.h"
+
+#include
+#include
+
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+
+namespace WAR = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime;
+
+namespace Test::CompatibilityTests
+{
+ class CompatibilityTests
+ {
+ public:
+ BEGIN_TEST_CLASS(CompatibilityTests)
+ TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") // MTA is required for ::Test::Bootstrap::SetupPackages()
+ TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"RestrictedUser")
+ TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") // each test sets its own CompatibilityOptions
+ END_TEST_CLASS()
+
+ TEST_CLASS_SETUP(ClassSetup)
+ {
+ ::Test::Bootstrap::SetupPackages();
+ return true;
+ }
+
+ TEST_CLASS_CLEANUP(ClassCleanup)
+ {
+ ::Test::Bootstrap::CleanupPackages();
+ return true;
+ }
+
+ TEST_METHOD_SETUP(MethodInit)
+ {
+ VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework());
+
+ // The test method setup and execution is on a different thread than the class setup.
+ // Initialize the framework for the test thread.
+ ::Test::Bootstrap::SetupBootstrap();
+ return true;
+ }
+
+ TEST_METHOD_CLEANUP(MethodUninit)
+ {
+ VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework());
+ ::Test::Bootstrap::CleanupBootstrap();
+ return true;
+ }
+
+ TEST_METHOD(CanSetCompatibilityOptions)
+ {
+ WEX::Logging::Log::Comment(WEX::Common::String(L"Starting CanSetCompatibilityOptions..."));
+ winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::CompatibilityOptions options;
+ WEX::Logging::Log::Comment(WEX::Common::String(L" Created CompatibilityOptions..."));
+ options.PatchMode1({ WINDOWSAPPSDK_RELEASE_MAJOR, WINDOWSAPPSDK_RELEASE_MINOR, 3 });
+ options.Apply();
+ WEX::Logging::Log::Comment(WEX::Common::String(L" Applied CompatibilityOptions..."));
+
+ try
+ {
+ WEX::Logging::Log::Comment(WEX::Common::String(L" Applying CompatibilityOptions with different patch mode..."));
+ winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::CompatibilityOptions options2;
+ options2.PatchMode1({ WINDOWSAPPSDK_RELEASE_MAJOR, WINDOWSAPPSDK_RELEASE_MINOR, 6 });
+ options2.Apply();
+ VERIFY_FAIL(L"Success is not expected when setting a different configuration");
+ }
+ catch (winrt::hresult_error& e)
+ {
+ VERIFY_ARE_EQUAL(E_ILLEGAL_STATE_CHANGE, e.code());
+ }
+
+ try
+ {
+ WEX::Logging::Log::Comment(WEX::Common::String(L" Applying CompatibilityOptions with no patch mode..."));
+ winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::CompatibilityOptions options3;
+ options3.Apply();
+ VERIFY_FAIL(L"Success is not expected when setting a different configuration");
+ }
+ catch (winrt::hresult_error& e)
+ {
+ VERIFY_ARE_EQUAL(E_ILLEGAL_STATE_CHANGE, e.code());
+ }
+ }
+
+ TEST_METHOD(VerifyNoMatchingPatchModeBehavior)
+ {
+ WEX::Logging::Log::Comment(WEX::Common::String(L"Setting CompatibilityOptions with no matching patch mode"));
+ winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::CompatibilityOptions options;
+ options.PatchMode1({ 0, 8, 3 });
+ options.PatchMode2({ 1, 1, 4 });
+ options.Apply();
+
+ // Set a CompatibilityOptions with no patch mode, which should be allowed since neither
+ // set a patch mode matching the runtime version.
+ winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::CompatibilityOptions options2;
+ options2.Apply();
+ }
+
+ TEST_METHOD(VerifyConflictingPatchModeBehavior)
+ {
+ WEX::Logging::Log::Comment(WEX::Common::String(L"Setting CompatibilityOptions with conflicting patch modes"));
+ winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::CompatibilityOptions options;
+ options.PatchMode1({ 1, 7, 3 });
+ options.PatchMode2({ 1, 7, 6 }); // Conflicting patch mode for 1.7.x! Apply should fail.
+ try
+ {
+ options.Apply();
+ VERIFY_FAIL(L"Success is not expected when setting a conflicting configuration");
+ }
+ catch (winrt::hresult_error& e)
+ {
+ VERIFY_ARE_EQUAL(E_INVALIDARG, e.code());
+ }
+ }
+
+ TEST_METHOD(VerifyDisabledChanges)
+ {
+ winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::CompatibilityOptions options;
+ options.PatchMode1({ WINDOWSAPPSDK_RELEASE_MAJOR, WINDOWSAPPSDK_RELEASE_MINOR, 3 });
+ options.DisabledChanges().Append((WAR::CompatibilityChange)12345);
+ options.DisabledChanges().Append((WAR::CompatibilityChange)23456);
+ options.DisabledChanges().Append((WAR::CompatibilityChange)34567);
+ options.DisabledChanges().Append(WAR::CompatibilityChange::None); // just to confirm compilation using a real enum value
+ options.Apply();
+
+ WEX::Logging::Log::Comment(WEX::Common::String(L"CompatibilityOptions with DisabledChanges applied."));
+
+ // Verify that the specified DisabledChanges are disabled.
+ VERIFY_IS_FALSE((WinAppSdk::Containment::IsChangeEnabled<12345, WinAppSDK_Security>()));
+ VERIFY_IS_FALSE((WinAppSdk::Containment::IsChangeEnabled<23456, WinAppSDK_Security>()));
+ VERIFY_IS_FALSE((WinAppSdk::Containment::IsChangeEnabled<34567, WinAppSDK_Security>()));
+
+ // A different value not in DisabledChanges should remain enabled.
+ VERIFY_IS_TRUE((WinAppSdk::Containment::IsChangeEnabled<99999, WinAppSDK_Security>()));
+ }
+ };
+}
diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.testdef b/test/Compatibility/CompatibilityTests/CompatibilityTests.testdef
new file mode 100644
index 0000000000..74ab26c2d6
--- /dev/null
+++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.testdef
@@ -0,0 +1,11 @@
+{
+ "Tests": [
+ {
+ "Description": "CompatibilityOptions tests (x86 not currently enabled)",
+ "Filename": "CompatibilityTests.dll",
+ "Parameters": "",
+ "Architectures": ["x64", "arm64"],
+ "Status": "Enabled"
+ }
+ ]
+}
diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj
new file mode 100644
index 0000000000..ee37756ff4
--- /dev/null
+++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj
@@ -0,0 +1,152 @@
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ 17.0
+ Win32Proj
+ {040bb64b-012e-4e4f-bb02-e85ef46d3475}
+ CompatibilityTests
+ 10.0
+
+
+ DynamicLibrary
+ v143
+ Unicode
+
+
+ false
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Use
+ true
+ pch.h
+ $(RepoRoot)\test\inc;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common
+ $(RepoRoot);%(AdditionalIncludeDirectories)
+
+
+ Windows
+ onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
+ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+
+
+
+
+ WIN32;%(PreprocessorDefinitions)
+
+
+
+
+ Create
+
+
+ $(RepoRoot)\build\VersionInfo;%(AdditionalIncludeDirectories)
+
+
+
+
+
+
+
+
+
+
+ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.ApplicationModel.WindowsAppRuntime.winmd
+ true
+
+
+
+
+ {f76b776e-86f5-48c5-8fc7-d2795ecc9746}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj.filters b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj.filters
new file mode 100644
index 0000000000..dc1c446641
--- /dev/null
+++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj.filters
@@ -0,0 +1,36 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/test/Compatibility/CompatibilityTests/packages.config b/test/Compatibility/CompatibilityTests/packages.config
new file mode 100644
index 0000000000..63e5716140
--- /dev/null
+++ b/test/Compatibility/CompatibilityTests/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/test/Compatibility/CompatibilityTests/pch.cpp b/test/Compatibility/CompatibilityTests/pch.cpp
new file mode 100644
index 0000000000..a77728ba07
--- /dev/null
+++ b/test/Compatibility/CompatibilityTests/pch.cpp
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
diff --git a/test/Compatibility/CompatibilityTests/pch.h b/test/Compatibility/CompatibilityTests/pch.h
new file mode 100644
index 0000000000..d9ababf69f
--- /dev/null
+++ b/test/Compatibility/CompatibilityTests/pch.h
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#ifndef PCH_H
+#define PCH_H
+
+#include
+
+#include
+
+#include
+#include
+
+#include
+
+#include
+
+#include
+#include
+#include
+
+#include
+
+#endif //PCH_H
diff --git a/test/Compatibility/Test_CompatibilitySetter_CPP/Test_CompatibilitySetter_CPP.vcxproj b/test/Compatibility/Test_CompatibilitySetter_CPP/Test_CompatibilitySetter_CPP.vcxproj
new file mode 100644
index 0000000000..827c45f4b5
--- /dev/null
+++ b/test/Compatibility/Test_CompatibilitySetter_CPP/Test_CompatibilitySetter_CPP.vcxproj
@@ -0,0 +1,169 @@
+
+
+
+
+ 1.7.3
+ 1.8.2
+
+ None, None, (CompatibilityChange)23456, None
+
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ 17.0
+ Win32Proj
+ {7fafcbd2-bdd5-433c-b3d4-700b5c5a67aa}
+ TestCompatibilitySetterCPP
+ 10.0
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Use
+ true
+ pch.h
+ $(RepoRoot)\test\inc;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common
+ $(RepoRoot);%(AdditionalIncludeDirectories)
+
+
+ Windows
+ onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;%(AdditionalDependencies)
+ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+
+
+
+
+ WIN32;%(PreprocessorDefinitions)
+
+
+
+
+ Create
+
+
+
+
+
+ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.ApplicationModel.WindowsAppRuntime.winmd
+ true
+
+
+
+
+ {f76b776e-86f5-48c5-8fc7-d2795ecc9746}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
diff --git a/test/Compatibility/Test_CompatibilitySetter_CPP/Test_CompatibilitySetter_CPP.vcxproj.filters b/test/Compatibility/Test_CompatibilitySetter_CPP/Test_CompatibilitySetter_CPP.vcxproj.filters
new file mode 100644
index 0000000000..a8a65633bf
--- /dev/null
+++ b/test/Compatibility/Test_CompatibilitySetter_CPP/Test_CompatibilitySetter_CPP.vcxproj.filters
@@ -0,0 +1,17 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
\ No newline at end of file
diff --git a/test/Compatibility/Test_CompatibilitySetter_CPP/main.cpp b/test/Compatibility/Test_CompatibilitySetter_CPP/main.cpp
new file mode 100644
index 0000000000..9c977dbf3e
--- /dev/null
+++ b/test/Compatibility/Test_CompatibilitySetter_CPP/main.cpp
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include
+
+namespace Microsoft::Windows::ApplicationModel::WindowsAppRuntime::Compatibility
+{
+ namespace AutoInitialize { void Initialize(); };
+}
+
+int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/)
+{
+ // Note: This test app currently only tests that the compatibility properties specified in
+ // the project file generates the Initialize() function and compiles successfully.
+ Microsoft::Windows::ApplicationModel::WindowsAppRuntime::Compatibility::AutoInitialize::Initialize();
+ // Apps using the or project properties should
+ // NOT directly call the above function. This test calls it just to verify that the function is generated.
+
+ return 0;
+}
diff --git a/test/Compatibility/Test_CompatibilitySetter_CPP/pch.cpp b/test/Compatibility/Test_CompatibilitySetter_CPP/pch.cpp
new file mode 100644
index 0000000000..a77728ba07
--- /dev/null
+++ b/test/Compatibility/Test_CompatibilitySetter_CPP/pch.cpp
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
diff --git a/test/Compatibility/Test_CompatibilitySetter_CPP/pch.h b/test/Compatibility/Test_CompatibilitySetter_CPP/pch.h
new file mode 100644
index 0000000000..7efade56bc
--- /dev/null
+++ b/test/Compatibility/Test_CompatibilitySetter_CPP/pch.h
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#ifndef PCH_H
+#define PCH_H
+
+#include
+
+#include
+
+#include
+#include
+
+#include
+
+//#include
+
+//#include
+//#include
+//#include
+
+#include
+
+#endif //PCH_H
diff --git a/test/Compatibility/Test_CompatibilitySetter_CS/Program.cs b/test/Compatibility/Test_CompatibilitySetter_CS/Program.cs
new file mode 100644
index 0000000000..a66d210f15
--- /dev/null
+++ b/test/Compatibility/Test_CompatibilitySetter_CS/Program.cs
@@ -0,0 +1,19 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+
+using System;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ // Note: This test app currently only tests that the compatibility properties specified in
+ // the project file generates the ConfigureCompatibility() function and compiles successfully.
+ Microsoft.Windows.ApplicationModel.WindowsAppRuntime.Compatibility.AutoInitialize.ConfigureCompatibility();
+ // Apps using the or project properties should
+ // NOT directly call the above function. This test calls it just to verify that the function is generated.
+
+ Console.WriteLine("hello world");
+ Environment.Exit(0);
+ }
+}
diff --git a/test/Compatibility/Test_CompatibilitySetter_CS/Test_CompatibilitySetter_CS.csproj b/test/Compatibility/Test_CompatibilitySetter_CS/Test_CompatibilitySetter_CS.csproj
new file mode 100644
index 0000000000..603519686e
--- /dev/null
+++ b/test/Compatibility/Test_CompatibilitySetter_CS/Test_CompatibilitySetter_CS.csproj
@@ -0,0 +1,33 @@
+
+
+
+ Exe
+ net6.0
+ net6.0-windows10.0.19041.0
+ 10.0.17763.0
+ x86;x64;arm64;AnyCPU
+
+
+
+
+
+
+
+
+ 1.7.3
+ 1.8.2
+
+ None, None, (CompatibilityChange)23456, None
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Default/Test_DeploymentManagerAutoInitialize_CPP_Default.vcxproj b/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Default/Test_DeploymentManagerAutoInitialize_CPP_Default.vcxproj
index d45927dca1..4b42c2047d 100644
--- a/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Default/Test_DeploymentManagerAutoInitialize_CPP_Default.vcxproj
+++ b/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Default/Test_DeploymentManagerAutoInitialize_CPP_Default.vcxproj
@@ -104,6 +104,12 @@
+
+
+ true
+
+
+
$(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.ApplicationModel.WindowsAppRuntime.winmd
diff --git a/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_Default/Test_DeploymentManagerAutoInitialize_CPP_Options_Default.vcxproj b/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_Default/Test_DeploymentManagerAutoInitialize_CPP_Options_Default.vcxproj
index c12c69907e..e3d453339b 100644
--- a/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_Default/Test_DeploymentManagerAutoInitialize_CPP_Options_Default.vcxproj
+++ b/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_Default/Test_DeploymentManagerAutoInitialize_CPP_Options_Default.vcxproj
@@ -105,6 +105,12 @@
+
+
+ true
+
+
+
$(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.ApplicationModel.WindowsAppRuntime.winmd
diff --git a/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_Defined/Test_DeploymentManagerAutoInitialize_CPP_Options_Defined.vcxproj b/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_Defined/Test_DeploymentManagerAutoInitialize_CPP_Options_Defined.vcxproj
index 7f5cd6010a..bd4cd76a70 100644
--- a/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_Defined/Test_DeploymentManagerAutoInitialize_CPP_Options_Defined.vcxproj
+++ b/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_Defined/Test_DeploymentManagerAutoInitialize_CPP_Options_Defined.vcxproj
@@ -105,6 +105,12 @@
+
+
+ true
+
+
+
$(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.ApplicationModel.WindowsAppRuntime.winmd
diff --git a/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_None/Test_DeploymentManagerAutoInitialize_CPP_Options_None.vcxproj b/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_None/Test_DeploymentManagerAutoInitialize_CPP_Options_None.vcxproj
index 2fea49a7fe..4ead437416 100644
--- a/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_None/Test_DeploymentManagerAutoInitialize_CPP_Options_None.vcxproj
+++ b/test/Deployment/Test_DeploymentManagerAutoInitialize/CPP/Test_DeploymentManagerAutoInitialize_CPP_Options_None/Test_DeploymentManagerAutoInitialize_CPP_Options_None.vcxproj
@@ -105,6 +105,12 @@
+
+
+ true
+
+
+
$(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.ApplicationModel.WindowsAppRuntime.winmd
diff --git a/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Default/Test_DeploymentManagerAutoInitialize_CS_Default.csproj b/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Default/Test_DeploymentManagerAutoInitialize_CS_Default.csproj
index cdd19c17fb..f50fac0f73 100644
--- a/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Default/Test_DeploymentManagerAutoInitialize_CS_Default.csproj
+++ b/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Default/Test_DeploymentManagerAutoInitialize_CS_Default.csproj
@@ -28,4 +28,9 @@
+
+ true
+
+
+
diff --git a/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_Default/Test_DeploymentManagerAutoInitialize_CS_Options_Default.csproj b/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_Default/Test_DeploymentManagerAutoInitialize_CS_Options_Default.csproj
index 667c0a8d09..22d03b0f0d 100644
--- a/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_Default/Test_DeploymentManagerAutoInitialize_CS_Options_Default.csproj
+++ b/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_Default/Test_DeploymentManagerAutoInitialize_CS_Options_Default.csproj
@@ -32,4 +32,9 @@
$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_DEPLOYMENTMANAGER_AUTO_INITIALIZE_OPTIONS_DEFAULT
+
+ true
+
+
+
diff --git a/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_Defined/Test_DeploymentManagerAutoInitialize_CS_Options_Defined.csproj b/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_Defined/Test_DeploymentManagerAutoInitialize_CS_Options_Defined.csproj
index 9c2e6cd230..7cd30f6bbd 100644
--- a/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_Defined/Test_DeploymentManagerAutoInitialize_CS_Options_Defined.csproj
+++ b/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_Defined/Test_DeploymentManagerAutoInitialize_CS_Options_Defined.csproj
@@ -32,4 +32,21 @@
$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_DEPLOYMENTMANAGER_AUTO_INITIALIZE_OPTIONS_ONERROR_SHOWUI
+
+ true
+
+
+
+
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_BOOTSTRAP
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_DEPLOYMENTMANAGER
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_UNDOCKEDREGFREEWINRT
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_COMPATIBILITY
+
+
+
+
+
+
+
diff --git a/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_None/Test_DeploymentManagerAutoInitialize_CS_Options_None.csproj b/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_None/Test_DeploymentManagerAutoInitialize_CS_Options_None.csproj
index dd7cb976ff..621efc53c0 100644
--- a/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_None/Test_DeploymentManagerAutoInitialize_CS_Options_None.csproj
+++ b/test/Deployment/Test_DeploymentManagerAutoInitialize/CS/Test_DeploymentManagerAutoInitialize_CS_Options_None/Test_DeploymentManagerAutoInitialize_CS_Options_None.csproj
@@ -32,4 +32,9 @@
$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_DEPLOYMENTMANAGER_AUTO_INITIALIZE_OPTIONS_NONE
+
+ true
+
+
+
diff --git a/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Default/Test_BootstrapAutoInitialize_CPP_Default.vcxproj b/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Default/Test_BootstrapAutoInitialize_CPP_Default.vcxproj
index 6ae0e95ea3..d6e38a1fc7 100644
--- a/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Default/Test_BootstrapAutoInitialize_CPP_Default.vcxproj
+++ b/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Default/Test_BootstrapAutoInitialize_CPP_Default.vcxproj
@@ -104,6 +104,12 @@
+
+
+ true
+
+
+
{f76b776e-86f5-48c5-8fc7-d2795ecc9746}
diff --git a/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_Default/Test_BootstrapAutoInitialize_CPP_Options_Default.vcxproj b/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_Default/Test_BootstrapAutoInitialize_CPP_Options_Default.vcxproj
index 06b51e1b63..00fff1528a 100644
--- a/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_Default/Test_BootstrapAutoInitialize_CPP_Options_Default.vcxproj
+++ b/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_Default/Test_BootstrapAutoInitialize_CPP_Options_Default.vcxproj
@@ -105,6 +105,12 @@
+
+
+ true
+
+
+
{f76b776e-86f5-48c5-8fc7-d2795ecc9746}
diff --git a/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_Defined/Test_BootstrapAutoInitialize_CPP_Options_Defined.vcxproj b/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_Defined/Test_BootstrapAutoInitialize_CPP_Options_Defined.vcxproj
index c56712e266..5a34d17988 100644
--- a/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_Defined/Test_BootstrapAutoInitialize_CPP_Options_Defined.vcxproj
+++ b/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_Defined/Test_BootstrapAutoInitialize_CPP_Options_Defined.vcxproj
@@ -109,6 +109,12 @@
+
+
+ true
+
+
+
{f76b776e-86f5-48c5-8fc7-d2795ecc9746}
diff --git a/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_None/Test_BootstrapAutoInitialize_CPP_Options_None.vcxproj b/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_None/Test_BootstrapAutoInitialize_CPP_Options_None.vcxproj
index 2fe73168e1..cef7c4d1b9 100644
--- a/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_None/Test_BootstrapAutoInitialize_CPP_Options_None.vcxproj
+++ b/test/DynamicDependency/Test_BootstrapAutoInitialize/CPP/Test_BootstrapAutoInitialize_CPP_Options_None/Test_BootstrapAutoInitialize_CPP_Options_None.vcxproj
@@ -105,6 +105,12 @@
+
+
+ true
+
+
+
{f76b776e-86f5-48c5-8fc7-d2795ecc9746}
diff --git a/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Default/Test_BootstrapAutoInitialize_CS_Default.csproj b/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Default/Test_BootstrapAutoInitialize_CS_Default.csproj
index 7b04aad9e2..b047757058 100644
--- a/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Default/Test_BootstrapAutoInitialize_CS_Default.csproj
+++ b/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Default/Test_BootstrapAutoInitialize_CS_Default.csproj
@@ -44,4 +44,9 @@
+
+ true
+
+
+
diff --git a/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_Default/Test_BootstrapAutoInitialize_CS_Options_Default.csproj b/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_Default/Test_BootstrapAutoInitialize_CS_Options_Default.csproj
index 698b55808d..13e52bf6e9 100644
--- a/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_Default/Test_BootstrapAutoInitialize_CS_Options_Default.csproj
+++ b/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_Default/Test_BootstrapAutoInitialize_CS_Options_Default.csproj
@@ -48,4 +48,9 @@
$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT
+
+ true
+
+
+
diff --git a/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_Defined/Test_BootstrapAutoInitialize_CS_Options_Defined.csproj b/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_Defined/Test_BootstrapAutoInitialize_CS_Options_Defined.csproj
index decac1ca42..0e4a8f04b5 100644
--- a/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_Defined/Test_BootstrapAutoInitialize_CS_Options_Defined.csproj
+++ b/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_Defined/Test_BootstrapAutoInitialize_CS_Options_Defined.csproj
@@ -52,4 +52,9 @@
$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP
+
+ true
+
+
+
diff --git a/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_None/Test_BootstrapAutoInitialize_CS_Options_None.csproj b/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_None/Test_BootstrapAutoInitialize_CS_Options_None.csproj
index 76cd979f05..d115efc614 100644
--- a/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_None/Test_BootstrapAutoInitialize_CS_Options_None.csproj
+++ b/test/DynamicDependency/Test_BootstrapAutoInitialize/CS/Test_BootstrapAutoInitialize_CS_Options_None/Test_BootstrapAutoInitialize_CS_Options_None.csproj
@@ -48,4 +48,9 @@
$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_NONE
+
+ true
+
+
+
diff --git a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml
index d48537271f..218336622f 100644
--- a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml
+++ b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml
@@ -34,6 +34,28 @@
in the same manifest with the same ActivatableClassId (regardless in same
or different s).
-->
+
+
+
+ Microsoft.WindowsAppRuntime.dll
+
+
+
+
+
+ Microsoft.WindowsAppRuntime.dll
+
+
+
+
+
+
+
+
+
+
+
+
Microsoft.WindowsAppRuntime.dll
@@ -157,6 +179,12 @@
+
+
+ Microsoft.WindowsAppRuntime.dll
+
+
+
PushNotificationsLongRunningTask.ProxyStub.dll
diff --git a/test/OAuth2ManagerTests/OAuth2APITests.cpp b/test/OAuth2ManagerTests/OAuth2APITests.cpp
new file mode 100644
index 0000000000..4b886e2cb8
--- /dev/null
+++ b/test/OAuth2ManagerTests/OAuth2APITests.cpp
@@ -0,0 +1,1224 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#include "pch.h"
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "OAuth2APITests.h"
+
+// NOTE: Thise files don't include everything they need, hence they are here last
+#include
+#include
+
+#include // Included last to enable the most features
+
+using namespace std::literals;
+using namespace WEX::Common;
+using namespace WEX::Logging;
+using namespace WEX::TestExecution;
+using namespace winrt::Microsoft::Security::Authentication::OAuth;
+using namespace winrt::Windows::Data::Json;
+using namespace winrt::Windows::Foundation;
+using namespace winrt::Windows::Foundation::Collections;
+using namespace winrt::Windows::Security::Cryptography;
+using namespace winrt::Windows::Security::Cryptography::Core;
+using namespace winrt::Windows::Storage::Streams;
+
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+EXTERN_C IMAGE_DOS_HEADER __ImageBase;
+
+namespace OAuth2ManagerTests
+{
+ class OAuth2APITests
+ {
+ public:
+ BEGIN_TEST_CLASS(OAuth2APITests)
+ TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA")
+ END_TEST_CLASS()
+
+ TEST_METHOD_SETUP(MethodInit)
+ {
+ VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework());
+ return true;
+ }
+
+ TEST_METHOD_CLEANUP(MethodUninit)
+ {
+ VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework());
+ return true;
+ }
+
+ TEST_CLASS_SETUP(Setup)
+ {
+ // Initialize the Windows Runtime
+ winrt::init_apartment();
+ Test::Bootstrap::Setup();
+ Test::Packages::WapProj::AddPackage(Test::TAEF::GetDeploymentDir(), L"OAuthTestAppPackage", L".msix");
+
+ // Detour ShellExecuteW
+ ::DetourTransactionBegin();
+ ::DetourUpdateThread(::GetCurrentThread());
+ if (auto err = ::DetourAttach(reinterpret_cast(&RealShellExecuteW), &DetouredShellExecuteW))
+ {
+ Log::Error(WEX::Common::String().Format(L"DetourAttach failed: %d", err));
+ ::DetourTransactionAbort();
+ return false;
+ }
+ ::DetourTransactionCommit();
+
+ // Initialize the HTTP server we use for token requests
+ VERIFY_WIN32_SUCCEEDED(::HttpInitialize(HTTPAPI_VERSION_2, HTTP_INITIALIZE_SERVER, nullptr));
+ VERIFY_WIN32_SUCCEEDED(::HttpCreateRequestQueue(HTTPAPI_VERSION_2, nullptr, nullptr, 0, &m_requestQueue));
+ VERIFY_WIN32_SUCCEEDED(::HttpCreateServerSession(HTTPAPI_VERSION_2, &m_serverSessionId, 0));
+ VERIFY_WIN32_SUCCEEDED(::HttpCreateUrlGroup(m_serverSessionId, &m_urlGroup, 0));
+
+ HTTP_BINDING_INFO bindingInfo = {};
+ bindingInfo.Flags.Present = 1;
+ bindingInfo.RequestQueueHandle = m_requestQueue;
+ VERIFY_WIN32_SUCCEEDED(::HttpSetUrlGroupProperty(m_urlGroup, HttpServerBindingProperty, &bindingInfo,
+ static_cast(sizeof(bindingInfo))));
+
+ // Find an open port; note that ports in the low 50000s are frequently claimed, hence the large iteration bounds
+ ULONG err = 0;
+ for (std::uint16_t i = 0; i < 500; ++i)
+ {
+ wchar_t buffer[18 + 5 + 1]; // 18 for base URL, 5 for port number, 1 for null terminator
+ std::swprintf(buffer, std::size(buffer), L"http://127.0.0.1:%d/", m_serverPort);
+
+ err = ::HttpAddUrlToUrlGroup(m_urlGroup, buffer, 0, 0);
+ if (err == NO_ERROR)
+ {
+ m_serverUrlBase = std::wstring(buffer); // Copy the buffer to a std::wstring to avoid dangling pointer
+ break;
+ }
+
+ ++m_serverPort;
+ }
+
+ VERIFY_WIN32_SUCCEEDED(err, L"Looking for an open port");
+ m_httpServerThread = std::thread([this]
+ {
+ RunHttpServer();
+ });
+
+ return true;
+ }
+
+ TEST_CLASS_CLEANUP(Cleanup)
+ {
+ ::Test::Bootstrap::CleanupPackages();
+ Test::Packages::RemovePackage(L"OAuthTestAppPackage_1.0.0.0_" WINDOWSAPPRUNTIME_TEST_PACKAGE_DDLM_ARCHITECTURE L"__8wekyb3d8bbwe");
+
+ // Tear down the HTTP server
+ m_serverShutdownEvent.SetEvent();
+ m_httpServerThread.join();
+
+ if (m_urlGroup)
+ {
+ ::HttpCloseUrlGroup(m_urlGroup);
+ m_urlGroup = 0;
+ }
+
+ if (m_serverSessionId)
+ {
+ ::HttpCloseServerSession(m_serverSessionId);
+ m_serverSessionId = 0;
+ }
+
+ if (m_requestQueue)
+ {
+ ::HttpCloseRequestQueue(m_requestQueue);
+ m_requestQueue = nullptr;
+ }
+
+ ::HttpTerminate(HTTP_INITIALIZE_SERVER, nullptr);
+
+ // Clean up our detours
+ ::DetourTransactionBegin();
+ ::DetourUpdateThread(::GetCurrentThread());
+ ::DetourDetach(reinterpret_cast(&RealShellExecuteW), &DetouredShellExecuteW);
+ ::DetourTransactionCommit();
+
+ Test::Bootstrap::Cleanup();
+
+ return true;
+ }
+
+ template
+ static void WaitWithTimeout(const IAsyncOperation& op, AsyncStatus expectedStatus)
+ {
+ wil::unique_event event(wil::EventOptions::None);
+ op.Completed([event = event.get()](const IAsyncOperation&, AsyncStatus)
+ {
+ ::SetEvent(event);
+ });
+
+ // 10 seconds is beyond
+ if (::WaitForSingleObject(event.get(), 10000) == WAIT_OBJECT_0)
+ {
+ VERIFY_ARE_EQUAL(expectedStatus, op.Status());
+ return;
+ }
+
+ Log::Warning(L"Timed out waiting for IAsyncOperation to complete; cancelling...");
+ op.Cancel();
+
+ // Cancel should cause the operation to complete with the cancellation
+ if (::WaitForSingleObject(event.get(), 1000) != WAIT_OBJECT_0)
+ {
+ // Lambda holds a reference to the event. Best just to leak it here
+ Log::Warning(L"Failed to cancel IAsyncOperation; leaking event");
+ event.release();
+ }
+
+ VERIFY_FAIL(L"IAsyncOperation did not complete in a reasonable amount of time");
+ }
+
+ template
+ static void VerifyErrorNull(const ErrorT& error)
+ {
+ if (error)
+ {
+ Log::Error(WEX::Common::String().Format(L"Error object expected to be null! Message: %ls",
+ error.ErrorDescription().c_str()));
+ }
+ VERIFY_IS_NULL(error);
+ }
+
+ AuthResponse InitiateAndWaitForSuccessfulAuthResponse(const AuthRequestParams& params)
+ {
+ auto op = OAuth2Manager::RequestAuthWithParamsAsync(winrt::Microsoft::UI::WindowId(123456789), Uri{ auth_url }, params);
+ auto par = params.CodeChallenge();
+ WaitWithTimeout(op, AsyncStatus::Completed);
+
+ auto result = op.GetResults();
+ VerifyErrorNull(result.Failure());
+
+ auto response = result.Response();
+ VERIFY_IS_NOT_NULL(response);
+ VERIFY_ARE_EQUAL(params.State(), response.State());
+
+ return response;
+ }
+
+ TokenResponse RequestTokenAndWaitForSuccessfulResponse(const TokenRequestParams& params, const ClientAuthentication& auth = { nullptr })
+ {
+ IAsyncOperation op{ nullptr };
+ if (auth)
+ {
+ op = OAuth2Manager::RequestTokenAsync(Uri{ m_serverUrlBase + L"token" }, params, auth);
+ }
+ else
+ {
+ op = OAuth2Manager::RequestTokenAsync(Uri{ m_serverUrlBase + L"token" }, params);
+ }
+ WaitWithTimeout(op, AsyncStatus::Completed);
+
+ auto result = op.GetResults();
+ VerifyErrorNull(result.Failure());
+
+ auto response = result.Response();
+ VERIFY_IS_NOT_NULL(response);
+ VERIFY_ARE_EQUAL(token, response.AccessToken());
+ VERIFY_ARE_EQUAL(L"Bearer", response.TokenType());
+ VERIFY_ARE_EQUAL(3600, response.ExpiresIn());
+ VERIFY_ARE_EQUAL(refresh_token, response.RefreshToken());
+ VERIFY_ARE_EQUAL(L"all", response.Scope());
+
+ return response;
+ }
+
+ static inline constexpr std::wstring_view auth_url = L"http://oauthtests.com/oauth"sv;
+
+ // Redirect URIs
+ static inline constexpr std::wstring_view localhost_redirect_uri = L"http://127.0.0.1/oauth"sv;
+ static inline constexpr std::wstring_view protocol_redirect_uri = L"oauthtestapp:oauth"sv;
+
+ void DoEndToEndAuthCodeTest(const AuthRequestParams& requestParams)
+ {
+ auto authResponse = InitiateAndWaitForSuccessfulAuthResponse(requestParams);
+ VERIFY_IS_FALSE(authResponse.Code().empty());
+
+ auto tokenParams = TokenRequestParams::CreateForAuthorizationCodeRequest(authResponse);
+ RequestTokenAndWaitForSuccessfulResponse(tokenParams);
+ }
+
+ void DoBasicEndToEndAuthCodeTest(std::wstring_view clientId, std::wstring_view redirectUri)
+ {
+ auto requestParams = AuthRequestParams::CreateForAuthorizationCodeRequest(clientId, Uri{ redirectUri });
+ DoEndToEndAuthCodeTest(requestParams);
+ }
+
+ TEST_METHOD(Protocol_AuthorizationCode_BasicEndToEnd)
+ {
+ if (!::Microsoft::Security::Authentication::OAuth::Feature_OAuth::IsEnabled())
+ {
+ Log::Result(TestResults::Skipped, L"OAuth2Manager API Features are not enabled.");
+ return;
+ }
+ static constexpr std::wstring_view client_id = GRANT_TYPE_CODE REDIRECT_TYPE_PROTOCOL;
+ DoBasicEndToEndAuthCodeTest(client_id, protocol_redirect_uri);
+ }
+
+ TEST_METHOD(AuthorizationCodeWithClientAuth)
+ {
+ if (!::Microsoft::Security::Authentication::OAuth::Feature_OAuth::IsEnabled())
+ {
+ Log::Result(TestResults::Skipped, L"OAuth2Manager API Features are not enabled.");
+ return;
+ }
+ // NOTE: This is testing client auth, which is a token request only thing, hence only using a single redirection type
+ static constexpr std::wstring_view client_id = GRANT_TYPE_CODE REDIRECT_TYPE_LOCALHOST AUTH_TYPE_HEADER;
+ auto requestParams = AuthRequestParams::CreateForAuthorizationCodeRequest(client_id, Uri{ localhost_redirect_uri });
+ auto authResponse = InitiateAndWaitForSuccessfulAuthResponse(requestParams);
+
+ auto tokenParams = TokenRequestParams::CreateForAuthorizationCodeRequest(authResponse);
+ auto auth = ClientAuthentication::CreateForBasicAuthorization(client_id, L"password");
+ auto tokenAsyncOp = OAuth2Manager::RequestTokenAsync(Uri{ m_serverUrlBase + L"token" }, tokenParams, auth);
+ WaitWithTimeout(tokenAsyncOp, AsyncStatus::Completed);
+
+ auto tokenResult = tokenAsyncOp.GetResults();
+ auto tokenResponse = tokenResult.Response();
+ VerifyErrorNull(tokenResult.Failure());
+ VERIFY_IS_NOT_NULL(tokenResponse);
+ VERIFY_ARE_EQUAL(token, tokenResponse.AccessToken());
+ }
+
+ TEST_METHOD(ClientCredentialsTokenRequest)
+ {
+ if (!::Microsoft::Security::Authentication::OAuth::Feature_OAuth::IsEnabled())
+ {
+ Log::Result(TestResults::Skipped, L"OAuth2Manager API Features are not enabled.");
+ return;
+ }
+ static constexpr std::wstring_view client_id = GRANT_TYPE_CLIENT AUTH_TYPE_HEADER;
+ auto tokenParams = TokenRequestParams::CreateForClientCredentials();
+ auto auth = ClientAuthentication::CreateForBasicAuthorization(client_id, L"password");
+ RequestTokenAndWaitForSuccessfulResponse(tokenParams, auth);
+ }
+
+ TEST_METHOD(RefreshTokenRequest)
+ {
+ if (!::Microsoft::Security::Authentication::OAuth::Feature_OAuth::IsEnabled())
+ {
+ Log::Result(TestResults::Skipped, L"OAuth2Manager API Features are not enabled.");
+ return;
+ }
+ static constexpr std::wstring_view client_id = GRANT_TYPE_REFRESH AUTH_TYPE_HEADER;
+ auto tokenParams = TokenRequestParams::CreateForRefreshToken(refresh_token_old);
+ auto auth = ClientAuthentication::CreateForBasicAuthorization(client_id, L"password");
+ RequestTokenAndWaitForSuccessfulResponse(tokenParams, auth);
+ }
+
+ TEST_METHOD(ExtensionTokenRequest)
+ {
+ if (!::Microsoft::Security::Authentication::OAuth::Feature_OAuth::IsEnabled())
+ {
+ Log::Result(TestResults::Skipped, L"OAuth2Manager API Features are not enabled.");
+ return;
+ }
+ static constexpr std::wstring_view client_id = GRANT_TYPE_EXTENSION AUTH_TYPE_HEADER;
+ auto tokenParams = TokenRequestParams::CreateForExtension(Uri{ extension_grant_uri });
+ auto auth = ClientAuthentication::CreateForBasicAuthorization(client_id, L"password");
+ RequestTokenAndWaitForSuccessfulResponse(tokenParams, auth);
+ }
+
+ TEST_METHOD(TokenRequestErrorResponse)
+ {
+ if (!::Microsoft::Security::Authentication::OAuth::Feature_OAuth::IsEnabled())
+ {
+ Log::Result(TestResults::Skipped, L"OAuth2Manager API Features are not enabled.");
+ return;
+ }
+ static constexpr std::wstring_view client_id = GRANT_TYPE_CLIENT TOKEN_ERROR_RESPONSE;
+ auto tokenParams = TokenRequestParams::CreateForClientCredentials();
+ auto auth = ClientAuthentication::CreateForBasicAuthorization(client_id, L"password");
+ auto tokenAsyncOp = OAuth2Manager::RequestTokenAsync(Uri{ m_serverUrlBase + L"token" }, tokenParams, auth);
+ WaitWithTimeout(tokenAsyncOp, AsyncStatus::Completed);
+
+ auto tokenResult = tokenAsyncOp.GetResults();
+ auto tokenError = tokenResult.Failure();
+ VERIFY_IS_NULL(tokenResult.Response());
+ VERIFY_IS_NOT_NULL(tokenError);
+ auto additionalParams = tokenError.AdditionalParams();
+ VERIFY_IS_NOT_NULL(additionalParams);
+
+ VERIFY_ARE_EQUAL(E_FAIL, tokenError.ErrorCode().value);
+ VERIFY_ARE_EQUAL(L"server_error", tokenError.Error());
+ VERIFY_ARE_EQUAL(error_description, tokenError.ErrorDescription());
+ VERIFY_IS_NOT_NULL(tokenError.ErrorUri());
+ VERIFY_ARE_EQUAL(error_uri, tokenError.ErrorUri().RawUri());
+
+ VERIFY_IS_TRUE(additionalParams.HasKey(additional_param_key));
+ auto jsonValue = additionalParams.Lookup(additional_param_key);
+ VERIFY_ARE_EQUAL(JsonValueType::String, jsonValue.ValueType());
+ VERIFY_ARE_EQUAL(additional_param_value, jsonValue.GetString());
+ }
+
+ TEST_METHOD(AdditionalParams)
+ {
+ if (!::Microsoft::Security::Authentication::OAuth::Feature_OAuth::IsEnabled())
+ {
+ Log::Result(TestResults::Skipped, L"OAuth2Manager API Features are not enabled.");
+ return;
+ }
+ static constexpr std::wstring_view client_id = GRANT_TYPE_CODE REDIRECT_TYPE_LOCALHOST ADDITIONAL_PARAMS;
+ auto requestParams = AuthRequestParams::CreateForAuthorizationCodeRequest(client_id, Uri{ localhost_redirect_uri });
+ auto additionalRequestParams = requestParams.AdditionalParams();
+ additionalRequestParams.Insert(additional_param_key, additional_param_value);
+ auto authResponse = InitiateAndWaitForSuccessfulAuthResponse(requestParams);
+
+ auto tokenParams = TokenRequestParams::CreateForAuthorizationCodeRequest(authResponse);
+ auto additionalTokenParams = tokenParams.AdditionalParams();
+ additionalTokenParams.Insert(additional_param_key, additional_param_value);
+
+ auto tokenAsyncOp = OAuth2Manager::RequestTokenAsync(Uri{ m_serverUrlBase + L"token" }, tokenParams);
+ WaitWithTimeout(tokenAsyncOp, AsyncStatus::Completed);
+
+ auto tokenResult = tokenAsyncOp.GetResults();
+ auto tokenResponse = tokenResult.Response();
+ VerifyErrorNull(tokenResult.Failure());
+ VERIFY_IS_NOT_NULL(tokenResponse);
+ }
+
+ TEST_METHOD(CompleteInvalidState)
+ {
+ if (!::Microsoft::Security::Authentication::OAuth::Feature_OAuth::IsEnabled())
+ {
+ Log::Result(TestResults::Skipped, L"OAuth2Manager API Features are not enabled.");
+ return;
+ }
+ VERIFY_IS_FALSE(OAuth2Manager::CompleteAuthRequest(Uri{ L"unknown-protocol:" })); // No query parameters at all
+ VERIFY_IS_FALSE(OAuth2Manager::CompleteAuthRequest(Uri{ L"http://127.0.0.1/oauth?code=abc123" })); // Missing state
+ VERIFY_IS_FALSE(OAuth2Manager::CompleteAuthRequest(Uri{ L"oauthtestapp:oauth?code=abc&state=invalid" }));
+ VERIFY_IS_FALSE(OAuth2Manager::CompleteAuthRequest(Uri{ L"http://127.0.0.1/oauth?code=abc123&state=invalid" }));
+ }
+
+ // Detoured Functions
+ static BOOL __stdcall DetouredShellExecuteW(SHELLEXECUTEINFO* sei) try
+ {
+ std::wstring_view fileStr = sei->lpFile;
+ if (fileStr.substr(0, auth_url.size()) == auth_url)
+ {
+ winrt::hstring errorString;
+ winrt::hstring errorMessage;
+ auto assignInvalidRequestError = [&](std::wstring_view msg)
+ {
+ if (errorString.empty())
+ {
+ errorString = L"invalid_request";
+ errorMessage = msg;
+ }
+ };
+ auto assignMismatchedArgsError = [&](std::wstring_view name, std::wstring_view expected, std::wstring_view actual)
+ {
+ if (errorString.empty())
+ {
+ std::wstring msg = L"Unexpected value for '";
+ msg.append(name);
+ msg += L"'. Expected '";
+ msg.append(expected);
+ msg += L"' but got '";
+ msg.append(actual);
+ msg += L"'";
+ errorString = L"invalid_request";
+ errorMessage = msg;
+ }
+ };
+
+ // There's no point in launching the browser and trying to fake an authorization flow as that would do
+ // nothing to test the API. Instead, perform the logic of the browser and authorization flow here in-proc
+ winrt::hstring responseType;
+ winrt::hstring clientId;
+ Uri redirectUri{ nullptr };
+ winrt::hstring scope;
+ winrt::hstring state;
+ winrt::hstring codeChallenge;
+ winrt::hstring codeChallengeMethod;
+ winrt::hstring additionalParam;
+ for (auto&& entry : Uri(fileStr).QueryParsed())
+ {
+ auto name = entry.Name();
+ auto value = entry.Value();
+ if (name == L"response_type")
+ {
+ responseType = value;
+ }
+ else if (name == L"client_id")
+ {
+ clientId = value;
+ }
+ else if (name == L"redirect_uri")
+ {
+ redirectUri = Uri{ value };
+ }
+ else if (name == L"scope")
+ {
+ scope = value;
+ }
+ else if (name == L"state")
+ {
+ state = value;
+ }
+ else if (name == L"code_challenge")
+ {
+ codeChallenge = value;
+ }
+ else if (name == L"code_challenge_method")
+ {
+ codeChallengeMethod = value;
+ }
+ else if (name == additional_param_key)
+ {
+ additionalParam = value;
+ }
+ else
+ {
+ assignInvalidRequestError(L"Unrecognized query parameter '"s + name + L"'");
+ }
+ }
+
+ // Some behavior is encoded in the client id
+ winrt::hstring expectedGrantType;
+ winrt::hstring expectedRedirectType;
+ winrt::hstring expectedPkceType = L"S256";
+ winrt::hstring expectedScopeType = L"none";
+ winrt::hstring expectedError = L"none";
+ bool completeRequest = true;
+ bool expectAdditionalParams = false;
+ for (auto&& entry : WwwFormUrlDecoder{ clientId })
+ {
+ auto name = entry.Name();
+ auto value = entry.Value();
+ if (name == L"grant")
+ {
+ expectedGrantType = value;
+ }
+ else if (name == L"redirect")
+ {
+ expectedRedirectType = value;
+ }
+ else if (name == L"pkce")
+ {
+ expectedPkceType = value;
+ }
+ else if (name == L"scope")
+ {
+ expectedScopeType = value;
+ }
+ else if (name == L"error")
+ {
+ expectedError = value;
+ }
+ else if (name == L"complete")
+ {
+ completeRequest = (value == L"true");
+ }
+ else if (name == L"additional_params")
+ {
+ expectAdditionalParams = (value == L"true");
+ }
+ // Ignore other values as these are specific to the token request
+ }
+
+ if (state.empty())
+ {
+ // If no state is provided, we'll be unable to correlate the response to the request. The best we can
+ // really do here is to fail the launch which will fail the test early and reliably
+ Log::Error(L"No 'state' value provided in the URI");
+ ::SetLastError(ERROR_INVALID_PARAMETER);
+ return false;
+ }
+ else if (responseType.empty())
+ {
+ assignInvalidRequestError(L"Missing 'response_type'");
+ }
+ else if (clientId.empty())
+ {
+ assignInvalidRequestError(L"Missing 'client_id'");
+ }
+ else if (expectedGrantType.empty())
+ {
+ assignInvalidRequestError(L"Client id is missing the expected grant type");
+ }
+ else if (expectedRedirectType.empty())
+ {
+ assignInvalidRequestError(L"Client id is missing the expected redirect type");
+ }
+
+ if (responseType != expectedGrantType)
+ {
+ assignMismatchedArgsError(L"response_type", expectedGrantType, responseType);
+ }
+
+ auto expectedUri = (expectedRedirectType == L"localhost") ? localhost_redirect_uri : protocol_redirect_uri;
+ if (redirectUri.RawUri() != expectedUri)
+ {
+ assignMismatchedArgsError(L"redirect_uri", expectedUri, redirectUri.RawUri());
+ }
+
+ if (expectedPkceType == L"none")
+ {
+ if (!codeChallengeMethod.empty())
+ {
+ assignMismatchedArgsError(L"code_challenge_method", L"", codeChallengeMethod);
+ }
+ }
+ else if (expectedPkceType != codeChallengeMethod)
+ {
+ assignMismatchedArgsError(L"code_challenge_method", expectedPkceType, codeChallengeMethod);
+ }
+
+ if (expectedScopeType == L"none")
+ {
+ if (!scope.empty())
+ {
+ assignMismatchedArgsError(L"scope", L"", scope);
+ }
+ }
+ else if (scope.empty())
+ {
+ assignInvalidRequestError(L"Expected a 'scope' parameter, but none provided");
+ }
+
+ if (expectAdditionalParams)
+ {
+ if (additionalParam.empty())
+ {
+ assignInvalidRequestError(L"Expected additional params, but none provided");
+ }
+ else if (additionalParam != additional_param_value)
+ {
+ assignMismatchedArgsError(L"additional param", additional_param_value, additionalParam);
+ }
+ }
+ else if (!additionalParam.empty())
+ {
+ assignInvalidRequestError(L"Expected no additional params, but one was provided");
+ }
+
+ Uri responseUri{ nullptr };
+ if (expectedError == L"auth")
+ {
+ uri_builder builder(redirectUri, responseType != L"token");
+ builder.add(L"state", state);
+ builder.add(L"error", L"server_error");
+ builder.add(L"error_description", error_description);
+ builder.add(L"error_uri", error_uri);
+ builder.add(additional_param_key, additional_param_value);
+ responseUri = builder.get();
+ }
+ else if (responseType == L"code")
+ {
+ // For simplicity, encode the client id and PKCE info in the code
+ std::wstring code = L"client=";
+ code += Uri::EscapeComponent(clientId);
+ if (codeChallengeMethod.empty())
+ {
+ code += L"&challenge_method=none";
+ }
+ else
+ {
+ code += L"&challenge_method=";
+ code += codeChallengeMethod;
+ code += L"&challenge=";
+ code += codeChallenge;
+ }
+
+ // NOTE: The 'scope' should be empty, but we should never indicate an expected 'scope' other than 'none'
+ // for tests that use the auth code grant type
+
+ uri_builder builder{ redirectUri };
+ builder.add(L"code", code);
+ builder.add(L"state", state);
+ responseUri = builder.get();
+ }
+ else
+ {
+ assignInvalidRequestError(L"Unknown response type '"s + responseType + L"'");
+ }
+
+ if (!errorString.empty())
+ {
+ // NOTE: We may have created a response URI already, in which case we want to overwrite it here
+ uri_builder builder(redirectUri, responseType != L"token");
+ builder.add(L"state", state);
+ builder.add(L"error", errorString);
+ builder.add_optional(L"error_description", errorMessage);
+ responseUri = builder.get();
+ }
+ SHELLEXECUTEINFO sei = { sizeof(sei) };
+ sei.fMask = SEE_MASK_NOCLOSEPROCESS;
+ sei.hwnd = nullptr;
+ sei.lpVerb = L"open";
+ sei.lpFile = responseUri.RawUri().c_str();
+ sei.lpParameters = nullptr;
+ sei.lpDirectory = nullptr;
+ sei.nShow = SW_SHOWDEFAULT;
+ sei.hInstApp = nullptr;
+ if (responseUri.SchemeName() != L"http")
+ {
+ // Protocol activation
+ return RealShellExecuteW(&sei);
+ }
+
+ // Simulating a localhost server. This would give the response back in-proc so we can just go ahead and
+ // do that directly. Note that we do this in the same callstack as that will test more interesting code
+ // paths. TODO: Async completion as a parameter? Or just let protocol activation test that path
+ if (completeRequest && !OAuth2Manager::CompleteAuthRequest(responseUri))
+ {
+ Log::Warning(L"Failed to complete auth request");
+ }
+
+ return TRUE;
+ }
+
+ // Not intercepting. Let this "fall through" to the implementation
+ return RealShellExecuteW(sei);
+ }
+ catch (...)
+ {
+ ::SetLastError(ERROR_FILE_NOT_FOUND);
+ return FALSE;
+ }
+
+ // HTTP Server Thread Callback
+ void RunHttpServer()
+ {
+ wil::unique_event event{ wil::EventOptions::None };
+ OVERLAPPED overlapped = {};
+ overlapped.hEvent = event.get();
+
+ ULONG bufferSize = 0x1000; // 4 KB
+ auto buffer = std::make_unique(bufferSize);
+ auto request = reinterpret_cast(buffer.get());
+ while (true)
+ {
+ auto err = ::HttpReceiveHttpRequest(m_requestQueue, HTTP_NULL_ID, HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY,
+ request, bufferSize, nullptr, &overlapped);
+ if (err == ERROR_IO_PENDING)
+ {
+ // Wait for either shutdown or a request to come in
+ HANDLE handles[] = { event.get(), m_serverShutdownEvent.get() };
+ auto waitResult = ::WaitForMultipleObjects(2, handles, false, INFINITE);
+ if (waitResult == (WAIT_OBJECT_0 + 1))
+ {
+ // Shutdown
+ ::CancelIo(m_requestQueue);
+ break;
+ }
+ else if (waitResult != WAIT_OBJECT_0)
+ {
+ Log::Warning(WEX::Common::String().Format(
+ L"WaitForMultipleObjects failed in the HTTP server thread: %d", ::GetLastError()));
+ ::CancelIo(m_requestQueue);
+ break;
+ }
+ }
+
+ // We have a request; we'll block here until we have all data, if needed
+ DWORD bytes;
+ ::GetOverlappedResult(m_requestQueue, &overlapped, &bytes, false);
+ err = ::GetLastError();
+ if (err == ERROR_MORE_DATA)
+ {
+ bufferSize = bytes;
+ buffer = std::make_unique(bufferSize);
+ request = reinterpret_cast(buffer.get());
+ err = ::HttpReceiveHttpRequest(m_requestQueue, request->RequestId, HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY,
+ request, bufferSize, &bytes, nullptr);
+ }
+
+ if (err == ERROR_CONNECTION_INVALID)
+ {
+ // Connection corrupted by peer
+ continue;
+ }
+ else if (err != ERROR_SUCCESS)
+ {
+ Log::Warning(WEX::Common::String().Format(L"HttpReceiveHttpRequest failed: %d", err));
+ break;
+ }
+
+ switch (request->Verb)
+ {
+ case HttpVerbPOST:
+ HandlePostRequest(request);
+ break;
+
+ default:
+ Log::Warning(L"Received an HTTP request with an unexpected verb");
+ break;
+ }
+ }
+ }
+
+ void HandlePostRequest(HTTP_REQUEST* request)
+ {
+ std::string body;
+ for (USHORT i = 0; i < request->EntityChunkCount; ++i)
+ {
+ auto& chunk = request->pEntityChunks[i];
+ WINRT_ASSERT(chunk.DataChunkType == HttpDataChunkFromMemory);
+ auto& data = chunk.FromMemory;
+ body.append(static_cast(data.pBuffer), data.BufferLength);
+ }
+
+ if (request->Flags & HTTP_REQUEST_FLAG_MORE_ENTITY_BODY_EXISTS)
+ {
+ ULONG bufferLength = 2048;
+ auto buffer = std::make_unique(bufferLength);
+ while (true)
+ {
+ ULONG bytes = 0;
+ auto result = ::HttpReceiveRequestEntityBody(m_requestQueue, request->RequestId, 0, buffer.get(),
+ bufferLength, &bytes, nullptr);
+ if ((result == NO_ERROR) || (result == ERROR_HANDLE_EOF))
+ {
+ body.append(buffer.get(), bytes);
+ }
+ else
+ {
+ Log::Warning(WEX::Common::String().Format(L"HttpReceiveRequestEntityBody failed: %d", result));
+ return; // TODO: Should we send a response here? Getting an error probably means we shouldn't?
+ }
+
+ if (result == ERROR_HANDLE_EOF) break;
+ }
+ }
+
+ winrt::hstring errorString;
+ winrt::hstring errorMessage;
+ auto assignInvalidRequestError = [&](std::wstring_view msg)
+ {
+ if (errorString.empty())
+ {
+ errorString = L"invalid_request";
+ errorMessage = msg;
+ }
+ };
+ auto assignMismatchedArgsError = [&](std::wstring_view name, std::wstring_view expected, std::wstring_view actual)
+ {
+ if (errorString.empty())
+ {
+ std::wstring msg = L"Unexpected value for '";
+ msg.append(name);
+ msg += L"'. Expected '";
+ msg.append(expected);
+ msg += L"' but got '";
+ msg.append(actual);
+ msg += L"'";
+ errorString = L"invalid_request";
+ errorMessage = msg;
+ }
+ };
+
+ winrt::hstring grantType;
+ winrt::hstring code;
+ Uri redirectUri{ nullptr };
+ winrt::hstring clientId;
+ winrt::hstring codeVerifier;
+ winrt::hstring scope;
+ winrt::hstring refreshToken;
+ winrt::hstring additionalParam;
+ for (auto&& entry : WwwFormUrlDecoder(winrt::to_hstring(body)))
+ {
+ auto name = entry.Name();
+ auto value = entry.Value();
+ if (name == L"grant_type")
+ {
+ grantType = value;
+ }
+ else if (name == L"code")
+ {
+ code = value;
+ }
+ else if (name == L"redirect_uri")
+ {
+ redirectUri = Uri{ value };
+ }
+ else if (name == L"client_id")
+ {
+ clientId = value;
+ }
+ else if (name == L"code_verifier")
+ {
+ codeVerifier = value;
+ }
+ else if (name == L"scope")
+ {
+ scope = value;
+ }
+ else if (name == L"refresh_token")
+ {
+ refreshToken = value;
+ }
+ else if (name == additional_param_key)
+ {
+ additionalParam = value;
+ }
+ else
+ {
+ assignInvalidRequestError(L"Unrecognized query parameter '"s + name + L"'");
+ }
+ }
+
+ auto& authHeader = request->Headers.KnownHeaders[HttpHeaderAuthorization];
+ if (authHeader.RawValueLength > 0)
+ {
+ // Should be of the form ' '
+ std::string_view authHeaderStr(authHeader.pRawValue, authHeader.RawValueLength);
+ auto firstSpace = authHeaderStr.find_first_of(' ');
+ if (firstSpace == authHeaderStr.npos)
+ {
+ assignInvalidRequestError(L"Bad Authorization hedaer");
+ }
+ else
+ {
+ auto scheme = authHeaderStr.substr(0, firstSpace);
+ auto value = authHeaderStr.substr(firstSpace + 1);
+ if (scheme != "Basic")
+ {
+ assignInvalidRequestError(L"Authorization must use 'Basic' type");
+ }
+ else
+ {
+ // 'value' is 'client_id:client_crednetials' base64urlencoded
+ auto credsBuffer = CryptographicBuffer::DecodeFromBase64String(winrt::to_hstring(value));
+ auto fullCreds = CryptographicBuffer::ConvertBinaryToString(BinaryStringEncoding::Utf8, credsBuffer);
+ std::wstring_view fullCredsStr = fullCreds;
+ auto colonPos = fullCredsStr.find_first_of(':');
+ if (colonPos == fullCredsStr.npos)
+ {
+ assignInvalidRequestError(L"Bad Authorization header");
+ }
+ else
+ {
+ auto credsClientId = fullCredsStr.substr(0, colonPos);
+ auto credsClientSecret = fullCredsStr.substr(colonPos + 1);
+ if (credsClientSecret != L"password")
+ {
+ assignMismatchedArgsError(L"Authorization client secret", L"password", credsClientSecret);
+ }
+ else if (clientId.empty())
+ {
+ clientId = credsClientId;
+ }
+ else if (credsClientId != clientId)
+ {
+ assignMismatchedArgsError(L"Authorization client id", clientId, credsClientId);
+ }
+ }
+ }
+ }
+ }
+
+ if (clientId.empty())
+ {
+ assignInvalidRequestError(L"Client id not provided");
+ }
+
+ winrt::hstring expectedGrantType;
+ winrt::hstring expectedRedirectType;
+ winrt::hstring expectedPkceType = L"S256";
+ winrt::hstring expectedScopeType = L"none";
+ winrt::hstring expectedAuthType = L"none";
+ winrt::hstring expectedError = L"none";
+ bool expectAdditionalParams = false;
+ for (auto&& entry : WwwFormUrlDecoder{ clientId })
+ {
+ auto name = entry.Name();
+ auto value = entry.Value();
+ if (name == L"grant")
+ {
+ expectedGrantType = value;
+ }
+ else if (name == L"redirect")
+ {
+ expectedRedirectType = value;
+ }
+ else if (name == L"pkce")
+ {
+ expectedPkceType = value;
+ }
+ else if (name == L"scope")
+ {
+ expectedScopeType = value;
+ }
+ else if (name == L"auth")
+ {
+ expectedAuthType = value;
+ }
+ else if (name == L"error")
+ {
+ expectedError = value;
+ }
+ else if (name == L"additional_params")
+ {
+ expectAdditionalParams = (value == L"true");
+ }
+ // Ignore other values as these are specific to the authorization request
+ }
+
+ auto checkUnexpectedArg = [&](std::wstring_view name, const winrt::hstring& value)
+ {
+ if (!value.empty())
+ {
+ assignMismatchedArgsError(name, L"", value);
+ }
+ };
+
+ if (expectAdditionalParams)
+ {
+ if (additionalParam.empty())
+ {
+ assignInvalidRequestError(L"Expected additional params, but none provided");
+ }
+ else if (additionalParam != additional_param_value)
+ {
+ assignMismatchedArgsError(L"additional param", additional_param_value, additionalParam);
+ }
+ }
+ else if (!additionalParam.empty())
+ {
+ assignInvalidRequestError(L"Expected no additional params, but one was provided");
+ }
+
+ if ((expectedAuthType == L"header") && (authHeader.RawValueLength == 0))
+ {
+ assignInvalidRequestError(L"Authorization header expected, but not provided");
+ }
+
+ std::wstring responseJson;
+ if (expectedError == L"token")
+ {
+ errorString = L"server_error";
+ errorMessage = json_escaped_error_description;
+ }
+ else if (grantType == L"authorization_code")
+ {
+ if (expectedGrantType != L"code")
+ {
+ assignMismatchedArgsError(L"grant_type", expectedGrantType, grantType);
+ }
+ else if (code.empty())
+ {
+ assignInvalidRequestError(L"Authorization code not provided");
+ }
+
+ if (redirectUri)
+ {
+ auto expectedUri = (expectedRedirectType == L"protocol") ? protocol_redirect_uri : localhost_redirect_uri;
+ if (redirectUri.RawUri() != expectedUri)
+ {
+ assignMismatchedArgsError(L"redirect_uri", expectedUri, redirectUri.RawUri());
+ }
+ }
+ else if (expectedRedirectType != L"inferred")
+ {
+ assignInvalidRequestError(L"Expected a 'redirect_uri', but none provided");
+ }
+
+ checkUnexpectedArg(L"scope", scope); // Only expected during auth request
+ checkUnexpectedArg(L"refresh_token", refreshToken);
+
+ winrt::hstring codeClientId;
+ winrt::hstring codeChallengeMethod;
+ winrt::hstring codeChallenge;
+ for (auto&& entry : WwwFormUrlDecoder{ code })
+ {
+ auto name = entry.Name();
+ auto value = entry.Value();
+ if (name == L"client")
+ {
+ codeClientId = value;
+ }
+ else if (name == L"challenge_method")
+ {
+ codeChallengeMethod = value;
+ }
+ else if (name == L"challenge")
+ {
+ codeChallenge = value;
+ }
+ else
+ {
+ assignInvalidRequestError(L"Unrecognized query parameter '" + name + L"' in code");
+ }
+ }
+
+ if (clientId != codeClientId)
+ {
+ assignMismatchedArgsError(L"client_id", codeClientId, clientId);
+ }
+
+ if (expectedPkceType != codeChallengeMethod)
+ {
+ assignMismatchedArgsError(L"code challenge method", expectedPkceType, codeChallengeMethod);
+ }
+ else if (codeChallengeMethod == L"none")
+ {
+ if (!codeVerifier.empty())
+ {
+ assignMismatchedArgsError(L"code_verifier", L"", codeVerifier);
+ }
+ }
+ else if (codeVerifier.empty())
+ {
+ assignInvalidRequestError(L"Expected 'code_verifier', but none provided");
+ }
+
+ if (codeChallengeMethod == L"S256")
+ {
+ // We can't "unhash" the code challenge, so hash the code verifier and base64urlencode it
+ auto algo = HashAlgorithmProvider::OpenAlgorithm(HashAlgorithmNames::Sha256());
+ auto hash = algo.HashData(CryptographicBuffer::ConvertStringToBinary(codeVerifier, BinaryStringEncoding::Utf8));
+ auto base64Hash = CryptographicBuffer::EncodeToBase64String(hash);
+ std::wstring base64urlencodedHash;
+ base64urlencodedHash.reserve(base64Hash.size());
+ for (auto ch : base64Hash)
+ {
+ switch (ch)
+ {
+ case '+': base64urlencodedHash.push_back('-'); break;
+ case '/': base64urlencodedHash.push_back('_'); break;
+ case '=': break; // No padding
+ default: base64urlencodedHash.push_back(ch); break;
+ }
+ }
+
+ if (codeChallenge != base64urlencodedHash)
+ {
+ assignInvalidRequestError(L"The code verifier does not match the original code challenge");
+ }
+ }
+ else if (codeChallengeMethod == L"plain")
+ {
+ if (codeChallenge != codeVerifier)
+ {
+ assignInvalidRequestError(L"Code verifier does not match the expected value");
+ }
+ }
+ }
+ else if (grantType == L"client_credentials")
+ {
+ if (expectedGrantType != L"client")
+ {
+ assignMismatchedArgsError(L"grant_type", expectedGrantType, grantType);
+ }
+
+ checkUnexpectedArg(L"code", code);
+ checkUnexpectedArg(L"code_verifier", codeVerifier);
+ checkUnexpectedArg(L"refresh_token", refreshToken);
+ }
+ else if (grantType == L"refresh_token")
+ {
+ if (expectedGrantType != L"refresh")
+ {
+ assignMismatchedArgsError(L"grant_type", expectedGrantType, grantType);
+ }
+ else if (refreshToken != refresh_token_old)
+ {
+ assignMismatchedArgsError(L"refresh_token", refresh_token_old, refreshToken);
+ }
+
+ checkUnexpectedArg(L"code", code);
+ checkUnexpectedArg(L"code_verifier", codeVerifier);
+ }
+ else if (grantType == extension_grant_uri)
+ {
+ if (expectedGrantType != L"extension")
+ {
+ assignMismatchedArgsError(L"grant_type", expectedGrantType, grantType);
+ }
+
+ checkUnexpectedArg(L"code", code);
+ checkUnexpectedArg(L"code_verifier", codeVerifier);
+ checkUnexpectedArg(L"refresh_token", refreshToken);
+ }
+ else
+ {
+ assignInvalidRequestError(L"Unrecognized grant type '"s + grantType + L"'");
+ }
+
+ if (errorString.empty())
+ {
+ // NOTE: All responses are the same
+ responseJson = L"{\"access_token\":\"";
+ responseJson += json_escaped_token;
+ responseJson += L"\",\"token_type\":\"Bearer\",\"expires_in\":3600,\"refresh_token\":\"";
+ responseJson += json_escaped_refresh_token;
+ responseJson += L"\"";
+ if (scope.empty())
+ {
+ responseJson += L",\"scope\":\"all\"";
+ }
+ responseJson += L"}";
+ }
+ else
+ {
+ responseJson = L"{\"error\":\"" + errorString + L"\",\"error_description\":\"" + errorMessage +
+ L"\",\"error_uri\":\"" + error_uri + L"\",\"" + additional_param_key + L"\":\"" +
+ additional_param_value + L"\"}";
+ }
+
+ WINRT_ASSERT(!responseJson.empty());
+
+ HTTP_RESPONSE response = {};
+ response.StatusCode = 200;
+ response.pReason = "OK";
+ response.ReasonLength = 2;
+ auto& contentTypeHeader = response.Headers.KnownHeaders[HttpHeaderContentType];
+ contentTypeHeader.pRawValue = "application/json; charset=UTF-8";
+ contentTypeHeader.RawValueLength = static_cast(::strlen(contentTypeHeader.pRawValue));
+
+ auto responseJsonUtf8 = winrt::to_string(responseJson);
+ HTTP_DATA_CHUNK dataChunk = {};
+ dataChunk.DataChunkType = HttpDataChunkFromMemory;
+ dataChunk.FromMemory.pBuffer = responseJsonUtf8.data();
+ dataChunk.FromMemory.BufferLength = static_cast(responseJsonUtf8.size());
+
+ response.EntityChunkCount = 1;
+ response.pEntityChunks = &dataChunk;
+
+ ULONG bytesSent;
+ auto sendResult = ::HttpSendHttpResponse(m_requestQueue, request->RequestId, 0, &response, nullptr, &bytesSent,
+ nullptr, 0, nullptr, nullptr);
+ if (sendResult != NO_ERROR)
+ {
+ Log::Warning(WEX::Common::String().Format(L"HttpSendHttpResponse failed: %d", sendResult));
+ }
+ }
+
+ // Detours Information
+ static inline decltype(&ShellExecuteExW) RealShellExecuteW = &ShellExecuteExW;
+
+ // Local server for performing the token exchange
+ wil::unique_event m_serverShutdownEvent{ wil::EventOptions::None };
+ std::thread m_httpServerThread;
+ HANDLE m_requestQueue = nullptr;
+ HTTP_SERVER_SESSION_ID m_serverSessionId = 0;
+ HTTP_URL_GROUP_ID m_urlGroup = 0;
+ std::uint16_t m_serverPort = 50001;
+ std::wstring m_serverUrlBase;
+ };
+}
diff --git a/test/OAuth2ManagerTests/OAuth2APITests.h b/test/OAuth2ManagerTests/OAuth2APITests.h
new file mode 100644
index 0000000000..23075593e0
--- /dev/null
+++ b/test/OAuth2ManagerTests/OAuth2APITests.h
@@ -0,0 +1,87 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#pragma once
+
+#include
+#include
+
+
+// The 'client_id' describes the behavior and expectations of our mocked authorization server
+// Specifying grant type is required
+#define GRANT_TYPE_CODE L"grant=code"
+#define GRANT_TYPE_TOKEN L"grant=token"
+#define GRANT_TYPE_CLIENT L"grant=client"
+#define GRANT_TYPE_REFRESH L"grant=refresh"
+#define GRANT_TYPE_EXTENSION L"grant=extension"
+
+// Specifying redirect type is required
+#define REDIRECT_TYPE_LOCALHOST "&redirect=localhost"
+#define REDIRECT_TYPE_PROTOCOL "&redirect=protocol"
+
+// 'none' is the default if not specified
+#define AUTH_TYPE_HEADER "&auth=header"
+
+// 'none' is the default if not specified
+#define TOKEN_ERROR_RESPONSE "&error=token"
+
+// 'false' is the default if not specified
+#define ADDITIONAL_PARAMS "&additional_params=true"
+
+// Constants to validate expectations. The strings are specifically chosen to validate proper escaping of special characters
+inline constexpr std::wstring_view error_description = L"This is an error & it contains characters like \"=\"";
+inline constexpr std::wstring_view json_escaped_error_description = L"This is an error & it contains characters like \\\"=\\\"";
+inline constexpr std::wstring_view error_uri = L"https://contoso.com/errors?foo=bar";
+
+inline constexpr std::wstring_view additional_param_key = L"use=key&name=foo";
+inline constexpr std::wstring_view additional_param_value = L"use=value&name=bar";
+
+inline constexpr std::wstring_view extension_grant_uri = L"oauth:test:extension";
+
+inline constexpr std::wstring_view token = L"tacos=yummy&location=\"my tummy\"";
+inline constexpr std::wstring_view json_escaped_token = L"tacos=yummy&location=\\\"my tummy\\\"";
+inline constexpr std::wstring_view refresh_token_old = L"~!@#$%^&*()_+`-=[]\\{};':\",./<>?-old";
+inline constexpr std::wstring_view refresh_token = L"~!@#$%^&*()_+`-=[]\\{};':\",./<>?";
+inline constexpr std::wstring_view json_escaped_refresh_token = L"~!@#$%^&*()_+`-=[]\\\\{};':\\\",./<>?";
+
+struct uri_builder
+{
+ std::wstring uri;
+ wchar_t prefix;
+
+ uri_builder(const winrt::Windows::Foundation::Uri& uri, bool useQuery = true) :
+ uri(uri.RawUri())
+ {
+ if (useQuery)
+ {
+ prefix = uri.Query().empty() ? L'?' : '&';
+ }
+ else
+ {
+ prefix = '#';
+ }
+ }
+
+ void add(std::wstring_view name, std::wstring_view value)
+ {
+ assert(!name.empty() && !value.empty());
+
+ uri.push_back(prefix);
+ prefix = L'&';
+ uri.append(winrt::Windows::Foundation::Uri::EscapeComponent(name));
+ uri.push_back(L'=');
+ uri.append(winrt::Windows::Foundation::Uri::EscapeComponent(value));
+ }
+
+ void add_optional(std::wstring_view name, std::wstring_view value)
+ {
+ if (!value.empty())
+ {
+ add(name, value);
+ }
+ }
+
+ winrt::Windows::Foundation::Uri get()
+ {
+ return winrt::Windows::Foundation::Uri{ uri };
+ }
+};
diff --git a/test/OAuth2ManagerTests/OAuth2ManagerTests.vcxproj b/test/OAuth2ManagerTests/OAuth2ManagerTests.vcxproj
new file mode 100644
index 0000000000..f55c102344
--- /dev/null
+++ b/test/OAuth2ManagerTests/OAuth2ManagerTests.vcxproj
@@ -0,0 +1,286 @@
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ 17.0
+ Win32Proj
+ {0ff6a68f-6c7f-4e66-8cb8-c0b9501060ca}
+ OAuth2ManagerTests
+ 10.0
+
+
+
+ DynamicLibrary
+ true
+ v143
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v143
+ true
+ Unicode
+
+
+ DynamicLibrary
+ true
+ v143
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v143
+ true
+ Unicode
+
+
+ DynamicLibrary
+ true
+ v143
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;OAUTH2MANAGERTESTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common;$(MSBuildProjectDirectory)\..\..\dev\Detours
+
+
+ Windows
+ true
+ false
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;OAUTH2MANAGERTESTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common;$(MSBuildProjectDirectory)\..\..\dev\Detours
+
+
+ Windows
+ true
+ true
+ true
+ false
+
+
+
+
+ httpapi.lib;%(AdditionalDependencies)
+
+
+
+
+ Level3
+ true
+ _DEBUG;OAUTH2MANAGERTESTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common;$(MSBuildProjectDirectory)\..\..\dev\Detours
+
+
+ Windows
+ true
+ false
+ Microsoft.WindowsAppRuntime.dll;%(DelayLoadDLLs)
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;OAUTH2MANAGERTESTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common;$(MSBuildProjectDirectory)\..\..\dev\Detours
+
+
+ Windows
+ true
+ true
+ true
+ false
+
+
+
+
+ Level3
+ true
+ _DEBUG;OAUTH2MANAGERTESTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common;$(MSBuildProjectDirectory)\..\..\dev\Detours
+
+
+ Windows
+ true
+ false
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;OAUTH2MANAGERTESTS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+ $(ProjectDir)..\inc;$(ProjectDir)..\..\dev\WindowsAppRuntime_BootstrapDLL\;$(MSBuildProjectDirectory)\..\..\dev\common;$(MSBuildProjectDirectory)\..\..\dev\Detours
+
+
+ Windows
+ true
+ true
+ true
+ false
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
+
+
+ .Debug
+ _Debug
+ $(AppxPackageDir)\..\..\AppxPackages\OAuthTestAppPackage_1.0.0.0_$(PlatformTarget)$(TestPkgDebugConfigName)_Test
+ $(TestPkgOutputPath)\OAuthTestAppPackage_1.0.0.0_$(PlatformTarget)$(TestPkgDebugConfigName).msix
+
+
+
+
+
+
+
+ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Security.Authentication.OAuth.winmd
+ true
+ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.dll
+
+
+
+
+ {d6bc25c5-1aa7-4c4a-a02c-b42dedbfea33}
+
+
+ {f76b776e-86f5-48c5-8fc7-d2795ecc9746}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/OAuth2ManagerTests/OAuth2ManagerTests.vcxproj.filters b/test/OAuth2ManagerTests/OAuth2ManagerTests.vcxproj.filters
new file mode 100644
index 0000000000..1e57c7b1be
--- /dev/null
+++ b/test/OAuth2ManagerTests/OAuth2ManagerTests.vcxproj.filters
@@ -0,0 +1,33 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/test/OAuth2ManagerTests/packages.config b/test/OAuth2ManagerTests/packages.config
new file mode 100644
index 0000000000..0184e4db4f
--- /dev/null
+++ b/test/OAuth2ManagerTests/packages.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/test/OAuth2ManagerTests/pch.cpp b/test/OAuth2ManagerTests/pch.cpp
new file mode 100644
index 0000000000..241e1cf2a6
--- /dev/null
+++ b/test/OAuth2ManagerTests/pch.cpp
@@ -0,0 +1,7 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
diff --git a/test/OAuth2ManagerTests/pch.h b/test/OAuth2ManagerTests/pch.h
new file mode 100644
index 0000000000..725228010f
--- /dev/null
+++ b/test/OAuth2ManagerTests/pch.h
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+// pch.h: This is a precompiled header file.
+// Files listed below are compiled only once, improving build performance for future builds.
+// This also affects IntelliSense performance, including code completion and many code browsing features.
+// However, files listed here are ALL re-compiled if any one of them is updated between builds.
+// Do not add files here that you will be updating frequently as this negates the performance advantage.
+
+#ifndef PCH_H
+#define PCH_H
+
+// add headers that you want to pre-compile here
+#ifndef INLINE_TEST_METHOD_MARKUP
+#define INLINE_TEST_METHOD_MARKUP
+#endif
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#include
+
+#include "WexTestClass.h"
+#include
+#include
+#include
+#include
+
+#include
+#endif //PCH_H
diff --git a/test/StoragePickersTests/StoragePickersTests.cpp b/test/StoragePickersTests/StoragePickersTests.cpp
new file mode 100644
index 0000000000..03065237a5
--- /dev/null
+++ b/test/StoragePickersTests/StoragePickersTests.cpp
@@ -0,0 +1,97 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "AssemblyInfo.h"
+
+#include
+#include
+#include
+
+namespace TB = ::Test::Bootstrap;
+namespace TP = ::Test::Packages;
+
+using namespace WEX::Common;
+using namespace WEX::Logging;
+using namespace WEX::TestExecution;
+
+namespace Test::StoragePickersTests
+{
+ class StoragePickersTests
+ {
+ public:
+ BEGIN_TEST_CLASS(StoragePickersTests)
+ TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") // MTA is required for ::Test::Bootstrap::SetupPackages()
+ TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"RestrictedUser")
+ //TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"UAP")
+ //TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
+
+ TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") // each test sets its own CompatibilityOptions
+ END_TEST_CLASS()
+
+ TEST_CLASS_SETUP(ClassSetup)
+ {
+ ::Test::Bootstrap::SetupPackages();
+ return true;
+ }
+
+ TEST_CLASS_CLEANUP(ClassCleanup)
+ {
+ ::Test::Bootstrap::CleanupPackages();
+ return true;
+ }
+
+ TEST_METHOD_SETUP(MethodInit)
+ {
+ VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework());
+
+ // The test method setup and execution is on a different thread than the class setup.
+ // Initialize the framework for the test thread.
+ ::Test::Bootstrap::SetupBootstrap();
+ return true;
+ }
+
+ TEST_METHOD_CLEANUP(MethodUninit)
+ {
+ VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework());
+ ::Test::Bootstrap::CleanupBootstrap();
+ return true;
+ }
+
+ TEST_METHOD(FileSavePicker_ShouldCreateNewFile)
+ {
+ try
+ {
+ auto parentWindow = ::GetForegroundWindow();
+ winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) };
+ winrt::Microsoft::Windows::Storage::Pickers::FileSavePicker savePicker(windowId);
+ //savePicker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary);
+ savePicker.FileTypeChoices().Insert(L"Plain Text", winrt::single_threaded_vector({ L".txt" }));
+ savePicker.SuggestedFileName(L"test.txt");
+ // Act
+ auto fileOperation = savePicker.PickSaveFileAsync();
+ auto file = fileOperation.get();
+
+ // Assert
+ if (file != nullptr)
+ {
+ Log::Comment(L"File save was successful.");
+ }
+ else
+ {
+ Log::Error(L"Photo capture failed or was canceled.");
+ }
+ }
+ catch (const winrt::hresult_error& ex)
+ {
+ Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str());
+ VERIFY_FAIL(L"Exception occurred during photo capture.");
+ }
+ catch (const std::exception& ex)
+ {
+ Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str());
+ VERIFY_FAIL(L"Standard exception occurred during photo capture.");
+ }
+ }
+ };
+}
diff --git a/test/StoragePickersTests/StoragePickersTests.vcxproj b/test/StoragePickersTests/StoragePickersTests.vcxproj
new file mode 100644
index 0000000000..ebe73a74e7
--- /dev/null
+++ b/test/StoragePickersTests/StoragePickersTests.vcxproj
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ 17.0
+ Win32Proj
+ {85C86306-46D1-4563-8303-0A79DF923586}
+ StoragePickersTests
+ 10.0
+ StoragePickersTests
+
+
+ DynamicLibrary
+ v143
+ Unicode
+
+
+ false
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Use
+ true
+ pch.h
+ $(RepoRoot)\test\inc;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common
+ $(RepoRoot);%(AdditionalIncludeDirectories)
+
+
+ Windows
+ onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies)
+ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+
+
+
+
+ WIN32;%(PreprocessorDefinitions)
+
+
+
+
+ Create
+
+
+ $(RepoRoot)\build\VersionInfo;%(AdditionalIncludeDirectories)
+
+
+
+
+
+
+
+
+
+
+ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd
+ true
+
+
+
+
+ {f76b776e-86f5-48c5-8fc7-d2795ecc9746}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/StoragePickersTests/StoragePickersTests.vcxproj.filters b/test/StoragePickersTests/StoragePickersTests.vcxproj.filters
new file mode 100644
index 0000000000..404acd038b
--- /dev/null
+++ b/test/StoragePickersTests/StoragePickersTests.vcxproj.filters
@@ -0,0 +1,36 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/test/StoragePickersTests/packages.config b/test/StoragePickersTests/packages.config
new file mode 100644
index 0000000000..63e5716140
--- /dev/null
+++ b/test/StoragePickersTests/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/test/StoragePickersTests/pch.cpp b/test/StoragePickersTests/pch.cpp
new file mode 100644
index 0000000000..a77728ba07
--- /dev/null
+++ b/test/StoragePickersTests/pch.cpp
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
diff --git a/test/StoragePickersTests/pch.h b/test/StoragePickersTests/pch.h
new file mode 100644
index 0000000000..0c38a1ba77
--- /dev/null
+++ b/test/StoragePickersTests/pch.h
@@ -0,0 +1,22 @@
+// Copyright (c) Microsoft Corporation and Contributors.
+// Licensed under the MIT License.
+
+#ifndef PCH_H
+#define PCH_H
+
+#include
+
+#include
+
+#include
+#include
+
+#include "winrt/Microsoft.Windows.Storage.Pickers.h"
+
+#include
+
+#include
+#include
+#include
+
+#endif //PCH_H
diff --git a/test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj b/test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj
new file mode 100644
index 0000000000..7245ebd21f
--- /dev/null
+++ b/test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj
@@ -0,0 +1,153 @@
+
+
+
+
+ true
+ true
+ true
+ true
+ 15.0
+ {4caa3052-7fae-4c5b-a1cb-02d7f910c991}
+ Win32Proj
+ OAuthTestApp
+ 10.0
+ 10.0.17134.0
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ Application
+ v143
+ v142
+ v141
+ v140
+ Unicode
+
+
+ true
+ true
+
+
+ false
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+ Use
+ pch.h
+ $(IntDir)pch.pch
+ _CONSOLE;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)
+ Level4
+ %(AdditionalOptions) /permissive- /bigobj
+
+
+
+
+ Disabled
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ Console
+ false
+
+
+
+
+ WIN32;%(PreprocessorDefinitions)
+
+
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ Console
+ true
+ true
+ false
+
+
+
+
+
+
+
+
+ Create
+
+
+
+
+
+
+
+ {f76b776e-86f5-48c5-8fc7-d2795ecc9746}
+
+
+
+
+ $(BaseOutputPath)\WindowsAppRuntime_DLL\Microsoft.Windows.AppLifecycle.winmd
+ true
+ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.dll
+
+
+ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Security.Authentication.OAuth.winmd
+ true
+ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.dll
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj.filters b/test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj.filters
new file mode 100644
index 0000000000..388ab2e234
--- /dev/null
+++ b/test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj.filters
@@ -0,0 +1,37 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/TestApps/OAuthTestApp/main.cpp b/test/TestApps/OAuthTestApp/main.cpp
new file mode 100644
index 0000000000..4f9c1e81d4
--- /dev/null
+++ b/test/TestApps/OAuthTestApp/main.cpp
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#include "pch.h"
+#include
+#include
+#include
+#include
+#include
+
+using namespace winrt::Microsoft::Windows::AppLifecycle;
+using namespace winrt::Microsoft::Security::Authentication::OAuth;
+using namespace winrt::Windows::ApplicationModel::Activation;
+
+int main()
+{
+ try
+ {
+ auto args = AppInstance::GetCurrent().GetActivatedEventArgs();
+ auto kind = args.Kind();
+ if (kind == ExtendedActivationKind::Protocol)
+ {
+ auto uri = args.Data().as().Uri();
+ if (!OAuth2Manager::CompleteAuthRequest(uri))
+ {
+ std::printf("WARNING: Failed to complete auth request with uri '%ls'.\n", uri.RawUri().c_str());
+ std::printf("WARNING: This may or may not be expected depending on which test is running.\n");
+ }
+ }
+ else
+ {
+ std::printf("WARNING: Application was launched with something other than protocol activation!\n");
+ }
+ }
+ catch (const std::exception& ex)
+ {
+ std::printf("Standard exception: %s\n", ex.what());
+ }
+}
diff --git a/test/TestApps/OAuthTestApp/packages.config b/test/TestApps/OAuthTestApp/packages.config
new file mode 100644
index 0000000000..cbf6205e62
--- /dev/null
+++ b/test/TestApps/OAuthTestApp/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/test/TestApps/OAuthTestApp/pch.cpp b/test/TestApps/OAuthTestApp/pch.cpp
new file mode 100644
index 0000000000..8c646996e9
--- /dev/null
+++ b/test/TestApps/OAuthTestApp/pch.cpp
@@ -0,0 +1,3 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#include "pch.h"
diff --git a/test/TestApps/OAuthTestApp/pch.h b/test/TestApps/OAuthTestApp/pch.h
new file mode 100644
index 0000000000..ed146c708c
--- /dev/null
+++ b/test/TestApps/OAuthTestApp/pch.h
@@ -0,0 +1,5 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See LICENSE in the project root for license information.
+#pragma once
+#include
+#include
diff --git a/test/TestApps/OAuthTestAppPackage/Images/LockScreenLogo.scale-200.png b/test/TestApps/OAuthTestAppPackage/Images/LockScreenLogo.scale-200.png
new file mode 100644
index 0000000000..735f57adb5
Binary files /dev/null and b/test/TestApps/OAuthTestAppPackage/Images/LockScreenLogo.scale-200.png differ
diff --git a/test/TestApps/OAuthTestAppPackage/Images/SplashScreen.scale-200.png b/test/TestApps/OAuthTestAppPackage/Images/SplashScreen.scale-200.png
new file mode 100644
index 0000000000..023e7f1fed
Binary files /dev/null and b/test/TestApps/OAuthTestAppPackage/Images/SplashScreen.scale-200.png differ
diff --git a/test/TestApps/OAuthTestAppPackage/Images/Square150x150Logo.scale-200.png b/test/TestApps/OAuthTestAppPackage/Images/Square150x150Logo.scale-200.png
new file mode 100644
index 0000000000..af49fec1a5
Binary files /dev/null and b/test/TestApps/OAuthTestAppPackage/Images/Square150x150Logo.scale-200.png differ
diff --git a/test/TestApps/OAuthTestAppPackage/Images/Square44x44Logo.scale-200.png b/test/TestApps/OAuthTestAppPackage/Images/Square44x44Logo.scale-200.png
new file mode 100644
index 0000000000..ce342a2ec8
Binary files /dev/null and b/test/TestApps/OAuthTestAppPackage/Images/Square44x44Logo.scale-200.png differ
diff --git a/test/TestApps/OAuthTestAppPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png b/test/TestApps/OAuthTestAppPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png
new file mode 100644
index 0000000000..f6c02ce97e
Binary files /dev/null and b/test/TestApps/OAuthTestAppPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png differ
diff --git a/test/TestApps/OAuthTestAppPackage/Images/StoreLogo.png b/test/TestApps/OAuthTestAppPackage/Images/StoreLogo.png
new file mode 100644
index 0000000000..7385b56c0e
Binary files /dev/null and b/test/TestApps/OAuthTestAppPackage/Images/StoreLogo.png differ
diff --git a/test/TestApps/OAuthTestAppPackage/Images/Wide310x150Logo.scale-200.png b/test/TestApps/OAuthTestAppPackage/Images/Wide310x150Logo.scale-200.png
new file mode 100644
index 0000000000..288995b397
Binary files /dev/null and b/test/TestApps/OAuthTestAppPackage/Images/Wide310x150Logo.scale-200.png differ
diff --git a/test/TestApps/OAuthTestAppPackage/OAuthTestAppPackage.wapproj b/test/TestApps/OAuthTestAppPackage/OAuthTestAppPackage.wapproj
new file mode 100644
index 0000000000..f06008490c
--- /dev/null
+++ b/test/TestApps/OAuthTestAppPackage/OAuthTestAppPackage.wapproj
@@ -0,0 +1,98 @@
+
+
+
+
+ 15.0
+
+
+
+
+ Debug
+ x86
+
+
+ Release
+ x86
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM
+
+
+ Release
+ ARM
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+ Debug
+ AnyCPU
+
+
+ Release
+ AnyCPU
+
+
+
+
+ $(MSBuildExtensionsPath)\Microsoft\DesktopBridge\
+
+
+
+
+
+ 455c01f8-0a3e-42c4-9f22-13992eb909ec
+ 10.0.19041.0
+ 10.0.17763.0
+ en-US
+ True
+ ..\OAuthTestApp\OAuthTestApp.vcxproj
+ true
+ False
+ $(RepoTestCertificatePFX)
+ $(RepoTestCertificatePassword)
+ false
+ SHA256
+ True
+ True
+ $(Platform)
+ 0
+
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/TestApps/OAuthTestAppPackage/Package.appxmanifest b/test/TestApps/OAuthTestAppPackage/Package.appxmanifest
new file mode 100644
index 0000000000..19234b69d4
--- /dev/null
+++ b/test/TestApps/OAuthTestAppPackage/Package.appxmanifest
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+ OAuthTestAppPackage
+ Microsoft Corporation
+ Images\StoreLogo.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ OAuth Test App
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/test.autoinitializer.CS.targets b/test/test.autoinitializer.CS.targets
new file mode 100644
index 0000000000..017fada5ee
--- /dev/null
+++ b/test/test.autoinitializer.CS.targets
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_BOOTSTRAP
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_DEPLOYMENTMANAGER
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_UNDOCKEDREGFREEWINRT
+ $(DefineConstants);MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_COMPATIBILITY
+
+
+
+
+
+
+
+
+
+
diff --git a/test/test.autoinitializer.Native.targets b/test/test.autoinitializer.Native.targets
new file mode 100644
index 0000000000..fd0b286896
--- /dev/null
+++ b/test/test.autoinitializer.Native.targets
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+ NotUsing
+ MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_BOOTSTRAP;%(PreprocessorDefinitions)
+ MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_DEPLOYMENTMANAGER;%(PreprocessorDefinitions)
+ MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_UNDOCKEDREGFREEWINRT;%(PreprocessorDefinitions)
+ MICROSOFT_WINDOWSAPPSDK_AUTOINITIALIZE_COMPATIBILITY;%(PreprocessorDefinitions)
+
+
+
+
+
+
+ $(BeforeClCompileTargets); WindowsAppRuntimeAutoInitializer;
+
+
+
+