From 965abecb53a409b40c3eeb1d4a7b4732a48cdb09 Mon Sep 17 00:00:00 2001 From: "Xiang Hong (from Dev Box)" Date: Fri, 20 Dec 2024 11:29:55 +0800 Subject: [PATCH 01/13] adding basic tests --- .../CameraCaptureUITests.vcxproj | 7 ++ .../CameraCaptureUITests.vcxproj.filters | 4 + test/CameraCaptureUITests/PickersAPITests.cpp | 100 ++++++++++++++++++ .../appxmanifest.xml | 8 ++ 4 files changed, 119 insertions(+) create mode 100644 test/CameraCaptureUITests/PickersAPITests.cpp diff --git a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj index 1c4a3d46dc..0ea4c6a937 100644 --- a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj +++ b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj @@ -212,6 +212,7 @@ + Create Create @@ -233,6 +234,12 @@ true + + + $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd + true + + {f76b776e-86f5-48c5-8fc7-d2795ecc9746} diff --git a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters index 2fe119871b..18f283828d 100644 --- a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters +++ b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters @@ -23,6 +23,10 @@ Source Files + + Source Files + + Source Files diff --git a/test/CameraCaptureUITests/PickersAPITests.cpp b/test/CameraCaptureUITests/PickersAPITests.cpp new file mode 100644 index 0000000000..6f469223f8 --- /dev/null +++ b/test/CameraCaptureUITests/PickersAPITests.cpp @@ -0,0 +1,100 @@ +#include "pch.h" +#include "winrt\Microsoft.Windows.Storage.Pickers.h" +#include "winrt\Microsoft.Windows.Media.Capture.h" +#include +#include +#include +#include +#include +#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; + } + + 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/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml index a4f395306f..d48537271f 100644 --- a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml +++ b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml @@ -113,6 +113,14 @@ + + + Microsoft.WindowsAppRuntime.dll + + + + + Microsoft.WindowsAppRuntime.dll From ee017d221df5b9c2e4e8d03cf9492b47c47dabc5 Mon Sep 17 00:00:00 2001 From: Mike Crider <45052236+codendone@users.noreply.github.com> Date: Thu, 19 Dec 2024 21:56:35 -0800 Subject: [PATCH 02/13] App-configurable compatibility options implementation: CompatibilityOptions (#4976) --- BuildAll.ps1 | 5 + WindowsAppRuntime.sln | 70 ++++++++ ...dowsAppSDK-SetupBuildEnvironment-Steps.yml | 8 + build/CopyFilesToStagingDir.ps1 | 4 + build/NuSpecs/AppxManifest.xml | 3 + ...t.WindowsAppSDK.AutoInitializer.CS.targets | 19 ++ ...indowsAppSDK.AutoInitializerCommon.targets | 16 ++ ...ndowsAppSDK.CompatibilitySetter.CS.targets | 64 +++++++ ...Microsoft.WindowsAppSDK.Foundation.targets | 5 + ...ppSDK-Nuget-Native.AutoInitializer.targets | 23 +++ ...K-Nuget-Native.CompatibilitySetter.targets | 73 ++++++++ .../WindowsAppSDK-Nuget-Native.targets | 5 + build/VersionInfo/AssemblyInfo.h | 14 ++ build/VersionInfo/GenerateVersionInfo.ps1 | 22 ++- dev/Common/Common.vcxitems | 6 +- ...nalVelocityFeatures-CompatibilityOptions.h | 32 ++++ ...lVelocityFeatures-CompatibilityOptions.xml | 16 ++ .../WindowsAppRuntimeAutoInitializer.cpp | 59 ++++++ .../WindowsAppRuntimeAutoInitializer.cs | 35 ++++ .../CompatibilityOptions.cpp | 64 +++++++ .../CompatibilityOptions.h | 34 ++++ .../CompatibilityOptions.idl | 53 ++++++ .../CompatibilityOptions.vcxitems | 32 ++++ .../DeploymentManagerAutoInitializer.cpp | 13 +- .../DeploymentManagerAutoInitializer.cs | 2 +- .../UndockedRegFreeWinRT-AutoInitializer.cpp | 6 +- .../UndockedRegFreeWinRT-AutoInitializer.cs | 2 +- .../MddBootstrapAutoInitializer.cpp | 14 +- .../MddBootstrapAutoInitializer.cs | 2 +- .../WindowsAppRuntime_DLL.vcxproj | 1 + docs/Coding-Guidelines/GettingStarted.md | 4 +- .../CompatibilityTests/CompatibilityTests.cpp | 142 +++++++++++++++ .../CompatibilityTests.testdef | 11 ++ .../CompatibilityTests.vcxproj | 152 ++++++++++++++++ .../CompatibilityTests.vcxproj.filters | 36 ++++ .../CompatibilityTests/packages.config | 6 + test/Compatibility/CompatibilityTests/pch.cpp | 8 + test/Compatibility/CompatibilityTests/pch.h | 24 +++ .../Test_CompatibilitySetter_CPP.vcxproj | 169 ++++++++++++++++++ ...st_CompatibilitySetter_CPP.vcxproj.filters | 17 ++ .../Test_CompatibilitySetter_CPP/main.cpp | 21 +++ .../Test_CompatibilitySetter_CPP/pch.cpp | 8 + .../Test_CompatibilitySetter_CPP/pch.h | 24 +++ .../Test_CompatibilitySetter_CS/Program.cs | 19 ++ .../Test_CompatibilitySetter_CS.csproj | 33 ++++ ...tManagerAutoInitialize_CPP_Default.vcxproj | 6 + ...AutoInitialize_CPP_Options_Default.vcxproj | 6 + ...AutoInitialize_CPP_Options_Defined.vcxproj | 6 + ...gerAutoInitialize_CPP_Options_None.vcxproj | 6 + ...entManagerAutoInitialize_CS_Default.csproj | 5 + ...erAutoInitialize_CS_Options_Default.csproj | 5 + ...erAutoInitialize_CS_Options_Defined.csproj | 17 ++ ...nagerAutoInitialize_CS_Options_None.csproj | 5 + ...ootstrapAutoInitialize_CPP_Default.vcxproj | 6 + ...AutoInitialize_CPP_Options_Default.vcxproj | 6 + ...AutoInitialize_CPP_Options_Defined.vcxproj | 6 + ...rapAutoInitialize_CPP_Options_None.vcxproj | 6 + ..._BootstrapAutoInitialize_CS_Default.csproj | 5 + ...apAutoInitialize_CS_Options_Default.csproj | 5 + ...apAutoInitialize_CS_Options_Defined.csproj | 5 + ...strapAutoInitialize_CS_Options_None.csproj | 5 + .../appxmanifest.xml | 6 + test/test.autoinitializer.CS.targets | 21 +++ test/test.autoinitializer.Native.targets | 25 +++ 64 files changed, 1500 insertions(+), 28 deletions(-) create mode 100644 build/NuSpecs/Microsoft.WindowsAppSDK.AutoInitializer.CS.targets create mode 100644 build/NuSpecs/Microsoft.WindowsAppSDK.AutoInitializerCommon.targets create mode 100644 build/NuSpecs/Microsoft.WindowsAppSDK.CompatibilitySetter.CS.targets create mode 100644 build/NuSpecs/WindowsAppSDK-Nuget-Native.AutoInitializer.targets create mode 100644 build/NuSpecs/WindowsAppSDK-Nuget-Native.CompatibilitySetter.targets create mode 100644 build/VersionInfo/AssemblyInfo.h create mode 100644 dev/Common/TerminalVelocityFeatures-CompatibilityOptions.h create mode 100644 dev/Common/TerminalVelocityFeatures-CompatibilityOptions.xml create mode 100644 dev/Common/WindowsAppRuntimeAutoInitializer.cpp create mode 100644 dev/Common/WindowsAppRuntimeAutoInitializer.cs create mode 100644 dev/CompatibilityOptions/CompatibilityOptions.cpp create mode 100644 dev/CompatibilityOptions/CompatibilityOptions.h create mode 100644 dev/CompatibilityOptions/CompatibilityOptions.idl create mode 100644 dev/CompatibilityOptions/CompatibilityOptions.vcxitems create mode 100644 test/Compatibility/CompatibilityTests/CompatibilityTests.cpp create mode 100644 test/Compatibility/CompatibilityTests/CompatibilityTests.testdef create mode 100644 test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj create mode 100644 test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj.filters create mode 100644 test/Compatibility/CompatibilityTests/packages.config create mode 100644 test/Compatibility/CompatibilityTests/pch.cpp create mode 100644 test/Compatibility/CompatibilityTests/pch.h create mode 100644 test/Compatibility/Test_CompatibilitySetter_CPP/Test_CompatibilitySetter_CPP.vcxproj create mode 100644 test/Compatibility/Test_CompatibilitySetter_CPP/Test_CompatibilitySetter_CPP.vcxproj.filters create mode 100644 test/Compatibility/Test_CompatibilitySetter_CPP/main.cpp create mode 100644 test/Compatibility/Test_CompatibilitySetter_CPP/pch.cpp create mode 100644 test/Compatibility/Test_CompatibilitySetter_CPP/pch.h create mode 100644 test/Compatibility/Test_CompatibilitySetter_CS/Program.cs create mode 100644 test/Compatibility/Test_CompatibilitySetter_CS/Test_CompatibilitySetter_CS.csproj create mode 100644 test/test.autoinitializer.CS.targets create mode 100644 test/test.autoinitializer.Native.targets 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 d9c55d3f34..2d8f0e9b39 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -577,6 +577,20 @@ 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}" +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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -2030,6 +2044,54 @@ 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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2215,6 +2277,12 @@ Global {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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} @@ -2223,6 +2291,7 @@ Global test\inc\inc.vcxitems*{08bc78e0-63c6-49a7-81b3-6afc3deac4de}*SharedItemsImports = 4 dev\PushNotifications\PushNotifications.vcxitems*{103c0c23-7ba8-4d44-a63c-83488e2e3a81}*SharedItemsImports = 9 dev\Notifications\BaseNotifications\BaseNotifications.vcxitems*{2bd7a1bb-d3d8-484f-9180-409d781dccf9}*SharedItemsImports = 9 + dev\CompatibilityOptions\CompatibilityOptions.vcxitems*{1f7b9e9f-9987-490b-9e6e-093c7f63fec4}*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 test\inc\inc.vcxitems*{412d023e-8635-4ad2-a0ea-e19e08d36915}*SharedItemsImports = 4 @@ -2244,6 +2313,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 f73036ee7c..e3165ac28b 100644 --- a/build/CopyFilesToStagingDir.ps1 +++ b/build/CopyFilesToStagingDir.ps1 @@ -212,6 +212,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 6dac600300..630f446630 100644 --- a/build/NuSpecs/AppxManifest.xml +++ b/build/NuSpecs/AppxManifest.xml @@ -114,6 +114,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.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.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets index 506c223359..a51d55d97c 100644 --- a/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets +++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets @@ -152,4 +152,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/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/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/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 4ffc28bcad..569ff9bd0a 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/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 a4f395306f..c4c6300513 100644 --- a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml +++ b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml @@ -149,6 +149,12 @@ + + + Microsoft.WindowsAppRuntime.dll + + + PushNotificationsLongRunningTask.ProxyStub.dll 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; + + + + From f61910f146a6756c1c1927d313c2c6dfd4243381 Mon Sep 17 00:00:00 2001 From: Ayush Jaiswal Date: Fri, 20 Dec 2024 18:51:00 +0530 Subject: [PATCH 03/13] Unit tests for OAuth2Manager API (#4975) * Unit tests for OAuth2.0 API * incorporated comments * fix build error --- WindowsAppRuntime.sln | 66 + .../appxmanifest.xml | 15 + test/OAuth2ManagerTests/OAuth2APITests.cpp | 1224 +++++++++++++++++ test/OAuth2ManagerTests/OAuth2APITests.h | 87 ++ .../OAuth2ManagerTests.vcxproj | 286 ++++ .../OAuth2ManagerTests.vcxproj.filters | 33 + test/OAuth2ManagerTests/packages.config | 7 + test/OAuth2ManagerTests/pch.cpp | 7 + test/OAuth2ManagerTests/pch.h | 27 + .../OAuthTestApp/OAuthTestApp.vcxproj | 153 +++ .../OAuthTestApp/OAuthTestApp.vcxproj.filters | 37 + test/TestApps/OAuthTestApp/main.cpp | 38 + test/TestApps/OAuthTestApp/packages.config | 4 + test/TestApps/OAuthTestApp/pch.cpp | 3 + test/TestApps/OAuthTestApp/pch.h | 5 + .../Images/LockScreenLogo.scale-200.png | Bin 0 -> 1430 bytes .../Images/SplashScreen.scale-200.png | Bin 0 -> 7700 bytes .../Images/Square150x150Logo.scale-200.png | Bin 0 -> 2937 bytes .../Images/Square44x44Logo.scale-200.png | Bin 0 -> 1647 bytes ...x44Logo.targetsize-24_altform-unplated.png | Bin 0 -> 1255 bytes .../OAuthTestAppPackage/Images/StoreLogo.png | Bin 0 -> 1451 bytes .../Images/Wide310x150Logo.scale-200.png | Bin 0 -> 3204 bytes .../OAuthTestAppPackage.wapproj | 98 ++ .../OAuthTestAppPackage/Package.appxmanifest | 58 + 24 files changed, 2148 insertions(+) create mode 100644 test/OAuth2ManagerTests/OAuth2APITests.cpp create mode 100644 test/OAuth2ManagerTests/OAuth2APITests.h create mode 100644 test/OAuth2ManagerTests/OAuth2ManagerTests.vcxproj create mode 100644 test/OAuth2ManagerTests/OAuth2ManagerTests.vcxproj.filters create mode 100644 test/OAuth2ManagerTests/packages.config create mode 100644 test/OAuth2ManagerTests/pch.cpp create mode 100644 test/OAuth2ManagerTests/pch.h create mode 100644 test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj create mode 100644 test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj.filters create mode 100644 test/TestApps/OAuthTestApp/main.cpp create mode 100644 test/TestApps/OAuthTestApp/packages.config create mode 100644 test/TestApps/OAuthTestApp/pch.cpp create mode 100644 test/TestApps/OAuthTestApp/pch.h create mode 100644 test/TestApps/OAuthTestAppPackage/Images/LockScreenLogo.scale-200.png create mode 100644 test/TestApps/OAuthTestAppPackage/Images/SplashScreen.scale-200.png create mode 100644 test/TestApps/OAuthTestAppPackage/Images/Square150x150Logo.scale-200.png create mode 100644 test/TestApps/OAuthTestAppPackage/Images/Square44x44Logo.scale-200.png create mode 100644 test/TestApps/OAuthTestAppPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png create mode 100644 test/TestApps/OAuthTestAppPackage/Images/StoreLogo.png create mode 100644 test/TestApps/OAuthTestAppPackage/Images/Wide310x150Logo.scale-200.png create mode 100644 test/TestApps/OAuthTestAppPackage/OAuthTestAppPackage.wapproj create mode 100644 test/TestApps/OAuthTestAppPackage/Package.appxmanifest diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 2d8f0e9b39..8d0871f9f8 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -592,6 +592,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test_CompatibilitySetter_CP 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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2044,6 +2050,62 @@ 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 + {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 {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 @@ -2277,6 +2339,9 @@ Global {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} + {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} {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} @@ -2289,6 +2354,7 @@ Global 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\Notifications\BaseNotifications\BaseNotifications.vcxitems*{2bd7a1bb-d3d8-484f-9180-409d781dccf9}*SharedItemsImports = 9 dev\CompatibilityOptions\CompatibilityOptions.vcxitems*{1f7b9e9f-9987-490b-9e6e-093c7f63fec4}*SharedItemsImports = 9 diff --git a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml index c4c6300513..aa55c769ec 100644 --- a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml +++ b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml @@ -34,6 +34,21 @@ in the same manifest with the same ActivatableClassId (regardless in same or different s). --> + + + Microsoft.WindowsAppRuntime.dll + + + + + + + + + + + + Microsoft.WindowsAppRuntime.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/TestApps/OAuthTestApp/OAuthTestApp.vcxproj b/test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj new file mode 100644 index 0000000000..c910a901cd --- /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.26100.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 0000000000000000000000000000000000000000..735f57adb5dfc01886d137b4e493d7e97cf13af3 GIT binary patch literal 1430 zcmaJ>TTC2P7~aKltDttVHYH6u8Io4i*}3fO&d$gd*bA_<3j~&e7%8(eXJLfhS!M@! zKrliY>>6yT4+Kr95$!DoD(Qn-5TP|{V_KS`k~E6(LGS@#`v$hQo&^^BKsw3HIsZBT z_y6C2n`lK@apunKojRQ^(_P}Mgewt$(^BBKCTZ;*xa?J3wQ7~@S0lUvbcLeq1Bg4o zH-bvQi|wt~L7q$~a-gDFP!{&TQfc3fX*6=uHv* zT&1&U(-)L%Xp^djI2?~eBF2cxC@YOP$+9d?P&h?lPy-9M2UT9fg5jKm1t$m#iWE{M zIf%q9@;fyT?0UP>tcw-bLkz;s2LlKl2qeP0w zECS7Ate+Awk|KQ+DOk;fl}Xsy4o^CY=pwq%QAAKKl628_yNPsK>?A>%D8fQG6IgdJ ztnxttBz#NI_a@fk7SU`WtrpsfZsNs9^0(2a z@C3#YO3>k~w7?2hipBf{#b6`}Xw1hlG$yi?;1dDs7k~xDAw@jiI*+tc;t2Lflg&bM)0!Y;0_@=w%`LW^8DsYpS#-bLOklX9r?Ei}TScw|4DbpW%+7 zFgAI)f51s}{y-eWb|vrU-Ya!GuYKP)J7z#*V_k^Xo>4!1Yqj*m)x&0L^tg3GJbVAJ zJ-Pl$R=NAabouV=^z_t;^K*0AvFs!vYU>_<|I^#c?>>CR<(T?=%{;U=aI*SbZADLH z&(f2wz_Y0??Tf|g;?|1Znw6}6U43Q#qNRwv1vp9uFn1)V#*4p&%$mP9x&15^OaBiDS(XppT|z^>;B{PLVEbS3IFYV yGvCsSX*m literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..023e7f1feda78d5100569825acedfd213a0d84e9 GIT binary patch literal 7700 zcmeHLYj~4Yw%(;oxoEH#Kxq-eR|+VkP17b#Vk;?4QwkI+A{L04G+#<<(x#Un1#+h5>eArRq zTw$)ZvTWW_Y?bDho0nPVTh08+s`sp!j74rJTTtXIDww0SILedFv?sZ?yb@@}GN;#8 znk_b~Q(A0YR#uV4ef!osoV1M3;vQ8N$O|fStfgf$S5;ddUNv`tWtGjM;koG#N;7M< zP*84lnx(bn_KF&9Z5Ai$)#Cs3a|$OFw>WKCT$of*L7_CqQEinflT|W{JT+aKp-E0v zsxmYg)1(T>DROm+LN1eQw8}KCTp=C!$H7`PU!t9_Hw@TsTI2`udRZv*!a5`#A9hK6Y95L(CDUX&_@QxKV z_feX{UhA#ZWlvgpL$#w^D#lq`_A4AzDqd|Zv6y9PX&DNcN|l}_D^{q@GG&H^Pg583 z8FI6N8^H7b5WjGp;urW)d7F+_lcp%KsLX0viCmE(OHH+=%ZfD_=`voUuoUxFO^L;- z;!;2{g-YiiO6m4bs89OuF9!p{FGtH-f%8<2gY!h9s)4ciN%{Kh1+`}{^}M~+TDH9N z^Z5PlgVXMC&2&k*Hw^Lb9gny#ro$MOIxIt{+r)EA10$VR3 zanN8D{TUkl+v0CQ_>ZoHP<M-x#8@8ZiT#$Kh`(uRaX1g$Bg|qy$<#7 zSSAi{Nb8Y=lvNVeio+UGLCAtoLBfL`iOv`)yoJMDJBN>4IH@(l7YRF;61@>qq1iM9 zr@b#OC~SAxSle?5Pp8Z78{VO0YFr1x7kZU64Z23eLf2T2#6J_t;-E}DkB?NufZ0Ug zi?J&byXeaB-uTNVhuiM!UVQw}bZrJ3GtAETYp->!{q#zfN7D3AS9@Q7*V^85jGx#R z(QxYV(wW#F0XF9^^s>>H8pPlVJ>)3Oz z&_X8Sf@~?cH_O*cgi$U#`v`RRfv#y3m(ZpKk^5uLup+lVs$~}FZU$r_+}#hl%?g5m z-u-}-666ssp-xWQak~>PPy$mRc|~?pVSs1_@mBEXpPVfLF6(Ktf1S* zPPh@QZ=tFMs?LM2(5P3L2;l_6XX6s&cYsP1ip#eg0`ZEP0HGYh{UmS@o`MihLLvkU zgyAG0G`b1|qjxxh1(ODKFE%AP}Dq=3vK$P7TXP4GrM1kQ72!GUVMDl`rDC&2;TA}*nF z8$nQD&6ys_nc1*E7$*1S@R8$ymy(sQV}imGSedB@{!QR5P&N_H=-^o!?LsWs+2|mH z-e=)T^SvI)=_JIm7}j4;@*Z17=(#}m=~YF~z~CLI+vdAGlJDcdF$TM?CVI1%LhUrN zaa6DJ=Yh$)$k&Oz{-~8yw^GM^8prYxSxo zvI4k#ibryMa%%*8oI-5m61Koa_A_xg=(fwp0aBX{;X4Q;NXUhtaoJDo1>TqhWtn=_ zd5~chq#&6~c%8JZK#t_&J(9EVUU&upYeIovLt1>vaHe}UUq>#RGQj!EN#5+0@T`(@ z^g~>*c`VGRiSt;!$_4+0hk^I!@O3``5=sZ8IwlxWW7km1B&_t&E*u0_9UBa#VqwY* zz>nxv?FAsVnRaD(Bui=6i==BFUw0k4n$>`umU`F2l?7CYTD^)c2X+d9X&ddS9|gj? zM?knGkGCX&W8offw8aLC2$D{PjC3nVZwd4k?eZH8*mZ)U@3Qk8RDFOz_#WUA#vnzy zyP>KrCfKwSXea7}jgJjBc}PGY+4#6%lbZyjhy`5sZd_Vy6Wz;ixa?czkN}J9It1K6 zY!eu>|AwF^fwZlLAYyQI*lM@^>O>Iu6Vf6i>Q$?v!SeUS<{>UYMwz$*%Aq?w^`j{h z!$GZbhu=^D{&ET8;))LL%ZBDZkQqRd2;u~!d9bHGmLRhLDctNgYyjsuvoSZ#iVdoB z2!f--UUA#U;<{je#?cYt^{PIyKa%hW>}uepWMyAI{{Zo7?2>?$c9;whJae%oN|I-kpTQSx_C$Z&;f zi2i)qmEn=y4U0uvk)$m;zKfjPK@oc?I`}1Jzl$Q~aoKBd3kt7L#7gyt|A_qgz6ai< z=X%D1i!d2h?rHR^R8SUj&G||dkC?DT>{o#Yau<@uqVT{Xef&XG}5*E4aPk{}~ zplx&XhaV)&1EfI3Em;Bw#O5SV^c;{twb-1Rw)+=0!e_BLbd7tYmXCH0wrlOSS+~`7He8Iqx0{CN+DVit9;*6L~JAN zD&cyT)2?h}xnYmL?^)<7YyzZ3$FHU^Eg;DLqAV{#wv#Wj7S`Jdl1pX&{3(uZ?!uh} zDc$ZTNV*7le_W6}Hju~GMTxZQ1aWCeUc%!jv3MHAzt>Y-nQK%zfT*3ebDQA5b?iGn; zBjv3B+GhLTexd_(CzZDP4|#n5^~scvB6#Pk%Ho!kQ>yYw((Dv{6=$g3jT1!u6gORW zx5#`7Wy-ZHRa~IxGHdrp(bm%lf>2%J660nj$fCqN(epv@y!l9s7@k6EvxS{AMP>WY zX4$@F8^kayphIx-RGO$+LYl9YdoI5d|4#q9##`_F5Xnx`&GPzp2fB{-{P@ATw=X@~ z_|&^UMWAKD;jjBKTK(~o?cUFRK8EX=6>cXpfzg4ZpMB>*w_^8GSiT-Jp|xBOnzM+j z*09-@-~qJ(eqWq5@R4i^u4^{McCP(!3}C|v_WsTR*bIUxN(Nx`u##3B4{sE`Z`v8w zAwIG`?1~PkID~W{uDzmqH98Pew_1(;x2%8r^vY{)_&J2K)cN{W+h5+g)ZcjP&Ci#O zgy|8K@4kyMfwilHd&6TDlhb%++Pk!>9HRld6HT7gwyZGrxS$}CsD6`>6!!2K1@Mjf z(P0WYB7V_OFZyeWrbOFb>O54BNXf~K&?}3=^v;v_wT{DKr?jN^DtN&DXwX%u?s*c6`%8>WFz z7}YW^tp0bp^NriE)AB6M2l<7rn7fzePtR*omOevpfm9n?}2V*+0iW;S)C zhg`NAjL?D=W#k*$aR{>pGf~lD-rVtD;5jW1_*Jn1j1=es@Kcx4ySM_bwcQCT=d+DV z>Sz~L=Hj@(X%31nK$mWI@7d>}ORB`K(p=+`UD)+99YUGQc7y^bHZ1F(8|tL0 zdK*DT0kSXG_{BKTpP2*2PecdKV9;dq$^ZZDP;Nyq1kp-&GI5eAyZsK!e3V zK@rPy*{(`KIfo+lc878mDKk^V#`VT05}64kBtk%DgwLrOvLMj5-;*GNKv6c6pzMuL z6EP%ob|_0IW}lLRXCP2!9wWhEw3LA7iF#1O1mIZ@Z=6&bz41F;@S_GvYAG-#CW3z{ zP3+6vHhvP&A3$##Vo9$dT^#MoGg^|MDm=Bt1d2RRwSZ<;ZHICpLBv5Xs!D?BH^(9_ z7`H=N&^v|Z-%mP}wNzG{aiFCsRgwzwq!N6obW9+7(R; z(SZ=23`|`>qil!LMGG{_Heq!BD>(Y-zV9wD)}hz25JA37YR%39;kI4y9pgtcUass6 zP24}ZY$vvYeI`zy&)A_X#nY3017ap*0&jx|mVwyGhg3;!keU53a}Uhm3BZI$N$6Se zLWlAmy1S0xKJm4G_U@sN_Tm=`$xWJSEwKU98rZ&)1R^*$$1vA3oG#&*%SMxY_~oGP zP&PFJatFLM-Ps%84IV-+Ow)T{C7cqUAvauy4C z(FRz&?6$Rypj{xO!`y=*J5o4@U8Q-(y5(*=YoKeZ+-1YdljXxkA#B)zo=FeQH#?Le zycNUmEEHWO9a=X^pb#&cOq7-`7UA87#|S22)<7RUtZo|(zibX=w;K3qur9vy#`MNV z6UUcf9ZwEnKCCp+OoBnF@OdbvH)ANXO0o~Pi9l8=x3))}L<#vO0-~O4!~--Ket?d} zJaqsj<@CD1%S2cTW%rOP{Vto%0sGW~1RMa_j^)5nil0Yw- z0EE#bP+l4#P^%PQ+N*oxu1Zq05xZ!bXfYTg>9c{(Iw*lnjR^>kz%lAN^zFce7rppy zY8zA~3GD=A6d*hze&l4D_wA~+O!56)BZTe_rEu}Ezi<4!kG|W#amBZ5{&XS2@6R~H z{9o^y*BkH4$~yX9U&@CgbOzX1bn9xqF|zh$Dh0Y5y*E0e90*$!ObrHY3Ok0`2=O~r zCuke6KrP9KOf?V(YDsM<6pX2nVoN%M$LT^q#FmtaF?1^27F*IcNX~XRB(|hCFvdcc zc)$=S-)acdk$g4?_>jRqxpI6M3vHZk?0c^3=byamYDNf;uB{3NlKW5IhnOS3DNkMV z?tK8?kJ}pmvp%&&eTVOVjHP`q34hN1@!aK}H(K!vI`~gf|Gv+FNEQD5Yd<~yX7k_l h&G-K)@HZb3BABY{)U1?^%I#E6`MGoTtustd{~yM6srvu` literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..af49fec1a5484db1d52a7f9b5ec90a27c7030186 GIT binary patch literal 2937 zcma)84OCO-8BSud5)jwMLRVKgX(S?$n?Ld|vrsm<$CF7)&zTbyy1FE5bU`Q17MRv`9ue$;R(@8kR;#vJ*IM0>cJIAOte!d7oRgdH zd%ySjdB6L9=gX^A6)VzH7p2l@v~3zJAMw|DFy#^)F@@F*`mqUn=Il>l)8_+ab;nOW{%+iPx z+s{Eu|&pIs)Z7{La9~?xKfyl z#43?gjEL15d4WbOZo#SiP%>DB^+BcnJ=7dHEe;r#G=tuw|ka z%q@}##Uh7;tc%L_64m(kHtw74ty%BJMb)_1)#S0j`)F8_1jF7vScpsnH=0V19bO8y zR`0SjIdCUo&=>JwMQF8KHA<{ODHTiQh}0^@5QRmCA?gOH6_H3K^-_sNB^RrdNuK-R zOO*vOrKCVvDwgUck`kF(E7j{I#iiN;b*ZdCt4m@HPA`EuEqGGf4%!K<;(=I=&Vyrw z%TwcWtxa}8mCZ%Cyf&ActJ6_$ox5z6-D!0-dvnRx6t7y3d+h6QYpKWO;8OdnvERo7 zuEf>ih5`wqY)~o@OeVt-wM?Q!>QzdGRj!bz6fzYrfw$hZfAKzr2-M+D+R>}~oT574c;_3zquHcElqKIsryILt3g8n3jcMb+j?i?-L3FpZJ z2WRVBRdDPc+G5aaYg#5hpE+6nQ|(VSoxT3|biF;BUq#==-27Xi=gihDPYP$7?=9cP zYKE$jeQ|3~_L0VG-(F~2ZPyD0=k{J4Q~h(t__{-mz_w8{JDY9{`1ouzz!Vr5!ECdE z6U~O1k8c}24V7~zzXWTV-Pe4)y}wQJS&q%H5`Fo_f_JvIU489aCX$;P`u#!I-=^4ijC2{&9!O&h>mi?9oYD=GC#%)6{GzN6nQYw+Fal50!#x^asjBBR50i`+mho*ttoqV)ubM2KD9S~k7+FR4>{29?6 z{!l6kDdyTN0YJ9LgkPWeXm|gyi@zM3?0@{&pXT12w|78&W-q!RRF)&iLCEZVH<|fR zN0fr2^t8H(>L?>K#>^+jWROLral(Qy-xoBq1U7A&DV||wClb)Otd9?(gZ|8znMF}D zf<1haWz^s0qgecz;RFGt0C-B4g`jNGHsFU+;{<%t65v^sjk^h$lmWn#B0#_)9ij&d z-~lc`A)YYExi^7sBuPM^Y|wA2g*5?`K?#7tzELQYNxGo$UB$4J8RJp1k(8Jj+~hMT zlN~>M@KTTh^--8y3PK_NZ@AC!{PT=CziBzGd+wTJ^@icH!Bd}%)g8V)%K?|c&WTUk zy}qv1C%(fjRoZ4ozC3{O%@5?)XzH35zHns$pgU*Q?fj4v?fp1Qbm+j;3l;9jam9Da zXVcKjPlQ73x78QPu|Ffm6x?`~e3oD=gl=4kYK?={kD5j~QCXU)`HSdduNNENzA*2$ zOm3PzF!lN5e*06-f1Uot67wY#{o-S1!KZ7E=!~7ynnk9_iJR#kFoNbAOT#^2Gd17F zMmvU6>lndZQGd|ax9kUoXXO+$N?|j@6qpsF&_j7YXvwo_C{JpmLw5&#e6k>atv%es z5)7r*Wvv_JkUpT}M!_o!nVlEk1Zbl=a*2hQ*<|%*K1Glj^FcF`6kTzGQ3lz~2tCc@ z&x|tj;aH&1&9HwcJBcT`;{?a+pnej;M1HO(6Z{#J!cZA04hnFl;NXA+&`=7bjW_^o zfC40u3LMG?NdPtwGl>Tq6u}*QG)}-y;)lu-_>ee3kibW(69n0$0Zy!}9rQz%*v1iO zT9_H>99yIrSPYVy6^);rR}7Yo=J_T@hi+qhTZXnVWyf;JDYm5#eYLTxr*?kiNn!+Y zQ+LUkBafNJ#rH#C(?d5^;gw9o#%daEI{mA*LHPIHPU`#|H$hD zwm>0&+kahQ)E#%~k>&5@&#Vg82H?s%71=)(soi@174pi9--2{w{1$}Sz4zGn3Du&x bht0Iza^2ykEt4(epJ78uh5nDlX8(TxzDYwP literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ce342a2ec8a61291ba76c54604aea7e9d20af11b GIT binary patch literal 1647 zcmaJ?eM}Q)7(e+G1Q(|`V9JhTI2>MkceK4;p;PR&$Pi?ejk3YQ_3o`S&|W_dsOZ8# zWPTt69g`t$ab`0cj-Y0yiBSOqmd)tG7G(}M5aP0_%&9TijB#&)I{zSE^4@#z^FF`l z`8{8`o%wlL(UI|y2!cdsuVamHH~H86F!*-15em4)NqUpCQM5?aoC_eCf@lV4wvF2a zjDQn1JBL69f&@2M3rvzJcfE!eZ8FZUBlFlC5RD)it33{mF9#B82AiyQE%w)`vlwa> zv{<1sm&kSKK$&%2jSFn7$t&P%%6Ue>R=EAnG8N7fqynWG8L3p!4801a;8{+nliO(qd(jNJ_?+9W3#hLIDLoT6~3fx9=`CC-D}-AMrpEO7HK zt3$GicGPc?GmDjy7K2P@La;eu4!$zWCZ`ym{Z$b zu-O6RM&K4JT|BIZB`E-gxqG%FzanI#+2FFmqHqXG7yxWB=w55RGOM)$xMb(>kSNR z2w=1AZi%z=AmG~yea~XaXJR!v7vLn(RUnELfiB1|6D84ICOS}^Zo2AdN}<&*h}G_u z{xZ!(%>tLT3J3<5XhWy-tg+6)0nmUUENLW8TWA{R6bgVd3X;anYFZ^IRis*_P-C-r z;i>%1^eL3UI2-{w8nuFFcs0e~7J{O2k^~Ce%+Ly4U?|=!0LH=t6()xi<^I-rs+9sF z*q{E-CxZbGPeu#a;XJwE;9S1?#R&uns>^0G3p`hEUF*v`M?@h%T%J%RChmD|EVydq zmHWh*_=S%emRC*mhxaVLzT@>Z2SX0u9v*DIJ@WC^kLVdlGV6LpK$KIrlJqc zpJ921)+3JJdTx|<`G&kXpKkjGJv=76R`yYIQ{#c-`%+`#V(7}Q;&@6U8!Td1`d;?N z_9mnI#?AA}4J!r)LN4!E-@H5eXauuB7TOawS>Y|{-P?NNx-lq+z1W-+y(;39P&&LP zL{N80?&=C*qKmdA^moMZRuPcD!B<*mq$ch=0Cnlitw#txRWhb3%TQvPqjkC`F69G4b! ze7z9MZ#+;_#l?H37UqUhDFb^l&s2{oM$3I0o^Q!yx;;V)QmCMo)Tb_ui|mit8MS?U zm##6$sZZ1$@|s%?l@>4Z<*Q}sRBSKMhb4I{e5LdEhsHIHTe8Bod5c>6QtT>$XgUBz z6MK`kO$=jmt@FqggOhJ5j~e@ygRbG;<{Vu)*+nn9aQeo0;$#j;|MS=S$&L?BeV25z xs3B`@=#`5TF{^6(A1rvdY@|-RtQ|iS5{tyX+wH?;n8E)G$kykv-D^wh{{!TZT%7;_ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f6c02ce97e0a802b85f6021e822c89f8bf57d5cd GIT binary patch literal 1255 zcmaJ>TWs4@7*5+{G#S+&C!qC#> zf>5N3P6jO*Cz>ug*(_DmW=)kea&m$gZ^+nyiF`;j%w@}y8)>p*SH}C`m?DXeieF2U zyQHecc_L%Gh!7GMt+hG06y;+|p4>m~}PjA}rKViGiEnn7G0ZO<>G|7q;2?NwGCM3s?eued6%hd$B+ z*kQJ{#~$S=DFE(%=E+UkmlEI*%3llUf~8Ja9YU1Vui0IbGBkW_gHB%Rd&!!ioX zs40O?i9I{};kle7GMvE7(rk`la=gTI)47=>%?q@^iL-nUo3}h4S}N-KHn8t5mVP8w z&bSErwp+37 zNJJ8?a|{r5Q3R0Z5s-LB1WHOwYC@7pCHWND#cL1cZ?{kJ368_*(UDWUDyb<}0y@o# zfMF016iMWPCb6obAxT$JlB6(2DrlXDTB&!0`!m??4F(qWMhjVZo?JXQmz`1*58Z=& zcDmB|S-E@j?BoFGix0flckqdS4jsPNzhfWyWIM98GxcLs89C(~dw%$_t;JjX-SD}E zfiGV;{8Q%8r}w9x>EEigW81>`kvnU@pK)4+xk9@+bNj9L!AAZ@SZ@q|)&BmY3+HZx zul~BeG4|}-;L%cHViQGQX?^zFfO0&#cHwel=d`lH9sJ-@Sl@n*(8J2>%Ac`IxyY?Q z{=GhWvC#gu-~Ia7*n{=+;qM?Ul_wy1+u7ho;=`>EwP^g~R@{unBds`!#@}tluZQpS zm)M~nYEifJWJGx?_6DcTy>#uh%>!H9=hb^(v`=m3F1{L>db=<5_tm+_&knAQ2EU$s Mu9UqpbNZeC0BbUo^Z)<= literal 0 HcmV?d00001 diff --git a/test/TestApps/OAuthTestAppPackage/Images/StoreLogo.png b/test/TestApps/OAuthTestAppPackage/Images/StoreLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..7385b56c0e4d3c6b0efe3324aa1194157d837826 GIT binary patch literal 1451 zcmaJ>eN5D57_Z|bH;{0+1#mbl)eTU3{h)Wf7EZV?;HD@XL@{B`Ui%(2aMxQ~xdXSv z5nzWi(LW)U2=Vc-cY@s7nPt{i0hc6!7xN4NNHI#EQl>YNBy8l4%x9gr_W-j zEZMQmmTIy(>;lblRfh`dIyTgc9W5d!VP$L4(kKrN1c5G~(O_#xG zAJCNTstD^5SeXFB+&$h=ToJP2H>xr$iqPs-#O*;4(!Fjw25-!gEb*)mU}=)J;Iu>w zxK(5XoD0wrPSKQ~rbL^Cw6O_03*l*}i=ydbu7adJ6y;%@tjFeXIXT+ms30pmbOP%Q zX}S;+LBh8Tea~TSkHzvX6$rYb)+n&{kSbIqh|c7hmlxmwSiq5iVhU#iEQ<>a18|O^Sln-8t&+t`*{qBWo5M?wFM(JuimAOb5!K#D}XbslM@#1ZVz_;!9U zpfEpLAOz=0g@bd6Xj_ILi-x^!M}73h^o@}hM$1jflTs|Yuj9AL@A3<-?MV4!^4q`e z)fO@A;{9K^?W?DbnesnPr6kK>$zaKo&;FhFd(GYFCIU^T+OIMb%Tqo+P%oq(IdX7S zf6+HLO?7o0m+p>~Tp5UrXWh!UH!wZ5kv!E`_w)PTpI(#Iw{AS`gH4^b(bm^ZCq^FZ zY9DD7bH}rq9mg88+KgA$Zp!iWncuU2n1AuIa@=sWvUR-s`Qb{R*kk(SPU^`$6BXz8 zn#7yaFOIK%qGxyi`dYtm#&qqox0$h=pNi#u=M8zUG@bpiZ=3sT=1}Trr}39cC)H|v zbL?W)=&s4zrh)7>L(|cc%$1#!zfL?HjpeP%T+x_a+jZ16b^iKOHxFEX$7d|8${H-* zIrOJ5w&i$>*D>AKaIoYg`;{L@jM((Kt?$N$5OnuPqVvq**Nm}(f0wwOF%iX_Pba;V z;m@wxX&NcV3?<1+u?A{y_DIj7#m3Af1rCE)o`D&Y3}0%7E;iX1yMDiS)sh0wKi!36 zL!Wmq?P^Ku&rK~HJd97KkLTRl>ScGFYZNlYytWnhmuu|)L&ND8_PmkayQb{HOY640 bno1(wj@u8DCVuFR|31B*4ek@pZJqxCDDe1x literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..288995b397fdbef1fb7e85afd71445d5de1952c5 GIT binary patch literal 3204 zcmbVPeQXow8NYmBd90>}0NP?GhXW~VaeThm=a0tV#EwJMI!)6M3}|c4_Bl3=Kd>G0 z(GHx1wl<7(tP?FsOQkTilSo*iIvF%uArExJ73~P zSv1xEy!U(Wd4A9D`FQV@W3@F^qJ@PEF$@z`Z!*BbFsS(^?B zyiAzJ+q})bkgiQHWqEb*jJD-coHYr1^iocg)l!Qa{Xqs-l~6J}p-|##ZHYofskQ3$ zI0;xzXyhazBeXhIsg5A=%ufo@f)1yy&ScKS0;HF^!r_2UE^lpZEom(+@duma3awTv zCrCL-%D_SvYWIcdHkmI}#50(fkUi)Qgx!80ju>g1za^}ff>JI8Z@^-iCiaCgg@TgF z+vtE?Q9{VQUX&MW9SYYmGcxA14%N2@7FwBTD4N<(2{nWgV8$e3?-F=L^&FrtWn~(U_Q~~^uYiyeY6-KoTnfh9AWz@ zIKje0)u!_Lw)E}G!#kEfwKVdNt(UAf9*f>tEL_(=xco-T%jTi@7YlC3hs2ik%Le0H ztj}RTeCF(5mwvi3_56>-yB?l;J>-1%!9~=fs|QcNG3J~a@JCu`4SB460s0ZO+##4fFUSGLcj_ja^fL4&BKALfb#$6$O?>P@qx2Agl^x0i&ugt zsy5Pyu=()`7HRMG3IB7F1@`_ z+-!J%#i6e^U$e#+C%Q>_qVRzWRsG^W_n+@OcX@vzI&z;mzHNb!GQ?LWA(wtpqHqTM z1OFw_{Zn?fD)p)`c`kOgv{de=v@suGRqY{N^U7gI1VF3*F=obwaXI6ob5__Yn zVTguS!%(NI09J8x#AO_aW!9W7k*UvB;IWDFC3srwftr{kHj%g)fvnAm;&h_dnl~

MY- zf+K}sCe8qU6Ujs`3ua{U0Of$R_gVQBuUA za0v=mu#vIOqiiAZOr&h*$WyOw&k-xr$;G4Ixa!#TJNr>95(h>l%)PUy4p+^SgR(uR zta%k*?ny-+nAr8spEk1fo{J4i!b^Fia`N{_F6@zidA2ZTTrjl#^5Z-2KfB@Cu}l9s z(*|Z2jc?p~vn2f)3y9i*7zJV1L{$?|&q)4oaT;uXi6>1GkRXVTOzAz(RHEmr=eFIi z`}<>-Q?K0GN8!IYxeP1XKXO+jsJbp~o^);Bc;%b7Flpe7;1`Ny@3r7ZR;?R)aJt8C ziNlEC<@3f_lIV4TwV}&e;D!Ee5_|e#g0LUh=5vmYWYm7&2h*M>QPKvGh9-)wfMMW3 z8J9b%1k7dzPzO0_NGQy92BZ^FR6R~6;^6?lqO;-QUP4BY%cG%3vEhbm#>4vIhPBh3 z-+pZGjh$x%Hp{?=FHsMp0&wNPlj00us{&`1ZOZTqs8%4X&xH=UDr*xyBW(Zp&Em94 zf)ZSfn#yg0N)>!1kWdkqJ^S*z0FF5|fj&qcE#Na|%OY0$uO>!&hP+1ywfD_WXk@4J(?MBftK7>$Nvqh@tDuarN%PrTLQ2Uzysx>UV=V zk^RrDSvdQ?0;=hY67EgII-f4`t=+i*yS=Y~!XlqIy_4x&%+OdfbKOFPXS2X5%4R{N z$SQMX^AK6(fA + + + + 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.26100.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 + + + + + + + + + + + From e0308f23110b4a04ef1b48c3befa1d21b6852cdd Mon Sep 17 00:00:00 2001 From: "Godly T.Alias" Date: Sat, 21 Dec 2024 13:53:00 +0600 Subject: [PATCH 04/13] Unit tests for BackgroundTaskBuilder API (#4967) * UnitTests for BackgroundTaskBuilder API Signed-off-by: Godly Alias --- WindowsAppRuntime.sln | 22 ++ .../BackgroundTaskBuilder-AppxManifest.xml | 64 +++++ .../BackgroundTaskBuilderTests.cpp | 88 ++++++ .../BackgroundTaskTests.vcxproj | 266 ++++++++++++++++++ .../BackgroundTaskTests.vcxproj.filters | 39 +++ test/BackgroundTaskTests/packages.config | 6 + test/BackgroundTaskTests/pch.cpp | 8 + test/BackgroundTaskTests/pch.h | 27 ++ .../appxmanifest.xml | 7 + 9 files changed, 527 insertions(+) create mode 100644 test/BackgroundTaskTests/BackgroundTaskBuilder-AppxManifest.xml create mode 100644 test/BackgroundTaskTests/BackgroundTaskBuilderTests.cpp create mode 100644 test/BackgroundTaskTests/BackgroundTaskTests.vcxproj create mode 100644 test/BackgroundTaskTests/BackgroundTaskTests.vcxproj.filters create mode 100644 test/BackgroundTaskTests/packages.config create mode 100644 test/BackgroundTaskTests/pch.cpp create mode 100644 test/BackgroundTaskTests/pch.h diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 8d0871f9f8..6018a36495 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}" @@ -2034,6 +2039,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 @@ -2333,6 +2354,7 @@ 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} 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/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml index aa55c769ec..be70d9faab 100644 --- a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml +++ b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml @@ -34,6 +34,13 @@ in the same manifest with the same ActivatableClassId (regardless in same or different s). --> + + + + Microsoft.WindowsAppRuntime.dll + + + Microsoft.WindowsAppRuntime.dll From d2b26bbcee007c5857ffffd0921b68b2fa1d1e59 Mon Sep 17 00:00:00 2001 From: Ayush Jaiswal Date: Sun, 22 Dec 2024 09:53:36 +0530 Subject: [PATCH 05/13] Updating windows SDK version to 10.0 (#4997) --- test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj | 2 +- test/TestApps/OAuthTestAppPackage/OAuthTestAppPackage.wapproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj b/test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj index c910a901cd..7245ebd21f 100644 --- a/test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj +++ b/test/TestApps/OAuthTestApp/OAuthTestApp.vcxproj @@ -10,7 +10,7 @@ {4caa3052-7fae-4c5b-a1cb-02d7f910c991} Win32Proj OAuthTestApp - 10.0.26100.0 + 10.0 10.0.17134.0 diff --git a/test/TestApps/OAuthTestAppPackage/OAuthTestAppPackage.wapproj b/test/TestApps/OAuthTestAppPackage/OAuthTestAppPackage.wapproj index 3402cf21de..f06008490c 100644 --- a/test/TestApps/OAuthTestAppPackage/OAuthTestAppPackage.wapproj +++ b/test/TestApps/OAuthTestAppPackage/OAuthTestAppPackage.wapproj @@ -56,7 +56,7 @@ 455c01f8-0a3e-42c4-9f22-13992eb909ec - 10.0.26100.0 + 10.0.19041.0 10.0.17763.0 en-US True From 18f3a2740ee1be2111759142e4174db08adb6397 Mon Sep 17 00:00:00 2001 From: Akanksha Patel Date: Mon, 23 Dec 2024 16:40:33 +0530 Subject: [PATCH 06/13] [OAuth2Manager] Remove APIs for Implicit grant type (#4979) * [OAuth2Manager] Remove APIs for Implicit grant type * Remove implicit refernces * Telemetry * Add security recommendations to OAuth2Manager spec. --- dev/OAuth/AuthRequestAsyncOperation.cpp | 52 ---------- dev/OAuth/AuthRequestAsyncOperation.h | 1 - dev/OAuth/OAuth.idl | 49 ++------- dev/OAuth/OAuth2Manager.cpp | 92 ----------------- dev/OAuth/OAuth2Manager.h | 21 ---- dev/OAuth/OAuth2ManagerTelemetry.h | 2 - dev/OAuth/TokenRequestParams.cpp | 10 -- dev/OAuth/TokenRequestParams.h | 2 - specs/OAuth/OAuth2Manager.md | 128 ++---------------------- 9 files changed, 15 insertions(+), 342 deletions(-) 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/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(); From 4deb44ef5c76e4932a88bc7eadbd6d1f0aaf0732 Mon Sep 17 00:00:00 2001 From: "Godly T.Alias" Date: Thu, 26 Dec 2024 12:17:07 +0530 Subject: [PATCH 07/13] Added TaskGroup property support to BackgroundTaskBuilder API (#4994) Signed-off-by: godlytalias --- .../BackgroundTaskBuilder/BackgroundTaskBuilder.cpp | 10 ++++++++++ .../BackgroundTaskBuilder/BackgroundTaskBuilder.h | 3 +++ .../BackgroundTaskBuilder/BackgroundTaskBuilder.idl | 1 + specs/BackgroundTask/BackgroundTaskBuilder.md | 1 + 4 files changed, 15 insertions(+) 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/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( ); From 5a994385179f5af0e9f8985903ff301ecab87431 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:50:38 -0800 Subject: [PATCH 08/13] Update dependencies from https://dev.azure.com/microsoft/LiftedIXP/_git/DCPP build 20241219.1 (#4991) Microsoft.FrameworkUdk , Microsoft.ProjectReunion.InteractiveExperiences.TransportPackage From Version 1.8.0-CI-26107.1730.241212-1315.0 -> To Version 1.8.0-CI-26107.1731.241219-1415.0 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 From 430b3a2924aa6025864ddb154de2f7c1ef189957 Mon Sep 17 00:00:00 2001 From: Mike Crider <45052236+codendone@users.noreply.github.com> Date: Fri, 3 Jan 2025 21:45:08 -0800 Subject: [PATCH 09/13] Add auto initializer targets via BeforeClCompileTargets to get better timing for picking up added compiler options. (#5003) --- .../WindowsAppSDK-Nuget-Native.Bootstrap.targets | 8 +++++++- ...owsAppSDK-Nuget-Native.DeploymentManager.targets | 8 +++++++- ...AppSDK-Nuget-Native.UndockedRegFreeWinRT.targets | 13 ++++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) 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.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; + + + From b42b78105e48930aee199300ebe27f8a24e00076 Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Fri, 10 Jan 2025 15:41:05 +0800 Subject: [PATCH 10/13] work in progress --- WindowsAppRuntime.sln | 109 +++++++++--------- .../CompatibilityTests/CompatibilityTests.cpp | 45 ++++++++ .../CompatibilityTests.vcxproj | 6 + 3 files changed, 108 insertions(+), 52 deletions(-) diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 968f8f6267..ef056539ec 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -582,6 +582,7 @@ 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}" @@ -602,10 +603,13 @@ 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("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StoragePickersTests", "StoragePickersTests", "{179D0CF8-4A10-4973-A245-64A380E9FFBD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2074,6 +2078,54 @@ 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 @@ -2130,54 +2182,6 @@ Global {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 - {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 {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 @@ -2380,17 +2384,18 @@ Global {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} - {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} {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} + {179D0CF8-4A10-4973-A245-64A380E9FFBD} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} @@ -2399,8 +2404,8 @@ Global 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\Notifications\BaseNotifications\BaseNotifications.vcxitems*{2bd7a1bb-d3d8-484f-9180-409d781dccf9}*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 test\inc\inc.vcxitems*{412d023e-8635-4ad2-a0ea-e19e08d36915}*SharedItemsImports = 4 diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp index 8bbe369856..56564617ae 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp @@ -6,10 +6,15 @@ #include #include +#include "winrt\Microsoft.Windows.Storage.Pickers.h" namespace TB = ::Test::Bootstrap; namespace TP = ::Test::Packages; +using namespace WEX::Common; +using namespace WEX::Logging; +using namespace WEX::TestExecution; + namespace WAR = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime; namespace Test::CompatibilityTests @@ -28,6 +33,46 @@ namespace Test::CompatibilityTests ::Test::Bootstrap::SetupPackages(); return true; } + 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."); + } + } TEST_CLASS_CLEANUP(ClassCleanup) { diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj index ee37756ff4..e2b4443bb0 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj @@ -122,6 +122,12 @@ true + + + $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd + true + + {f76b776e-86f5-48c5-8fc7-d2795ecc9746} From 77cc4857b16f69c429f5b2ae27bd9f458b5468f2 Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Wed, 15 Jan 2025 15:31:38 +0800 Subject: [PATCH 11/13] ad hoc working, examing in progress --- .../TerminalVelocityFeatures-StoragePickers.h | 27 ++++++++ ...erminalVelocityFeatures-StoragePickers.xml | 20 ++++++ test/CameraCaptureUITests/PickersAPITests.cpp | 49 +++++++++++++- .../CompatibilityTests/CompatibilityTests.cpp | 64 ++++++++++--------- .../CompatibilityTests.vcxproj | 7 ++ test/Compatibility/CompatibilityTests/pch.h | 1 + 6 files changed, 136 insertions(+), 32 deletions(-) create mode 100644 dev/Common/TerminalVelocityFeatures-StoragePickers.h create mode 100644 dev/Common/TerminalVelocityFeatures-StoragePickers.xml 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/test/CameraCaptureUITests/PickersAPITests.cpp b/test/CameraCaptureUITests/PickersAPITests.cpp index 6f469223f8..1ac27691ed 100644 --- a/test/CameraCaptureUITests/PickersAPITests.cpp +++ b/test/CameraCaptureUITests/PickersAPITests.cpp @@ -7,7 +7,8 @@ #include #include #include - +#include "winrt\Microsoft.Windows.Media.Capture.h" +#include using namespace std::chrono_literals; using namespace WEX::Common; @@ -56,6 +57,52 @@ namespace CameraCaptureUITests 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 diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp index 56564617ae..96de98ab30 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp @@ -6,7 +6,9 @@ #include #include -#include "winrt\Microsoft.Windows.Storage.Pickers.h" +#include +#include +#include namespace TB = ::Test::Bootstrap; namespace TP = ::Test::Packages; @@ -25,23 +27,48 @@ namespace Test::CompatibilityTests 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"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() + END_TEST_CLASS() - TEST_CLASS_SETUP(ClassSetup) + 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::Media::Capture::CameraCaptureUI cameraUI(windowId); - //} + 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" })); @@ -54,12 +81,10 @@ namespace Test::CompatibilityTests 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) @@ -74,29 +99,6 @@ namespace Test::CompatibilityTests } } - 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...")); diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj index e2b4443bb0..41d7247bc3 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj @@ -122,6 +122,12 @@ true + + + $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Media.Capture.winmd + true + + $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd @@ -139,6 +145,7 @@ + diff --git a/test/Compatibility/CompatibilityTests/pch.h b/test/Compatibility/CompatibilityTests/pch.h index d9ababf69f..5518c5fd5c 100644 --- a/test/Compatibility/CompatibilityTests/pch.h +++ b/test/Compatibility/CompatibilityTests/pch.h @@ -12,6 +12,7 @@ #include #include +#include "winrt/Microsoft.Windows.Storage.Pickers.h" #include From c4d276803f5487dd1d8cce2e4c13d334455ca4db Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Thu, 16 Jan 2025 11:13:35 +0800 Subject: [PATCH 12/13] add unit test project for storage pickers APIs --- WindowsAppRuntime.sln | 19 +++ .../CameraCaptureUITests.vcxproj | 7 - .../CameraCaptureUITests.vcxproj.filters | 4 - .../CompatibilityTests/CompatibilityTests.cpp | 51 +----- .../CompatibilityTests.vcxproj | 13 -- test/Compatibility/CompatibilityTests/pch.h | 1 - .../StoragePickers.vcxproj | 152 ++++++++++++++++++ .../StoragePickersTests.cpp | 97 +++++++++++ .../StoragePickersTests.vcxproj.filters | 36 +++++ test/StoragePickersTests/packages.config | 6 + test/StoragePickersTests/pch.cpp | 8 + test/StoragePickersTests/pch.h | 22 +++ 12 files changed, 342 insertions(+), 74 deletions(-) create mode 100644 test/StoragePickersTests/StoragePickers.vcxproj create mode 100644 test/StoragePickersTests/StoragePickersTests.cpp create mode 100644 test/StoragePickersTests/StoragePickersTests.vcxproj.filters create mode 100644 test/StoragePickersTests/packages.config create mode 100644 test/StoragePickersTests/pch.cpp create mode 100644 test/StoragePickersTests/pch.h diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index ef056539ec..dc573116f1 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -610,6 +610,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "dev\Inter EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StoragePickersTests", "StoragePickersTests", "{179D0CF8-4A10-4973-A245-64A380E9FFBD}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "test\StoragePickersTests\StoragePickers.vcxproj", "{85C86306-46D1-4563-8303-0A79DF923586}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2198,6 +2200,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 @@ -2396,6 +2414,7 @@ Global {8E01AA4F-A16A-4E3F-A59F-6D49422B4410} = {716C26A0-E6B0-4981-8412-D14A4D410531} {A39E7B2F-5F67-47DD-8443-531D095CA7F3} = {3B706C5C-55E0-4B76-BF59-89E20FE46795} {179D0CF8-4A10-4973-A245-64A380E9FFBD} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} + {85C86306-46D1-4563-8303-0A79DF923586} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} diff --git a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj index 0ea4c6a937..1c4a3d46dc 100644 --- a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj +++ b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj @@ -212,7 +212,6 @@ - Create Create @@ -234,12 +233,6 @@ true - - - $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd - true - - {f76b776e-86f5-48c5-8fc7-d2795ecc9746} diff --git a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters index 18f283828d..2fe119871b 100644 --- a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters +++ b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters @@ -23,10 +23,6 @@ Source Files - - Source Files - - Source Files diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp index 96de98ab30..8bbe369856 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp @@ -6,17 +6,10 @@ #include #include -#include -#include -#include namespace TB = ::Test::Bootstrap; namespace TP = ::Test::Packages; -using namespace WEX::Common; -using namespace WEX::Logging; -using namespace WEX::TestExecution; - namespace WAR = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime; namespace Test::CompatibilityTests @@ -27,13 +20,10 @@ namespace Test::CompatibilityTests 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"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() + END_TEST_CLASS() - TEST_CLASS_SETUP(ClassSetup) + TEST_CLASS_SETUP(ClassSetup) { ::Test::Bootstrap::SetupPackages(); return true; @@ -62,43 +52,6 @@ namespace Test::CompatibilityTests return true; } - 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."); - } - 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."); - } - } - TEST_METHOD(CanSetCompatibilityOptions) { WEX::Logging::Log::Comment(WEX::Common::String(L"Starting CanSetCompatibilityOptions...")); diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj index 41d7247bc3..ee37756ff4 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj @@ -122,18 +122,6 @@ true - - - $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Media.Capture.winmd - true - - - - - $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd - true - - {f76b776e-86f5-48c5-8fc7-d2795ecc9746} @@ -145,7 +133,6 @@ - diff --git a/test/Compatibility/CompatibilityTests/pch.h b/test/Compatibility/CompatibilityTests/pch.h index 5518c5fd5c..d9ababf69f 100644 --- a/test/Compatibility/CompatibilityTests/pch.h +++ b/test/Compatibility/CompatibilityTests/pch.h @@ -12,7 +12,6 @@ #include #include -#include "winrt/Microsoft.Windows.Storage.Pickers.h" #include diff --git a/test/StoragePickersTests/StoragePickers.vcxproj b/test/StoragePickersTests/StoragePickers.vcxproj new file mode 100644 index 0000000000..0fba931b4b --- /dev/null +++ b/test/StoragePickersTests/StoragePickers.vcxproj @@ -0,0 +1,152 @@ + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + 17.0 + Win32Proj + {85C86306-46D1-4563-8303-0A79DF923586} + StoragePickersTests + 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.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}. + + + + + + + + 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.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 From a1e2c91f0138a1fd65b106dd0dedc1a95fb3350e Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Thu, 16 Jan 2025 14:46:03 +0800 Subject: [PATCH 13/13] fix project name --- WindowsAppRuntime.sln | 5 +---- .../{StoragePickers.vcxproj => StoragePickersTests.vcxproj} | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) rename test/StoragePickersTests/{StoragePickers.vcxproj => StoragePickersTests.vcxproj} (99%) diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index dc573116f1..cd77601b04 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -608,9 +608,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.Storage.P EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "dev\Interop\StoragePickers\StoragePickers.vcxitems", "{A39E7B2F-5F67-47DD-8443-531D095CA7F3}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StoragePickersTests", "StoragePickersTests", "{179D0CF8-4A10-4973-A245-64A380E9FFBD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "test\StoragePickersTests\StoragePickers.vcxproj", "{85C86306-46D1-4563-8303-0A79DF923586}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickersTests", "test\StoragePickersTests\StoragePickersTests.vcxproj", "{85C86306-46D1-4563-8303-0A79DF923586}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -2413,7 +2411,6 @@ Global {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} - {179D0CF8-4A10-4973-A245-64A380E9FFBD} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} {85C86306-46D1-4563-8303-0A79DF923586} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/test/StoragePickersTests/StoragePickers.vcxproj b/test/StoragePickersTests/StoragePickersTests.vcxproj similarity index 99% rename from test/StoragePickersTests/StoragePickers.vcxproj rename to test/StoragePickersTests/StoragePickersTests.vcxproj index 0fba931b4b..ebe73a74e7 100644 --- a/test/StoragePickersTests/StoragePickers.vcxproj +++ b/test/StoragePickersTests/StoragePickersTests.vcxproj @@ -34,6 +34,7 @@ {85C86306-46D1-4563-8303-0A79DF923586} StoragePickersTests 10.0 + StoragePickersTests DynamicLibrary @@ -149,4 +150,4 @@ - + \ No newline at end of file