From 0ca6d3df33bdcc6d292ed542b9b2ad55ece510bd Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Tue, 3 Aug 2021 17:29:19 -0700 Subject: [PATCH 01/50] Original skeleton --- WindowsAppSDK.sln | 43 +- .../PushNotificationsLRP.idl | 34 ++ ...NotificationsLongRunningTask.ProxyStub.def | 3 + ...ficationsLongRunningTask.ProxyStub.vcxproj | 457 ++++++++++++++++++ ...sLongRunningTask.ProxyStub.vcxproj.filters | 49 ++ .../framework.h | 8 + .../pch.cpp | 5 + .../pch.h | 9 + .../PushNotificationsLongRunningTask.vcxproj | 26 +- ...tificationsLongRunningTask.vcxproj.filters | 20 +- .../externs.h | 11 + .../packages.config | 5 + .../PushNotificationsLongRunningTask/pch.h | 23 + .../platform.cpp | 119 +++++ .../platform.h | 36 ++ .../platformfactory.cpp | 29 ++ .../platformfactory.h | 9 + .../winmain.cpp | 72 ++- .../WindowsAppSDK_DLL.vcxproj | 3 + .../Makefile.mak | 10 +- ...hNotificationsLongRunningTask.Msix.vcxproj | 5 +- .../appxmanifest.xml | 8 +- 22 files changed, 964 insertions(+), 20 deletions(-) create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLRP.idl create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.def create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/framework.h create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/pch.cpp create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/pch.h create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/externs.h create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/packages.config create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/platform.h create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h diff --git a/WindowsAppSDK.sln b/WindowsAppSDK.sln index 5f65d8e582..9386c49a01 100644 --- a/WindowsAppSDK.sln +++ b/WindowsAppSDK.sln @@ -169,7 +169,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PowerNotifications", "Power EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerNotifications", "dev\PowerNotifications\PowerNotifications.vcxitems", "{B75C1B22-553C-40E4-B38E-6AB4D01FDB9D}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerNotifications", "test\PowerNotifications\PowerNotifications.vcxproj", "{A9D7357B-FA9A-4548-B21E-F305DD63BC68}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerNotifications", "test\PowerNotifications\PowerNotifications.vcxproj", "{CBD95746-61CE-4F31-B6CC-C5ABF1766180}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PushNotificationsLongRunningTask.ProxyStub", "dev\PushNotifications\PushNotificationsLongRunningTask.ProxyStub\PushNotificationsLongRunningTask.ProxyStub.vcxproj", "{BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution @@ -595,18 +597,30 @@ Global {C422B090-F501-4204-8068-1084B0799405}.Release|x64.Build.0 = Release|x64 {C422B090-F501-4204-8068-1084B0799405}.Release|x86.ActiveCfg = Release|Win32 {C422B090-F501-4204-8068-1084B0799405}.Release|x86.Build.0 = Release|Win32 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|ARM64.ActiveCfg = Debug|Win32 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|x64.ActiveCfg = Debug|x64 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|x64.Build.0 = Debug|x64 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|x86.ActiveCfg = Debug|Win32 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|x86.Build.0 = Debug|Win32 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|Any CPU.ActiveCfg = Release|Win32 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|ARM64.ActiveCfg = Release|Win32 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|x64.ActiveCfg = Release|x64 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|x64.Build.0 = Release|x64 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|x86.ActiveCfg = Release|Win32 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|x86.Build.0 = Release|Win32 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|ARM64.ActiveCfg = Debug|Win32 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|x64.ActiveCfg = Debug|x64 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|x64.Build.0 = Debug|x64 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|x86.ActiveCfg = Debug|Win32 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|x86.Build.0 = Debug|Win32 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|Any CPU.ActiveCfg = Release|Win32 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|ARM64.ActiveCfg = Release|Win32 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|x64.ActiveCfg = Release|x64 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|x64.Build.0 = Release|x64 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|x86.ActiveCfg = Release|Win32 + {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|x86.Build.0 = Release|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|ARM64.ActiveCfg = Debug|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x64.ActiveCfg = Debug|x64 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x64.Build.0 = Debug|x64 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x86.ActiveCfg = Debug|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x86.Build.0 = Debug|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|Any CPU.ActiveCfg = Release|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|ARM64.ActiveCfg = Release|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x64.ActiveCfg = Release|x64 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x64.Build.0 = Release|x64 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x86.ActiveCfg = Release|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -658,7 +672,8 @@ Global {C422B090-F501-4204-8068-1084B0799405} = {A1B25DCF-6A54-414D-8E24-F4D24EE9299D} {E9117D76-63AC-4289-A628-AB39EF6E5D19} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A} {B75C1B22-553C-40E4-B38E-6AB4D01FDB9D} = {E9117D76-63AC-4289-A628-AB39EF6E5D19} - {A9D7357B-FA9A-4548-B21E-F305DD63BC68} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} + {CBD95746-61CE-4F31-B6CC-C5ABF1766180} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0} = {91D03B95-1B0C-4BEB-8441-30DA7D615538} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLRP.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLRP.idl new file mode 100644 index 0000000000..cbfef6a482 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLRP.idl @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +import "oaidl.idl"; +import "ocidl.idl"; + +// #include "..\PushNotifications-Constants.h" + +[object] +[uuid(60FC21B2-B396-4D49-94F0-7555869FB93C)] +[pointer_default(unique)] +interface IWpnLrpPlatform : IUnknown +{ + HRESULT RegisterActivator([in] LPCWSTR processName); + + HRESULT UnregisterActivator([in] LPCWSTR processName); + + HRESULT RegisterForegroundActivator([in] LPCWSTR processName); + + HRESULT UnregisterForegroundActivator([in] LPCWSTR processName); + + HRESULT RegisterFullTrustApplication([in] LPCWSTR processName, [out] GUID* appId); +}; + +[uuid(60C6A2D9-04D9-42C3-B4E9-71158389D422)] // PR_DYNDEP_LIBID_UUID +[version(1.0)] +library WpnLrpPlatformLib +{ + [uuid(330EC755-31F2-40A7-977D-B0ABB1E1E52E)] // PR_DYNDEP_DATASTORE_CLSID_UUID + coclass WpnLrpPlatform + { + [default] interface IWpnLrpPlatform; + }; +}; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.def b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.def new file mode 100644 index 0000000000..753f222d5b --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.def @@ -0,0 +1,3 @@ +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj new file mode 100644 index 0000000000..86917f4648 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj @@ -0,0 +1,457 @@ + + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + 16.0 + Win32Proj + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0} + PushNotificationsLongRunningTask.ProxyStub + 10.0 + PushNotificationsLongRunningTask.ProxyStub + true + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + true + v142 + Unicode + + + DynamicLibrary + false + true + v142 + Unicode + + + DynamicLibrary + false + true + v142 + Unicode + + + DynamicLibrary + false + true + v142 + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + PostBuildEvent + $(PlatformTarget)\$(Configuration)\ + + + true + PostBuildEvent + + + false + PostBuildEvent + + + true + PostBuildEvent + + + false + PostBuildEvent + + + false + PostBuildEvent + $(PlatformTarget)\$(Configuration)\ + + + true + PostBuildEvent + + + false + PostBuildEvent + + + + + MultiThreadedDebug + + + + %(IgnoreSpecificDefaultLibraries);libucrtd.lib + %(AdditionalOptions) /defaultlib:ucrtd.lib + + + + + + MultiThreaded + + + + %(IgnoreSpecificDefaultLibraries);libucrt.lib + %(AdditionalOptions) /defaultlib:ucrt.lib + + + + + Level4 + true + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + Windows + DebugFull + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + PushNotificationsLongRunningTask.ProxyStub.def + + + dlldata.c + false + $(PlatformTarget)\$(Configuration)\ + + + + + Level4 + true + _ARM_;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + Windows + DebugFull + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + PushNotificationsLongRunningTask.ProxyStub.def + + + dlldata.c + false + $(PlatformTarget)\$(Configuration)\ + + + + + Level4 + true + true + true + _ARM_;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + Windows + true + true + DebugFull + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + PushNotificationsLongRunningTask.ProxyStub.def + + + dlldata.c + false + $(PlatformTarget)\$(Configuration)\ + + + + + Level4 + true + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + Windows + DebugFull + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + PushNotificationsLongRunningTask.ProxyStub.def + + + dlldata.c + false + $(PlatformTarget)\$(Configuration)\ + + + + + Level4 + true + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + Windows + true + true + DebugFull + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + PushNotificationsLongRunningTask.ProxyStub.def + + + dlldata.c + false + $(PlatformTarget)\$(Configuration)\ + + + + + Level4 + true + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + Windows + true + true + DebugFull + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + PushNotificationsLongRunningTask.ProxyStub.def + + + dlldata.c + false + $(PlatformTarget)\$(Configuration)\ + + + + + Level4 + true + _DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + Windows + DebugFull + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + + + PushNotificationsLongRunningTask.ProxyStub.def + + + dlldata.c + false + $(PlatformTarget)\$(Configuration)\ + + + + + Level4 + true + true + true + NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + Windows + true + true + DebugFull + onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + PushNotificationsLongRunningTask.ProxyStub.def + + + dlldata.c + false + $(PlatformTarget)\$(Configuration)\ + + + + + + + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + NotUsing + + + Create + Create + Create + Create + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters new file mode 100644 index 0000000000..7a312fc125 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters @@ -0,0 +1,49 @@ + + + + + {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 + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/framework.h b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/framework.h new file mode 100644 index 0000000000..cfc853b95d --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/framework.h @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/pch.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/pch.cpp new file mode 100644 index 0000000000..64b7eef6d6 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/pch.cpp @@ -0,0 +1,5 @@ +// 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/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/pch.h b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/pch.h new file mode 100644 index 0000000000..0d9fb298f7 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/pch.h @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +#ifndef PCH_H +#define PCH_H + +#include "framework.h" + +#endif //PCH_H diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index c3a92d0ec8..05fa7c91cd 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -1,5 +1,6 @@ + Debug @@ -210,12 +211,35 @@ + + + + + + + + + + + + {bf3fced0-cadb-490a-93a7-4d90e1f45ab0} + + + - + + + 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/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters index 457e18b40e..e64fc5dd65 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters @@ -18,6 +18,15 @@ Header Files + + Header Files + + + Header Files + + + Header Files + @@ -26,5 +35,14 @@ Source Files + + Source Files + + + Source Files + + + + - + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h new file mode 100644 index 0000000000..f0522f70e8 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h @@ -0,0 +1,11 @@ +#pragma once +#include "pch.h" +#include "platform.h" + +wil::unique_event& GetWinMainEvent(); + +WpnLrpPlatformImpl* GetPlatform(); + +HRESULT InitializePlatform(); + +void CleanPlatform(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config b/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config new file mode 100644 index 0000000000..c48ce9eaae --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h index 24a1188504..8e60e4ea5c 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h @@ -4,3 +4,26 @@ #pragma once #include +#include + +#include +#include + +// Temporarily disable C4324 because WRL generates a false (well, irrelevant) warning +// 'Microsoft::WRL::Details::StaticStorage::GenericReleaseNotifier,Microsoft::WRL::Details::StorageInstance::OutOfProcCallbackBuffer1,ModuleT>': structure was padded due to alignment specifier +#pragma warning(push) +#pragma warning(disable:4324) +#include +#pragma warning(pop) + +#include +#include +#include +#include + +#include +#include + +#include + +#include diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp new file mode 100644 index 0000000000..ba8fec9d5d --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -0,0 +1,119 @@ +#include "pch.h" + +// FIX REF!!! +#include "..\..\PushNotificationsLongRunningTask.ProxyStub\x64\Debug\PushNotificationsLRP_h.h" +//#include + +#include "platform.h" + +wil::unique_event g_winmainEvent(wil::EventOptions::None); + +Microsoft::WRL::ComPtr g_platform; + +WpnLrpPlatformImpl* GetPlatform() +{ + if (!g_platform) + { + g_platform = Microsoft::WRL::Make(); + } + + g_platform->AddRef(); + return g_platform.Get(); +} + +// create void function for copying com ptr to iinspectable + +void CleanPlatform() +{ + g_platform = nullptr; +} + +HRESULT InitializePlatform() +{ + if (!g_platform) + { + g_platform = Microsoft::WRL::Make(); + } + g_platform->InitializePlatform(); + return S_OK; +} + +wil::unique_event& GetWinMainEvent() +{ + return g_winmainEvent; +} + +WpnLrpPlatformImpl::WpnLrpPlatformImpl() +{ + m_lock.create(); +} + +void WpnLrpPlatformImpl::InitializePlatform() +{ + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + + auto lock = m_lock.acquire(); + + if (m_initialized) + { + return; + } + + /* Load your components */ + + m_initialized = true; +} + +void WpnLrpPlatformImpl::ShutdownPlatform() +{ + if (m_shutdown) + { + return; + } + + auto lock = m_lock.acquire(); + + /* Shut down your components */ + + m_shutdown = true; +} + +bool WpnLrpPlatformImpl::IsPlatformInitialized() +{ + return m_initialized; +} + +STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::RegisterActivator(/*[in]*/ PCWSTR /*processName*/) +{ + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + auto lock = m_lock.acquire(); + return S_OK; +} + +STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::UnregisterActivator(/*[in]*/ PCWSTR /*processName*/) +{ + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + auto lock = m_lock.acquire(); + return S_OK; +} + +STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::RegisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) +{ + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + auto lock = m_lock.acquire(); + return S_OK; +} + +STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::UnregisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) +{ + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + auto lock = m_lock.acquire(); + return S_OK; +} + +STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::RegisterFullTrustApplication(/*[in]*/ PCWSTR /*processName*/, /*[out]*/ GUID* /*appId*/) +{ + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + auto lock = m_lock.acquire(); + return S_OK; +} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h new file mode 100644 index 0000000000..92715b51fa --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -0,0 +1,36 @@ +#pragma once + +struct __declspec(uuid("330EC755-31F2-40A7-977D-B0ABB1E1E52E")) WpnLrpPlatformImpl WrlFinal : +Microsoft::WRL::RuntimeClass, IWpnLrpPlatform, Microsoft::WRL::FtmBase> +{ + WpnLrpPlatformImpl(); + + void InitializePlatform(); + + void ShutdownPlatform(); + + bool IsPlatformInitialized(); + + /* IWpnLrpPlatform functions */ + + STDMETHOD(RegisterActivator)(/*[in]*/ PCWSTR processName); + + STDMETHOD(UnregisterActivator)(/*[in]*/ PCWSTR processName); + + STDMETHOD(RegisterForegroundActivator)(/*[in]*/ PCWSTR processName); + + STDMETHOD(UnregisterForegroundActivator)(/*[in]*/ PCWSTR processName); + + STDMETHOD(RegisterFullTrustApplication)(/*[in]*/ PCWSTR processName, /*[out]*/ GUID* appId); + + /* Add your functions to retrieve the platform components */ + +private: + + wil::unique_mutex m_lock; + + bool m_initialized = false; + bool m_shutdown = false; + + // Here we will define the Platform components i.e. the map wrappings +}; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp new file mode 100644 index 0000000000..3015847a96 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp @@ -0,0 +1,29 @@ +#include "pch.h" + +// FIX REF!!! +#include "..\..\PushNotificationsLongRunningTask.ProxyStub\x64\Debug\PushNotificationsLRP_h.h" +//#include + +#include "externs.h" +#include "platform.h" +#include +#include +#include "platformfactory.h" + +using namespace Microsoft::WRL; + +IFACEMETHODIMP WpnLrpPlatformFactory::CreateInstance( + _In_opt_ IUnknown* /*outer*/, + _In_ REFIID /*riid*/, + _COM_Outptr_ void** obj) noexcept +{ + *obj = nullptr; + *obj = GetPlatform(); + + if (!GetPlatform()->IsPlatformInitialized()) + { + THROW_IF_FAILED(InitializePlatform()); + } + + return S_OK; +} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h new file mode 100644 index 0000000000..f3ddc3b498 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h @@ -0,0 +1,9 @@ +#pragma once + +struct WpnLrpPlatformFactory WrlFinal : public Microsoft::WRL::ClassFactory<> +{ + IFACEMETHODIMP CreateInstance( + _In_opt_ IUnknown* outer, + _In_ REFIID riid, + _COM_Outptr_ void** ppvObject) noexcept override; +}; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index 1b2da5cdd5..666b69cb48 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -1,10 +1,80 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#include #include "pch.h" +// include notifications constants file here + +// FIX REF!!! +#include "..\..\PushNotificationsLongRunningTask.ProxyStub\x64\Debug\PushNotificationsLRP_h.h" +//#include + +// Temporarily disable C4324 because WRL generates a false (well, irrelevant) warning +// 'Microsoft::WRL::Details::StaticStorage::GenericReleaseNotifier,Microsoft::WRL::Details::StorageInstance::OutOfProcCallbackBuffer1,ModuleT>': structure was padded due to alignment specifier +#pragma warning(push) +#pragma warning(disable:4324) +#include +#pragma warning(pop) + +#include "platform.h" +#include "platformfactory.h" +#include "externs.h" + +using namespace Microsoft::WRL; + +void SignalEvent() +{ + GetWinMainEvent().SetEvent(); +} + int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { + // Time to connect to a debugger. Eventually should be removed. + Sleep(20000); + + RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); + + // Callback to be signaled by COM if it considers that the event should exit. + auto& module = Module::Create(SignalEvent); + + unsigned long count = module.IncrementObjectCount(); + + DWORD cookie = 0; + ComPtr platformFactory; + THROW_IF_FAILED(MakeAndInitialize(&platformFactory)); + + CLSID clsid = __uuidof(WpnLrpPlatform); + + THROW_IF_FAILED(module.RegisterCOMObject( + nullptr, + &clsid, + platformFactory.GetAddressOf(), + &cookie, + 1 + )); + + InitializePlatform(); + + GetWinMainEvent().wait(); + + GetPlatform()->ShutdownPlatform(); + CleanPlatform(); + + count = module.DecrementObjectCount(); + + (void)LOG_IF_FAILED(module.UnregisterCOMObject(nullptr, &cookie, 1)); + module.Terminate(); + + ::CoUninitialize(); + return 0; } + +STDAPI_(BOOL) DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void*) +{ + if (reason == DLL_PROCESS_ATTACH) + { + DisableThreadLibraryCalls(hinst); + } + return TRUE; +} diff --git a/dev/WindowsAppSDK_DLL/WindowsAppSDK_DLL.vcxproj b/dev/WindowsAppSDK_DLL/WindowsAppSDK_DLL.vcxproj index 0c0aa9b18f..b08c5add7d 100644 --- a/dev/WindowsAppSDK_DLL/WindowsAppSDK_DLL.vcxproj +++ b/dev/WindowsAppSDK_DLL/WindowsAppSDK_DLL.vcxproj @@ -387,6 +387,9 @@ {1a41bb90-cc34-4edd-9a27-50714cdbc169} + + {bf3fced0-cadb-490a-93a7-4d90e1f45ab0} + {1307dd1b-bbe8-4cd0-b1a0-0db6d61eeaa0} diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak index 28e229b287..40bc48b95b 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak @@ -18,7 +18,7 @@ SIGNTOOL_OPTS=/v !MESSAGE ProjectDir =$(ProjectDir) !MESSAGE OutDir =$(OutDir) !MESSAGE TargetName =$(TargetName) -!MESSAGE WindowsAppSDKBuildPipeline =$(WindowsAppSDKBuildPipeline) +!MESSAGE WindowsAppSDKBuildPipeline =$(WindowsAppSDKBuildPipeline) !ENDIF TARGET_BASENAME=PushNotificationsLongRunningTask @@ -27,6 +27,13 @@ TARGET_EXE=$(TARGET_BASENAME) TARGET_EXE_DIR=$(OutDir)$(TARGET_EXE) TARGET_EXE_FILE=$(TARGET_EXE_DIR)\$(TARGET_EXE).exe +TARGET_PROXYSTUB=PushNotificationsLongRunningTask.ProxyStub +TARGET_PROXYSTUB_DIR=$(OutDir)$(TARGET_PROXYSTUB) +TARGET_PROXYSTUB_FILE=$(TARGET_PROXYSTUB_DIR)\$(TARGET_PROXYSTUB).dll +!IFDEF VERBOSE +!MESSAGE $(TARGET_PROXYSTUB_FILE) +!ENDIF + TargetDir=$(OutDir)$(TargetName) WorkDir=$(TargetDir)\msix OutMsix=$(TargetDir)\$(TargetName) @@ -44,6 +51,7 @@ $(OutMsix): $(ProjectDir)appxmanifest.xml @if not exist $(WorkDir)\Assets md $(WorkDir)\Assets >NUL @copy /Y $(ProjectDir)Assets\* $(WorkDir)\Assets\* >NUL @copy /Y $(TARGET_EXE_FILE) $(WorkDir) >NUL + @copy /Y $(TARGET_PROXYSTUB_FILE) $(WorkDir) >NUL @makeappx.exe pack $(MAKEAPPX_OPTS) /o /h SHA256 /d $(WorkDir) /p $(OutMsix) @signtool.exe sign /a $(SIGNTOOL_OPTS) /fd SHA256 /f $(SolutionDir)temp\MSTest.pfx $(OutMsix) diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj index bb65945377..7245c42b04 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj @@ -129,6 +129,9 @@ + + {bf3fced0-cadb-490a-93a7-4d90e1f45ab0} + {1307dd1b-bbe8-4cd0-b1a0-0db6d61eeaa0} @@ -136,4 +139,4 @@ - + \ No newline at end of file diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml index 8b27f15a26..b23f7b04bf 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml @@ -46,10 +46,16 @@ - + + + + + + + Date: Wed, 4 Aug 2021 10:13:31 -0700 Subject: [PATCH 02/50] Corrected mismatches against PowerNotifications change --- WindowsAppSDK.sln | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/WindowsAppSDK.sln b/WindowsAppSDK.sln index 9386c49a01..f0356c79da 100644 --- a/WindowsAppSDK.sln +++ b/WindowsAppSDK.sln @@ -169,7 +169,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PowerNotifications", "Power EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerNotifications", "dev\PowerNotifications\PowerNotifications.vcxitems", "{B75C1B22-553C-40E4-B38E-6AB4D01FDB9D}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerNotifications", "test\PowerNotifications\PowerNotifications.vcxproj", "{CBD95746-61CE-4F31-B6CC-C5ABF1766180}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerNotifications", "test\PowerNotifications\PowerNotifications.vcxproj", "{A9D7357B-FA9A-4548-B21E-F305DD63BC68}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PushNotificationsLongRunningTask.ProxyStub", "dev\PushNotifications\PushNotificationsLongRunningTask.ProxyStub\PushNotificationsLongRunningTask.ProxyStub.vcxproj", "{BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}" EndProject @@ -597,18 +597,18 @@ Global {C422B090-F501-4204-8068-1084B0799405}.Release|x64.Build.0 = Release|x64 {C422B090-F501-4204-8068-1084B0799405}.Release|x86.ActiveCfg = Release|Win32 {C422B090-F501-4204-8068-1084B0799405}.Release|x86.Build.0 = Release|Win32 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|ARM64.ActiveCfg = Debug|Win32 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|x64.ActiveCfg = Debug|x64 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|x64.Build.0 = Debug|x64 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|x86.ActiveCfg = Debug|Win32 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|x86.Build.0 = Debug|Win32 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|Any CPU.ActiveCfg = Release|Win32 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|ARM64.ActiveCfg = Release|Win32 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|x64.ActiveCfg = Release|x64 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|x64.Build.0 = Release|x64 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|x86.ActiveCfg = Release|Win32 - {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Release|x86.Build.0 = Release|Win32 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|ARM64.ActiveCfg = Debug|Win32 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|x64.ActiveCfg = Debug|x64 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|x64.Build.0 = Debug|x64 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|x86.ActiveCfg = Debug|Win32 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|x86.Build.0 = Debug|Win32 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|Any CPU.ActiveCfg = Release|Win32 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|ARM64.ActiveCfg = Release|Win32 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|x64.ActiveCfg = Release|x64 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|x64.Build.0 = Release|x64 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|x86.ActiveCfg = Release|Win32 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Release|x86.Build.0 = Release|Win32 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|Any CPU.ActiveCfg = Debug|Win32 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|ARM64.ActiveCfg = Debug|Win32 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x64.ActiveCfg = Debug|x64 @@ -672,7 +672,7 @@ Global {C422B090-F501-4204-8068-1084B0799405} = {A1B25DCF-6A54-414D-8E24-F4D24EE9299D} {E9117D76-63AC-4289-A628-AB39EF6E5D19} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A} {B75C1B22-553C-40E4-B38E-6AB4D01FDB9D} = {E9117D76-63AC-4289-A628-AB39EF6E5D19} - {CBD95746-61CE-4F31-B6CC-C5ABF1766180} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} + {A9D7357B-FA9A-4548-B21E-F305DD63BC68} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0} = {91D03B95-1B0C-4BEB-8441-30DA7D615538} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution From 66f90736df8d8d2298037862cd9b749595b62bb6 Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Wed, 4 Aug 2021 12:50:38 -0700 Subject: [PATCH 03/50] Correcting few nits --- .../PushNotificationsLongRunningTask.vcxproj | 6 ++++ .../externs.h | 4 ++- .../platform.cpp | 33 ++++++++++--------- .../platformfactory.cpp | 8 ++--- .../winmain.cpp | 11 +++---- .../PushNotificationsDemoApp/main.cpp | 1 + 6 files changed, 34 insertions(+), 29 deletions(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index 05fa7c91cd..a8b4b5dd35 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -123,6 +123,7 @@ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -139,6 +140,7 @@ true stdcpp17 Guard + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -154,6 +156,7 @@ _DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -170,6 +173,7 @@ true stdcpp17 Guard + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -185,6 +189,7 @@ _DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -201,6 +206,7 @@ true Guard stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h index f0522f70e8..9b8b819eb2 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h @@ -4,8 +4,10 @@ wil::unique_event& GetWinMainEvent(); -WpnLrpPlatformImpl* GetPlatform(); +WpnLrpPlatformImpl* RetrievePlatform(); HRESULT InitializePlatform(); +HRESULT ShutdownPlatform(); + void CleanPlatform(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index ba8fec9d5d..25c8aaac96 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -1,8 +1,6 @@ #include "pch.h" -// FIX REF!!! -#include "..\..\PushNotificationsLongRunningTask.ProxyStub\x64\Debug\PushNotificationsLRP_h.h" -//#include +#include #include "platform.h" @@ -10,7 +8,7 @@ wil::unique_event g_winmainEvent(wil::EventOptions::None); Microsoft::WRL::ComPtr g_platform; -WpnLrpPlatformImpl* GetPlatform() +WpnLrpPlatformImpl* RetrievePlatform() { if (!g_platform) { @@ -21,8 +19,6 @@ WpnLrpPlatformImpl* GetPlatform() return g_platform.Get(); } -// create void function for copying com ptr to iinspectable - void CleanPlatform() { g_platform = nullptr; @@ -38,6 +34,16 @@ HRESULT InitializePlatform() return S_OK; } +HRESULT ShutdownPlatform() +{ + if (g_platform) + { + g_platform->ShutdownPlatform(); + } + + return S_OK; +} + wil::unique_event& GetWinMainEvent() { return g_winmainEvent; @@ -86,34 +92,29 @@ bool WpnLrpPlatformImpl::IsPlatformInitialized() STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::RegisterActivator(/*[in]*/ PCWSTR /*processName*/) { THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - auto lock = m_lock.acquire(); - return S_OK; + return E_NOTIMPL; } STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::UnregisterActivator(/*[in]*/ PCWSTR /*processName*/) { THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - auto lock = m_lock.acquire(); - return S_OK; + return E_NOTIMPL; } STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::RegisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) { THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - auto lock = m_lock.acquire(); - return S_OK; + return E_NOTIMPL; } STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::UnregisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) { THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - auto lock = m_lock.acquire(); - return S_OK; + return E_NOTIMPL; } STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::RegisterFullTrustApplication(/*[in]*/ PCWSTR /*processName*/, /*[out]*/ GUID* /*appId*/) { THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - auto lock = m_lock.acquire(); - return S_OK; + return E_NOTIMPL; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp index 3015847a96..86b3504fb7 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp @@ -1,8 +1,6 @@ #include "pch.h" -// FIX REF!!! -#include "..\..\PushNotificationsLongRunningTask.ProxyStub\x64\Debug\PushNotificationsLRP_h.h" -//#include +#include #include "externs.h" #include "platform.h" @@ -18,9 +16,9 @@ IFACEMETHODIMP WpnLrpPlatformFactory::CreateInstance( _COM_Outptr_ void** obj) noexcept { *obj = nullptr; - *obj = GetPlatform(); + *obj = RetrievePlatform(); - if (!GetPlatform()->IsPlatformInitialized()) + if (!RetrievePlatform()->IsPlatformInitialized()) { THROW_IF_FAILED(InitializePlatform()); } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index 666b69cb48..cbd587a721 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -5,9 +5,7 @@ // include notifications constants file here -// FIX REF!!! -#include "..\..\PushNotificationsLongRunningTask.ProxyStub\x64\Debug\PushNotificationsLRP_h.h" -//#include +#include // Temporarily disable C4324 because WRL generates a false (well, irrelevant) warning // 'Microsoft::WRL::Details::StaticStorage::GenericReleaseNotifier,Microsoft::WRL::Details::StorageInstance::OutOfProcCallbackBuffer1,ModuleT>': structure was padded due to alignment specifier @@ -34,7 +32,7 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); - // Callback to be signaled by COM if it considers that the event should exit. + // Callback to be signaled by COM if it considers that the process should exit. auto& module = Module::Create(SignalEvent); unsigned long count = module.IncrementObjectCount(); @@ -50,14 +48,13 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* &clsid, platformFactory.GetAddressOf(), &cookie, - 1 - )); + 1)); InitializePlatform(); GetWinMainEvent().wait(); - GetPlatform()->ShutdownPlatform(); + ShutdownPlatform(); CleanPlatform(); count = module.DecrementObjectCount(); diff --git a/test/TestApps/PushNotificationsDemoApp/main.cpp b/test/TestApps/PushNotificationsDemoApp/main.cpp index 45a0cdcfaf..3ac0dba7b6 100644 --- a/test/TestApps/PushNotificationsDemoApp/main.cpp +++ b/test/TestApps/PushNotificationsDemoApp/main.cpp @@ -89,6 +89,7 @@ winrt::Microsoft::Windows::PushNotifications::PushNotificationChannel RequestCha int main() { + Sleep(20000); PushNotificationActivationInfo info( PushNotificationRegistrationOptions::PushTrigger | PushNotificationRegistrationOptions::ComActivator, winrt::guid("ccd2ae3f-764f-4ae3-be45-9804761b28b2")); // same clsid as app manifest From 065be70d4258d2fe347269aee116cb79fe9f2fd0 Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Wed, 4 Aug 2021 17:05:26 -0700 Subject: [PATCH 04/50] Added constants usage, std::call_once and improved abstraction --- .../PushNotifications-Constants.h | 5 +-- .../PushNotificationsLRP.idl | 6 ++-- .../externs.h | 4 ++- .../platform.cpp | 26 +++++--------- .../platform.h | 6 ++-- .../platformfactory.cpp | 9 +++-- .../winmain.cpp | 35 +++++++++++++++++++ .../appxmanifest.xml | 2 +- 8 files changed, 59 insertions(+), 34 deletions(-) diff --git a/dev/PushNotifications/PushNotifications-Constants.h b/dev/PushNotifications/PushNotifications-Constants.h index ac2ccbe47d..fe924ba682 100644 --- a/dev/PushNotifications/PushNotifications-Constants.h +++ b/dev/PushNotifications/PushNotifications-Constants.h @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. // Rely on _STRINGIZE(x) in yvals_core.h @@ -12,9 +12,6 @@ #define PUSHNOTIFICATIONS_IMPL_CLSID_UUID E739C755-0D09-48DF-A468-A5DF0B5422DC #define PUSHNOTIFICATIONS_IMPL_CLSID_STRING _STRINGIZE(PUSHNOTIFICATIONS_IMPL_CLSID_UUID) -#define PUSHNOTIFICATIONS_TASK_CLSID_UUID 8FCFB82B-DB93-4E1D-9008-76D768CEB9EA -#define PUSHNOTIFICATIONS_TASK_CLSID_STRING _STRINGIZE(PUSHNOTIFICATIONS_TASK_CLSID_UUID) - #if defined(WINDOWSAPPSDK_BUILD_PIPELINE) && (WINDOWSAPPSDK_BUILD_PIPELINE == 1) #include "PushNotifications-Override.h" #endif diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLRP.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLRP.idl index cbfef6a482..a318d0fc85 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLRP.idl +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLRP.idl @@ -4,7 +4,7 @@ import "oaidl.idl"; import "ocidl.idl"; -// #include "..\PushNotifications-Constants.h" +#include "../PushNotifications-Constants.h" [object] [uuid(60FC21B2-B396-4D49-94F0-7555869FB93C)] @@ -22,11 +22,11 @@ interface IWpnLrpPlatform : IUnknown HRESULT RegisterFullTrustApplication([in] LPCWSTR processName, [out] GUID* appId); }; -[uuid(60C6A2D9-04D9-42C3-B4E9-71158389D422)] // PR_DYNDEP_LIBID_UUID +[uuid(PUSHNOTIFICATIONS_LIBID_UUID)] [version(1.0)] library WpnLrpPlatformLib { - [uuid(330EC755-31F2-40A7-977D-B0ABB1E1E52E)] // PR_DYNDEP_DATASTORE_CLSID_UUID + [uuid(PUSHNOTIFICATIONS_IMPL_CLSID_UUID)] coclass WpnLrpPlatform { [default] interface IWpnLrpPlatform; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h index 9b8b819eb2..8d77fe1f77 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h @@ -4,10 +4,12 @@ wil::unique_event& GetWinMainEvent(); -WpnLrpPlatformImpl* RetrievePlatform(); +WpnLrpPlatformImpl* GetPlatform(); HRESULT InitializePlatform(); HRESULT ShutdownPlatform(); void CleanPlatform(); + +wil::unique_threadpool_timer SetTimerForEvent(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index 25c8aaac96..52c5b2f49a 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -8,14 +8,10 @@ wil::unique_event g_winmainEvent(wil::EventOptions::None); Microsoft::WRL::ComPtr g_platform; -WpnLrpPlatformImpl* RetrievePlatform() -{ - if (!g_platform) - { - g_platform = Microsoft::WRL::Make(); - } +std::once_flag m_isPlatformCreated; - g_platform->AddRef(); +WpnLrpPlatformImpl* GetPlatform() +{ return g_platform.Get(); } @@ -26,11 +22,12 @@ void CleanPlatform() HRESULT InitializePlatform() { - if (!g_platform) - { - g_platform = Microsoft::WRL::Make(); - } - g_platform->InitializePlatform(); + std::call_once(m_isPlatformCreated, + [&] { + g_platform = Microsoft::WRL::Make(); + g_platform->InitializePlatform(); + }); + return S_OK; } @@ -84,11 +81,6 @@ void WpnLrpPlatformImpl::ShutdownPlatform() m_shutdown = true; } -bool WpnLrpPlatformImpl::IsPlatformInitialized() -{ - return m_initialized; -} - STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::RegisterActivator(/*[in]*/ PCWSTR /*processName*/) { THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 92715b51fa..5025c369aa 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -1,6 +1,8 @@ #pragma once -struct __declspec(uuid("330EC755-31F2-40A7-977D-B0ABB1E1E52E")) WpnLrpPlatformImpl WrlFinal : +#include "../PushNotifications-Constants.h" + +struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) WpnLrpPlatformImpl WrlFinal : Microsoft::WRL::RuntimeClass, IWpnLrpPlatform, Microsoft::WRL::FtmBase> { WpnLrpPlatformImpl(); @@ -9,8 +11,6 @@ Microsoft::WRL::RuntimeClassIsPlatformInitialized()) - { - THROW_IF_FAILED(InitializePlatform()); - } + THROW_IF_FAILED(InitializePlatform()); + + *obj = GetPlatform(); + reinterpret_cast(obj)->AddRef(); return S_OK; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index cbd587a721..0aa480515a 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -25,11 +25,44 @@ void SignalEvent() GetWinMainEvent().SetEvent(); } +wil::unique_threadpool_timer SetTimerForEvent() +{ + wil::unique_threadpool_timer methodExecutionTimer; + + try + { + methodExecutionTimer.reset(CreateThreadpoolTimer( + [](PTP_CALLBACK_INSTANCE, _Inout_ PVOID, _Inout_ PTP_TIMER) + { + SignalEvent(); + }, + reinterpret_cast(GetCurrentThreadId()), + nullptr)); + + THROW_LAST_ERROR_IF_NULL(methodExecutionTimer); + + // Negative times in SetThreadpoolTimer are relative. Allow 30 seconds to fire. + FILETIME dueTime{}; + *reinterpret_cast(&dueTime) = -static_cast(30000 * 10000); + SetThreadpoolTimer(methodExecutionTimer.get(), &dueTime, 0, 0); + } + catch (...) + { + LOG_IF_FAILED(wil::ResultFromCaughtException()); + } + + return methodExecutionTimer; +} + int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { // Time to connect to a debugger. Eventually should be removed. Sleep(20000); + // Schedule event signaling after 30 seconds. This is in case we don't have any apps to track in the LRP. + // If we realize that we need to persist the LRP, timer will be canceled. + wil::unique_threadpool_timer timer = SetTimerForEvent(); + RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); // Callback to be signaled by COM if it considers that the process should exit. @@ -52,6 +85,8 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* InitializePlatform(); + //timer.reset(); + GetWinMainEvent().wait(); ShutdownPlatform(); diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml index b23f7b04bf..c78e972caa 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml @@ -46,7 +46,7 @@ - + From a2b978edaf6ea66a86f358a46cca236f56188212 Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Thu, 5 Aug 2021 10:50:25 -0700 Subject: [PATCH 05/50] Added StartupTask exe --- WindowsAppSDK.sln | 17 +- ...tificationsLongRunningTask.StartupTask.cpp | 20 ++ ...cationsLongRunningTask.StartupTask.vcxproj | 246 ++++++++++++++++++ ...ongRunningTask.StartupTask.vcxproj.filters | 22 ++ .../pch.cpp | 1 + .../pch.h | 20 ++ .../winmain.cpp | 15 ++ .../Makefile.mak | 5 + ...hNotificationsLongRunningTask.Msix.vcxproj | 3 + .../appxmanifest.xml | 2 +- 10 files changed, 349 insertions(+), 2 deletions(-) create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.cpp create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj.filters create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/pch.cpp create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/pch.h create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp diff --git a/WindowsAppSDK.sln b/WindowsAppSDK.sln index f0356c79da..cf8f1f00b9 100644 --- a/WindowsAppSDK.sln +++ b/WindowsAppSDK.sln @@ -173,6 +173,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerNotifications", "test\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PushNotificationsLongRunningTask.ProxyStub", "dev\PushNotifications\PushNotificationsLongRunningTask.ProxyStub\PushNotificationsLongRunningTask.ProxyStub.vcxproj", "{BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PushNotificationsLongRunningTask.StartupTask", "dev\PushNotifications\PushNotificationsLongRunningTask.StartupTask\PushNotificationsLongRunningTask.StartupTask.vcxproj", "{1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution test\inc\inc.vcxitems*{0a5fee93-48b7-40ec-bb9a-b27d11060da9}*SharedItemsImports = 4 @@ -597,7 +599,7 @@ Global {C422B090-F501-4204-8068-1084B0799405}.Release|x64.Build.0 = Release|x64 {C422B090-F501-4204-8068-1084B0799405}.Release|x86.ActiveCfg = Release|Win32 {C422B090-F501-4204-8068-1084B0799405}.Release|x86.Build.0 = Release|Win32 - {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|Any CPU.ActiveCfg = Debug|Win32 {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|ARM64.ActiveCfg = Debug|Win32 {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|x64.ActiveCfg = Debug|x64 {A9D7357B-FA9A-4548-B21E-F305DD63BC68}.Debug|x64.Build.0 = Debug|x64 @@ -621,6 +623,18 @@ Global {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x64.Build.0 = Release|x64 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x86.ActiveCfg = Release|Win32 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x86.Build.0 = Release|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|ARM64.ActiveCfg = Debug|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x64.ActiveCfg = Debug|x64 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x64.Build.0 = Debug|x64 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x86.ActiveCfg = Debug|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x86.Build.0 = Debug|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|Any CPU.ActiveCfg = Release|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|ARM64.ActiveCfg = Release|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x64.ActiveCfg = Release|x64 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x64.Build.0 = Release|x64 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x86.ActiveCfg = Release|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -674,6 +688,7 @@ Global {B75C1B22-553C-40E4-B38E-6AB4D01FDB9D} = {E9117D76-63AC-4289-A628-AB39EF6E5D19} {A9D7357B-FA9A-4548-B21E-F305DD63BC68} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0} = {91D03B95-1B0C-4BEB-8441-30DA7D615538} + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42} = {91D03B95-1B0C-4BEB-8441-30DA7D615538} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.cpp new file mode 100644 index 0000000000..3fec5d9110 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.cpp @@ -0,0 +1,20 @@ +// PushNotificationsLongRunningTask.StartupTask.cpp : This file contains the 'main' function. Program execution begins and ends there. +// + +#include + +int main() +{ + std::cout << "Hello World!\n"; +} + +// Run program: Ctrl + F5 or Debug > Start Without Debugging menu +// Debug program: F5 or Debug > Start Debugging menu + +// Tips for Getting Started: +// 1. Use the Solution Explorer window to add/manage files +// 2. Use the Team Explorer window to connect to source control +// 3. Use the Output window to see build output and other messages +// 4. Use the Error List window to view errors +// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project +// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj new file mode 100644 index 0000000000..320ef953d5 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj @@ -0,0 +1,246 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + 16.0 + Win32Proj + {1debbff6-ee6e-4944-9de2-35b7a686af42} + PushNotificationsLongRunningTask.StartupTask + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + true + + + false + + + + Level4 + true + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub + + + Windows + DebugFull + + + + + Level4 + true + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + stdcpp17 + Guard + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub + + + Windows + true + true + DebugFull + + + + + Level4 + true + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub + + + Windows + DebugFull + + + + + Level4 + true + true + true + NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + stdcpp17 + Guard + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub + + + Windows + true + true + DebugFull + + + + + Level4 + true + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub + + + Windows + DebugFull + + + + + Level4 + true + true + true + NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + Guard + stdcpp17 + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub + + + Windows + true + true + DebugFull + + + + + + + + + + + + + + + {bf3fced0-cadb-490a-93a7-4d90e1f45ab0} + + + + + + + + + + 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/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj.filters new file mode 100644 index 0000000000..2f2c04437d --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {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 + + + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/pch.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/pch.cpp new file mode 100644 index 0000000000..bcb5590be1 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/pch.h b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/pch.h new file mode 100644 index 0000000000..a41f481d20 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/pch.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +// Temporarily disable C4324 because WRL generates a false (well, irrelevant) warning +// 'Microsoft::WRL::Details::StaticStorage::GenericReleaseNotifier,Microsoft::WRL::Details::StorageInstance::OutOfProcCallbackBuffer1,ModuleT>': structure was padded due to alignment specifier +/*#pragma warning(push) +#pragma warning(disable:4324) +#include +#pragma warning(pop)*/ + +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp new file mode 100644 index 0000000000..2be065e7e1 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp @@ -0,0 +1,15 @@ +#include +#include "pch.h" + +#include "../PushNotifications-Constants.h" + +#include +#include + +int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) +{ + wil::com_ptr reunionEndpoint{ + wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + + return 0; +} diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak index 40bc48b95b..2d45033e54 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak @@ -27,6 +27,10 @@ TARGET_EXE=$(TARGET_BASENAME) TARGET_EXE_DIR=$(OutDir)$(TARGET_EXE) TARGET_EXE_FILE=$(TARGET_EXE_DIR)\$(TARGET_EXE).exe +TARGET_STARTUPEXE=$(TARGET_BASENAME).StartupTask +TARGET_STARTUPEXE_DIR=$(OutDir)$(TARGET_STARTUPEXE) +TARGET_STARTUPEXE_FILE=$(TARGET_STARTUPEXE_DIR)\$(TARGET_STARTUPEXE).exe + TARGET_PROXYSTUB=PushNotificationsLongRunningTask.ProxyStub TARGET_PROXYSTUB_DIR=$(OutDir)$(TARGET_PROXYSTUB) TARGET_PROXYSTUB_FILE=$(TARGET_PROXYSTUB_DIR)\$(TARGET_PROXYSTUB).dll @@ -51,6 +55,7 @@ $(OutMsix): $(ProjectDir)appxmanifest.xml @if not exist $(WorkDir)\Assets md $(WorkDir)\Assets >NUL @copy /Y $(ProjectDir)Assets\* $(WorkDir)\Assets\* >NUL @copy /Y $(TARGET_EXE_FILE) $(WorkDir) >NUL + @copy /Y $(TARGET_STARTUPEXE_FILE) $(WorkDir) >NUL @copy /Y $(TARGET_PROXYSTUB_FILE) $(WorkDir) >NUL @makeappx.exe pack $(MAKEAPPX_OPTS) /o /h SHA256 /d $(WorkDir) /p $(OutMsix) @signtool.exe sign /a $(SIGNTOOL_OPTS) /fd SHA256 /f $(SolutionDir)temp\MSTest.pfx $(OutMsix) diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj index 7245c42b04..5da79f1a47 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj @@ -132,6 +132,9 @@ {bf3fced0-cadb-490a-93a7-4d90e1f45ab0} + + {1debbff6-ee6e-4944-9de2-35b7a686af42} + {1307dd1b-bbe8-4cd0-b1a0-0db6d61eeaa0} diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml index c78e972caa..ead9cdd55a 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml @@ -58,7 +58,7 @@ Date: Thu, 5 Aug 2021 16:41:56 -0700 Subject: [PATCH 06/50] Fixed some bugs --- ...ongRunningTask.StartupTask.vcxproj.filters | 13 +++++++++- .../winmain.cpp | 10 ++++++-- .../externs.h | 5 +++- .../platform.cpp | 22 ++++++++++++++-- .../platform.h | 2 ++ .../platformfactory.cpp | 3 +-- .../platformfactory.h | 2 +- .../winmain.cpp | 25 +++++++++---------- 8 files changed, 60 insertions(+), 22 deletions(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj.filters index 2f2c04437d..76d9cae5d8 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj.filters @@ -15,8 +15,19 @@ - + Source Files + + Source Files + + + + + + + + Header Files + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp index 2be065e7e1..fa62ae7f86 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp @@ -8,8 +8,14 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { - wil::com_ptr reunionEndpoint{ - wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); + + { + wil::com_ptr reunionEndpoint{ + wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + } + + ::CoUninitialize(); return 0; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h index 8d77fe1f77..a7fd1e3e47 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h @@ -12,4 +12,7 @@ HRESULT ShutdownPlatform(); void CleanPlatform(); -wil::unique_threadpool_timer SetTimerForEvent(); +bool IsPlatformShutdown(); + +void SetTimerForEvent(); +void CancelTimerForEvent(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index 52c5b2f49a..7f81ae07ce 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -8,10 +8,13 @@ wil::unique_event g_winmainEvent(wil::EventOptions::None); Microsoft::WRL::ComPtr g_platform; -std::once_flag m_isPlatformCreated; +std::once_flag m_isPlatformInitialized; WpnLrpPlatformImpl* GetPlatform() { + // We have to call InitializePlatform() before retrieving the platform on the factory. + // Throw if Platform is already reset or was shut down. + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, !g_platform || g_platform->IsPlatformShutdown()); return g_platform.Get(); } @@ -22,10 +25,14 @@ void CleanPlatform() HRESULT InitializePlatform() { - std::call_once(m_isPlatformCreated, + std::call_once(m_isPlatformInitialized, [&] { g_platform = Microsoft::WRL::Make(); g_platform->InitializePlatform(); + + // Prevent scenario where if the first client goes out of scope, + // then triggers WpnLrpPlatformImpl dtor. + g_platform->AddRef(); }); return S_OK; @@ -41,6 +48,11 @@ HRESULT ShutdownPlatform() return S_OK; } +bool IsPlatformShutdown() +{ + return g_platform->IsPlatformShutdown(); +} + wil::unique_event& GetWinMainEvent() { return g_winmainEvent; @@ -81,6 +93,12 @@ void WpnLrpPlatformImpl::ShutdownPlatform() m_shutdown = true; } +bool WpnLrpPlatformImpl::IsPlatformShutdown() +{ + auto lock = m_lock.acquire(); + return m_shutdown; +} + STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::RegisterActivator(/*[in]*/ PCWSTR /*processName*/) { THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 5025c369aa..8d0d2804de 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -11,6 +11,8 @@ Microsoft::WRL::RuntimeClass(obj)->AddRef(); return S_OK; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h index f3ddc3b498..961507cc1c 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h @@ -5,5 +5,5 @@ struct WpnLrpPlatformFactory WrlFinal : public Microsoft::WRL::ClassFactory<> IFACEMETHODIMP CreateInstance( _In_opt_ IUnknown* outer, _In_ REFIID riid, - _COM_Outptr_ void** ppvObject) noexcept override; + _COM_Outptr_ void** ppvObject) override; }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index 0aa480515a..89751e88dd 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -25,13 +25,13 @@ void SignalEvent() GetWinMainEvent().SetEvent(); } -wil::unique_threadpool_timer SetTimerForEvent() -{ - wil::unique_threadpool_timer methodExecutionTimer; +wil::unique_threadpool_timer g_timer; +void SetTimerForEvent() +{ try { - methodExecutionTimer.reset(CreateThreadpoolTimer( + g_timer.reset(CreateThreadpoolTimer( [](PTP_CALLBACK_INSTANCE, _Inout_ PVOID, _Inout_ PTP_TIMER) { SignalEvent(); @@ -39,29 +39,30 @@ wil::unique_threadpool_timer SetTimerForEvent() reinterpret_cast(GetCurrentThreadId()), nullptr)); - THROW_LAST_ERROR_IF_NULL(methodExecutionTimer); + THROW_LAST_ERROR_IF_NULL(g_timer); // Negative times in SetThreadpoolTimer are relative. Allow 30 seconds to fire. FILETIME dueTime{}; *reinterpret_cast(&dueTime) = -static_cast(30000 * 10000); - SetThreadpoolTimer(methodExecutionTimer.get(), &dueTime, 0, 0); + SetThreadpoolTimer(g_timer.get(), &dueTime, 0, 0); } catch (...) { LOG_IF_FAILED(wil::ResultFromCaughtException()); } +} - return methodExecutionTimer; +// This function has to be called after we realized that we want to persist the LRP. +void CancelTimerForEvent() +{ + g_timer.reset(); } int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { - // Time to connect to a debugger. Eventually should be removed. - Sleep(20000); - // Schedule event signaling after 30 seconds. This is in case we don't have any apps to track in the LRP. // If we realize that we need to persist the LRP, timer will be canceled. - wil::unique_threadpool_timer timer = SetTimerForEvent(); + SetTimerForEvent(); RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); @@ -85,8 +86,6 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* InitializePlatform(); - //timer.reset(); - GetWinMainEvent().wait(); ShutdownPlatform(); From 31b33c2c9277891ffc4b53eaa68cf501d06dead2 Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Fri, 6 Aug 2021 17:15:39 -0700 Subject: [PATCH 07/50] Mostly renaming and cleaning --- ...dl => NotificationsLongRunningProcess.idl} | 8 ++-- ...ficationsLongRunningTask.ProxyStub.vcxproj | 10 ++--- ...sLongRunningTask.ProxyStub.vcxproj.filters | 6 +-- ...tificationsLongRunningTask.StartupTask.cpp | 20 --------- .../winmain.cpp | 13 +++--- .../externs.h | 2 +- .../PushNotificationsLongRunningTask/pch.h | 5 +-- .../platform.cpp | 42 +++++++++---------- .../platform.h | 11 ++--- .../platformfactory.cpp | 2 +- .../winmain.cpp | 10 +++-- 11 files changed, 55 insertions(+), 74 deletions(-) rename dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/{PushNotificationsLRP.idl => NotificationsLongRunningProcess.idl} (78%) delete mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.cpp diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLRP.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl similarity index 78% rename from dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLRP.idl rename to dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl index a318d0fc85..6e190b7baf 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLRP.idl +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl @@ -9,7 +9,7 @@ import "ocidl.idl"; [object] [uuid(60FC21B2-B396-4D49-94F0-7555869FB93C)] [pointer_default(unique)] -interface IWpnLrpPlatform : IUnknown +interface INotificationsLongRunningPlatform : IUnknown { HRESULT RegisterActivator([in] LPCWSTR processName); @@ -24,11 +24,11 @@ interface IWpnLrpPlatform : IUnknown [uuid(PUSHNOTIFICATIONS_LIBID_UUID)] [version(1.0)] -library WpnLrpPlatformLib +library NotificationsLongRunningPlatformLibrary { [uuid(PUSHNOTIFICATIONS_IMPL_CLSID_UUID)] - coclass WpnLrpPlatform + coclass NotificationsLongRunningPlatform { - [default] interface IWpnLrpPlatform; + [default] interface INotificationsLongRunningPlatform; }; }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj index 86917f4648..2535dae86e 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj @@ -406,7 +406,7 @@ NotUsing NotUsing - + NotUsing NotUsing NotUsing @@ -416,7 +416,7 @@ NotUsing NotUsing - + NotUsing NotUsing NotUsing @@ -438,7 +438,7 @@ - + @@ -447,8 +447,8 @@ - - + + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters index 7a312fc125..4fb8c588f6 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters @@ -15,7 +15,7 @@ - + Source Files @@ -23,10 +23,10 @@ Source Files - + Source Files - + Source Files diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.cpp deleted file mode 100644 index 3fec5d9110..0000000000 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// PushNotificationsLongRunningTask.StartupTask.cpp : This file contains the 'main' function. Program execution begins and ends there. -// - -#include - -int main() -{ - std::cout << "Hello World!\n"; -} - -// Run program: Ctrl + F5 or Debug > Start Without Debugging menu -// Debug program: F5 or Debug > Start Debugging menu - -// Tips for Getting Started: -// 1. Use the Solution Explorer window to add/manage files -// 2. Use the Team Explorer window to connect to source control -// 3. Use the Output window to see build output and other messages -// 4. Use the Error List window to view errors -// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project -// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp index fa62ae7f86..8c455313b1 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp @@ -3,19 +3,20 @@ #include "../PushNotifications-Constants.h" -#include +#include #include int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { + Sleep(20000); + RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); - { - wil::com_ptr reunionEndpoint{ - wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; - } + auto scopeExit = wil::scope_exit( + [&]() { CoUninitialize(); }); - ::CoUninitialize(); + wil::com_ptr longRunningProcessPlatform + { wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; return 0; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h index a7fd1e3e47..b90fedbba6 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h @@ -4,7 +4,7 @@ wil::unique_event& GetWinMainEvent(); -WpnLrpPlatformImpl* GetPlatform(); +NotificationsLongRunningPlatformImpl* GetPlatform(); HRESULT InitializePlatform(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h index 8e60e4ea5c..8586e30347 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h @@ -6,9 +6,6 @@ #include #include -#include -#include - // Temporarily disable C4324 because WRL generates a false (well, irrelevant) warning // 'Microsoft::WRL::Details::StaticStorage::GenericReleaseNotifier,Microsoft::WRL::Details::StorageInstance::OutOfProcCallbackBuffer1,ModuleT>': structure was padded due to alignment specifier #pragma warning(push) @@ -16,6 +13,8 @@ #include #pragma warning(pop) +#include + #include #include #include diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index 7f81ae07ce..278a6749dd 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -1,16 +1,16 @@ #include "pch.h" -#include +#include #include "platform.h" wil::unique_event g_winmainEvent(wil::EventOptions::None); -Microsoft::WRL::ComPtr g_platform; +Microsoft::WRL::ComPtr g_platform; std::once_flag m_isPlatformInitialized; -WpnLrpPlatformImpl* GetPlatform() +NotificationsLongRunningPlatformImpl* GetPlatform() { // We have to call InitializePlatform() before retrieving the platform on the factory. // Throw if Platform is already reset or was shut down. @@ -27,7 +27,7 @@ HRESULT InitializePlatform() { std::call_once(m_isPlatformInitialized, [&] { - g_platform = Microsoft::WRL::Make(); + g_platform = Microsoft::WRL::Make(); g_platform->InitializePlatform(); // Prevent scenario where if the first client goes out of scope, @@ -58,17 +58,11 @@ wil::unique_event& GetWinMainEvent() return g_winmainEvent; } -WpnLrpPlatformImpl::WpnLrpPlatformImpl() -{ - m_lock.create(); -} - -void WpnLrpPlatformImpl::InitializePlatform() +void NotificationsLongRunningPlatformImpl::InitializePlatform() { + auto lock = m_lock.lock_exclusive(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - auto lock = m_lock.acquire(); - if (m_initialized) { return; @@ -79,52 +73,56 @@ void WpnLrpPlatformImpl::InitializePlatform() m_initialized = true; } -void WpnLrpPlatformImpl::ShutdownPlatform() +void NotificationsLongRunningPlatformImpl::ShutdownPlatform() { + auto lock = m_lock.lock_exclusive(); if (m_shutdown) { return; } - auto lock = m_lock.acquire(); - /* Shut down your components */ m_shutdown = true; } -bool WpnLrpPlatformImpl::IsPlatformShutdown() +bool NotificationsLongRunningPlatformImpl::IsPlatformShutdown() { - auto lock = m_lock.acquire(); + auto lock = m_lock.lock_shared(); return m_shutdown; } -STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::RegisterActivator(/*[in]*/ PCWSTR /*processName*/) +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterActivator(/*[in]*/ PCWSTR /*processName*/) { + auto lock = m_lock.lock_shared(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); return E_NOTIMPL; } -STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::UnregisterActivator(/*[in]*/ PCWSTR /*processName*/) +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterActivator(/*[in]*/ PCWSTR /*processName*/) { + auto lock = m_lock.lock_shared(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); return E_NOTIMPL; } -STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::RegisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) { + auto lock = m_lock.lock_shared(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); return E_NOTIMPL; } -STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::UnregisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) { + auto lock = m_lock.lock_shared(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); return E_NOTIMPL; } -STDMETHODIMP_(HRESULT __stdcall) WpnLrpPlatformImpl::RegisterFullTrustApplication(/*[in]*/ PCWSTR /*processName*/, /*[out]*/ GUID* /*appId*/) +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterFullTrustApplication(/*[in]*/ PCWSTR /*processName*/, /*[out]*/ GUID* /*appId*/) { + auto lock = m_lock.lock_shared(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); return E_NOTIMPL; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 8d0d2804de..72d4e8727b 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -2,11 +2,12 @@ #include "../PushNotifications-Constants.h" -struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) WpnLrpPlatformImpl WrlFinal : -Microsoft::WRL::RuntimeClass, IWpnLrpPlatform, Microsoft::WRL::FtmBase> +struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRunningPlatformImpl WrlFinal : +Microsoft::WRL::RuntimeClass< + Microsoft::WRL::RuntimeClassFlags, + INotificationsLongRunningPlatform, + Microsoft::WRL::FtmBase> { - WpnLrpPlatformImpl(); - void InitializePlatform(); void ShutdownPlatform(); @@ -29,7 +30,7 @@ Microsoft::WRL::RuntimeClass +#include #include "externs.h" #include "platform.h" diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index 89751e88dd..33b22ab73c 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -5,7 +5,7 @@ // include notifications constants file here -#include +#include // Temporarily disable C4324 because WRL generates a false (well, irrelevant) warning // 'Microsoft::WRL::Details::StaticStorage::GenericReleaseNotifier,Microsoft::WRL::Details::StorageInstance::OutOfProcCallbackBuffer1,ModuleT>': structure was padded due to alignment specifier @@ -60,9 +60,11 @@ void CancelTimerForEvent() int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { + Sleep(20000); + // Schedule event signaling after 30 seconds. This is in case we don't have any apps to track in the LRP. // If we realize that we need to persist the LRP, timer will be canceled. - SetTimerForEvent(); + //SetTimerForEvent(); RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); @@ -75,7 +77,7 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* ComPtr platformFactory; THROW_IF_FAILED(MakeAndInitialize(&platformFactory)); - CLSID clsid = __uuidof(WpnLrpPlatform); + CLSID clsid = __uuidof(NotificationsLongRunningPlatformImpl); THROW_IF_FAILED(module.RegisterCOMObject( nullptr, @@ -84,7 +86,7 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* &cookie, 1)); - InitializePlatform(); + //InitializePlatform(); GetWinMainEvent().wait(); From 18563254d65393420912ae9aba29fa8b59eea67b Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Tue, 10 Aug 2021 10:27:14 -0700 Subject: [PATCH 08/50] Removed timer externals and let winmain to own Platform lifetime --- .../PushNotificationManager.cpp | 1 - .../NotificationsLongRunningProcess.idl | 2 +- .../externs.h | 5 -- .../platform.cpp | 10 +-- .../platform.h | 2 +- .../platformfactory.cpp | 73 ++++++++++++++++++- .../platformfactory.h | 17 +++++ .../winmain.cpp | 73 +++++-------------- 8 files changed, 112 insertions(+), 71 deletions(-) diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index aeaf075359..6c42a05708 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -21,7 +21,6 @@ using namespace std::literals; constexpr std::wstring_view backgroundTaskName = L"PushBackgroundTaskName"sv; -constexpr winrt::guid PushNotificationsTask_guid{ PUSHNOTIFICATIONS_TASK_CLSID_STRING }; static wil::unique_event g_waitHandleForArgs; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl index 6e190b7baf..6f1fd648a9 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl @@ -19,7 +19,7 @@ interface INotificationsLongRunningPlatform : IUnknown HRESULT UnregisterForegroundActivator([in] LPCWSTR processName); - HRESULT RegisterFullTrustApplication([in] LPCWSTR processName, [out] GUID* appId); + HRESULT RegisterFullTrustApplication([in] LPCWSTR processName, [in] GUID remoteId, [out] GUID* appId); }; [uuid(PUSHNOTIFICATIONS_LIBID_UUID)] diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h index b90fedbba6..ae8b4539e9 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h @@ -2,8 +2,6 @@ #include "pch.h" #include "platform.h" -wil::unique_event& GetWinMainEvent(); - NotificationsLongRunningPlatformImpl* GetPlatform(); HRESULT InitializePlatform(); @@ -13,6 +11,3 @@ HRESULT ShutdownPlatform(); void CleanPlatform(); bool IsPlatformShutdown(); - -void SetTimerForEvent(); -void CancelTimerForEvent(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index 278a6749dd..f969ce5959 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -3,8 +3,7 @@ #include #include "platform.h" - -wil::unique_event g_winmainEvent(wil::EventOptions::None); +//#include "platformfactory.h" Microsoft::WRL::ComPtr g_platform; @@ -53,11 +52,6 @@ bool IsPlatformShutdown() return g_platform->IsPlatformShutdown(); } -wil::unique_event& GetWinMainEvent() -{ - return g_winmainEvent; -} - void NotificationsLongRunningPlatformImpl::InitializePlatform() { auto lock = m_lock.lock_exclusive(); @@ -120,7 +114,7 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::Unregiste return E_NOTIMPL; } -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterFullTrustApplication(/*[in]*/ PCWSTR /*processName*/, /*[out]*/ GUID* /*appId*/) +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterFullTrustApplication(/*[in]*/ PCWSTR /*processName*/, /*[in]*/ GUID /*remoteId*/, /*[out]*/ GUID* /*appId*/) { auto lock = m_lock.lock_shared(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 72d4e8727b..aeb215e6cd 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -24,7 +24,7 @@ Microsoft::WRL::RuntimeClass< STDMETHOD(UnregisterForegroundActivator)(/*[in]*/ PCWSTR processName); - STDMETHOD(RegisterFullTrustApplication)(/*[in]*/ PCWSTR processName, /*[out]*/ GUID* appId); + STDMETHOD(RegisterFullTrustApplication)(/*[in]*/ PCWSTR processName, /*[in]*/ GUID remoteId, /*[out]*/ GUID* appId); /* Add your functions to retrieve the platform components */ diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp index d1f78f0430..f514564c94 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp @@ -10,6 +10,15 @@ using namespace Microsoft::WRL; +wil::unique_event g_event; +wil::unique_threadpool_timer g_timer; + +HRESULT WpnLrpPlatformFactory::MakeAndInitialize() +{ + g_event = wil::unique_event(wil::EventOptions::None); + return S_OK; +} + IFACEMETHODIMP WpnLrpPlatformFactory::CreateInstance( _In_opt_ IUnknown* /*outer*/, _In_ REFIID /*riid*/, @@ -17,9 +26,69 @@ IFACEMETHODIMP WpnLrpPlatformFactory::CreateInstance( { *obj = nullptr; - THROW_IF_FAILED(InitializePlatform()); + if (m_isPlatformInitialized) + { + *obj = m_platform.Get(); + } + else + { + std::call_once(m_platformInitializedFlag, + [&] { + ComPtr platform; + + platform = Microsoft::WRL::Make(); + platform->InitializePlatform(); + + // Prevent scenario where if the first client goes out of scope, + // then triggers WpnLrpPlatformImpl dtor. // NEED TO CHECK THIS + platform->AddRef(); - *obj = GetPlatform(); + AsWeak(platform.Get(), &m_platform); + *obj = platform.Detach(); + + m_isPlatformInitialized = true; + }); + } return S_OK; } + +void WpnLrpPlatformFactory::SignalEvent() +{ + g_event.SetEvent(); +} + +void WpnLrpPlatformFactory::WaitForEvent() +{ + g_event.wait(); +} + +void WpnLrpPlatformFactory::SetupTimer() +{ + try + { + g_timer.reset(CreateThreadpoolTimer( + [](PTP_CALLBACK_INSTANCE, _Inout_ PVOID, _Inout_ PTP_TIMER) + { + SignalEvent(); + }, + reinterpret_cast(GetCurrentThreadId()), + nullptr)); + + THROW_LAST_ERROR_IF_NULL(g_timer); + + // Negative times in SetThreadpoolTimer are relative. Allow 30 seconds to fire. + FILETIME dueTime{}; + *reinterpret_cast(&dueTime) = -static_cast(30000 * 10000); + SetThreadpoolTimer(g_timer.get(), &dueTime, 0, 0); + } + catch (...) + { + LOG_IF_FAILED(wil::ResultFromCaughtException()); + } +} + +void WpnLrpPlatformFactory::CancelTimer() +{ + g_timer.reset(); +} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h index 961507cc1c..b8c99a8111 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h @@ -2,8 +2,25 @@ struct WpnLrpPlatformFactory WrlFinal : public Microsoft::WRL::ClassFactory<> { + HRESULT MakeAndInitialize(); + IFACEMETHODIMP CreateInstance( _In_opt_ IUnknown* outer, _In_ REFIID riid, _COM_Outptr_ void** ppvObject) override; + + static void SignalEvent(); + + static void WaitForEvent(); + + static void SetupTimer(); + + static void CancelTimer(); + +private: + + // WinMain is the owner of the platform reference + Microsoft::WRL::WeakRef m_platform; + std::once_flag m_platformInitializedFlag; + bool m_isPlatformInitialized = false; }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index 33b22ab73c..fc510187a0 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -20,78 +20,45 @@ using namespace Microsoft::WRL; -void SignalEvent() +int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { - GetWinMainEvent().SetEvent(); -} - -wil::unique_threadpool_timer g_timer; + Sleep(20000); -void SetTimerForEvent() -{ - try - { - g_timer.reset(CreateThreadpoolTimer( - [](PTP_CALLBACK_INSTANCE, _Inout_ PVOID, _Inout_ PTP_TIMER) - { - SignalEvent(); - }, - reinterpret_cast(GetCurrentThreadId()), - nullptr)); - - THROW_LAST_ERROR_IF_NULL(g_timer); - - // Negative times in SetThreadpoolTimer are relative. Allow 30 seconds to fire. - FILETIME dueTime{}; - *reinterpret_cast(&dueTime) = -static_cast(30000 * 10000); - SetThreadpoolTimer(g_timer.get(), &dueTime, 0, 0); - } - catch (...) - { - LOG_IF_FAILED(wil::ResultFromCaughtException()); - } -} + THROW_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); -// This function has to be called after we realized that we want to persist the LRP. -void CancelTimerForEvent() -{ - g_timer.reset(); -} + ComPtr platformFactory; + THROW_IF_FAILED(MakeAndInitialize(&platformFactory)); -int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) -{ - Sleep(20000); + ComPtr platformFactoryAsClassFactory; + THROW_IF_FAILED(platformFactory.As(&platformFactoryAsClassFactory)); // Schedule event signaling after 30 seconds. This is in case we don't have any apps to track in the LRP. // If we realize that we need to persist the LRP, timer will be canceled. - //SetTimerForEvent(); - - RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); + platformFactory->SetupTimer(); // Callback to be signaled by COM if it considers that the process should exit. - auto& module = Module::Create(SignalEvent); + auto& module = Module::Create(WpnLrpPlatformFactory::SignalEvent); - unsigned long count = module.IncrementObjectCount(); - - DWORD cookie = 0; - ComPtr platformFactory; - THROW_IF_FAILED(MakeAndInitialize(&platformFactory)); + unsigned long count = module.IncrementObjectCount(); // May remove CLSID clsid = __uuidof(NotificationsLongRunningPlatformImpl); - + DWORD cookie = 0; THROW_IF_FAILED(module.RegisterCOMObject( nullptr, &clsid, - platformFactory.GetAddressOf(), + platformFactoryAsClassFactory.GetAddressOf(), &cookie, - 1)); + 1)); + + ComPtr platform; + THROW_IF_FAILED(platformFactory->CreateInstance(nullptr, __uuidof(INotificationsLongRunningPlatform), &platform)); - //InitializePlatform(); + platform->InitializePlatform(); - GetWinMainEvent().wait(); + platformFactory->WaitForEvent(); - ShutdownPlatform(); - CleanPlatform(); + platform->ShutdownPlatform(); + platform = nullptr; // May check again CoUninitialize behavior count = module.DecrementObjectCount(); From 8ed23050f2a61be3fa1c449675b4ccc21a02e845 Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Tue, 10 Aug 2021 12:27:09 -0700 Subject: [PATCH 09/50] Correction -> factory should own the platform --- .../PushNotificationsLongRunningTask.vcxproj | 1 - ...tificationsLongRunningTask.vcxproj.filters | 3 - .../externs.h | 13 ---- .../platform.cpp | 59 +------------------ .../platform.h | 6 +- .../platformfactory.cpp | 31 +++------- .../platformfactory.h | 2 +- .../winmain.cpp | 6 +- 8 files changed, 17 insertions(+), 104 deletions(-) delete mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/externs.h diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index a8b4b5dd35..1e3945e1a4 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -222,7 +222,6 @@ - diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters index e64fc5dd65..4804663994 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters @@ -21,9 +21,6 @@ Header Files - - Header Files - Header Files diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h b/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h deleted file mode 100644 index ae8b4539e9..0000000000 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/externs.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "pch.h" -#include "platform.h" - -NotificationsLongRunningPlatformImpl* GetPlatform(); - -HRESULT InitializePlatform(); - -HRESULT ShutdownPlatform(); - -void CleanPlatform(); - -bool IsPlatformShutdown(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index f969ce5959..9e2ab83882 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -3,56 +3,9 @@ #include #include "platform.h" -//#include "platformfactory.h" +#include "platformfactory.h" -Microsoft::WRL::ComPtr g_platform; - -std::once_flag m_isPlatformInitialized; - -NotificationsLongRunningPlatformImpl* GetPlatform() -{ - // We have to call InitializePlatform() before retrieving the platform on the factory. - // Throw if Platform is already reset or was shut down. - THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, !g_platform || g_platform->IsPlatformShutdown()); - return g_platform.Get(); -} - -void CleanPlatform() -{ - g_platform = nullptr; -} - -HRESULT InitializePlatform() -{ - std::call_once(m_isPlatformInitialized, - [&] { - g_platform = Microsoft::WRL::Make(); - g_platform->InitializePlatform(); - - // Prevent scenario where if the first client goes out of scope, - // then triggers WpnLrpPlatformImpl dtor. - g_platform->AddRef(); - }); - - return S_OK; -} - -HRESULT ShutdownPlatform() -{ - if (g_platform) - { - g_platform->ShutdownPlatform(); - } - - return S_OK; -} - -bool IsPlatformShutdown() -{ - return g_platform->IsPlatformShutdown(); -} - -void NotificationsLongRunningPlatformImpl::InitializePlatform() +void NotificationsLongRunningPlatformImpl::Initialize() { auto lock = m_lock.lock_exclusive(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); @@ -67,7 +20,7 @@ void NotificationsLongRunningPlatformImpl::InitializePlatform() m_initialized = true; } -void NotificationsLongRunningPlatformImpl::ShutdownPlatform() +void NotificationsLongRunningPlatformImpl::Shutdown() { auto lock = m_lock.lock_exclusive(); if (m_shutdown) @@ -80,12 +33,6 @@ void NotificationsLongRunningPlatformImpl::ShutdownPlatform() m_shutdown = true; } -bool NotificationsLongRunningPlatformImpl::IsPlatformShutdown() -{ - auto lock = m_lock.lock_shared(); - return m_shutdown; -} - STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterActivator(/*[in]*/ PCWSTR /*processName*/) { auto lock = m_lock.lock_shared(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index aeb215e6cd..909bb6437d 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -8,11 +8,9 @@ Microsoft::WRL::RuntimeClass< INotificationsLongRunningPlatform, Microsoft::WRL::FtmBase> { - void InitializePlatform(); + void Initialize(); - void ShutdownPlatform(); - - bool IsPlatformShutdown(); + void Shutdown(); /* IWpnLrpPlatform functions */ diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp index f514564c94..60dedbbeeb 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp @@ -2,7 +2,6 @@ #include -#include "externs.h" #include "platform.h" #include #include @@ -26,29 +25,17 @@ IFACEMETHODIMP WpnLrpPlatformFactory::CreateInstance( { *obj = nullptr; - if (m_isPlatformInitialized) - { - *obj = m_platform.Get(); - } - else - { - std::call_once(m_platformInitializedFlag, - [&] { - ComPtr platform; + std::call_once(m_platformInitializedFlag, + [&] { + m_platform = Microsoft::WRL::Make(); + m_platform->Initialize(); - platform = Microsoft::WRL::Make(); - platform->InitializePlatform(); + // Prevent scenario where if the first client goes out of scope, + // then triggers WpnLrpPlatformImpl dtor. // NEED TO CHECK THIS + m_platform->AddRef(); + }); - // Prevent scenario where if the first client goes out of scope, - // then triggers WpnLrpPlatformImpl dtor. // NEED TO CHECK THIS - platform->AddRef(); - - AsWeak(platform.Get(), &m_platform); - *obj = platform.Detach(); - - m_isPlatformInitialized = true; - }); - } + *obj = m_platform.Get(); return S_OK; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h index b8c99a8111..3b9d9f34e9 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h @@ -20,7 +20,7 @@ struct WpnLrpPlatformFactory WrlFinal : public Microsoft::WRL::ClassFactory<> private: // WinMain is the owner of the platform reference - Microsoft::WRL::WeakRef m_platform; + Microsoft::WRL::ComPtr m_platform; std::once_flag m_platformInitializedFlag; bool m_isPlatformInitialized = false; }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index fc510187a0..6915eb0dbd 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -16,7 +16,6 @@ #include "platform.h" #include "platformfactory.h" -#include "externs.h" using namespace Microsoft::WRL; @@ -51,13 +50,12 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* 1)); ComPtr platform; + // Get an initialized instance of the LRP platform THROW_IF_FAILED(platformFactory->CreateInstance(nullptr, __uuidof(INotificationsLongRunningPlatform), &platform)); - platform->InitializePlatform(); - platformFactory->WaitForEvent(); - platform->ShutdownPlatform(); + platform->Shutdown(); platform = nullptr; // May check again CoUninitialize behavior count = module.DecrementObjectCount(); From 5f6d8a6abf9262558a627cd1e6551ff2466aef4d Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Wed, 11 Aug 2021 18:04:44 -0700 Subject: [PATCH 10/50] Addressed lifetime crashes and other issues --- .../winmain.cpp | 11 +++++++---- .../PushNotificationsLongRunningTask/platform.cpp | 10 +++++----- .../platformfactory.cpp | 13 +++++-------- .../platformfactory.h | 2 -- .../PushNotificationsLongRunningTask/winmain.cpp | 13 +++---------- 5 files changed, 20 insertions(+), 29 deletions(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp index 8c455313b1..1e2a14a536 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp @@ -12,11 +12,14 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); - auto scopeExit = wil::scope_exit( - [&]() { CoUninitialize(); }); + try + { + wil::com_ptr longRunningProcessPlatform + { wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + } + CATCH_LOG() - wil::com_ptr longRunningProcessPlatform - { wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + CoUninitialize(); return 0; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index 9e2ab83882..569661a547 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -36,34 +36,34 @@ void NotificationsLongRunningPlatformImpl::Shutdown() STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterActivator(/*[in]*/ PCWSTR /*processName*/) { auto lock = m_lock.lock_shared(); - THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); return E_NOTIMPL; } STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterActivator(/*[in]*/ PCWSTR /*processName*/) { auto lock = m_lock.lock_shared(); - THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); return E_NOTIMPL; } STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) { auto lock = m_lock.lock_shared(); - THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); return E_NOTIMPL; } STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) { auto lock = m_lock.lock_shared(); - THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); return E_NOTIMPL; } STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterFullTrustApplication(/*[in]*/ PCWSTR /*processName*/, /*[in]*/ GUID /*remoteId*/, /*[out]*/ GUID* /*appId*/) { auto lock = m_lock.lock_shared(); - THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); return E_NOTIMPL; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp index 60dedbbeeb..05324e8609 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp @@ -9,12 +9,11 @@ using namespace Microsoft::WRL; -wil::unique_event g_event; +wil::unique_event g_event(wil::EventOptions::None); wil::unique_threadpool_timer g_timer; HRESULT WpnLrpPlatformFactory::MakeAndInitialize() { - g_event = wil::unique_event(wil::EventOptions::None); return S_OK; } @@ -28,14 +27,12 @@ IFACEMETHODIMP WpnLrpPlatformFactory::CreateInstance( std::call_once(m_platformInitializedFlag, [&] { m_platform = Microsoft::WRL::Make(); - m_platform->Initialize(); - - // Prevent scenario where if the first client goes out of scope, - // then triggers WpnLrpPlatformImpl dtor. // NEED TO CHECK THIS - m_platform->AddRef(); + m_platform->Initialize(); }); *obj = m_platform.Get(); + // Add one ref per platform instance request. Deref occurs automatically. + m_platform->AddRef(); return S_OK; } @@ -66,7 +63,7 @@ void WpnLrpPlatformFactory::SetupTimer() // Negative times in SetThreadpoolTimer are relative. Allow 30 seconds to fire. FILETIME dueTime{}; - *reinterpret_cast(&dueTime) = -static_cast(30000 * 10000); + *reinterpret_cast(&dueTime) = -static_cast(60000 * 10000); SetThreadpoolTimer(g_timer.get(), &dueTime, 0, 0); } catch (...) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h index 3b9d9f34e9..f113f26612 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h @@ -19,8 +19,6 @@ struct WpnLrpPlatformFactory WrlFinal : public Microsoft::WRL::ClassFactory<> private: - // WinMain is the owner of the platform reference Microsoft::WRL::ComPtr m_platform; std::once_flag m_platformInitializedFlag; - bool m_isPlatformInitialized = false; }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index 6915eb0dbd..1d4e4210f4 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -35,10 +35,7 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* // If we realize that we need to persist the LRP, timer will be canceled. platformFactory->SetupTimer(); - // Callback to be signaled by COM if it considers that the process should exit. - auto& module = Module::Create(WpnLrpPlatformFactory::SignalEvent); - - unsigned long count = module.IncrementObjectCount(); // May remove + auto& module = Module::Create(); CLSID clsid = __uuidof(NotificationsLongRunningPlatformImpl); DWORD cookie = 0; @@ -53,14 +50,10 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* // Get an initialized instance of the LRP platform THROW_IF_FAILED(platformFactory->CreateInstance(nullptr, __uuidof(INotificationsLongRunningPlatform), &platform)); - platformFactory->WaitForEvent(); - - platform->Shutdown(); - platform = nullptr; // May check again CoUninitialize behavior - - count = module.DecrementObjectCount(); + WpnLrpPlatformFactory::WaitForEvent(); (void)LOG_IF_FAILED(module.UnregisterCOMObject(nullptr, &cookie, 1)); + module.Terminate(); ::CoUninitialize(); From 1b11db4d6ba2ad557962dd9154346f387dabe0d1 Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Thu, 12 Aug 2021 14:12:30 -0700 Subject: [PATCH 11/50] Improved timer/event management --- .../winmain.cpp | 2 - .../platform.cpp | 50 +++++++++++++++++++ .../platform.h | 8 +++ .../platformfactory.cpp | 47 +---------------- .../platformfactory.h | 10 +--- .../winmain.cpp | 26 ++++------ 6 files changed, 71 insertions(+), 72 deletions(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp index 1e2a14a536..8b84b93179 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp @@ -8,8 +8,6 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { - Sleep(20000); - RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); try diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index 569661a547..f5e839a4a6 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -5,6 +5,9 @@ #include "platform.h" #include "platformfactory.h" +wil::unique_event s_event(wil::EventOptions::None); +wil::unique_threadpool_timer s_timer; + void NotificationsLongRunningPlatformImpl::Initialize() { auto lock = m_lock.lock_exclusive(); @@ -15,6 +18,12 @@ void NotificationsLongRunningPlatformImpl::Initialize() return; } + // Schedule event signaling after 30 seconds. This is in case we don't have any apps to track in the LRP. + // If we realize that we need to persist the LRP, timer should be canceled. + SetupTimer(); + + /* Verify registry and UDK list and make sure we have apps to be tracked */ + /* Load your components */ m_initialized = true; @@ -33,6 +42,46 @@ void NotificationsLongRunningPlatformImpl::Shutdown() m_shutdown = true; } +void NotificationsLongRunningPlatformImpl::SignalEvent() +{ + s_event.SetEvent(); +} + +void NotificationsLongRunningPlatformImpl::WaitForEvent() +{ + s_event.wait(); +} + +void NotificationsLongRunningPlatformImpl::SetupTimer() +{ + try + { + s_timer.reset(CreateThreadpoolTimer( + [](PTP_CALLBACK_INSTANCE, _Inout_ PVOID, _Inout_ PTP_TIMER) + { + SignalEvent(); + }, + reinterpret_cast(GetCurrentThreadId()), + nullptr)); + + THROW_LAST_ERROR_IF_NULL(s_timer); + + // Negative times in SetThreadpoolTimer are relative. Allow 30 seconds to fire. + FILETIME dueTime{}; + *reinterpret_cast(&dueTime) = -static_cast(30000 * 10000); + SetThreadpoolTimer(s_timer.get(), &dueTime, 0, 0); + } + catch (...) + { + LOG_IF_FAILED(wil::ResultFromCaughtException()); + } +} + +void CancelTimer() +{ + s_timer.reset(); +} + STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterActivator(/*[in]*/ PCWSTR /*processName*/) { auto lock = m_lock.lock_shared(); @@ -67,3 +116,4 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterF RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); return E_NOTIMPL; } + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 909bb6437d..81dbbe85c1 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -12,6 +12,10 @@ Microsoft::WRL::RuntimeClass< void Shutdown(); + static void SignalEvent(); + + void WaitForEvent(); + /* IWpnLrpPlatform functions */ STDMETHOD(RegisterActivator)(/*[in]*/ PCWSTR processName); @@ -28,6 +32,10 @@ Microsoft::WRL::RuntimeClass< private: + void SetupTimer(); + + void CancelTimer(); + wil::srwlock m_lock; bool m_initialized = false; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp index 05324e8609..2b83ead1b6 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp @@ -9,15 +9,12 @@ using namespace Microsoft::WRL; -wil::unique_event g_event(wil::EventOptions::None); -wil::unique_threadpool_timer g_timer; - -HRESULT WpnLrpPlatformFactory::MakeAndInitialize() +HRESULT NotificationsLongRunningProcessFactory::MakeAndInitialize() { return S_OK; } -IFACEMETHODIMP WpnLrpPlatformFactory::CreateInstance( +IFACEMETHODIMP NotificationsLongRunningProcessFactory::CreateInstance( _In_opt_ IUnknown* /*outer*/, _In_ REFIID /*riid*/, _COM_Outptr_ void** obj) @@ -36,43 +33,3 @@ IFACEMETHODIMP WpnLrpPlatformFactory::CreateInstance( return S_OK; } - -void WpnLrpPlatformFactory::SignalEvent() -{ - g_event.SetEvent(); -} - -void WpnLrpPlatformFactory::WaitForEvent() -{ - g_event.wait(); -} - -void WpnLrpPlatformFactory::SetupTimer() -{ - try - { - g_timer.reset(CreateThreadpoolTimer( - [](PTP_CALLBACK_INSTANCE, _Inout_ PVOID, _Inout_ PTP_TIMER) - { - SignalEvent(); - }, - reinterpret_cast(GetCurrentThreadId()), - nullptr)); - - THROW_LAST_ERROR_IF_NULL(g_timer); - - // Negative times in SetThreadpoolTimer are relative. Allow 30 seconds to fire. - FILETIME dueTime{}; - *reinterpret_cast(&dueTime) = -static_cast(60000 * 10000); - SetThreadpoolTimer(g_timer.get(), &dueTime, 0, 0); - } - catch (...) - { - LOG_IF_FAILED(wil::ResultFromCaughtException()); - } -} - -void WpnLrpPlatformFactory::CancelTimer() -{ - g_timer.reset(); -} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h index f113f26612..d12af0d3ef 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h @@ -1,6 +1,6 @@ #pragma once -struct WpnLrpPlatformFactory WrlFinal : public Microsoft::WRL::ClassFactory<> +struct NotificationsLongRunningProcessFactory WrlFinal : public Microsoft::WRL::ClassFactory<> { HRESULT MakeAndInitialize(); @@ -9,14 +9,6 @@ struct WpnLrpPlatformFactory WrlFinal : public Microsoft::WRL::ClassFactory<> _In_ REFIID riid, _COM_Outptr_ void** ppvObject) override; - static void SignalEvent(); - - static void WaitForEvent(); - - static void SetupTimer(); - - static void CancelTimer(); - private: Microsoft::WRL::ComPtr m_platform; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index 1d4e4210f4..eba7cdbdf9 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -21,22 +21,20 @@ using namespace Microsoft::WRL; int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { - Sleep(20000); - THROW_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); - ComPtr platformFactory; - THROW_IF_FAILED(MakeAndInitialize(&platformFactory)); - - ComPtr platformFactoryAsClassFactory; - THROW_IF_FAILED(platformFactory.As(&platformFactoryAsClassFactory)); + ComPtr platformFactory; + THROW_IF_FAILED(MakeAndInitialize(&platformFactory)); - // Schedule event signaling after 30 seconds. This is in case we don't have any apps to track in the LRP. - // If we realize that we need to persist the LRP, timer will be canceled. - platformFactory->SetupTimer(); + ComPtr platform; + // Get an initialized instance of the LRP platform + THROW_IF_FAILED(platformFactory->CreateInstance(nullptr, __uuidof(INotificationsLongRunningPlatform), &platform)); auto& module = Module::Create(); + ComPtr platformFactoryAsClassFactory; + THROW_IF_FAILED(platformFactory.As(&platformFactoryAsClassFactory)); + CLSID clsid = __uuidof(NotificationsLongRunningPlatformImpl); DWORD cookie = 0; THROW_IF_FAILED(module.RegisterCOMObject( @@ -44,13 +42,9 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* &clsid, platformFactoryAsClassFactory.GetAddressOf(), &cookie, - 1)); - - ComPtr platform; - // Get an initialized instance of the LRP platform - THROW_IF_FAILED(platformFactory->CreateInstance(nullptr, __uuidof(INotificationsLongRunningPlatform), &platform)); + 1)); - WpnLrpPlatformFactory::WaitForEvent(); + platform->WaitForEvent(); (void)LOG_IF_FAILED(module.UnregisterCOMObject(nullptr, &cookie, 1)); From 793e412d12fdb60588de218abe926679536b6ded Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Thu, 12 Aug 2021 17:17:28 -0700 Subject: [PATCH 12/50] Addressed feedback --- .../NotificationsLongRunningProcess.idl | 8 -- .../winmain.cpp | 7 +- .../platform.cpp | 77 ++++++------------- .../platform.h | 15 ++-- .../platformfactory.cpp | 13 ++-- .../platformfactory.h | 4 +- .../winmain.cpp | 14 ++-- .../PushNotificationsDemoApp/main.cpp | 1 - 8 files changed, 47 insertions(+), 92 deletions(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl index 6f1fd648a9..64bc2f82ea 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl @@ -11,14 +11,6 @@ import "ocidl.idl"; [pointer_default(unique)] interface INotificationsLongRunningPlatform : IUnknown { - HRESULT RegisterActivator([in] LPCWSTR processName); - - HRESULT UnregisterActivator([in] LPCWSTR processName); - - HRESULT RegisterForegroundActivator([in] LPCWSTR processName); - - HRESULT UnregisterForegroundActivator([in] LPCWSTR processName); - HRESULT RegisterFullTrustApplication([in] LPCWSTR processName, [in] GUID remoteId, [out] GUID* appId); }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp index 8b84b93179..6e8ccaafad 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp @@ -10,14 +10,15 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* { RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); + auto scopeExit = wil::scope_exit( + [&]() { CoUninitialize(); }); + try { wil::com_ptr longRunningProcessPlatform { wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; } - CATCH_LOG() - - CoUninitialize(); + CATCH_RETURN() return 0; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index f5e839a4a6..c705a1da82 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -5,9 +5,6 @@ #include "platform.h" #include "platformfactory.h" -wil::unique_event s_event(wil::EventOptions::None); -wil::unique_threadpool_timer s_timer; - void NotificationsLongRunningPlatformImpl::Initialize() { auto lock = m_lock.lock_exclusive(); @@ -44,76 +41,50 @@ void NotificationsLongRunningPlatformImpl::Shutdown() void NotificationsLongRunningPlatformImpl::SignalEvent() { - s_event.SetEvent(); + m_event.SetEvent(); } void NotificationsLongRunningPlatformImpl::WaitForEvent() { - s_event.wait(); + m_event.wait(); } void NotificationsLongRunningPlatformImpl::SetupTimer() { - try - { - s_timer.reset(CreateThreadpoolTimer( - [](PTP_CALLBACK_INSTANCE, _Inout_ PVOID, _Inout_ PTP_TIMER) - { - SignalEvent(); - }, - reinterpret_cast(GetCurrentThreadId()), - nullptr)); - - THROW_LAST_ERROR_IF_NULL(s_timer); + // Already guarded by the lock in Initialize() + m_timer.reset(CreateThreadpoolTimer( + [](PTP_CALLBACK_INSTANCE, _Inout_ PVOID platform, _Inout_ PTP_TIMER) + { + NotificationsLongRunningPlatformImpl* platformImpl = reinterpret_cast(platform); - // Negative times in SetThreadpoolTimer are relative. Allow 30 seconds to fire. - FILETIME dueTime{}; - *reinterpret_cast(&dueTime) = -static_cast(30000 * 10000); - SetThreadpoolTimer(s_timer.get(), &dueTime, 0, 0); - } - catch (...) - { - LOG_IF_FAILED(wil::ResultFromCaughtException()); - } -} - -void CancelTimer() -{ - s_timer.reset(); -} + if (platformImpl != nullptr) + { + platformImpl->SignalEvent(); + } + }, + this, + nullptr)); -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterActivator(/*[in]*/ PCWSTR /*processName*/) -{ - auto lock = m_lock.lock_shared(); - RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - return E_NOTIMPL; -} + THROW_LAST_ERROR_IF_NULL(m_timer); -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterActivator(/*[in]*/ PCWSTR /*processName*/) -{ - auto lock = m_lock.lock_shared(); - RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - return E_NOTIMPL; -} + // Negative times in SetThreadpoolTimer are relative. Allow 30 seconds to fire. + FILETIME dueTime{}; + *reinterpret_cast(&dueTime) = -static_cast(30000 * 10000); -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) -{ - auto lock = m_lock.lock_shared(); - RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - return E_NOTIMPL; + SetThreadpoolTimer(m_timer.get(), &dueTime, 0, 0); } -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterForegroundActivator(/*[in]*/ PCWSTR /*processName*/) +void NotificationsLongRunningPlatformImpl::CancelTimer() { - auto lock = m_lock.lock_shared(); - RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - return E_NOTIMPL; + auto lock = m_lock.lock_exclusive(); + m_timer.reset(); } -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterFullTrustApplication(/*[in]*/ PCWSTR /*processName*/, /*[in]*/ GUID /*remoteId*/, /*[out]*/ GUID* /*appId*/) +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterFullTrustApplication(_In_ PCWSTR /*processName*/, _In_ GUID /*remoteId*/, _Out_ GUID* /*appId*/) noexcept { auto lock = m_lock.lock_shared(); RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + // Will implement this function once I synced up with Sharath regarding this return E_NOTIMPL; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 81dbbe85c1..fb54372789 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -12,21 +12,13 @@ Microsoft::WRL::RuntimeClass< void Shutdown(); - static void SignalEvent(); + void SignalEvent(); void WaitForEvent(); /* IWpnLrpPlatform functions */ - STDMETHOD(RegisterActivator)(/*[in]*/ PCWSTR processName); - - STDMETHOD(UnregisterActivator)(/*[in]*/ PCWSTR processName); - - STDMETHOD(RegisterForegroundActivator)(/*[in]*/ PCWSTR processName); - - STDMETHOD(UnregisterForegroundActivator)(/*[in]*/ PCWSTR processName); - - STDMETHOD(RegisterFullTrustApplication)(/*[in]*/ PCWSTR processName, /*[in]*/ GUID remoteId, /*[out]*/ GUID* appId); + STDMETHOD(RegisterFullTrustApplication)(_In_ PCWSTR processName, _In_ GUID remoteId, _Out_ GUID* appId) noexcept; /* Add your functions to retrieve the platform components */ @@ -41,5 +33,8 @@ Microsoft::WRL::RuntimeClass< bool m_initialized = false; bool m_shutdown = false; + wil::unique_event m_event{ wil::EventOptions::None }; + wil::unique_threadpool_timer m_timer; + // Here we will define the Platform components i.e. the map wrappings }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp index 2b83ead1b6..25be8468d1 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp @@ -9,9 +9,12 @@ using namespace Microsoft::WRL; -HRESULT NotificationsLongRunningProcessFactory::MakeAndInitialize() +HRESULT NotificationsLongRunningProcessFactory::RuntimeClassInitialize() { - return S_OK; + m_platform = Microsoft::WRL::Make(); + m_platform->Initialize(); + + return S_OK; } IFACEMETHODIMP NotificationsLongRunningProcessFactory::CreateInstance( @@ -21,12 +24,6 @@ IFACEMETHODIMP NotificationsLongRunningProcessFactory::CreateInstance( { *obj = nullptr; - std::call_once(m_platformInitializedFlag, - [&] { - m_platform = Microsoft::WRL::Make(); - m_platform->Initialize(); - }); - *obj = m_platform.Get(); // Add one ref per platform instance request. Deref occurs automatically. m_platform->AddRef(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h index d12af0d3ef..e45581b696 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h @@ -2,7 +2,7 @@ struct NotificationsLongRunningProcessFactory WrlFinal : public Microsoft::WRL::ClassFactory<> { - HRESULT MakeAndInitialize(); + HRESULT RuntimeClassInitialize(); IFACEMETHODIMP CreateInstance( _In_opt_ IUnknown* outer, @@ -10,7 +10,5 @@ struct NotificationsLongRunningProcessFactory WrlFinal : public Microsoft::WRL:: _COM_Outptr_ void** ppvObject) override; private: - Microsoft::WRL::ComPtr m_platform; - std::once_flag m_platformInitializedFlag; }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index eba7cdbdf9..f124778051 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -21,32 +21,34 @@ using namespace Microsoft::WRL; int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { - THROW_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); + RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); ComPtr platformFactory; - THROW_IF_FAILED(MakeAndInitialize(&platformFactory)); + RETURN_IF_FAILED(MakeAndInitialize(&platformFactory)); ComPtr platform; // Get an initialized instance of the LRP platform - THROW_IF_FAILED(platformFactory->CreateInstance(nullptr, __uuidof(INotificationsLongRunningPlatform), &platform)); + RETURN_IF_FAILED(platformFactory->CreateInstance(nullptr, __uuidof(INotificationsLongRunningPlatform), &platform)); auto& module = Module::Create(); ComPtr platformFactoryAsClassFactory; - THROW_IF_FAILED(platformFactory.As(&platformFactoryAsClassFactory)); + RETURN_IF_FAILED(platformFactory.As(&platformFactoryAsClassFactory)); CLSID clsid = __uuidof(NotificationsLongRunningPlatformImpl); DWORD cookie = 0; - THROW_IF_FAILED(module.RegisterCOMObject( + RETURN_IF_FAILED(module.RegisterCOMObject( nullptr, &clsid, platformFactoryAsClassFactory.GetAddressOf(), &cookie, 1)); + // Wait returns if the platform realizes there are no more apps to be tracked. + // It also returns if the timer initialized at the process start fires (see NotificationsLongRunningPlatformImpl::Initialize). platform->WaitForEvent(); - (void)LOG_IF_FAILED(module.UnregisterCOMObject(nullptr, &cookie, 1)); + RETURN_IF_FAILED(module.UnregisterCOMObject(nullptr, &cookie, 1)); module.Terminate(); diff --git a/test/TestApps/PushNotificationsDemoApp/main.cpp b/test/TestApps/PushNotificationsDemoApp/main.cpp index 3ac0dba7b6..45a0cdcfaf 100644 --- a/test/TestApps/PushNotificationsDemoApp/main.cpp +++ b/test/TestApps/PushNotificationsDemoApp/main.cpp @@ -89,7 +89,6 @@ winrt::Microsoft::Windows::PushNotifications::PushNotificationChannel RequestCha int main() { - Sleep(20000); PushNotificationActivationInfo info( PushNotificationRegistrationOptions::PushTrigger | PushNotificationRegistrationOptions::ComActivator, winrt::guid("ccd2ae3f-764f-4ae3-be45-9804761b28b2")); // same clsid as app manifest From f9ba159efda732ef061a5f3c039d1fd6dc732f1f Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Mon, 16 Aug 2021 15:51:49 -0700 Subject: [PATCH 13/50] Fixed compilation issues in other flavor+archs and added minor comments --- .../PushNotificationsLongRunningTask.ProxyStub.vcxproj | 4 ++-- .../PushNotificationsLongRunningTask/platform.cpp | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj index 2535dae86e..0b05d19fb6 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj @@ -406,7 +406,7 @@ NotUsing NotUsing - + NotUsing NotUsing NotUsing @@ -416,7 +416,7 @@ NotUsing NotUsing - + NotUsing NotUsing NotUsing diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index c705a1da82..c721bdf41f 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -19,9 +19,9 @@ void NotificationsLongRunningPlatformImpl::Initialize() // If we realize that we need to persist the LRP, timer should be canceled. SetupTimer(); - /* Verify registry and UDK list and make sure we have apps to be tracked */ + /* TODO: Verify registry and UDK list and make sure we have apps to be tracked */ - /* Load your components */ + /* TODO: Load platform components */ m_initialized = true; } @@ -34,7 +34,7 @@ void NotificationsLongRunningPlatformImpl::Shutdown() return; } - /* Shut down your components */ + /* TODO: Shut down your components */ m_shutdown = true; } @@ -80,11 +80,12 @@ void NotificationsLongRunningPlatformImpl::CancelTimer() m_timer.reset(); } +// Example of one function. We will add more as we need them. STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterFullTrustApplication(_In_ PCWSTR /*processName*/, _In_ GUID /*remoteId*/, _Out_ GUID* /*appId*/) noexcept { auto lock = m_lock.lock_shared(); RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - // Will implement this function once I synced up with Sharath regarding this + return E_NOTIMPL; } From 8387ffd20763b9a78d0ab3da062f85fd45376a4d Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Tue, 17 Aug 2021 11:55:18 -0700 Subject: [PATCH 14/50] Added a unit test (more coming!) --- test/PushNotificationTests/LRPTests.cpp | 93 +++++++++++++++++++ .../PushNotificationTests.vcxproj | 20 ++-- .../PushNotificationTests.vcxproj.filters | 4 + test/PushNotificationTests/pch.h | 1 + 4 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 test/PushNotificationTests/LRPTests.cpp diff --git a/test/PushNotificationTests/LRPTests.cpp b/test/PushNotificationTests/LRPTests.cpp new file mode 100644 index 0000000000..de9875b9ae --- /dev/null +++ b/test/PushNotificationTests/LRPTests.cpp @@ -0,0 +1,93 @@ +// 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 "MockBackgroundTaskInstance.h" + +#include + +using namespace WEX::Common; +using namespace WEX::Logging; +using namespace WEX::TestExecution; + +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::System; + +namespace Test::PushNotifications +{ + class LRPTests + { + + public: + BEGIN_TEST_CLASS(LRPTests) + TEST_CLASS_PROPERTY(L"Description", L"Windows App SDK Push Notifications Long Running Process tests") + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunAs:Class", L"RestrictedUser") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassInit) + { + try + { + TP::AddPackage_WindowsAppSDKFramework(); // Installs WASfwk + TP::AddPackage_DynamicDependencyDataStore(); // Installs WASmain + TP::AddPackage_DynamicDependencyLifetimeManager(); // Installs WASddlm + TP::AddPackage_PushNotificationsLongRunningTask(); // Installs the Push Notifications Long Running Process (LRP). + } + catch (...) + { + return false; + } + + return true; + } + + TEST_CLASS_CLEANUP(ClassUninit) + { + try + { + // Remove in reverse order to avoid conflicts between inter-dependent packages. + TP::RemovePackage_PushNotificationsLongRunningTask(); + TP::RemovePackage_DynamicDependencyLifetimeManager(); + TP::RemovePackage_DynamicDependencyDataStore(); + TP::RemovePackage_WindowsAppSDKFramework(); + } + catch (...) + { + return false; + } + return true; + } + + TEST_METHOD_SETUP(MethodInit) + { + VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppSDKFramework()); + VERIFY_IS_TRUE(TP::IsPackageRegistered_DynamicDependencyDataStore()); + VERIFY_IS_TRUE(TP::IsPackageRegistered_DynamicDependencyLifetimeManager()); + VERIFY_IS_TRUE(TP::IsPackageRegistered_PushNotificationsLongRunningTask()); + return true; + } + + TEST_METHOD_CLEANUP(MethodUninit) + { + VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppSDKFramework()); + VERIFY_IS_TRUE(TP::IsPackageRegistered_DynamicDependencyDataStore()); + VERIFY_IS_TRUE(TP::IsPackageRegistered_DynamicDependencyLifetimeManager()); + VERIFY_IS_TRUE(TP::IsPackageRegistered_PushNotificationsLongRunningTask()); + + return true; + } + + TEST_METHOD(LaunchLRP_FromCoCreateInstance) + { + VERIFY_SUCCEEDED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); + + auto scopeExit = wil::scope_exit( + [&]() { VERIFY_NO_THROW(CoUninitialize()); }); + + VERIFY_NO_THROW(winrt::create_instance(_uuidof(NotificationsLongRunningPlatform), CLSCTX_ALL)); + } + + }; +} diff --git a/test/PushNotificationTests/PushNotificationTests.vcxproj b/test/PushNotificationTests/PushNotificationTests.vcxproj index a7892dc544..b532982bed 100644 --- a/test/PushNotificationTests/PushNotificationTests.vcxproj +++ b/test/PushNotificationTests/PushNotificationTests.vcxproj @@ -126,7 +126,7 @@ true true true - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub WIN32;NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP true pch.h @@ -145,7 +145,7 @@ Use Level3 true - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub WIN32;_DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP true pch.h @@ -162,7 +162,7 @@ Use Level3 true - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP true pch.h @@ -179,7 +179,7 @@ Use Level3 true - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub _DEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP true pch.h @@ -198,7 +198,7 @@ true true true - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP true pch.h @@ -219,7 +219,7 @@ true true true - %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppSDK_DLL;..\inc;$(OutDir)\..\WindowsAppSDK_BootstrapDLL;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub NDEBUG;%(PreprocessorDefinitions);;INLINE_TEST_METHOD_MARKUP true pch.h @@ -252,6 +252,7 @@ Create Create + @@ -267,6 +268,11 @@ + + + {bf3fced0-cadb-490a-93a7-4d90e1f45ab0} + + @@ -285,4 +291,4 @@ - + \ No newline at end of file diff --git a/test/PushNotificationTests/PushNotificationTests.vcxproj.filters b/test/PushNotificationTests/PushNotificationTests.vcxproj.filters index 14a322dffb..2177e2386a 100644 --- a/test/PushNotificationTests/PushNotificationTests.vcxproj.filters +++ b/test/PushNotificationTests/PushNotificationTests.vcxproj.filters @@ -41,6 +41,9 @@ Source Files + + Source Files + @@ -52,5 +55,6 @@ CopyFiles + \ No newline at end of file diff --git a/test/PushNotificationTests/pch.h b/test/PushNotificationTests/pch.h index a5c643c188..57df428c71 100644 --- a/test/PushNotificationTests/pch.h +++ b/test/PushNotificationTests/pch.h @@ -20,6 +20,7 @@ #include #include +#include #include #include From 9f143ddcd81416a0333c1d6d3f839e1938570bfb Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Wed, 18 Aug 2021 16:00:02 -0700 Subject: [PATCH 15/50] Test enhancements --- test/PushNotificationTests/LRPTests.cpp | 85 +++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/test/PushNotificationTests/LRPTests.cpp b/test/PushNotificationTests/LRPTests.cpp index de9875b9ae..cd77442de4 100644 --- a/test/PushNotificationTests/LRPTests.cpp +++ b/test/PushNotificationTests/LRPTests.cpp @@ -4,6 +4,7 @@ #include "pch.h" #include #include "MockBackgroundTaskInstance.h" +#include #include @@ -87,6 +88,90 @@ namespace Test::PushNotifications [&]() { VERIFY_NO_THROW(CoUninitialize()); }); VERIFY_NO_THROW(winrt::create_instance(_uuidof(NotificationsLongRunningPlatform), CLSCTX_ALL)); + + VerifyLRP_IsRunning(true); + + // LRP should be up for 30 seconds. We don't expect any app to be tracked at this point. + Sleep(30000); + + // Verify the LRP is not running. + VerifyLRP_IsRunning(false); + } + + TEST_METHOD(LaunchLRP_FromStartupTask) + { + STARTUPINFO startupInfo = { 0 }; + wil::unique_process_information processInfo; + + ZeroMemory(&startupInfo, sizeof(startupInfo)); + startupInfo.cb = sizeof(startupInfo); + + // Build the Solution OutDir path where the Startup Task exe is. + auto startupTaskExePath = Test::FileSystem::GetSolutionOutDirPath(); + startupTaskExePath /= Test::Packages::PushNotificationsLongRunningTask::c_PackageDirName; + startupTaskExePath += L".Msix"; + startupTaskExePath /= L"msix"; + startupTaskExePath /= L"PushNotificationsLongRunningTask.StartupTask.exe"; + + BOOL wasProcessCreated = CreateProcess( + startupTaskExePath.c_str(), + nullptr, // command line options + nullptr, // process attributes + nullptr, // thread attributes + FALSE, // inherit handles + NORMAL_PRIORITY_CLASS, // creation flags + nullptr, // lpEnvironment + nullptr, // current directory for the process + &startupInfo, + &processInfo + ); + + if (wasProcessCreated == FALSE) + { + VERIFY_SUCCEEDED(GetLastError()); + } + + // Wait for the process to come up and be captured in the snapshot from verification step. + Sleep(1000); + VerifyLRP_IsRunning(true); + + // LRP should be up for 30 seconds. We don't expect any app to be tracked at this point. + Sleep(30000); + + // Verify the LRP is not running. + VerifyLRP_IsRunning(false); + } + + void VerifyLRP_IsRunning(bool isRunning) + { + wil::unique_handle processesSnapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)); + VERIFY_IS_NOT_NULL(processesSnapshot.get()); + + PROCESSENTRY32 processEntry = { 0 }; + processEntry.dwSize = sizeof(processEntry); + + BOOL result = Process32First(processesSnapshot.get(), &processEntry); + while (result != FALSE) + { + if (wcscmp(L"PushNotificationsLongRunningTask.exe", processEntry.szExeFile) == 0) + { + VERIFY_IS_TRUE(isRunning); + DWORD processId = processEntry.th32ProcessID; + + wil::unique_handle longRunningProcessHandle(OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processId)); + DWORD exitCode = 0; + BOOL exitCodeProcess = GetExitCodeProcess(longRunningProcessHandle.get(), &exitCode); + + VERIFY_SUCCEEDED(exitCodeProcess == FALSE ? GetLastError() : S_OK); + VERIFY_ARE_EQUAL(exitCode, STILL_ACTIVE); + + return; + } + + result = Process32Next(processesSnapshot.get(), &processEntry); + } + + VERIFY_IS_FALSE(isRunning); } }; From 0789a5dd22697a206db59a57459bd7a3d3a73c0a Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Fri, 20 Aug 2021 11:55:50 -0700 Subject: [PATCH 16/50] Addressed comments --- .../winmain.cpp | 33 ++++++++++++++++--- .../platform.cpp | 21 ++++++------ .../platform.h | 10 +++--- .../platformfactory.cpp | 5 ++- .../platformfactory.h | 2 +- .../winmain.cpp | 2 +- test/PushNotificationTests/LRPTests.cpp | 19 +++++++---- 7 files changed, 59 insertions(+), 33 deletions(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp index 6e8ccaafad..27b1889247 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp @@ -6,6 +6,15 @@ #include #include +inline bool isRetriableRpcError(HRESULT hr) +{ + return (hr == HRESULT_FROM_WIN32(EPT_S_NOT_REGISTERED)) || + (hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE)) || + (hr == HRESULT_FROM_WIN32(RPC_S_CALL_FAILED)) || + (hr == HRESULT_FROM_WIN32(RPC_S_CALL_FAILED_DNE)) || + (hr == HRESULT_FROM_WIN32(RPC_S_UNKNOWN_IF)); +} + int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); @@ -13,12 +22,26 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* auto scopeExit = wil::scope_exit( [&]() { CoUninitialize(); }); - try + unsigned int retries = 0; + bool isRpcRetriableError = false; + HRESULT hr = S_OK; + + while (retries < 3 && isRpcRetriableError) { - wil::com_ptr longRunningProcessPlatform - { wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + try + { + wil::com_ptr longRunningProcessPlatform + { wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + + isRpcRetriableError = false; + } + catch (...) + { + hr = wil::ResultFromCaughtException(); + isRpcRetriableError = isRetriableRpcError(hr); + retries++; + } } - CATCH_RETURN() - return 0; + return hr; } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index c721bdf41f..e7df97d6d5 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -15,9 +15,9 @@ void NotificationsLongRunningPlatformImpl::Initialize() return; } - // Schedule event signaling after 30 seconds. This is in case we don't have any apps to track in the LRP. + // Schedule event signaling after 5 seconds. This is in case we don't have any apps to track in the LRP. // If we realize that we need to persist the LRP, timer should be canceled. - SetupTimer(); + SetupShutdownTimer(); /* TODO: Verify registry and UDK list and make sure we have apps to be tracked */ @@ -26,7 +26,7 @@ void NotificationsLongRunningPlatformImpl::Initialize() m_initialized = true; } -void NotificationsLongRunningPlatformImpl::Shutdown() +void NotificationsLongRunningPlatformImpl::Shutdown() noexcept { auto lock = m_lock.lock_exclusive(); if (m_shutdown) @@ -39,17 +39,17 @@ void NotificationsLongRunningPlatformImpl::Shutdown() m_shutdown = true; } -void NotificationsLongRunningPlatformImpl::SignalEvent() +void NotificationsLongRunningPlatformImpl::SignalWinMainEvent() { m_event.SetEvent(); } -void NotificationsLongRunningPlatformImpl::WaitForEvent() +void NotificationsLongRunningPlatformImpl::WaitForWinMainEvent() { m_event.wait(); } -void NotificationsLongRunningPlatformImpl::SetupTimer() +void NotificationsLongRunningPlatformImpl::SetupShutdownTimer() { // Already guarded by the lock in Initialize() m_timer.reset(CreateThreadpoolTimer( @@ -59,7 +59,7 @@ void NotificationsLongRunningPlatformImpl::SetupTimer() if (platformImpl != nullptr) { - platformImpl->SignalEvent(); + platformImpl->SignalWinMainEvent(); } }, this, @@ -67,16 +67,15 @@ void NotificationsLongRunningPlatformImpl::SetupTimer() THROW_LAST_ERROR_IF_NULL(m_timer); - // Negative times in SetThreadpoolTimer are relative. Allow 30 seconds to fire. + // Negative times in SetThreadpoolTimer are relative. Allow 5 seconds to fire. FILETIME dueTime{}; - *reinterpret_cast(&dueTime) = -static_cast(30000 * 10000); + *reinterpret_cast(&dueTime) = -static_cast(5000 * 10000); SetThreadpoolTimer(m_timer.get(), &dueTime, 0, 0); } -void NotificationsLongRunningPlatformImpl::CancelTimer() +void NotificationsLongRunningPlatformImpl::CancelShutdownTimer() { - auto lock = m_lock.lock_exclusive(); m_timer.reset(); } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index fb54372789..3a7e2b7aaf 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -10,11 +10,11 @@ Microsoft::WRL::RuntimeClass< { void Initialize(); - void Shutdown(); + void Shutdown() noexcept; - void SignalEvent(); + void SignalWinMainEvent(); - void WaitForEvent(); + void WaitForWinMainEvent(); /* IWpnLrpPlatform functions */ @@ -24,9 +24,9 @@ Microsoft::WRL::RuntimeClass< private: - void SetupTimer(); + void SetupShutdownTimer(); - void CancelTimer(); + void CancelShutdownTimer(); wil::srwlock m_lock; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp index 25be8468d1..aaef26df24 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp @@ -9,21 +9,20 @@ using namespace Microsoft::WRL; -HRESULT NotificationsLongRunningProcessFactory::RuntimeClassInitialize() +HRESULT NotificationsLongRunningProcessFactory::RuntimeClassInitialize() noexcept try { m_platform = Microsoft::WRL::Make(); m_platform->Initialize(); return S_OK; } +CATCH_RETURN() IFACEMETHODIMP NotificationsLongRunningProcessFactory::CreateInstance( _In_opt_ IUnknown* /*outer*/, _In_ REFIID /*riid*/, _COM_Outptr_ void** obj) { - *obj = nullptr; - *obj = m_platform.Get(); // Add one ref per platform instance request. Deref occurs automatically. m_platform->AddRef(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h index e45581b696..52a9935c97 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h @@ -2,7 +2,7 @@ struct NotificationsLongRunningProcessFactory WrlFinal : public Microsoft::WRL::ClassFactory<> { - HRESULT RuntimeClassInitialize(); + HRESULT RuntimeClassInitialize() noexcept; IFACEMETHODIMP CreateInstance( _In_opt_ IUnknown* outer, diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index f124778051..bfbff0840b 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -46,7 +46,7 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* // Wait returns if the platform realizes there are no more apps to be tracked. // It also returns if the timer initialized at the process start fires (see NotificationsLongRunningPlatformImpl::Initialize). - platform->WaitForEvent(); + platform->WaitForWinMainEvent(); RETURN_IF_FAILED(module.UnregisterCOMObject(nullptr, &cookie, 1)); diff --git a/test/PushNotificationTests/LRPTests.cpp b/test/PushNotificationTests/LRPTests.cpp index cd77442de4..01e018f493 100644 --- a/test/PushNotificationTests/LRPTests.cpp +++ b/test/PushNotificationTests/LRPTests.cpp @@ -89,10 +89,12 @@ namespace Test::PushNotifications VERIFY_NO_THROW(winrt::create_instance(_uuidof(NotificationsLongRunningPlatform), CLSCTX_ALL)); - VerifyLRP_IsRunning(true); - - // LRP should be up for 30 seconds. We don't expect any app to be tracked at this point. - Sleep(30000); + // Poll the app status every second. It should be alive for 5 seconds. + for (int i = 0; i < 5; i++) + { + VerifyLRP_IsRunning(true); + Sleep(1000); + } // Verify the LRP is not running. VerifyLRP_IsRunning(false); @@ -133,10 +135,13 @@ namespace Test::PushNotifications // Wait for the process to come up and be captured in the snapshot from verification step. Sleep(1000); - VerifyLRP_IsRunning(true); - // LRP should be up for 30 seconds. We don't expect any app to be tracked at this point. - Sleep(30000); + // Poll the app status every second. It should be alive for 5 seconds. + for (int i = 0; i < 5; i++) + { + VerifyLRP_IsRunning(true); + Sleep(1000); + } // Verify the LRP is not running. VerifyLRP_IsRunning(false); From 30fddd34eed4170107e5f504c07da8f56baca735 Mon Sep 17 00:00:00 2001 From: Daniel Ayala Date: Fri, 20 Aug 2021 16:30:01 -0700 Subject: [PATCH 17/50] Moved timer/event logic to a platform component --- .../winmain.cpp | 2 +- .../PlatformLifetimeTimerManager.cpp | 45 +++++++++++++++++++ .../PlatformLifetimeTimerManager.h | 21 +++++++++ .../PushNotificationsLongRunningTask.vcxproj | 2 + ...tificationsLongRunningTask.vcxproj.filters | 6 +++ .../platform.cpp | 41 ++--------------- .../platform.h | 11 ++--- .../winmain.cpp | 1 + 8 files changed, 83 insertions(+), 46 deletions(-) create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.cpp create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.h diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp index 27b1889247..3e1c6ba159 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp @@ -23,7 +23,7 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* [&]() { CoUninitialize(); }); unsigned int retries = 0; - bool isRpcRetriableError = false; + bool isRpcRetriableError = true; HRESULT hr = S_OK; while (retries < 3 && isRpcRetriableError) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.cpp new file mode 100644 index 0000000000..5a73909181 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.cpp @@ -0,0 +1,45 @@ +#include "pch.h" + +#include "PlatformLifetimeTimerManager.h" + +void PlatformLifetimeTimerManager::Setup() +{ + auto lock = m_lock.lock_exclusive(); + + m_timer.reset(CreateThreadpoolTimer( + [](PTP_CALLBACK_INSTANCE, _Inout_ PVOID shutdownTimerManagerPtr, _Inout_ PTP_TIMER) + { + PlatformLifetimeTimerManager* shutdownTimerManager = reinterpret_cast(shutdownTimerManagerPtr); + + if (shutdownTimerManager != nullptr) + { + shutdownTimerManager->SignalWinMainEvent(); + } + }, + this, + nullptr)); + + THROW_LAST_ERROR_IF_NULL(m_timer); + + // Negative times in SetThreadpoolTimer are relative. Allow 5 seconds to fire. + FILETIME dueTime{}; + *reinterpret_cast(&dueTime) = -static_cast(5000 * 10000); + + SetThreadpoolTimer(m_timer.get(), &dueTime, 0, 0); +} + +void PlatformLifetimeTimerManager::Cancel() +{ + auto lock = m_lock.lock_exclusive(); + m_timer.reset(); +} + +void PlatformLifetimeTimerManager::Wait() +{ + m_event.wait(); +} + +void PlatformLifetimeTimerManager::SignalWinMainEvent() +{ + m_event.SetEvent(); +} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.h b/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.h new file mode 100644 index 0000000000..5e0d21c388 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.h @@ -0,0 +1,21 @@ +#pragma once + +class PlatformLifetimeTimerManager +{ +public: + + void Setup(); + + void Cancel(); + + void Wait(); + + void SignalWinMainEvent(); + +private: + + wil::srwlock m_lock; + + wil::unique_event m_event{ wil::EventOptions::None }; + wil::unique_threadpool_timer m_timer; +}; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index 1e3945e1a4..40044547c8 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -219,12 +219,14 @@ + + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters index 4804663994..7b32be73d3 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters @@ -24,6 +24,9 @@ Header Files + + Header Files + @@ -38,6 +41,9 @@ Source Files + + Source Files + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index e7df97d6d5..a16f0f7c42 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -17,7 +17,8 @@ void NotificationsLongRunningPlatformImpl::Initialize() // Schedule event signaling after 5 seconds. This is in case we don't have any apps to track in the LRP. // If we realize that we need to persist the LRP, timer should be canceled. - SetupShutdownTimer(); + m_shutdownTimerManager = std::make_unique(); + m_shutdownTimerManager->Setup(); /* TODO: Verify registry and UDK list and make sure we have apps to be tracked */ @@ -39,44 +40,10 @@ void NotificationsLongRunningPlatformImpl::Shutdown() noexcept m_shutdown = true; } -void NotificationsLongRunningPlatformImpl::SignalWinMainEvent() -{ - m_event.SetEvent(); -} - void NotificationsLongRunningPlatformImpl::WaitForWinMainEvent() { - m_event.wait(); -} - -void NotificationsLongRunningPlatformImpl::SetupShutdownTimer() -{ - // Already guarded by the lock in Initialize() - m_timer.reset(CreateThreadpoolTimer( - [](PTP_CALLBACK_INSTANCE, _Inout_ PVOID platform, _Inout_ PTP_TIMER) - { - NotificationsLongRunningPlatformImpl* platformImpl = reinterpret_cast(platform); - - if (platformImpl != nullptr) - { - platformImpl->SignalWinMainEvent(); - } - }, - this, - nullptr)); - - THROW_LAST_ERROR_IF_NULL(m_timer); - - // Negative times in SetThreadpoolTimer are relative. Allow 5 seconds to fire. - FILETIME dueTime{}; - *reinterpret_cast(&dueTime) = -static_cast(5000 * 10000); - - SetThreadpoolTimer(m_timer.get(), &dueTime, 0, 0); -} - -void NotificationsLongRunningPlatformImpl::CancelShutdownTimer() -{ - m_timer.reset(); + THROW_HR_IF_NULL(E_UNEXPECTED, m_shutdownTimerManager.get()); + m_shutdownTimerManager->Wait(); } // Example of one function. We will add more as we need them. diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 3a7e2b7aaf..99b353de1b 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -2,6 +2,8 @@ #include "../PushNotifications-Constants.h" +#include "PlatformLifetimeTimerManager.h" + struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRunningPlatformImpl WrlFinal : Microsoft::WRL::RuntimeClass< Microsoft::WRL::RuntimeClassFlags, @@ -12,8 +14,6 @@ Microsoft::WRL::RuntimeClass< void Shutdown() noexcept; - void SignalWinMainEvent(); - void WaitForWinMainEvent(); /* IWpnLrpPlatform functions */ @@ -24,17 +24,12 @@ Microsoft::WRL::RuntimeClass< private: - void SetupShutdownTimer(); - - void CancelShutdownTimer(); - wil::srwlock m_lock; bool m_initialized = false; bool m_shutdown = false; - wil::unique_event m_event{ wil::EventOptions::None }; - wil::unique_threadpool_timer m_timer; + std::unique_ptr m_shutdownTimerManager; // Here we will define the Platform components i.e. the map wrappings }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index bfbff0840b..bf1d4fcd20 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -63,5 +63,6 @@ STDAPI_(BOOL) DllMain(_In_opt_ HINSTANCE hinst, DWORD reason, _In_opt_ void*) { DisableThreadLibraryCalls(hinst); } + return TRUE; } From b0ce0a11fcd87572c6ea7388596dbe112e586d5e Mon Sep 17 00:00:00 2001 From: Sharath Manchala <10109130+sharath2727@users.noreply.github.com> Date: Fri, 20 Aug 2021 20:55:48 -0700 Subject: [PATCH 18/50] Install Frameworkudk for LRP (#1271) --- .../PushNotificationsLongRunningTask.vcxproj | 12 ++++++++++++ .../PushNotificationsLongRunningTask/packages.config | 3 +++ .../Makefile.mak | 1 + .../PushNotificationsLongRunningTask.Msix.vcxproj | 3 +++ ...NotificationsLongRunningTask.Msix.vcxproj.filters | 5 ++++- 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index 40044547c8..d4fa8ab079 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -128,6 +128,7 @@ Windows DebugFull + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -147,6 +148,7 @@ true true DebugFull + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -161,6 +163,7 @@ Windows DebugFull + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -180,6 +183,7 @@ true true DebugFull + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -194,6 +198,7 @@ Windows DebugFull + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -213,6 +218,7 @@ true true DebugFull + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -240,6 +246,9 @@ + + + @@ -248,5 +257,8 @@ + + + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config b/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config index c48ce9eaae..27bcb8d80f 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config @@ -1,5 +1,8 @@  + + + \ No newline at end of file diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak index 2d45033e54..3a3dd494f3 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak @@ -52,6 +52,7 @@ all: build $(OutMsix): $(ProjectDir)appxmanifest.xml @if not exist $(WorkDir) md $(WorkDir) @copy /Y $(ProjectDir)appxmanifest.xml $(WorkDir)\appxmanifest.xml + @copy /Y $(OutDir)WindowsAppSDK_DLL\Microsoft.Internal.FrameworkUdk.dll $(WorkDir)\Microsoft.Internal.FrameworkUdk.dll @if not exist $(WorkDir)\Assets md $(WorkDir)\Assets >NUL @copy /Y $(ProjectDir)Assets\* $(WorkDir)\Assets\* >NUL @copy /Y $(TARGET_EXE_FILE) $(WorkDir) >NUL diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj index 5da79f1a47..8b5a2708b5 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj @@ -139,6 +139,9 @@ {1307dd1b-bbe8-4cd0-b1a0-0db6d61eeaa0} + + + diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj.filters b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj.filters index c89a41cd82..d86bd6d01f 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj.filters +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/PushNotificationsLongRunningTask.Msix.vcxproj.filters @@ -17,4 +17,7 @@ - + + + + \ No newline at end of file From b2265f2101c2a025822d2d7637bda6953f0bb60c Mon Sep 17 00:00:00 2001 From: Paul Purifoy <33183370+pmpurifoy@users.noreply.github.com> Date: Tue, 31 Aug 2021 19:40:21 -0700 Subject: [PATCH 19/50] Introducing unpackaged foreground activation for PushNotifications (#1336) * Cleaned original code * Added IWpnNotificationSink COM interface to LRP MSIX * Just stuff for testing. Needs to be undone * Still working on it * Com proxy objects not being stored correctly * Receiving Data from LRP and changed sink container * Foreground activation working * Fix first round of nits * Still working on adding nits * Fix following FI of main * Addressing nits * Use com_array instead of byte* * Update dev/PushNotifications/PushNotificationDummyDeferral.h Co-authored-by: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> Co-authored-by: Daniel Ayala Co-authored-by: Eric Langlois Co-authored-by: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> --- .../PushNotificationChannel.cpp | 74 ++++++++++++++-- .../PushNotificationChannel.h | 18 +++- .../PushNotificationDummyDeferral.h | 28 ++++++ .../PushNotificationReceivedEventArgs.cpp | 88 +++++++++++++++---- .../PushNotificationReceivedEventArgs.h | 10 ++- .../PushNotifications.vcxitems | 5 +- .../NotificationsLongRunningProcess.idl | 15 ++++ .../ForegroundSinkManager.cpp | 36 ++++++++ .../ForegroundSinkManager.h | 26 ++++++ .../PushNotificationsLongRunningTask.vcxproj | 18 ++-- ...tificationsLongRunningTask.vcxproj.filters | 6 ++ .../platform.cpp | 22 +++++ .../platform.h | 14 ++- dev/PushNotifications/externs.h | 5 ++ .../WindowsAppRuntime_DLL.vcxproj | 16 ++-- .../appxmanifest.xml | 6 ++ .../PushNotificationsDemoApp/main.cpp | 2 +- 17 files changed, 339 insertions(+), 50 deletions(-) create mode 100644 dev/PushNotifications/PushNotificationDummyDeferral.h create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.cpp create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.h diff --git a/dev/PushNotifications/PushNotificationChannel.cpp b/dev/PushNotifications/PushNotificationChannel.cpp index e3d8ed743f..c790de4883 100644 --- a/dev/PushNotifications/PushNotificationChannel.cpp +++ b/dev/PushNotifications/PushNotificationChannel.cpp @@ -2,16 +2,19 @@ // Licensed under the MIT License. See LICENSE in the project root for license information. #include "pch.h" +#include #include "PushNotificationChannel.h" #include "Microsoft.Windows.PushNotifications.PushNotificationChannel.g.cpp" #include #include #include "PushNotificationReceivedEventArgs.h" +#include "externs.h" namespace winrt::Windows { using namespace winrt::Windows::Networking::PushNotifications; using namespace winrt::Windows::Foundation; + using namespace winrt::Windows::Metadata; } namespace winrt::Microsoft { @@ -26,10 +29,12 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { return winrt::Windows::Uri{ m_channel.Uri() }; } + winrt::Windows::DateTime PushNotificationChannel::ExpirationTime() { return m_channel.ExpirationTime(); } + void PushNotificationChannel::Close() { try @@ -48,18 +53,73 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation winrt::event_token PushNotificationChannel::PushReceived(winrt::Windows::TypedEventHandler handler) { - return m_channel.PushNotificationReceived([weak_self = get_weak(), handler](auto&&, auto&& args) + if (IsPackagedAppScenario()) { - auto strong = weak_self.get(); - if (strong) + return m_channel.PushNotificationReceived([weak_self = get_weak(), handler](auto&&, auto&& args) { - handler(*strong, winrt::make(args)); - }; - }); + if (auto strong = weak_self.get()) + { + handler(*strong, winrt::make(args)); + }; + }); + } + else + { + auto lock = m_lock.lock_exclusive(); + if (!m_foregroundHandlerCount++) + { + wil::com_ptr notificationsLongRunningPlatform{ + wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + + wil::unique_cotaskmem_string processName; + THROW_IF_FAILED(GetCurrentProcessPath(processName)); + + THROW_IF_FAILED(notificationsLongRunningPlatform->RegisterForegroundActivator(this, processName.get())); + } + return m_foregroundHandlers.add(handler); + } } void PushNotificationChannel::PushReceived(winrt::event_token const& token) noexcept { - m_channel.PushNotificationReceived(token); + if (IsPackagedAppScenario()) + { + m_channel.PushNotificationReceived(token); + } + else + { + auto lock = m_lock.lock_exclusive(); + m_foregroundHandlers.remove(token); + if (!--m_foregroundHandlerCount) + { + wil::com_ptr notificationsLongRunningPlatform{ + wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + + wil::unique_cotaskmem_string processName; + THROW_IF_FAILED(GetCurrentProcessPath(processName)); + + THROW_IF_FAILED(notificationsLongRunningPlatform->UnregisterForegroundActivator(processName.get())); + } + } + } + + HRESULT __stdcall PushNotificationChannel::InvokeAll(_In_ ULONG length, _In_ byte* payload, _Out_ BOOL* foregroundHandled) noexcept try + { + auto args = winrt::make(payload, length); + m_foregroundHandlers(*this, args); + *foregroundHandled = args.Handled(); + return S_OK; + } + CATCH_RETURN() + + bool PushNotificationChannel::IsBackgroundTaskBuilderAvailable() + { + return winrt::Windows::ApiInformation::IsMethodPresent(L"Windows.ApplicationModel.Background.BackgroundTaskBuilder", L"SetTaskEntryPointClsid"); + } + + // Determines if the caller should be treated as packaged app or not. + bool PushNotificationChannel::IsPackagedAppScenario() + { + return AppModel::Identity::IsPackagedProcess() && IsBackgroundTaskBuilderAvailable(); } } diff --git a/dev/PushNotifications/PushNotificationChannel.h b/dev/PushNotifications/PushNotificationChannel.h index 8349d8f6b8..d3764fb823 100644 --- a/dev/PushNotifications/PushNotificationChannel.h +++ b/dev/PushNotifications/PushNotificationChannel.h @@ -3,12 +3,18 @@ #pragma once #include "Microsoft.Windows.PushNotifications.PushNotificationChannel.g.h" +#include namespace winrt::Microsoft::Windows::PushNotifications::implementation { - struct PushNotificationChannel : PushNotificationChannelT + typedef winrt::Windows::Foundation::TypedEventHandler< + winrt::Microsoft::Windows::PushNotifications::PushNotificationChannel, + winrt::Microsoft::Windows::PushNotifications::PushNotificationReceivedEventArgs> PushNotificationEventHandler; + + struct PushNotificationChannel : PushNotificationChannelT { PushNotificationChannel(winrt::Windows::Networking::PushNotifications::PushNotificationChannel const& channel); + winrt::Windows::Foundation::Uri Uri(); winrt::Windows::Foundation::DateTime ExpirationTime(); void Close(); @@ -16,11 +22,21 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation winrt::event_token PushReceived(winrt::Windows::Foundation::TypedEventHandler handler); void PushReceived(winrt::event_token const& token) noexcept; + // IWpnForegroundSink + HRESULT __stdcall InvokeAll(_In_ ULONG length, _In_ byte* payload, _Out_ BOOL* foregroundHandled) noexcept; + private: + bool IsPackagedAppScenario(); + bool IsBackgroundTaskBuilderAvailable(); + const winrt::Windows::Networking::PushNotifications::PushNotificationChannel m_channel{ nullptr }; + winrt::event m_foregroundHandlers; + ULONG m_foregroundHandlerCount = 0; + wil::srwlock m_lock; }; } + namespace winrt::Microsoft::Windows::PushNotifications::factory_implementation { struct PushNotificationChannel : PushNotificationChannelT diff --git a/dev/PushNotifications/PushNotificationDummyDeferral.h b/dev/PushNotifications/PushNotificationDummyDeferral.h new file mode 100644 index 0000000000..35a3e826ba --- /dev/null +++ b/dev/PushNotifications/PushNotificationDummyDeferral.h @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +#pragma once +#include "pch.h" +#include +#include + +struct PushNotificationDummyDeferral : winrt::implements +{ + PushNotificationDummyDeferral() {} + + void Complete() { }; +}; + +struct PushNotificationDummyDeferralFactory : winrt::implements +{ + HRESULT __stdcall CreateInstance(_In_opt_ IUnknown* aggregateInterface, _In_ REFIID interfaceId, _Outptr_ VOID** object) noexcept final + { + RETURN_HR_IF(CLASS_E_NOAGGREGATION, aggregateInterface != nullptr); + return winrt::make().as(interfaceId, object); + } + + HRESULT __stdcall LockServer(BOOL) noexcept final + { + return S_OK; + } +}; diff --git a/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp b/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp index 9db256b051..29e3623f2f 100644 --- a/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp +++ b/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp @@ -11,6 +11,7 @@ #include "Microsoft.Windows.PushNotifications.PushNotificationReceivedEventArgs.g.cpp" #include #include +#include #include "ValueMarshaling.h" namespace winrt @@ -23,49 +24,100 @@ namespace winrt namespace winrt::Microsoft::Windows::PushNotifications::implementation { - PushNotificationReceivedEventArgs::PushNotificationReceivedEventArgs(winrt::IBackgroundTaskInstance const& backgroundTask): m_backgroundTaskInstance(backgroundTask), m_rawNotification(backgroundTask.TriggerDetails().as().ContentBytes()) {} + PushNotificationReceivedEventArgs::PushNotificationReceivedEventArgs(winrt::IBackgroundTaskInstance const& backgroundTask): + m_backgroundTaskInstance(backgroundTask), + m_rawNotificationPayload(BuildPayload(backgroundTask.TriggerDetails().as().ContentBytes())), + m_unpackagedAppScenario(false) {} - PushNotificationReceivedEventArgs::PushNotificationReceivedEventArgs(winrt::PushNotificationReceivedEventArgs const& args): m_args(args), m_rawNotification(args.RawNotification().ContentBytes()) {} + PushNotificationReceivedEventArgs::PushNotificationReceivedEventArgs(winrt::PushNotificationReceivedEventArgs const& args): + m_args(args), + m_rawNotificationPayload(BuildPayload(args.RawNotification().ContentBytes())), + m_unpackagedAppScenario(false) {} + + PushNotificationReceivedEventArgs::PushNotificationReceivedEventArgs(byte* const& payload, ULONG const& length) : + m_rawNotificationPayload(BuildPayload(payload, length)), + m_unpackagedAppScenario(true) {} + + std::vector PushNotificationReceivedEventArgs::BuildPayload(winrt::Windows::Storage::Streams::IBuffer const& buffer) + { + return { buffer.data(), buffer.data() + (buffer.Length() * sizeof(uint8_t)) }; + } + + std::vector PushNotificationReceivedEventArgs::BuildPayload(byte* const& payload, ULONG const& length) + { + return { payload, payload + (length * sizeof(uint8_t)) }; + } winrt::com_array PushNotificationReceivedEventArgs::Payload() { - auto rawNotificationData = m_rawNotification.data(); - return { rawNotificationData, rawNotificationData + (m_rawNotification.Length() * sizeof(uint8_t)) }; + return { m_rawNotificationPayload.data(), m_rawNotificationPayload.data() + (m_rawNotificationPayload.size() * sizeof(uint8_t)) }; } winrt::BackgroundTaskDeferral PushNotificationReceivedEventArgs::GetDeferral() { - THROW_HR_IF_NULL_MSG(E_ILLEGAL_METHOD_CALL, m_backgroundTaskInstance, "Foreground activation cannot call this."); - - return m_backgroundTaskInstance.GetDeferral(); + if (!m_unpackagedAppScenario) + { + THROW_HR_IF_NULL_MSG(E_ILLEGAL_METHOD_CALL, m_backgroundTaskInstance, "Foreground activation cannot call this."); + + return m_backgroundTaskInstance.GetDeferral(); + } + else + { + auto dummyDeferral = winrt::make(); + return dummyDeferral.as(); + } } winrt::event_token PushNotificationReceivedEventArgs::Canceled(winrt::BackgroundTaskCanceledEventHandler const& handler) { - THROW_HR_IF_NULL_MSG(E_ILLEGAL_METHOD_CALL, m_backgroundTaskInstance, "Foreground activation cannot call this."); - - return m_backgroundTaskInstance.Canceled(handler); + if (!m_unpackagedAppScenario) + { + THROW_HR_IF_NULL_MSG(E_ILLEGAL_METHOD_CALL, m_backgroundTaskInstance, "Foreground activation cannot call this."); + + return m_backgroundTaskInstance.Canceled(handler); + } + else + { + return { 0 }; + } } void PushNotificationReceivedEventArgs::Canceled(winrt::event_token const& token) noexcept { - THROW_HR_IF_NULL_MSG(E_ILLEGAL_METHOD_CALL, m_backgroundTaskInstance, "Foreground activation cannot call this."); + if (!m_unpackagedAppScenario) + { + THROW_HR_IF_NULL_MSG(E_ILLEGAL_METHOD_CALL, m_backgroundTaskInstance, "Foreground activation cannot call this."); - m_backgroundTaskInstance.Canceled(token); + m_backgroundTaskInstance.Canceled(token); + } } bool PushNotificationReceivedEventArgs::Handled() { - THROW_HR_IF_NULL_MSG(E_ILLEGAL_METHOD_CALL, m_args, "Background activation cannot call this."); - - return m_args.Cancel(); + if (!m_unpackagedAppScenario) + { + THROW_HR_IF_NULL_MSG(E_ILLEGAL_METHOD_CALL, m_args, "Background activation cannot call this."); + + return m_args.Cancel(); + } + else + { + return m_handledUnpackaged; + } } void PushNotificationReceivedEventArgs::Handled(bool value) { - THROW_HR_IF_NULL_MSG(E_ILLEGAL_METHOD_CALL, m_args, "Background activation cannot call this."); - - m_args.Cancel(value); + if (!m_unpackagedAppScenario) + { + THROW_HR_IF_NULL_MSG(E_ILLEGAL_METHOD_CALL, m_args, "Background activation cannot call this."); + + m_args.Cancel(value); + } + else + { + m_handledUnpackaged = value; + } } } diff --git a/dev/PushNotifications/PushNotificationReceivedEventArgs.h b/dev/PushNotifications/PushNotificationReceivedEventArgs.h index 017b1f2f08..e4ef6761ef 100644 --- a/dev/PushNotifications/PushNotificationReceivedEventArgs.h +++ b/dev/PushNotifications/PushNotificationReceivedEventArgs.h @@ -1,5 +1,6 @@ #pragma once #include "Microsoft.Windows.PushNotifications.PushNotificationReceivedEventArgs.g.h" +#include namespace winrt::Microsoft::Windows::PushNotifications::implementation { @@ -9,6 +10,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation PushNotificationReceivedEventArgs(winrt::Windows::ApplicationModel::Background::IBackgroundTaskInstance const& backgroundTask); PushNotificationReceivedEventArgs(winrt::Windows::Networking::PushNotifications::PushNotificationReceivedEventArgs const& args); + PushNotificationReceivedEventArgs(byte* const& payload, ULONG const& length); com_array Payload(); winrt::Windows::ApplicationModel::Background::BackgroundTaskDeferral GetDeferral(); @@ -18,8 +20,14 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation void Handled(bool value); private: - const winrt::Windows::Storage::Streams::IBuffer m_rawNotification{}; + std::vector BuildPayload(winrt::Windows::Storage::Streams::IBuffer const& buffer); + std::vector BuildPayload(byte* const& payload, ULONG const& length); + + std::vector m_rawNotificationPayload; const winrt::Windows::ApplicationModel::Background::IBackgroundTaskInstance m_backgroundTaskInstance{}; const winrt::Windows::Networking::PushNotifications::PushNotificationReceivedEventArgs m_args = nullptr; + + bool m_unpackagedAppScenario; + bool m_handledUnpackaged = true; }; } diff --git a/dev/PushNotifications/PushNotifications.vcxitems b/dev/PushNotifications/PushNotifications.vcxitems index ae0ad30459..6787c2d61b 100644 --- a/dev/PushNotifications/PushNotifications.vcxitems +++ b/dev/PushNotifications/PushNotifications.vcxitems @@ -1,4 +1,4 @@ - + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) @@ -10,7 +10,7 @@ %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) - + @@ -35,5 +35,6 @@ + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl index 64bc2f82ea..a1320b647c 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl @@ -6,12 +6,27 @@ import "ocidl.idl"; #include "../PushNotifications-Constants.h" +[object] +[uuid(25604D55-9B17-426F-9D67-2B11B3A65598)] +[pointer_default(unique)] +interface IWpnForegroundSink : IUnknown +{ + HRESULT InvokeAll([in] ULONG length, [in, size_is(length)] byte* data, [out] BOOL* foregroundHandled); +}; + [object] [uuid(60FC21B2-B396-4D49-94F0-7555869FB93C)] [pointer_default(unique)] interface INotificationsLongRunningPlatform : IUnknown { HRESULT RegisterFullTrustApplication([in] LPCWSTR processName, [in] GUID remoteId, [out] GUID* appId); + + HRESULT RegisterForegroundActivator([in] IWpnForegroundSink* sink, [in] LPCWSTR processName); + + HRESULT UnregisterForegroundActivator([in] LPCWSTR processName); + + HRESULT SendBackgroundNotification([in] LPCWSTR processName, [in] ULONG length, [in, size_is(length)] byte* data); + }; [uuid(PUSHNOTIFICATIONS_LIBID_UUID)] diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.cpp new file mode 100644 index 0000000000..4849a0735d --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.cpp @@ -0,0 +1,36 @@ +#pragma once + +#include "pch.h" + +#include +#include + +void ForegroundSinkManager::Add(std::wstring const& processName, IWpnForegroundSink* const& sink) +{ + auto lock = m_lock.lock_exclusive(); + m_foregroundMap[processName] = sink; +} + +void ForegroundSinkManager::Remove(std::wstring const& processName) +{ + auto lock = m_lock.lock_exclusive(); + m_foregroundMap.erase(processName); +} + +bool ForegroundSinkManager::InvokeForegroundHandlers(std::wstring const& processName, winrt::com_array const& payload, ULONG const& payloadSize) +{ + auto lock = m_lock.lock_exclusive(); + + auto it = m_foregroundMap.find(processName); + if (it != m_foregroundMap.end()) + { + BOOL foregroundHandled = true; + if (FAILED(it->second->InvokeAll(payloadSize, payload.data(), &foregroundHandled))) + { + Remove(processName); + return false; + } + return foregroundHandled; + } + return false; +} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.h b/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.h new file mode 100644 index 0000000000..19e99bc885 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.h @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +#include +#include +#include +#include + +class ForegroundSinkManager +{ +public: + ForegroundSinkManager() = default; + + void Add(std::wstring const& processName, IWpnForegroundSink* const& sink); + + void Remove(std::wstring const& processName); + + bool InvokeForegroundHandlers(std::wstring const& processName, winrt::com_array const& payload, ULONG const& payloadSize); + +private: + // An app can only have one activate foreground sink with Long Running Process. Event handlers in + // the sink are managed by the WindowsAppSDK. + std::unordered_map> m_foregroundMap = {}; + wil::srwlock m_lock; + +}; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index d4fa8ab079..9f207246b2 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -128,7 +128,7 @@ Windows DebugFull - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -148,7 +148,7 @@ true true DebugFull - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -163,7 +163,7 @@ Windows DebugFull - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -183,7 +183,7 @@ true true DebugFull - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -192,13 +192,13 @@ true _DEBUG;_WINDOWS;%(PreprocessorDefinitions) true - stdcpp17 + stdcpp20 %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows DebugFull - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -210,7 +210,7 @@ NDEBUG;_WINDOWS;%(PreprocessorDefinitions) true Guard - stdcpp17 + stdcpp20 %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL @@ -218,10 +218,11 @@ true true DebugFull - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + @@ -229,6 +230,7 @@ + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters index 7b32be73d3..103525bc94 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters @@ -27,6 +27,9 @@ Header Files + + Header Files + @@ -44,6 +47,9 @@ Source Files + + Source Files + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index a16f0f7c42..34147c2e26 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -55,3 +55,25 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterF return E_NOTIMPL; } +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterForegroundActivator(_In_ IWpnForegroundSink* sink, _In_ PCWSTR processName) +{ + RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + auto lock = m_lock.lock_exclusive(); + + m_foregroundSinkManager.Add(processName, sink); + return S_OK; +} + +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterForegroundActivator(_In_ PCWSTR processName) +{ + RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + auto lock = m_lock.lock_exclusive(); + + m_foregroundSinkManager.Remove(processName); + return S_OK; +} + +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::SendBackgroundNotification(_In_ PCWSTR processName, _In_ ULONG payloadSize, _In_ byte* payload) +{ + return S_OK; +} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 99b353de1b..129a586e8a 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -3,6 +3,7 @@ #include "../PushNotifications-Constants.h" #include "PlatformLifetimeTimerManager.h" +#include "ForegroundSinkManager.h" struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRunningPlatformImpl WrlFinal : Microsoft::WRL::RuntimeClass< @@ -20,16 +21,21 @@ Microsoft::WRL::RuntimeClass< STDMETHOD(RegisterFullTrustApplication)(_In_ PCWSTR processName, _In_ GUID remoteId, _Out_ GUID* appId) noexcept; - /* Add your functions to retrieve the platform components */ + STDMETHOD(RegisterForegroundActivator)(_In_ IWpnForegroundSink* sink, _In_ PCWSTR processName); + + STDMETHOD(UnregisterForegroundActivator)(_In_ PCWSTR processName); -private: + STDMETHOD(SendBackgroundNotification)(_In_ PCWSTR processName, _In_ ULONG payloadSize, _In_ byte* payload); + + /* Add your functions to retrieve the platform components */ + private: wil::srwlock m_lock; bool m_initialized = false; bool m_shutdown = false; - std::unique_ptr m_shutdownTimerManager; - // Here we will define the Platform components i.e. the map wrappings + std::unique_ptr m_shutdownTimerManager; + ForegroundSinkManager m_foregroundSinkManager; }; diff --git a/dev/PushNotifications/externs.h b/dev/PushNotifications/externs.h index 19776f45fb..00edb56363 100644 --- a/dev/PushNotifications/externs.h +++ b/dev/PushNotifications/externs.h @@ -7,3 +7,8 @@ wil::unique_event& GetWaitHandleForArgs(); inline const winrt::hstring ACTIVATED_EVENT_ARGS_KEY = L"GlobalActivatedEventArgs"; + +inline HRESULT GetCurrentProcessPath(wil::unique_cotaskmem_string& processName) +{ + return wil::GetModuleFileNameExW(GetCurrentProcess(), nullptr, processName); +}; diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj index dd5c04c42f..161e7bc430 100644 --- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj +++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj @@ -174,7 +174,7 @@ - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(SolutionDir)appmodel\identity;$(SolutionDir)common + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(SolutionDir)appmodel\identity;$(SolutionDir)common Use Level4 true @@ -193,7 +193,7 @@ - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(SolutionDir)common + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(SolutionDir)common Use Level4 true @@ -212,7 +212,7 @@ - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(SolutionDir)common + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(SolutionDir)common Use Level4 true @@ -231,7 +231,7 @@ - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(SolutionDir)common + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(SolutionDir)common Use Level4 true @@ -250,7 +250,7 @@ - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(SolutionDir)common + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(SolutionDir)common Use Level4 true @@ -273,7 +273,7 @@ - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(SolutionDir)common + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(SolutionDir)common Use Level4 true @@ -296,7 +296,7 @@ - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(SolutionDir)common + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(SolutionDir)common Use Level4 true @@ -319,7 +319,7 @@ - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(SolutionDir)common + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\DynamicDependency.DataStore.ProxyStub;$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(SolutionDir)common Use Level4 true diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml index 5794d7b2ff..789ada48b2 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/appxmanifest.xml @@ -56,6 +56,12 @@ + + + + + + RequestChan auto channelExpiry = result.Channel().ExpirationTime(); // Register Push Event for Foreground - result.Channel().PushReceived([](const auto&, PushNotificationReceivedEventArgs const& args) + winrt::event_token token = result.Channel().PushReceived([](const auto&, PushNotificationReceivedEventArgs const& args) { auto payload = args.Payload(); From 309f885faccacc7a12aed767b6c9b6b9c3e1f3a3 Mon Sep 17 00:00:00 2001 From: Eric Langlois Date: Wed, 1 Sep 2021 06:29:41 -0700 Subject: [PATCH 20/50] Not everything should be renamed Runtime --- .../Makefile.mak | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak index d55cfabe5d..e38f77f8b7 100644 --- a/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak +++ b/test/PushNotifications/PushNotificationsLongRunningTask.Msix/Makefile.mak @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See LICENSE in the project root for license information. -#!include +#!include MAKEAPPX_OPTS= !IFDEF VERBOSE @@ -14,11 +14,11 @@ SIGNTOOL_OPTS=/v !ENDIF !IFDEF VERBOSE -!MESSAGE SolutionDir =$(SolutionDir) -!MESSAGE ProjectDir =$(ProjectDir) -!MESSAGE OutDir =$(OutDir) -!MESSAGE TargetName =$(TargetName) -!MESSAGE WindowsAppRuntimeBuildPipeline =$(WindowsAppRuntimeBuildPipeline) +!MESSAGE SolutionDir =$(SolutionDir) +!MESSAGE ProjectDir =$(ProjectDir) +!MESSAGE OutDir =$(OutDir) +!MESSAGE TargetName =$(TargetName) +!MESSAGE WindowsAppSDKBuildPipeline =$(WindowsAppSDKBuildPipeline) !ENDIF TARGET_BASENAME=PushNotificationsLongRunningTask From 8185b1e1ec670df383acd1b47105a4be2d450511 Mon Sep 17 00:00:00 2001 From: eric langlois Date: Wed, 1 Sep 2021 12:21:03 -0700 Subject: [PATCH 21/50] Ensuring the LRP msix gets built after the framework (#1356) Co-authored-by: Eric Langlois --- WindowsAppRuntime.sln | 55 +++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 6f4f0b93f5..8d2f728dca 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -166,6 +166,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PushNotifications", "PushNotifications", "{A1B25DCF-6A54-414D-8E24-F4D24EE9299D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PushNotificationsLongRunningTask.Msix", "test\PushNotifications\PushNotificationsLongRunningTask.Msix\PushNotificationsLongRunningTask.Msix.vcxproj", "{C422B090-F501-4204-8068-1084B0799405}" + ProjectSection(ProjectDependencies) = postProject + {9C1A6C58-52D6-4514-9120-5C339C5DF4BE} = {9C1A6C58-52D6-4514-9120-5C339C5DF4BE} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PushNotificationsLongRunningTask.ProxyStub", "dev\PushNotifications\PushNotificationsLongRunningTask.ProxyStub\PushNotificationsLongRunningTask.ProxyStub.vcxproj", "{BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}" EndProject @@ -636,6 +639,30 @@ Global {C422B090-F501-4204-8068-1084B0799405}.Release|x64.Build.0 = Release|x64 {C422B090-F501-4204-8068-1084B0799405}.Release|x86.ActiveCfg = Release|Win32 {C422B090-F501-4204-8068-1084B0799405}.Release|x86.Build.0 = Release|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|ARM64.ActiveCfg = Debug|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x64.ActiveCfg = Debug|x64 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x64.Build.0 = Debug|x64 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x86.ActiveCfg = Debug|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x86.Build.0 = Debug|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|Any CPU.ActiveCfg = Release|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|ARM64.ActiveCfg = Release|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x64.ActiveCfg = Release|x64 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x64.Build.0 = Release|x64 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x86.ActiveCfg = Release|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x86.Build.0 = Release|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|ARM64.ActiveCfg = Debug|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x64.ActiveCfg = Debug|x64 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x64.Build.0 = Debug|x64 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x86.ActiveCfg = Debug|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x86.Build.0 = Debug|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|Any CPU.ActiveCfg = Release|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|ARM64.ActiveCfg = Release|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x64.ActiveCfg = Release|x64 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x64.Build.0 = Release|x64 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x86.ActiveCfg = Release|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x86.Build.0 = Release|Win32 {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|Any CPU.ActiveCfg = Debug|Win32 {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|ARM64.ActiveCfg = Debug|Win32 {CBD95746-61CE-4F31-B6CC-C5ABF1766180}.Debug|x64.ActiveCfg = Debug|x64 @@ -688,30 +715,6 @@ Global {8F2C21F1-47AB-428C-A110-EE33FD7D9493}.Release|x64.Build.0 = Release|x64 {8F2C21F1-47AB-428C-A110-EE33FD7D9493}.Release|x86.ActiveCfg = Release|Win32 {8F2C21F1-47AB-428C-A110-EE33FD7D9493}.Release|x86.Build.0 = Release|Win32 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|ARM64.ActiveCfg = Debug|Win32 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x64.ActiveCfg = Debug|x64 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x64.Build.0 = Debug|x64 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x86.ActiveCfg = Debug|Win32 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x86.Build.0 = Debug|Win32 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|Any CPU.ActiveCfg = Release|Win32 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|ARM64.ActiveCfg = Release|Win32 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x64.ActiveCfg = Release|x64 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x64.Build.0 = Release|x64 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x86.ActiveCfg = Release|Win32 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x86.Build.0 = Release|Win32 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|ARM64.ActiveCfg = Debug|Win32 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x64.ActiveCfg = Debug|x64 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x64.Build.0 = Debug|x64 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x86.ActiveCfg = Debug|Win32 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x86.Build.0 = Debug|Win32 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|Any CPU.ActiveCfg = Release|Win32 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|ARM64.ActiveCfg = Release|Win32 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x64.ActiveCfg = Release|x64 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x64.Build.0 = Release|x64 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x86.ActiveCfg = Release|Win32 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x86.Build.0 = Release|Win32 {2CD5CD9B-CF45-4FA7-9769-EE4E02426BF0}.Debug|Any CPU.ActiveCfg = Debug|Win32 {2CD5CD9B-CF45-4FA7-9769-EE4E02426BF0}.Debug|ARM64.ActiveCfg = Debug|Win32 {2CD5CD9B-CF45-4FA7-9769-EE4E02426BF0}.Debug|x64.ActiveCfg = Debug|x64 @@ -818,6 +821,8 @@ Global {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0} = {91D03B95-1B0C-4BEB-8441-30DA7D615538} {A1B25DCF-6A54-414D-8E24-F4D24EE9299D} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} {C422B090-F501-4204-8068-1084B0799405} = {A1B25DCF-6A54-414D-8E24-F4D24EE9299D} + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0} = {91D03B95-1B0C-4BEB-8441-30DA7D615538} + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42} = {91D03B95-1B0C-4BEB-8441-30DA7D615538} {E9117D76-63AC-4289-A628-AB39EF6E5D19} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A} {B75C1B22-553C-40E4-B38E-6AB4D01FDB9D} = {E9117D76-63AC-4289-A628-AB39EF6E5D19} {CBD95746-61CE-4F31-B6CC-C5ABF1766180} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} @@ -828,8 +833,6 @@ Global {8F2C21F1-47AB-428C-A110-EE33FD7D9493} = {0C534F12-B076-47E5-A05B-2A711233AC6F} {92801D0D-B76F-4EAA-914F-31F54241536F} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A} {2F3FAD1B-D3DF-4866-A3A3-C2C777D55638} = {92801D0D-B76F-4EAA-914F-31F54241536F} - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0} = {91D03B95-1B0C-4BEB-8441-30DA7D615538} - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42} = {91D03B95-1B0C-4BEB-8441-30DA7D615538} {034E840E-2165-4167-B560-50AF6B4A52DC} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A} {E15C3465-9D45-495D-92CE-B91EF45E8623} = {034E840E-2165-4167-B560-50AF6B4A52DC} {2CD5CD9B-CF45-4FA7-9769-EE4E02426BF0} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} From cfe344a98c4d49ae6d99fcd8acb7beb9e73e76af Mon Sep 17 00:00:00 2001 From: Eric Langlois Date: Wed, 1 Sep 2021 13:24:59 -0700 Subject: [PATCH 22/50] Bringing build management settings for release/arm64 in line with debug/arm64 --- WindowsAppRuntime.sln | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 8d2f728dca..e6f4e1117e 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -621,8 +621,8 @@ Global {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Debug|x86.ActiveCfg = Debug|Win32 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Debug|x86.Build.0 = Debug|Win32 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|Any CPU.ActiveCfg = Release|Win32 - {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|ARM64.ActiveCfg = Release|ARM64 - {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|ARM64.Build.0 = Release|ARM64 + {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|ARM64.ActiveCfg = Release|Win32 + {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|ARM64.Build.0 = Release|Win32 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|x64.ActiveCfg = Release|x64 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|x64.Build.0 = Release|x64 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|x86.ActiveCfg = Release|Win32 From 3a222ffb50b8a36d9e1083d4acb08e81fbb4a578 Mon Sep 17 00:00:00 2001 From: Eric Langlois Date: Wed, 1 Sep 2021 14:22:41 -0700 Subject: [PATCH 23/50] Fixing arm64 build --- WindowsAppRuntime.sln | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index e6f4e1117e..694ff50ca1 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -614,15 +614,15 @@ Global {0A5FEE93-48B7-40EC-BB9A-B27D11060DA9}.Release|x86.ActiveCfg = Release|Win32 {0A5FEE93-48B7-40EC-BB9A-B27D11060DA9}.Release|x86.Build.0 = Release|Win32 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Debug|ARM64.ActiveCfg = Debug|Win32 - {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Debug|ARM64.Build.0 = Debug|Win32 + {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Debug|ARM64.Build.0 = Debug|ARM64 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Debug|x64.ActiveCfg = Debug|x64 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Debug|x64.Build.0 = Debug|x64 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Debug|x86.ActiveCfg = Debug|Win32 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Debug|x86.Build.0 = Debug|Win32 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|Any CPU.ActiveCfg = Release|Win32 - {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|ARM64.ActiveCfg = Release|Win32 - {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|ARM64.Build.0 = Release|Win32 + {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|ARM64.ActiveCfg = Release|ARM64 + {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|ARM64.Build.0 = Release|ARM64 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|x64.ActiveCfg = Release|x64 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|x64.Build.0 = Release|x64 {1307DD1B-BBE8-4CD0-B1A0-0DB6D61EEAA0}.Release|x86.ActiveCfg = Release|Win32 @@ -640,25 +640,29 @@ Global {C422B090-F501-4204-8068-1084B0799405}.Release|x86.ActiveCfg = Release|Win32 {C422B090-F501-4204-8068-1084B0799405}.Release|x86.Build.0 = Release|Win32 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|ARM64.ActiveCfg = Debug|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|ARM64.Build.0 = Debug|ARM64 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x64.ActiveCfg = Debug|x64 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x64.Build.0 = Debug|x64 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x86.ActiveCfg = Debug|Win32 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Debug|x86.Build.0 = Debug|Win32 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|Any CPU.ActiveCfg = Release|Win32 - {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|ARM64.ActiveCfg = Release|Win32 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|ARM64.ActiveCfg = Release|ARM64 + {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|ARM64.Build.0 = Release|ARM64 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x64.ActiveCfg = Release|x64 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x64.Build.0 = Release|x64 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x86.ActiveCfg = Release|Win32 {BF3FCED0-CADB-490A-93A7-4D90E1F45AB0}.Release|x86.Build.0 = Release|Win32 {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|ARM64.ActiveCfg = Debug|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|ARM64.Build.0 = Debug|ARM64 {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x64.ActiveCfg = Debug|x64 {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x64.Build.0 = Debug|x64 {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x86.ActiveCfg = Debug|Win32 {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Debug|x86.Build.0 = Debug|Win32 {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|Any CPU.ActiveCfg = Release|Win32 - {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|ARM64.ActiveCfg = Release|Win32 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|ARM64.ActiveCfg = Release|ARM64 + {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|ARM64.Build.0 = Release|ARM64 {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x64.ActiveCfg = Release|x64 {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x64.Build.0 = Release|x64 {1DEBBFF6-EE6E-4944-9DE2-35B7A686AF42}.Release|x86.ActiveCfg = Release|Win32 From c9ef4978444f90bf956878a99ddea4b3a1879cc2 Mon Sep 17 00:00:00 2001 From: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> Date: Wed, 1 Sep 2021 19:59:26 -0700 Subject: [PATCH 24/50] Addressed comments --- .../NotificationsLongRunningProcess.idl | 3 --- .../winmain.cpp | 12 +++++++---- ...anager.cpp => PlatformLifetimeManager.cpp} | 20 ++++++++---------- ...merManager.h => PlatformLifetimeManager.h} | 6 ++++-- .../PushNotificationsLongRunningTask.vcxproj | 4 ++-- ...tificationsLongRunningTask.vcxproj.filters | 8 +++---- .../PushNotificationsLongRunningTask/pch.h | 2 +- .../platform.cpp | 21 +++++++------------ .../platform.h | 13 +++++------- .../winmain.cpp | 2 +- 10 files changed, 41 insertions(+), 50 deletions(-) rename dev/PushNotifications/PushNotificationsLongRunningTask/{PlatformLifetimeTimerManager.cpp => PlatformLifetimeManager.cpp} (56%) rename dev/PushNotifications/PushNotificationsLongRunningTask/{PlatformLifetimeTimerManager.h => PlatformLifetimeManager.h} (71%) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl index a1320b647c..b7f248875d 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl @@ -24,9 +24,6 @@ interface INotificationsLongRunningPlatform : IUnknown HRESULT RegisterForegroundActivator([in] IWpnForegroundSink* sink, [in] LPCWSTR processName); HRESULT UnregisterForegroundActivator([in] LPCWSTR processName); - - HRESULT SendBackgroundNotification([in] LPCWSTR processName, [in] ULONG length, [in, size_is(length)] byte* data); - }; [uuid(PUSHNOTIFICATIONS_LIBID_UUID)] diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp index 3e1c6ba159..fb160e78ed 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/winmain.cpp @@ -23,22 +23,26 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* [&]() { CoUninitialize(); }); unsigned int retries = 0; - bool isRpcRetriableError = true; HRESULT hr = S_OK; - while (retries < 3 && isRpcRetriableError) + while (retries < 3) { try { wil::com_ptr longRunningProcessPlatform { wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; - isRpcRetriableError = false; + break; } catch (...) { hr = wil::ResultFromCaughtException(); - isRpcRetriableError = isRetriableRpcError(hr); + + if (!isRetriableRpcError(hr)) + { + break; + } + retries++; } } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeManager.cpp similarity index 56% rename from dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.cpp rename to dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeManager.cpp index 5a73909181..d732e1f14b 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeManager.cpp @@ -1,20 +1,16 @@ #include "pch.h" -#include "PlatformLifetimeTimerManager.h" +#include "PlatformLifetimeManager.h" -void PlatformLifetimeTimerManager::Setup() +void PlatformLifetimeManager::Setup() { auto lock = m_lock.lock_exclusive(); m_timer.reset(CreateThreadpoolTimer( [](PTP_CALLBACK_INSTANCE, _Inout_ PVOID shutdownTimerManagerPtr, _Inout_ PTP_TIMER) { - PlatformLifetimeTimerManager* shutdownTimerManager = reinterpret_cast(shutdownTimerManagerPtr); - - if (shutdownTimerManager != nullptr) - { - shutdownTimerManager->SignalWinMainEvent(); - } + PlatformLifetimeManager* shutdownTimerManager = reinterpret_cast(shutdownTimerManagerPtr); + shutdownTimerManager->SignalEvent(); }, this, nullptr)); @@ -26,20 +22,22 @@ void PlatformLifetimeTimerManager::Setup() *reinterpret_cast(&dueTime) = -static_cast(5000 * 10000); SetThreadpoolTimer(m_timer.get(), &dueTime, 0, 0); + + m_event.ResetEvent(); } -void PlatformLifetimeTimerManager::Cancel() +void PlatformLifetimeManager::Cancel() { auto lock = m_lock.lock_exclusive(); m_timer.reset(); } -void PlatformLifetimeTimerManager::Wait() +void PlatformLifetimeManager::Wait() { m_event.wait(); } -void PlatformLifetimeTimerManager::SignalWinMainEvent() +void PlatformLifetimeManager::SignalEvent() { m_event.SetEvent(); } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.h b/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeManager.h similarity index 71% rename from dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.h rename to dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeManager.h index 5e0d21c388..705fb9ce3b 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeTimerManager.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PlatformLifetimeManager.h @@ -1,16 +1,18 @@ #pragma once -class PlatformLifetimeTimerManager +class PlatformLifetimeManager { public: + PlatformLifetimeManager() {}; + void Setup(); void Cancel(); void Wait(); - void SignalWinMainEvent(); + void SignalEvent(); private: diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index 9f207246b2..29f9ac4815 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -226,7 +226,7 @@ - + @@ -234,7 +234,7 @@ - + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters index 103525bc94..c8a1d35214 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters @@ -24,10 +24,10 @@ Header Files - + Header Files - + Header Files @@ -44,10 +44,10 @@ Source Files - + Source Files - + Source Files diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h index 8586e30347..608cadf8cf 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h @@ -25,4 +25,4 @@ #include -#include +#include \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index 34147c2e26..66d104f5ed 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -15,10 +15,9 @@ void NotificationsLongRunningPlatformImpl::Initialize() return; } - // Schedule event signaling after 5 seconds. This is in case we don't have any apps to track in the LRP. - // If we realize that we need to persist the LRP, timer should be canceled. - m_shutdownTimerManager = std::make_unique(); - m_shutdownTimerManager->Setup(); + // Schedule event signaling after 5 seconds. + // This is in case we later realize there are no apps to be tracked in the LRP. + m_lifetimeManager.Setup(); /* TODO: Verify registry and UDK list and make sure we have apps to be tracked */ @@ -40,10 +39,9 @@ void NotificationsLongRunningPlatformImpl::Shutdown() noexcept m_shutdown = true; } -void NotificationsLongRunningPlatformImpl::WaitForWinMainEvent() +void NotificationsLongRunningPlatformImpl::WaitForLifetimeEvent() { - THROW_HR_IF_NULL(E_UNEXPECTED, m_shutdownTimerManager.get()); - m_shutdownTimerManager->Wait(); + m_lifetimeManager.Wait(); } // Example of one function. We will add more as we need them. @@ -57,8 +55,8 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterF STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterForegroundActivator(_In_ IWpnForegroundSink* sink, _In_ PCWSTR processName) { - RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); auto lock = m_lock.lock_exclusive(); + RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); m_foregroundSinkManager.Add(processName, sink); return S_OK; @@ -66,14 +64,9 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterF STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterForegroundActivator(_In_ PCWSTR processName) { - RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); auto lock = m_lock.lock_exclusive(); + RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); m_foregroundSinkManager.Remove(processName); return S_OK; } - -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::SendBackgroundNotification(_In_ PCWSTR processName, _In_ ULONG payloadSize, _In_ byte* payload) -{ - return S_OK; -} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 129a586e8a..55d4fa0bec 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -2,7 +2,7 @@ #include "../PushNotifications-Constants.h" -#include "PlatformLifetimeTimerManager.h" +#include "PlatformLifetimeManager.h" #include "ForegroundSinkManager.h" struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRunningPlatformImpl WrlFinal : @@ -15,9 +15,9 @@ Microsoft::WRL::RuntimeClass< void Shutdown() noexcept; - void WaitForWinMainEvent(); + void WaitForLifetimeEvent(); - /* IWpnLrpPlatform functions */ + /* INotificationsLongRunningPlatform functions */ STDMETHOD(RegisterFullTrustApplication)(_In_ PCWSTR processName, _In_ GUID remoteId, _Out_ GUID* appId) noexcept; @@ -25,10 +25,7 @@ Microsoft::WRL::RuntimeClass< STDMETHOD(UnregisterForegroundActivator)(_In_ PCWSTR processName); - STDMETHOD(SendBackgroundNotification)(_In_ PCWSTR processName, _In_ ULONG payloadSize, _In_ byte* payload); - - /* Add your functions to retrieve the platform components */ - private: +private: wil::srwlock m_lock; @@ -36,6 +33,6 @@ Microsoft::WRL::RuntimeClass< bool m_shutdown = false; // Here we will define the Platform components i.e. the map wrappings - std::unique_ptr m_shutdownTimerManager; + PlatformLifetimeManager m_lifetimeManager{}; ForegroundSinkManager m_foregroundSinkManager; }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index bf1d4fcd20..00201be33e 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -46,7 +46,7 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* // Wait returns if the platform realizes there are no more apps to be tracked. // It also returns if the timer initialized at the process start fires (see NotificationsLongRunningPlatformImpl::Initialize). - platform->WaitForWinMainEvent(); + platform->WaitForLifetimeEvent(); RETURN_IF_FAILED(module.UnregisterCOMObject(nullptr, &cookie, 1)); From 55614f3b3092900c0520e8bda59afa56f77cfa0c Mon Sep 17 00:00:00 2001 From: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> Date: Wed, 1 Sep 2021 20:25:00 -0700 Subject: [PATCH 25/50] Using winrt constructs on NotificationsLongRunningPlatformImpl :) --- .../PushNotificationsLongRunningTask/platform.h | 7 ++----- .../PushNotificationsLongRunningTask/platformfactory.cpp | 4 ++-- .../PushNotificationsLongRunningTask/platformfactory.h | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 55d4fa0bec..57e951cf52 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -5,11 +5,8 @@ #include "PlatformLifetimeManager.h" #include "ForegroundSinkManager.h" -struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRunningPlatformImpl WrlFinal : -Microsoft::WRL::RuntimeClass< - Microsoft::WRL::RuntimeClassFlags, - INotificationsLongRunningPlatform, - Microsoft::WRL::FtmBase> +struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRunningPlatformImpl: + winrt::implements { void Initialize(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp index aaef26df24..dcc742b5b6 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp @@ -11,7 +11,7 @@ using namespace Microsoft::WRL; HRESULT NotificationsLongRunningProcessFactory::RuntimeClassInitialize() noexcept try { - m_platform = Microsoft::WRL::Make(); + m_platform = winrt::make_self(); m_platform->Initialize(); return S_OK; @@ -23,7 +23,7 @@ IFACEMETHODIMP NotificationsLongRunningProcessFactory::CreateInstance( _In_ REFIID /*riid*/, _COM_Outptr_ void** obj) { - *obj = m_platform.Get(); + *obj = m_platform.get(); // Add one ref per platform instance request. Deref occurs automatically. m_platform->AddRef(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h index 52a9935c97..03512d8174 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.h @@ -10,5 +10,5 @@ struct NotificationsLongRunningProcessFactory WrlFinal : public Microsoft::WRL:: _COM_Outptr_ void** ppvObject) override; private: - Microsoft::WRL::ComPtr m_platform; + winrt::com_ptr m_platform; }; From 56234840feabda150abc0aff5ca2212c20ad8286 Mon Sep 17 00:00:00 2001 From: Sharath Manchala <10109130+sharath2727@users.noreply.github.com> Date: Thu, 2 Sep 2021 16:58:03 -0700 Subject: [PATCH 26/50] Channel Request for unpackaged applications (#1290) * Channel requests for Packaged and Unpackaged applications * Fix comments * Update windowsappsdk_dll to locate PushNotificationsLongRunningTask.ProxyStub headers * Address minor comments * Fix channel.Close API to handle channels when requested through frameworkudk * Address comments and introduce GetAppIdentifier in LRP * Addressing nits * Fixing a few more nits * Update externs.h * Store pair in windows storage localsettings * Fix minor nits * Remove helpers.h references from PushNotificationsDemoApp * Remove unused APIs * Using WIL type for CoInitializeEx instead of working too hard Co-authored-by: Eric Langlois Co-authored-by: Paul Purifoy Co-authored-by: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> --- .../PushNotificationChannel.cpp | 30 ++++- .../PushNotificationChannel.h | 14 +- .../PushNotificationManager.cpp | 121 +++++++++++++++--- .../PushNotificationManager.h | 5 +- .../PushNotificationReceivedEventArgs.h | 1 + dev/PushNotifications/PushNotifications.idl | 2 - .../NotificationsLongRunningProcess.idl | 3 +- .../PushNotificationsLongRunningTask/pch.h | 4 +- .../platform.cpp | 47 ++++++- .../platform.h | 7 +- dev/PushNotifications/externs.h | 9 ++ dev/WindowsAppRuntime_DLL/pch.h | 2 + .../PushNotificationsDemoApp.vcxproj | 2 +- .../Package.appxmanifest | 2 +- .../PushNotificationsDemoPackage.wapproj | 6 +- 15 files changed, 202 insertions(+), 53 deletions(-) diff --git a/dev/PushNotifications/PushNotificationChannel.cpp b/dev/PushNotifications/PushNotificationChannel.cpp index 829f942621..698527f155 100644 --- a/dev/PushNotifications/PushNotificationChannel.cpp +++ b/dev/PushNotifications/PushNotificationChannel.cpp @@ -8,6 +8,7 @@ #include #include #include "PushNotificationReceivedEventArgs.h" +#include #include "externs.h" #include "PushNotificationTelemetry.h" @@ -25,23 +26,42 @@ namespace winrt::Microsoft namespace winrt::Microsoft::Windows::PushNotifications::implementation { - PushNotificationChannel::PushNotificationChannel(winrt::Windows::PushNotificationChannel const& channel): m_channel(channel) {} - winrt::Windows::Uri PushNotificationChannel::Uri() { - return winrt::Windows::Uri{ m_channel.Uri() }; + if (m_channel) + { + return winrt::Windows::Uri{ m_channel.Uri() }; + } + else + { + return winrt::Windows::Uri{ m_channelInfo.channelUri }; + } } winrt::Windows::DateTime PushNotificationChannel::ExpirationTime() { - return m_channel.ExpirationTime(); + if (m_channel) + { + return m_channel.ExpirationTime(); + } + else + { + return m_channelInfo.channelExpiryTime; + } } void PushNotificationChannel::Close() { try { - m_channel.Close(); + if (m_channel) + { + m_channel.Close(); + } + else + { + PushNotifications_CloseChannel(m_channelInfo.appUserModelId.c_str(), m_channelInfo.channelId.c_str()); + } PushNotificationTelemetry::ChannelClosedByApi(S_OK); } diff --git a/dev/PushNotifications/PushNotificationChannel.h b/dev/PushNotifications/PushNotificationChannel.h index d3764fb823..a12405f3e1 100644 --- a/dev/PushNotifications/PushNotificationChannel.h +++ b/dev/PushNotifications/PushNotificationChannel.h @@ -4,6 +4,8 @@ #pragma once #include "Microsoft.Windows.PushNotifications.PushNotificationChannel.g.h" #include +#include "winrt/Windows.Networking.PushNotifications.h" +#include "externs.h" namespace winrt::Microsoft::Windows::PushNotifications::implementation { @@ -13,7 +15,9 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation struct PushNotificationChannel : PushNotificationChannelT { - PushNotificationChannel(winrt::Windows::Networking::PushNotifications::PushNotificationChannel const& channel); + PushNotificationChannel(winrt::Windows::Networking::PushNotifications::PushNotificationChannel const& channel) : m_channel(channel) {}; + + PushNotificationChannel(struct ChannelDetails const& channelInfo) : m_channelInfo(channelInfo) {}; winrt::Windows::Foundation::Uri Uri(); winrt::Windows::Foundation::DateTime ExpirationTime(); @@ -30,16 +34,10 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation bool IsBackgroundTaskBuilderAvailable(); const winrt::Windows::Networking::PushNotifications::PushNotificationChannel m_channel{ nullptr }; + const struct ChannelDetails m_channelInfo{}; winrt::event m_foregroundHandlers; ULONG m_foregroundHandlerCount = 0; wil::srwlock m_lock; }; } - -namespace winrt::Microsoft::Windows::PushNotifications::factory_implementation -{ - struct PushNotificationChannel : PushNotificationChannelT - { - }; -} diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index a35d2023f0..91c94c0746 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -17,6 +17,8 @@ #include "PushNotificationChannel.h" #include "externs.h" #include +#include +#include "NotificationsLongRunningProcess_h.h" #include "PushNotificationTelemetry.h" using namespace std::literals; @@ -47,7 +49,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation const HRESULT WNP_E_RECONNECTING = static_cast(0x880403E9L); const HRESULT WNP_E_BIND_USER_BUSY = static_cast(0x880403FEL); - bool PushNotificationManager::IsChannelRequestRetryable(const hresult& hr) + bool IsChannelRequestRetryable(const hresult& hr) { switch (hr) { @@ -63,16 +65,60 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation } } + void RegisterUnpackagedApplicationHelper( + const winrt::guid& remoteId, + _Out_ wil::unique_cotaskmem_string &unpackagedAppUserModelId) + { + auto coInitialize = wil::CoInitializeEx(); + + auto notificationPlatform{ wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + + wil::unique_cotaskmem_string processName; + THROW_IF_FAILED(GetCurrentProcessPath(processName)); + + THROW_IF_FAILED(notificationPlatform->RegisterFullTrustApplication(processName.get(), remoteId, &unpackagedAppUserModelId)); + } + + winrt::hresult CreateChannelWithRemoteIdHelper(const winrt::guid& remoteId, ChannelDetails& channelInfo) noexcept try + { + wchar_t appUserModelId[APPLICATION_USER_MODEL_ID_MAX_LENGTH] = {}; + UINT32 appUserModelIdSize{ ARRAYSIZE(appUserModelId) }; + + THROW_IF_FAILED(GetCurrentApplicationUserModelId(&appUserModelIdSize, appUserModelId)); + + THROW_HR_IF(E_INVALIDARG, (appUserModelIdSize > APPLICATION_USER_MODEL_ID_MAX_LENGTH) || (appUserModelIdSize == 0)); + + HRESULT operationalCode{}; + ABI::Windows::Foundation::DateTime channelExpiryTime{}; + wil::unique_cotaskmem_string channelId; + wil::unique_cotaskmem_string channelUri; + + THROW_IF_FAILED(PushNotifications_CreateChannelWithRemoteIdentifier( + appUserModelId, + remoteId, + &operationalCode, + &channelId, + &channelUri, + &channelExpiryTime)); + + THROW_IF_FAILED(operationalCode); + + winrt::copy_from_abi(channelInfo.channelExpiryTime, &channelExpiryTime); + channelInfo.appUserModelId = winrt::hstring{ appUserModelId }; + channelInfo.channelId = winrt::hstring{ channelId.get() }; + channelInfo.channelUri = winrt::hstring{ channelUri.get() }; + + return S_OK; + } + CATCH_RETURN() + winrt::IAsyncOperationWithProgress PushNotificationManager::CreateChannelAsync(const winrt::guid &remoteId) { try { THROW_HR_IF(E_INVALIDARG, (remoteId == winrt::guid())); - // API supports channel requests only for packaged applications for v0.8 version - THROW_HR_IF(E_NOTIMPL, !AppModel::Identity::IsPackagedProcess()); - - auto cancellation{ co_await winrt::get_cancellation_token() }; + auto cancellation{ co_await winrt::get_cancellation_token() }; cancellation.enable_propagation(true); @@ -94,20 +140,60 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { try { - PushNotificationChannelManager channelManager{}; - winrt::PushNotificationChannel pushChannelReceived{ nullptr }; + if (IsActivatorSupported(PushNotificationRegistrationOptions::PushTrigger)) + { + ChannelDetails channelInfo{}; + winrt::hresult hr = CreateChannelWithRemoteIdHelper(remoteId, channelInfo); + + /* + RemoteId APIs are not applicable for downlevel OS versions. + So we get error E_NOTIMPL and we fallback to calling into + Public WinRT API CreatePushNotificationChannelForApplicationAsync + to request for channels + */ - pushChannelReceived = co_await channelManager.CreatePushNotificationChannelForApplicationAsync(); + if (SUCCEEDED(hr)) + { + co_return winrt::make( + winrt::make(channelInfo), + S_OK, + PushNotificationChannelStatus::CompletedSuccess); + } + else if (hr == E_NOTIMPL) + { + PushNotificationChannelManager channelManager{}; + winrt::PushNotificationChannel pushChannelReceived{ nullptr }; - PushNotificationTelemetry::ChannelRequestedByApi( - S_OK, - AppModel::Identity::IsPackagedProcess(), - remoteId); + pushChannelReceived = co_await channelManager.CreatePushNotificationChannelForApplicationAsync(); - co_return winrt::make( - winrt::make(pushChannelReceived), - S_OK, - PushNotificationChannelStatus::CompletedSuccess); + PushNotificationTelemetry::ChannelRequestedByApi( + S_OK, + AppModel::Identity::IsPackagedProcess(), + remoteId); + + co_return winrt::make( + winrt::make(pushChannelReceived), + S_OK, + PushNotificationChannelStatus::CompletedSuccess); + } + else + { + winrt::check_hresult(hr); + } + } + else + { + wil::unique_cotaskmem_string unpackagedAppUserModelId; + RegisterUnpackagedApplicationHelper(remoteId, unpackagedAppUserModelId); + + PushNotificationChannelManager channelManager{}; + winrt::PushNotificationChannel pushChannelReceived{ co_await channelManager.CreatePushNotificationChannelForApplicationAsync(unpackagedAppUserModelId.get()) }; + + co_return winrt::make( + winrt::make(pushChannelReceived), + S_OK, + PushNotificationChannelStatus::CompletedSuccess); + } } catch (...) { @@ -138,7 +224,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation co_await winrt::resume_after(backOffTime); } } - catch (...) { HRESULT hrError = wil::ResultFromCaughtException(); @@ -301,7 +386,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation return Metadata::ApiInformation::IsMethodPresent(L"Windows.ApplicationModel.Background.BackgroundTaskBuilder", L"SetTaskEntryPointClsid"); } - bool PushNotificationManager::IsBackgroundTaskBuilderAvailable() + bool IsBackgroundTaskBuilderAvailable() { static bool hasSetTaskEntrypoint = HasBackgroundTaskEntryPointClsid(); return hasSetTaskEntrypoint; diff --git a/dev/PushNotifications/PushNotificationManager.h b/dev/PushNotifications/PushNotificationManager.h index 952820a80a..bf68cebb19 100644 --- a/dev/PushNotifications/PushNotificationManager.h +++ b/dev/PushNotifications/PushNotificationManager.h @@ -3,6 +3,7 @@ #pragma once #include "Microsoft.Windows.PushNotifications.PushNotificationManager.g.h" +#include namespace winrt::Microsoft::Windows::PushNotifications::implementation { @@ -16,10 +17,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation static winrt::Windows::Foundation::IAsyncOperationWithProgress CreateChannelAsync(const winrt::guid &remoteId); static bool IsActivatorSupported(Microsoft::Windows::PushNotifications::PushNotificationRegistrationOptions const& options); - - private: - static bool IsChannelRequestRetryable(const winrt::hresult& hrException); - static bool IsBackgroundTaskBuilderAvailable(); }; } namespace winrt::Microsoft::Windows::PushNotifications::factory_implementation diff --git a/dev/PushNotifications/PushNotificationReceivedEventArgs.h b/dev/PushNotifications/PushNotificationReceivedEventArgs.h index e4ef6761ef..11ebb40fa8 100644 --- a/dev/PushNotifications/PushNotificationReceivedEventArgs.h +++ b/dev/PushNotifications/PushNotificationReceivedEventArgs.h @@ -1,6 +1,7 @@ #pragma once #include "Microsoft.Windows.PushNotifications.PushNotificationReceivedEventArgs.g.h" #include +#include namespace winrt::Microsoft::Windows::PushNotifications::implementation { diff --git a/dev/PushNotifications/PushNotifications.idl b/dev/PushNotifications/PushNotifications.idl index 8e9ec648b8..41f6df530b 100644 --- a/dev/PushNotifications/PushNotifications.idl +++ b/dev/PushNotifications/PushNotifications.idl @@ -74,8 +74,6 @@ namespace Microsoft.Windows.PushNotifications [experimental] runtimeclass PushNotificationChannel { - PushNotificationChannel(Windows.Networking.PushNotifications.PushNotificationChannel channel); - // The Channel Uri for app to Post a notification to. Windows.Foundation.Uri Uri { get; }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl index b7f248875d..12971ac044 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl @@ -19,7 +19,8 @@ interface IWpnForegroundSink : IUnknown [pointer_default(unique)] interface INotificationsLongRunningPlatform : IUnknown { - HRESULT RegisterFullTrustApplication([in] LPCWSTR processName, [in] GUID remoteId, [out] GUID* appId); + + HRESULT RegisterFullTrustApplication([in] LPCWSTR processName, [in] GUID remoteId, [out] LPWSTR* appId); HRESULT RegisterForegroundActivator([in] IWpnForegroundSink* sink, [in] LPCWSTR processName); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h index 608cadf8cf..14ac20ab85 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h @@ -25,4 +25,6 @@ #include -#include \ No newline at end of file +#include + +#define MIDL_NS_PREFIX diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index 66d104f5ed..0c37059693 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -4,6 +4,7 @@ #include "platform.h" #include "platformfactory.h" +#include void NotificationsLongRunningPlatformImpl::Initialize() { @@ -19,7 +20,8 @@ void NotificationsLongRunningPlatformImpl::Initialize() // This is in case we later realize there are no apps to be tracked in the LRP. m_lifetimeManager.Setup(); - /* TODO: Verify registry and UDK list and make sure we have apps to be tracked */ + // Creates storage if needed otherwise looks up container. + m_storage = winrt::Windows::Storage::ApplicationData::Current().LocalSettings().CreateContainer(L"LRP", winrt::Windows::Storage::ApplicationDataCreateDisposition::Always); /* TODO: Load platform components */ @@ -44,14 +46,45 @@ void NotificationsLongRunningPlatformImpl::WaitForLifetimeEvent() m_lifetimeManager.Wait(); } -// Example of one function. We will add more as we need them. -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterFullTrustApplication(_In_ PCWSTR /*processName*/, _In_ GUID /*remoteId*/, _Out_ GUID* /*appId*/) noexcept +wil::unique_cotaskmem_string NotificationsLongRunningPlatformImpl::GetAppIdentifier(const std::wstring& processName) { - auto lock = m_lock.lock_shared(); - RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - - return E_NOTIMPL; + auto values{ m_storage.Values() }; + + for (auto it = values.begin(); it != values.end(); it++) + { + winrt::hstring settingValue{ winrt::unbox_value(it.Current().Value()) }; + + if (processName.compare(settingValue.c_str()) == 0) + { + return wil::make_unique_string(it.Current().Key().c_str()); + } + } + + GUID guidReference; + THROW_IF_FAILED(CoCreateGuid(&guidReference)); + + wil::unique_cotaskmem_string guidStr; + THROW_IF_FAILED(StringFromCLSID(guidReference, &guidStr)); + + m_storage.Values().Insert(guidStr.get(), winrt::box_value(processName.c_str())); + return guidStr; +} + +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterFullTrustApplication( + _In_ PCWSTR processName, GUID remoteId, _Out_ PWSTR* appId) noexcept try +{ + auto lock = m_lock.lock_exclusive(); + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + + wil::unique_cotaskmem_string appIdentifier = GetAppIdentifier(processName); + + THROW_IF_FAILED(PushNotifications_RegisterFullTrustApplication(appIdentifier.get(), remoteId)); + + *appId = appIdentifier.get(); + + return S_OK; } +CATCH_RETURN() STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterForegroundActivator(_In_ IWpnForegroundSink* sink, _In_ PCWSTR processName) { diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 57e951cf52..fa79d1b0fb 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -16,7 +16,7 @@ struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRu /* INotificationsLongRunningPlatform functions */ - STDMETHOD(RegisterFullTrustApplication)(_In_ PCWSTR processName, _In_ GUID remoteId, _Out_ GUID* appId) noexcept; + STDMETHOD(RegisterFullTrustApplication)(_In_ PCWSTR processName, GUID remoteId, _Out_ PWSTR* appId) noexcept; STDMETHOD(RegisterForegroundActivator)(_In_ IWpnForegroundSink* sink, _In_ PCWSTR processName); @@ -29,7 +29,10 @@ struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRu bool m_initialized = false; bool m_shutdown = false; - // Here we will define the Platform components i.e. the map wrappings + winrt::Windows::Storage::ApplicationDataContainer m_storage{ nullptr }; + PlatformLifetimeManager m_lifetimeManager{}; ForegroundSinkManager m_foregroundSinkManager; + + wil::unique_cotaskmem_string GetAppIdentifier(const std::wstring& processName); }; diff --git a/dev/PushNotifications/externs.h b/dev/PushNotifications/externs.h index 00edb56363..090418cb8b 100644 --- a/dev/PushNotifications/externs.h +++ b/dev/PushNotifications/externs.h @@ -8,7 +8,16 @@ wil::unique_event& GetWaitHandleForArgs(); inline const winrt::hstring ACTIVATED_EVENT_ARGS_KEY = L"GlobalActivatedEventArgs"; +struct ChannelDetails +{ + winrt::hstring channelUri; + winrt::hstring channelId; + winrt::hstring appUserModelId; + winrt::Windows::Foundation::DateTime channelExpiryTime; +}; + inline HRESULT GetCurrentProcessPath(wil::unique_cotaskmem_string& processName) { return wil::GetModuleFileNameExW(GetCurrentProcess(), nullptr, processName); }; + diff --git a/dev/WindowsAppRuntime_DLL/pch.h b/dev/WindowsAppRuntime_DLL/pch.h index c53eb5e9cf..c5479df044 100644 --- a/dev/WindowsAppRuntime_DLL/pch.h +++ b/dev/WindowsAppRuntime_DLL/pch.h @@ -47,3 +47,5 @@ #include #include + +#define MIDL_NS_PREFIX diff --git a/test/TestApps/PushNotificationsDemoApp/PushNotificationsDemoApp.vcxproj b/test/TestApps/PushNotificationsDemoApp/PushNotificationsDemoApp.vcxproj index 31af7eb269..0d42ca9266 100644 --- a/test/TestApps/PushNotificationsDemoApp/PushNotificationsDemoApp.vcxproj +++ b/test/TestApps/PushNotificationsDemoApp/PushNotificationsDemoApp.vcxproj @@ -266,4 +266,4 @@ - + \ No newline at end of file diff --git a/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest b/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest index 71a2571567..1ce1db546b 100644 --- a/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest +++ b/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest @@ -11,7 +11,7 @@ + Version="11.0.2.0" /> Push Notifications Win32 Demo App diff --git a/test/TestApps/PushNotificationsDemoPackage/PushNotificationsDemoPackage.wapproj b/test/TestApps/PushNotificationsDemoPackage/PushNotificationsDemoPackage.wapproj index edaf9dee12..ff8c5ec76b 100644 --- a/test/TestApps/PushNotificationsDemoPackage/PushNotificationsDemoPackage.wapproj +++ b/test/TestApps/PushNotificationsDemoPackage/PushNotificationsDemoPackage.wapproj @@ -42,16 +42,17 @@ ..\PushNotificationsDemoApp\PushNotificationsDemoApp.vcxproj true False - $(SolutionDir)temp\MSTest.pfx + $(SolutionDir)temp\MSTest.pfx SHA256 True True $(Platform) 0 + C:\Users\vemancha\Desktop\ Always - + Always @@ -67,7 +68,6 @@ Always - Designer From a9b3295dfe5c1b53ddae98c2a9a90a2bbda0b740 Mon Sep 17 00:00:00 2001 From: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> Date: Thu, 2 Sep 2021 21:02:46 -0700 Subject: [PATCH 27/50] Notification delivery + Protocol Activation (#1358) * Protocol Activation skeleton * Further impl, mostly on the LRP * Integration with Foreground logic and some optimizations * Added calls to the LRP from SDK, and LRP improvements * Fixed some issues * Improved payload deserializing * Fixed merging goofs * Addressed feedback + few optimizations * Further improvements and added/removed comments * Addressed build errors after merging * Nit: Removed comment Co-authored-by: Daniel Ayala Co-authored-by: Eric Langlois --- dev/AppLifecycle/AppInstance.cpp | 24 ++- .../GetRawNotificationEventArgs.h | 13 +- .../PushNotificationManager.cpp | 31 +++- .../PushNotificationReceivedEventArgs.cpp | 24 +++ .../PushNotificationReceivedEventArgs.h | 9 ++ .../NotificationsLongRunningProcess.idl | 5 +- .../ForegroundSinkManager.cpp | 17 +- .../ForegroundSinkManager.h | 11 +- .../NotificationListener.cpp | 55 +++++++ .../NotificationListener.h | 21 +++ .../NotificationListenerManager.cpp | 50 ++++++ .../NotificationListenerManager.h | 24 +++ .../PushNotificationsLongRunningTask.vcxproj | 4 + ...tificationsLongRunningTask.vcxproj.filters | 12 ++ .../PushNotificationsLongRunningTask/pch.h | 9 ++ .../platform.cpp | 152 +++++++++++++----- .../platform.h | 24 +-- .../platformfactory.cpp | 2 - test/PushNotificationTests/APITests.cpp | 5 + .../Package.appxmanifest | 2 +- .../PushNotificationsDemoPackage.wapproj | 1 - 21 files changed, 421 insertions(+), 74 deletions(-) create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h diff --git a/dev/AppLifecycle/AppInstance.cpp b/dev/AppLifecycle/AppInstance.cpp index 1f09ce4845..0d129c4bd3 100644 --- a/dev/AppLifecycle/AppInstance.cpp +++ b/dev/AppLifecycle/AppInstance.cpp @@ -20,6 +20,8 @@ using namespace winrt::Windows::ApplicationModel::Activation; namespace winrt::Microsoft::Windows::AppLifecycle::implementation { + static PCWSTR c_pushPayloadAttribute{ L"-Payload:" }; + INIT_ONCE AppInstance::s_initOnce{}; winrt::com_ptr AppInstance::s_current; @@ -337,14 +339,26 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation // protocol, except the catch-all LaunchActivatedEventArgs case. if (!contractArgument.empty()) { - if (contractData.empty()) + if (CompareStringOrdinal(contractArgument.data(), static_cast(contractArgument.size()), L"WindowsAppRuntimePushServer", -1, TRUE) == CSTR_EQUAL) { - // If the contractData is empty, handle any aliased encoded launches. - if (CompareStringOrdinal(contractArgument.data(), static_cast(contractArgument.size()), L"WindowsAppRuntimePushServer", -1, TRUE) == CSTR_EQUAL) + // Generate a basic encoded launch Uri for all Push activations. + std::wstring tempContractData = GenerateEncodedLaunchUri(L"App", c_pushContractId); + contractArgument = c_protocolArgumentString; + + // A non-empty contractData means we have a payload. + // This contains a background notification. It is specific to unpackaged apps. + // It requires further processing to build PushNotificationReceivedEventArgs. + // For packaged apps we don't need extra processing. A basic encoded launch Uri is sufficient. + auto index = contractData.find(c_pushPayloadAttribute); + + if (!contractData.empty() && index == 0) { - contractData = GenerateEncodedLaunchUri(L"App", c_pushContractId); - contractArgument = c_protocolArgumentString; + tempContractData += L"&payload="; + // 11 -> the size of &payload= + starting quote + ending quote. + tempContractData += contractData.substr(10, contractData.size() - 11); } + + contractData = tempContractData; } if (CompareStringOrdinal(contractArgument.c_str(), static_cast(contractArgument.size()), c_protocolArgumentString, -1, TRUE) == CSTR_EQUAL) diff --git a/dev/PushNotifications/GetRawNotificationEventArgs.h b/dev/PushNotifications/GetRawNotificationEventArgs.h index 2279040ac2..02832c3165 100644 --- a/dev/PushNotifications/GetRawNotificationEventArgs.h +++ b/dev/PushNotifications/GetRawNotificationEventArgs.h @@ -10,8 +10,19 @@ constexpr PCWSTR c_pushContractId = L"Windows.Push"; namespace winrt::Microsoft::Windows::PushNotifications { - static winrt::Windows::Foundation::IInspectable Deserialize(winrt::Windows::Foundation::Uri const&) + static winrt::Windows::Foundation::IInspectable Deserialize(winrt::Windows::Foundation::Uri const& uri) { + // Verify if the uri contains a background notification payload. + // Otherwise, we expect to process the notification in a background task. + for (auto const& pair : uri.QueryParsed()) + { + if (pair.Name() == L"payload") + { + std::wstring payloadAsWstring{pair.Value()}; + return winrt::make(payloadAsWstring); + } + } + const DWORD receiveArgsTimeoutInMSec{ 2000 }; THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_TIMEOUT), !GetWaitHandleForArgs().wait(receiveArgsTimeoutInMSec)); return winrt::Windows::ApplicationModel::Core::CoreApplication::Properties().TryLookup(ACTIVATED_EVENT_ARGS_KEY).as(); diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index 91c94c0746..5b7d7b0326 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -246,7 +246,24 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation THROW_HR_IF(E_INVALIDARG, taskClsid == GUID_NULL); auto registrationOptions = details.Options(); - THROW_HR_IF(E_INVALIDARG, WI_AreAllFlagsClear(registrationOptions, PushNotificationRegistrationOptions::PushTrigger | PushNotificationRegistrationOptions::ComActivator)); + + auto isBackgroundTaskFlagSet{ WI_IsAnyFlagSet(registrationOptions, PushNotificationRegistrationOptions::PushTrigger | PushNotificationRegistrationOptions::ComActivator) }; + THROW_HR_IF(E_INVALIDARG, isBackgroundTaskFlagSet && !IsActivatorSupported(registrationOptions)); + + auto isProtocolActivatorSet{ WI_IsFlagSet(registrationOptions, PushNotificationRegistrationOptions::ProtocolActivator) }; + THROW_HR_IF(E_INVALIDARG, isProtocolActivatorSet && !IsActivatorSupported(registrationOptions)); + + if (isProtocolActivatorSet) + { + auto coInitialize = wil::CoInitializeEx(); + + wil::com_ptr notificationPlatform{ + wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + + wil::unique_cotaskmem_string processName; + THROW_IF_FAILED(GetCurrentProcessPath(processName)); + THROW_IF_FAILED(notificationPlatform->RegisterActivator(processName.get())); + } DWORD cookie = 0; IBackgroundTaskRegistration registeredTask = nullptr; @@ -370,6 +387,18 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { LOG_IF_FAILED(::CoRevokeClassObject(static_cast(token.Cookie()))); } + + if (WI_IsFlagSet(options, PushNotificationRegistrationOptions::ProtocolActivator)) + { + auto coInitialize = wil::CoInitializeEx(); + + wil::com_ptr notificationPlatform{ + wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + + wil::unique_cotaskmem_string processName; + THROW_IF_FAILED(GetCurrentProcessPath(processName)); + THROW_IF_FAILED(notificationPlatform->UnregisterActivator(processName.get())); + } } catch (...) diff --git a/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp b/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp index 29e3623f2f..1a508aebb1 100644 --- a/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp +++ b/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp @@ -10,6 +10,7 @@ #include "PushNotificationReceivedEventArgs.h" #include "Microsoft.Windows.PushNotifications.PushNotificationReceivedEventArgs.g.cpp" #include +#include #include #include #include "ValueMarshaling.h" @@ -38,6 +39,10 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation m_rawNotificationPayload(BuildPayload(payload, length)), m_unpackagedAppScenario(true) {} + PushNotificationReceivedEventArgs::PushNotificationReceivedEventArgs(std::wstring const& payload) : + m_rawNotificationPayload(BuildPayload(payload)), + m_unpackagedAppScenario(true) {} + std::vector PushNotificationReceivedEventArgs::BuildPayload(winrt::Windows::Storage::Streams::IBuffer const& buffer) { return { buffer.data(), buffer.data() + (buffer.Length() * sizeof(uint8_t)) }; @@ -48,6 +53,13 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation return { payload, payload + (length * sizeof(uint8_t)) }; } + std::vector PushNotificationReceivedEventArgs::BuildPayload(std::wstring const& payload) + { + std::string payloadToSimpleString = Utf16ToUtf8(payload.c_str()); + + return { payloadToSimpleString.c_str(), payloadToSimpleString.c_str() + (payloadToSimpleString.length() * sizeof(uint8_t)) }; + } + winrt::com_array PushNotificationReceivedEventArgs::Payload() { return { m_rawNotificationPayload.data(), m_rawNotificationPayload.data() + (m_rawNotificationPayload.size() * sizeof(uint8_t)) }; @@ -119,5 +131,17 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation m_handledUnpackaged = value; } } + + std::string PushNotificationReceivedEventArgs::Utf16ToUtf8(_In_z_ PCWSTR utf16) + { + int size_needed = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, nullptr, nullptr); + THROW_LAST_ERROR_IF(size_needed == 0); + + // size_needed minus the null character + std::string utf8(size_needed - 1, 0); + int size = WideCharToMultiByte(CP_UTF8, 0, utf16, size_needed - 1, &utf8[0], size_needed - 1, nullptr, nullptr); + THROW_LAST_ERROR_IF(size == 0); + return utf8; + } } diff --git a/dev/PushNotifications/PushNotificationReceivedEventArgs.h b/dev/PushNotifications/PushNotificationReceivedEventArgs.h index 11ebb40fa8..5b2774ea3b 100644 --- a/dev/PushNotifications/PushNotificationReceivedEventArgs.h +++ b/dev/PushNotifications/PushNotificationReceivedEventArgs.h @@ -11,6 +11,9 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation PushNotificationReceivedEventArgs(winrt::Windows::ApplicationModel::Background::IBackgroundTaskInstance const& backgroundTask); PushNotificationReceivedEventArgs(winrt::Windows::Networking::PushNotifications::PushNotificationReceivedEventArgs const& args); + + PushNotificationReceivedEventArgs(std::wstring const& payload); + PushNotificationReceivedEventArgs(byte* const& payload, ULONG const& length); com_array Payload(); @@ -21,10 +24,16 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation void Handled(bool value); private: + std::string Utf16ToUtf8(_In_z_ PCWSTR utf16); + + const winrt::Windows::Storage::Streams::IBuffer m_rawNotification{}; + std::vector BuildPayload(winrt::Windows::Storage::Streams::IBuffer const& buffer); std::vector BuildPayload(byte* const& payload, ULONG const& length); + std::vector BuildPayload(std::wstring const& payload); std::vector m_rawNotificationPayload; + const winrt::Windows::ApplicationModel::Background::IBackgroundTaskInstance m_backgroundTaskInstance{}; const winrt::Windows::Networking::PushNotifications::PushNotificationReceivedEventArgs m_args = nullptr; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl index 12971ac044..cfd8af1ddb 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl @@ -19,9 +19,12 @@ interface IWpnForegroundSink : IUnknown [pointer_default(unique)] interface INotificationsLongRunningPlatform : IUnknown { + HRESULT RegisterActivator([in] LPCWSTR processName); - HRESULT RegisterFullTrustApplication([in] LPCWSTR processName, [in] GUID remoteId, [out] LPWSTR* appId); + HRESULT UnregisterActivator([in] LPCWSTR processName); + HRESULT RegisterFullTrustApplication([in] LPCWSTR processName, [in] GUID remoteId, [out] LPWSTR* appId); + HRESULT RegisterForegroundActivator([in] IWpnForegroundSink* sink, [in] LPCWSTR processName); HRESULT UnregisterForegroundActivator([in] LPCWSTR processName); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.cpp index 4849a0735d..567363bcc7 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.cpp @@ -2,32 +2,29 @@ #include "pch.h" -#include -#include - -void ForegroundSinkManager::Add(std::wstring const& processName, IWpnForegroundSink* const& sink) +void ForegroundSinkManager::Add(std::wstring const& appId, IWpnForegroundSink* const& sink) { auto lock = m_lock.lock_exclusive(); - m_foregroundMap[processName] = sink; + m_foregroundMap[appId] = sink; } -void ForegroundSinkManager::Remove(std::wstring const& processName) +void ForegroundSinkManager::Remove(std::wstring const& appId) { auto lock = m_lock.lock_exclusive(); - m_foregroundMap.erase(processName); + m_foregroundMap.erase(appId); } -bool ForegroundSinkManager::InvokeForegroundHandlers(std::wstring const& processName, winrt::com_array const& payload, ULONG const& payloadSize) +bool ForegroundSinkManager::InvokeForegroundHandlers(std::wstring const& appId, winrt::com_array const& payload, ULONG const& payloadSize) { auto lock = m_lock.lock_exclusive(); - auto it = m_foregroundMap.find(processName); + auto it = m_foregroundMap.find(appId); if (it != m_foregroundMap.end()) { BOOL foregroundHandled = true; if (FAILED(it->second->InvokeAll(payloadSize, payload.data(), &foregroundHandled))) { - Remove(processName); + m_foregroundMap.erase(appId); return false; } return foregroundHandled; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.h b/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.h index 19e99bc885..9439ec6fc1 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/ForegroundSinkManager.h @@ -11,16 +11,15 @@ class ForegroundSinkManager public: ForegroundSinkManager() = default; - void Add(std::wstring const& processName, IWpnForegroundSink* const& sink); + void Add(std::wstring const& appId, IWpnForegroundSink* const& sink); - void Remove(std::wstring const& processName); + void Remove(std::wstring const& appId); - bool InvokeForegroundHandlers(std::wstring const& processName, winrt::com_array const& payload, ULONG const& payloadSize); + bool InvokeForegroundHandlers(std::wstring const& appId, winrt::com_array const& payload, ULONG const& payloadSize); private: - // An app can only have one activate foreground sink with Long Running Process. Event handlers in - // the sink are managed by the WindowsAppSDK. + // An app can only have one activate foreground sink with Long Running Process. + // Event handlers in the sink are managed by the WindowsAppSDK. std::unordered_map> m_foregroundMap = {}; wil::srwlock m_lock; - }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp new file mode 100644 index 0000000000..aa6cc78305 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp @@ -0,0 +1,55 @@ +#include "pch.h" + +HRESULT NotificationListener::RuntimeClassInitialize(std::shared_ptr foregroundSinkManager, std::wstring appId, std::wstring processName) +{ + m_foregroundSinkManager = foregroundSinkManager; + + m_appId = appId; + m_processName = processName; + + return S_OK; +} + +STDMETHODIMP_(HRESULT __stdcall) NotificationListener::OnRawNotificationReceived(unsigned int payloadLength, _In_ byte* payload, _In_ HSTRING /*correlationVector*/) noexcept try +{ + auto lock = m_lock.lock_exclusive(); + + winrt::com_array payloadArray{ payload, payload + (payloadLength * sizeof(uint8_t)) }; + + if (!m_foregroundSinkManager->InvokeForegroundHandlers(m_appId, payloadArray, payloadLength)) + { + std::string commandLine = "----WindowsAppSDKPushServer:-Payload:\""; + commandLine.append(reinterpret_cast(payload), payloadLength); + commandLine.append("\""); + + std::string processNameAsUtf8String = ConvertProcessNameToUtf8String(); + + SHELLEXECUTEINFOA shellExecuteInfo{}; + shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOA); + shellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_DOENVSUBST; + shellExecuteInfo.lpFile = processNameAsUtf8String.c_str(); + shellExecuteInfo.lpParameters = commandLine.c_str(); + + shellExecuteInfo.nShow = SW_NORMAL; + + if (!ShellExecuteExA(&shellExecuteInfo)) + { + THROW_IF_WIN32_ERROR(GetLastError()); + } + }; + + return S_OK; +} +CATCH_RETURN() + +std::string NotificationListener::ConvertProcessNameToUtf8String() +{ + int size_needed = WideCharToMultiByte(CP_UTF8, 0, m_processName.c_str(), -1, NULL, 0, nullptr, nullptr); + THROW_LAST_ERROR_IF(size_needed == 0); + + // size_needed minus the null character + std::string utf8(size_needed - 1, 0); + int size = WideCharToMultiByte(CP_UTF8, 0, m_processName.c_str(), size_needed - 1, &utf8[0], size_needed - 1, nullptr, nullptr); + THROW_LAST_ERROR_IF(size == 0); + return utf8; +} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h new file mode 100644 index 0000000000..e7872f8db4 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +class NotificationListener : public Microsoft::WRL::RuntimeClass<::ABI::Microsoft::Internal::PushNotifications::INotificationListener> +{ +public: + HRESULT RuntimeClassInitialize(std::shared_ptr foregroundSinkManager, std::wstring appId, std::wstring processName); + + STDMETHOD(OnRawNotificationReceived)(unsigned int payloadLength, _In_ byte* payload, _In_ HSTRING correlationVector) noexcept; + +private: + std::string ConvertProcessNameToUtf8String(); + + std::shared_ptr m_foregroundSinkManager; + + std::wstring m_appId; + std::wstring m_processName; + + wil::srwlock m_lock; +}; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp new file mode 100644 index 0000000000..2b830e8317 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp @@ -0,0 +1,50 @@ +#include "pch.h" + +using namespace Microsoft::WRL; +using namespace ::ABI::Microsoft::Internal::PushNotifications; + +void NotificationListenerManager::Initialize(std::shared_ptr foregroundSinkManager, std::map& appIdList) +{ + m_foregroundSinkManager = foregroundSinkManager; + + for (auto appData : appIdList) + { + AddListener(appData.first, appData.second); + } +} + +void NotificationListenerManager::AddListener(std::wstring appId, std::wstring processName) +{ + auto lock = m_lock.lock_exclusive(); + + THROW_HR_IF(E_INVALIDARG, appId.empty()); + THROW_HR_IF(E_INVALIDARG, processName.empty()); + + ComPtr listener; + THROW_IF_FAILED(MakeAndInitialize(&listener, m_foregroundSinkManager, appId, processName)); + THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appId.c_str(), listener.Get())); + + if (m_notificationListeners.find(appId) == std::end(m_notificationListeners)) + { + AgileRef agileListener; + THROW_IF_FAILED(AsAgile(listener.Get(), &agileListener)); + m_notificationListeners.insert({ appId, agileListener }); + } +} + +void NotificationListenerManager::RemoveListener(std::wstring appId) +{ + auto lock = m_lock.lock_exclusive(); + + THROW_HR_IF(E_INVALIDARG, appId.empty()); + + LOG_IF_FAILED(PushNotifications_UnregisterNotificationSinkForFullTrustApplication(appId.c_str())); + + m_notificationListeners.erase(appId); +} + +bool NotificationListenerManager::IsEmpty() +{ + auto lock = m_lock.lock_shared(); + return m_notificationListeners.empty(); +} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h new file mode 100644 index 0000000000..63d63ba0b0 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include + +class NotificationListenerManager +{ +public: + NotificationListenerManager() {}; + + void Initialize(std::shared_ptr foregroundSinkManager, std::map& appIdList); + + void AddListener(std::wstring appId, std::wstring processName); + void RemoveListener(std::wstring appId); + + bool IsEmpty(); + +private: + wil::srwlock m_lock; + + std::map m_notificationListeners; + std::shared_ptr m_foregroundSinkManager; +}; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index 29f9ac4815..2617e3f877 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -222,19 +222,23 @@ + + + + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters index c8a1d35214..53d4e755e9 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters @@ -27,6 +27,12 @@ Header Files + + Header Files + + + Header Files + Header Files @@ -47,6 +53,12 @@ Source Files + + Source Files + + + Source Files + Source Files diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h index 14ac20ab85..b32cb9b6d3 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/pch.h @@ -27,4 +27,13 @@ #include +// UDK/ProxyStub files #define MIDL_NS_PREFIX +#include +#include + +// LRP files +#include "ForegroundSinkManager.h" +#include "PlatformLifetimeManager.h" +#include "NotificationListener.h" +#include "NotificationListenerManager.h" diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index 0c37059693..fbd95c491b 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -1,11 +1,11 @@ #include "pch.h" -#include - #include "platform.h" #include "platformfactory.h" #include +using namespace winrt::Windows; + void NotificationsLongRunningPlatformImpl::Initialize() { auto lock = m_lock.lock_exclusive(); @@ -16,14 +16,24 @@ void NotificationsLongRunningPlatformImpl::Initialize() return; } - // Schedule event signaling after 5 seconds. + // Schedule event signaling to happen in 5 seconds. // This is in case we later realize there are no apps to be tracked in the LRP. m_lifetimeManager.Setup(); - // Creates storage if needed otherwise looks up container. - m_storage = winrt::Windows::Storage::ApplicationData::Current().LocalSettings().CreateContainer(L"LRP", winrt::Windows::Storage::ApplicationDataCreateDisposition::Always); + m_storage = Storage::ApplicationData::Current().LocalSettings().CreateContainer( + L"LRP", Storage::ApplicationDataCreateDisposition::Always); + + m_foregroundSinkManager = std::make_shared(); - /* TODO: Load platform components */ + auto fullTrustApps = GetFullTrustApps(); + + if (!fullTrustApps.empty()) + { + // We have at least one app that could receive notifications. + // Cancel the timer to persist the LRP. + m_lifetimeManager.Cancel(); + m_notificationListenerManager.Initialize(m_foregroundSinkManager, fullTrustApps); + } m_initialized = true; } @@ -36,8 +46,6 @@ void NotificationsLongRunningPlatformImpl::Shutdown() noexcept return; } - /* TODO: Shut down your components */ - m_shutdown = true; } @@ -46,60 +54,132 @@ void NotificationsLongRunningPlatformImpl::WaitForLifetimeEvent() m_lifetimeManager.Wait(); } -wil::unique_cotaskmem_string NotificationsLongRunningPlatformImpl::GetAppIdentifier(const std::wstring& processName) +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterFullTrustApplication( + _In_ PCWSTR processName, GUID remoteId, _Out_ PWSTR* appId) noexcept try { - auto values{ m_storage.Values() }; + auto lock = m_lock.lock_exclusive(); + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - for (auto it = values.begin(); it != values.end(); it++) - { - winrt::hstring settingValue{ winrt::unbox_value(it.Current().Value()) }; + std::wstring appIdentifier = GetAppIdentifier(processName); + THROW_IF_FAILED(PushNotifications_RegisterFullTrustApplication(appIdentifier.c_str(), remoteId)); - if (processName.compare(settingValue.c_str()) == 0) - { - return wil::make_unique_string(it.Current().Key().c_str()); - } - } + wil::unique_cotaskmem_string outAppId = wil::make_unique_string(appIdentifier.c_str()); + *appId = outAppId.release(); - GUID guidReference; - THROW_IF_FAILED(CoCreateGuid(&guidReference)); + return S_OK; +} +CATCH_RETURN() - wil::unique_cotaskmem_string guidStr; - THROW_IF_FAILED(StringFromCLSID(guidReference, &guidStr)); +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterActivator(_In_ PCWSTR processName) noexcept try +{ + auto lock = m_lock.lock_shared(); + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - m_storage.Values().Insert(guidStr.get(), winrt::box_value(processName.c_str())); - return guidStr; + std::wstring appId = GetAppIdentifier(processName); + m_notificationListenerManager.AddListener(appId, processName); + + m_lifetimeManager.Cancel(); + + return S_OK; } +CATCH_RETURN() -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterFullTrustApplication( - _In_ PCWSTR processName, GUID remoteId, _Out_ PWSTR* appId) noexcept try +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterActivator(_In_ PCWSTR processName) noexcept try { - auto lock = m_lock.lock_exclusive(); + auto lock = m_lock.lock_shared(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - wil::unique_cotaskmem_string appIdentifier = GetAppIdentifier(processName); + std::wstring appId = GetAppIdentifier(processName); + m_notificationListenerManager.RemoveListener(appId); + m_foregroundSinkManager->Remove(appId); - THROW_IF_FAILED(PushNotifications_RegisterFullTrustApplication(appIdentifier.get(), remoteId)); + RemoveAppIdentifier(appId); - *appId = appIdentifier.get(); + if (m_notificationListenerManager.IsEmpty()) + { + m_lifetimeManager.Setup(); + } return S_OK; } CATCH_RETURN() -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterForegroundActivator(_In_ IWpnForegroundSink* sink, _In_ PCWSTR processName) +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterForegroundActivator(_In_ IWpnForegroundSink* sink, _In_ PCWSTR processName) noexcept try { auto lock = m_lock.lock_exclusive(); - RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + + std::wstring appId = GetAppIdentifier(processName); + + m_notificationListenerManager.AddListener(appId, processName); + m_foregroundSinkManager->Add(appId, sink); - m_foregroundSinkManager.Add(processName, sink); return S_OK; } +CATCH_RETURN() -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterForegroundActivator(_In_ PCWSTR processName) +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterForegroundActivator(_In_ PCWSTR processName) noexcept try { auto lock = m_lock.lock_exclusive(); - RETURN_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); + + std::wstring appId = GetAppIdentifier(processName); + m_foregroundSinkManager->Remove(appId); - m_foregroundSinkManager.Remove(processName); return S_OK; } +CATCH_RETURN() + +// Returns a map of key-value pairs, where key is appId and value is processName. +// It should only be called by Initialize(), which already acquired a lock. +std::map NotificationsLongRunningPlatformImpl::GetFullTrustApps() +{ + std::map mapOfFullTrustApps; + + // Get list of full trust apps with valid channels from wpncore + wil::unique_cotaskmem_array_ptr appIds; + PushNotifications_GetFullTrustApplicationsWithChannels(appIds.addressof(), appIds.size_address()); + + // Get list of apps from Storage + auto values{ m_storage.Values() }; + + for (size_t i = 0; i < appIds.size(); ++i) + { + if (values.HasKey(appIds[i])) + { + winrt::hstring processName{ winrt::unbox_value(values.Lookup(appIds[i])) }; + mapOfFullTrustApps.emplace(reinterpret_cast(appIds[i]), processName.c_str()); + } + } + + return mapOfFullTrustApps; +} + +std::wstring NotificationsLongRunningPlatformImpl::GetAppIdentifier(std::wstring const& processName) +{ + auto values{ m_storage.Values() }; + + for (auto it = values.begin(); it != values.end(); it++) + { + winrt::hstring settingValue{ winrt::unbox_value(it.Current().Value()) }; + if (processName.compare(settingValue.c_str()) == 0) + { + return std::wstring{ it.Current().Key().c_str() }; + } + } + + GUID guidReference; + THROW_IF_FAILED(CoCreateGuid(&guidReference)); + + wil::unique_cotaskmem_string guidStr; + THROW_IF_FAILED(StringFromCLSID(guidReference, &guidStr)); + + m_storage.Values().Insert(guidStr.get(), winrt::box_value(processName.c_str())); + return guidStr.get(); +} + +void NotificationsLongRunningPlatformImpl::RemoveAppIdentifier(std::wstring const& appId) +{ + auto values{ m_storage.Values() }; + values.Remove(appId); +} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index fa79d1b0fb..9d2445e8a3 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -2,9 +2,6 @@ #include "../PushNotifications-Constants.h" -#include "PlatformLifetimeManager.h" -#include "ForegroundSinkManager.h" - struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRunningPlatformImpl: winrt::implements { @@ -18,21 +15,28 @@ struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRu STDMETHOD(RegisterFullTrustApplication)(_In_ PCWSTR processName, GUID remoteId, _Out_ PWSTR* appId) noexcept; - STDMETHOD(RegisterForegroundActivator)(_In_ IWpnForegroundSink* sink, _In_ PCWSTR processName); + STDMETHOD(RegisterActivator)(_In_ PCWSTR processName) noexcept; + + STDMETHOD(UnregisterActivator)(_In_ PCWSTR processName) noexcept; + + STDMETHOD(RegisterForegroundActivator)(_In_ IWpnForegroundSink* sink, _In_ PCWSTR processName) noexcept; - STDMETHOD(UnregisterForegroundActivator)(_In_ PCWSTR processName); + STDMETHOD(UnregisterForegroundActivator)(_In_ PCWSTR processName) noexcept; private: + std::map GetFullTrustApps(); + std::wstring GetAppIdentifier(std::wstring const& processName); + void RemoveAppIdentifier(std::wstring const& processName); + + winrt::Windows::Storage::ApplicationDataContainer m_storage{ nullptr }; + wil::srwlock m_lock; bool m_initialized = false; bool m_shutdown = false; - winrt::Windows::Storage::ApplicationDataContainer m_storage{ nullptr }; - PlatformLifetimeManager m_lifetimeManager{}; - ForegroundSinkManager m_foregroundSinkManager; - - wil::unique_cotaskmem_string GetAppIdentifier(const std::wstring& processName); + NotificationListenerManager m_notificationListenerManager{}; + std::shared_ptr m_foregroundSinkManager; }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp index dcc742b5b6..133e3dcf99 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platformfactory.cpp @@ -1,7 +1,5 @@ #include "pch.h" -#include - #include "platform.h" #include #include diff --git a/test/PushNotificationTests/APITests.cpp b/test/PushNotificationTests/APITests.cpp index 971ee64a3e..df54c4b2c9 100644 --- a/test/PushNotificationTests/APITests.cpp +++ b/test/PushNotificationTests/APITests.cpp @@ -272,5 +272,10 @@ namespace Test::PushNotifications { RunTest(L"VerifyNullActivatorNotSupported", testWaitTime()); } + + TEST_METHOD(VerifyProtocolActivation) + { + RunTestUnpackaged(L"----WindowsAppRuntimePushServer:-Payload:\"\"", testWaitTime()); + } }; } diff --git a/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest b/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest index 1ce1db546b..71a2571567 100644 --- a/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest +++ b/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest @@ -11,7 +11,7 @@ + Version="1.0.0.0" /> Push Notifications Win32 Demo App diff --git a/test/TestApps/PushNotificationsDemoPackage/PushNotificationsDemoPackage.wapproj b/test/TestApps/PushNotificationsDemoPackage/PushNotificationsDemoPackage.wapproj index ff8c5ec76b..34f6760256 100644 --- a/test/TestApps/PushNotificationsDemoPackage/PushNotificationsDemoPackage.wapproj +++ b/test/TestApps/PushNotificationsDemoPackage/PushNotificationsDemoPackage.wapproj @@ -48,7 +48,6 @@ True $(Platform) 0 - C:\Users\vemancha\Desktop\ Always From 6ea2a5651901f3761e2543617dda7673b9eac042 Mon Sep 17 00:00:00 2001 From: eric langlois Date: Fri, 3 Sep 2021 10:23:40 -0700 Subject: [PATCH 28/50] Unpackaged notification unit tests (#1340) * Adding initial unpackaged test series * This function now fails silently * This is not expected to work for unpackaged apps Co-authored-by: Eric Langlois --- test/PushNotificationTests/APITests.cpp | 84 +++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 5 deletions(-) diff --git a/test/PushNotificationTests/APITests.cpp b/test/PushNotificationTests/APITests.cpp index df54c4b2c9..4f1a17ef3b 100644 --- a/test/PushNotificationTests/APITests.cpp +++ b/test/PushNotificationTests/APITests.cpp @@ -173,6 +173,15 @@ namespace Test::PushNotifications VERIFY_NO_THROW(LocalBackgroundTask.Run(mockBackgroundTaskInstance)); } + TEST_METHOD(BackgroundActivation_Unpackaged) + { + RunTestUnpackaged(L"BackgroundActivationTest", testWaitTime()); // Need to launch one time to enable background activation. + + auto LocalBackgroundTask = winrt::create_instance(c_comServerId, CLSCTX_ALL); + auto mockBackgroundTaskInstance = winrt::make(); + VERIFY_NO_THROW(LocalBackgroundTask.Run(mockBackgroundTaskInstance)); + } + TEST_METHOD(MultipleBackgroundActivation) { RunTest(L"BackgroundActivationTest", testWaitTime()); // Need to launch one time to enable background activation. @@ -188,19 +197,44 @@ namespace Test::PushNotifications } + TEST_METHOD(MultipleBackgroundActivation_Unpackaged) + { + RunTestUnpackaged(L"BackgroundActivationTest", testWaitTime()); // Need to launch one time to enable background activation. + + auto LocalBackgroundTask1 = winrt::create_instance(c_comServerId, CLSCTX_ALL); + auto mockBackgroundTaskInstance1 = winrt::make(); + + auto LocalBackgroundTask2 = winrt::create_instance(c_comServerId, CLSCTX_ALL); + auto mockBackgroundTaskInstance2 = winrt::make(); + + VERIFY_NO_THROW(LocalBackgroundTask1.Run(mockBackgroundTaskInstance1)); + VERIFY_NO_THROW(LocalBackgroundTask2.Run(mockBackgroundTaskInstance2)); + + } + TEST_METHOD(ChannelRequestUsingNullRemoteId) { RunTest(L"ChannelRequestUsingNullRemoteId", testWaitTime()); } + TEST_METHOD(ChannelRequestUsingNullRemoteId_Unpackaged) + { + RunTestUnpackaged(L"ChannelRequestUsingNullRemoteId", testWaitTime()); + } + TEST_METHOD(ChannelRequestUsingRemoteId) { RunTest(L"ChannelRequestUsingRemoteId", channelTestWaitTime()); } - TEST_METHOD(MultipleChannelClose) + TEST_METHOD(ChannelRequestUsingRemoteId_Unpackaged) + { + RunTestUnpackaged(L"ChannelRequestUsingRemoteId", channelTestWaitTime()); + } + + TEST_METHOD(MultipleChannelClose_Unpackaged) { - RunTest(L"MultipleChannelClose", channelTestWaitTime()); + RunTestUnpackaged(L"MultipleChannelClose", channelTestWaitTime()); } TEST_METHOD(MultipleChannelRequestUsingSameRemoteId) @@ -208,11 +242,21 @@ namespace Test::PushNotifications RunTest(L"MultipleChannelRequestUsingSameRemoteId", channelTestWaitTime()); } + TEST_METHOD(MultipleChannelRequestUsingSameRemoteId_Unpackaged) + { + RunTestUnpackaged(L"MultipleChannelRequestUsingSameRemoteId", channelTestWaitTime()); + } + TEST_METHOD(MultipleChannelRequestUsingMultipleRemoteId) { RunTest(L"MultipleChannelRequestUsingMultipleRemoteId", channelTestWaitTime()); } + TEST_METHOD(MultipleChannelRequestUsingMultipleRemoteId_Unpackaged) + { + RunTestUnpackaged(L"MultipleChannelRequestUsingMultipleRemoteId", channelTestWaitTime()); + } + TEST_METHOD(ActivatorTest) { RunTest(L"ActivatorTest", testWaitTime()); @@ -223,37 +267,62 @@ namespace Test::PushNotifications RunTest(L"RegisterActivatorNullDetails", testWaitTime()); } + TEST_METHOD(RegisterActivatorNullDetails_Unpackaged) + { + RunTestUnpackaged(L"RegisterActivatorNullDetails", testWaitTime()); + } + TEST_METHOD(RegisterActivatorNullClsid) { RunTest(L"RegisterActivatorNullClsid", testWaitTime()); } + TEST_METHOD(RegisterActivatorNullClsid_Unpackaged) + { + RunTestUnpackaged(L"RegisterActivatorNullClsid", testWaitTime()); + } + TEST_METHOD(UnregisterActivatorNullToken) { RunTest(L"UnregisterActivatorNullToken", testWaitTime()); } + TEST_METHOD(UnregisterActivatorNullToken_Unpackaged) + { + RunTestUnpackaged(L"UnregisterActivatorNullToken", testWaitTime()); + } + TEST_METHOD(UnregisterActivatorNullBackgroundRegistration) { RunTest(L"UnregisterActivatorNullBackgroundRegistration", testWaitTime()); } + TEST_METHOD(UnregisterActivatorNullBackgroundRegistration_Unpackaged) + { + RunTestUnpackaged(L"UnregisterActivatorNullBackgroundRegistration", testWaitTime()); + } + TEST_METHOD(MultipleRegisterActivatorTest) { RunTest(L"MultipleRegisterActivatorTest", testWaitTime()); } + TEST_METHOD(MultipleRegisterActivatorTest_Unpackaged) + { + RunTestUnpackaged(L"MultipleRegisterActivatorTest", testWaitTime()); + } + TEST_METHOD(VerifyComActivatorSupported) { RunTest(L"VerifyComActivatorSupported", testWaitTime()); } - TEST_METHOD(VerifyComActivatorNotSupported) + TEST_METHOD(VerifyComActivatorNotSupported_Unpackaged) { RunTestUnpackaged(L"VerifyComActivatorNotSupported", testWaitTime()); } - TEST_METHOD(VerifyProtocolActivatorSupported) + TEST_METHOD(VerifyProtocolActivatorSupported_Unpackaged) { RunTestUnpackaged(L"VerifyProtocolActivatorSupported", testWaitTime()); } @@ -268,12 +337,17 @@ namespace Test::PushNotifications RunTest(L"VerifyComAndProtocolActivatorNotSupported", testWaitTime()); } + TEST_METHOD(VerifyComAndProtocolActivatorNotSupported_Unpackaged) + { + RunTestUnpackaged(L"VerifyComAndProtocolActivatorNotSupported", testWaitTime()); + } + TEST_METHOD(VerifyNullActivatorNotSupported) { RunTest(L"VerifyNullActivatorNotSupported", testWaitTime()); } - TEST_METHOD(VerifyProtocolActivation) + TEST_METHOD(VerifyProtocolActivation_Unpackaged) { RunTestUnpackaged(L"----WindowsAppRuntimePushServer:-Payload:\"\"", testWaitTime()); } From 7dfb673d3ab4100bbdf5243841e1aadbf445b273 Mon Sep 17 00:00:00 2001 From: Eric Langlois Date: Fri, 3 Sep 2021 11:35:30 -0700 Subject: [PATCH 29/50] Ensure errors get logged with telemetry --- dev/PushNotifications/PushNotificationChannel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/PushNotifications/PushNotificationChannel.cpp b/dev/PushNotifications/PushNotificationChannel.cpp index 698527f155..092b8d587b 100644 --- a/dev/PushNotifications/PushNotificationChannel.cpp +++ b/dev/PushNotifications/PushNotificationChannel.cpp @@ -60,7 +60,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation } else { - PushNotifications_CloseChannel(m_channelInfo.appUserModelId.c_str(), m_channelInfo.channelId.c_str()); + THROW_IF_FAILED(PushNotifications_CloseChannel(m_channelInfo.appUserModelId.c_str(), m_channelInfo.channelId.c_str())); } PushNotificationTelemetry::ChannelClosedByApi(S_OK); From 0e1661e9275f7a824c8423ef531b5b0c87404f7d Mon Sep 17 00:00:00 2001 From: eric langlois Date: Fri, 3 Sep 2021 12:11:13 -0700 Subject: [PATCH 30/50] Workaround UDK include issue (#1364) * Workaround UDK include issue * just duplicating files seem a better approach * Restoring vcproje files * PushNotificationsRT.h was interfering with package creation Co-authored-by: Eric Langlois --- .../PushNotificationsLongRunningTask.vcxproj | 12 +- dev/PushNotifications/PushNotificationsRT.h | 299 ++++++++++++++++++ 2 files changed, 305 insertions(+), 6 deletions(-) create mode 100644 dev/PushNotifications/PushNotificationsRT.h diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index 2617e3f877..499e213075 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -123,7 +123,7 @@ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp17 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. Windows @@ -141,7 +141,7 @@ true stdcpp17 Guard - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. Windows @@ -158,7 +158,7 @@ _DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp17 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. Windows @@ -176,7 +176,7 @@ true stdcpp17 Guard - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. Windows @@ -193,7 +193,7 @@ _DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp20 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. Windows @@ -211,7 +211,7 @@ true Guard stdcpp20 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. Windows diff --git a/dev/PushNotifications/PushNotificationsRT.h b/dev/PushNotifications/PushNotificationsRT.h new file mode 100644 index 0000000000..f922f1f5f3 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsRT.h @@ -0,0 +1,299 @@ +/* Header file automatically generated from pushnotificationsrt.idl */ +/* + * File built with Microsoft(R) MIDLRT Compiler Engine Version 10.00.0231 + */ + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 500 +#endif + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCSAL_H_VERSION__ +#define __REQUIRED_RPCSAL_H_VERSION__ 100 +#endif + +#include +#include + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif /* __RPCNDR_H_VERSION__ */ + +#ifndef COM_NO_WINDOWS_H +#include +#include +#endif /*COM_NO_WINDOWS_H*/ +#ifndef __pushnotificationsrt_h__ +#define __pushnotificationsrt_h__ +#ifndef __pushnotificationsrt_p_h__ +#define __pushnotificationsrt_p_h__ + + +#pragma once + +// Ensure that the setting of the /ns_prefix command line switch is consistent for all headers. +// If you get an error from the compiler indicating "warning C4005: 'CHECK_NS_PREFIX_STATE': macro redefinition", this +// indicates that you have included two different headers with different settings for the /ns_prefix MIDL command line switch +#if !defined(DISABLE_NS_PREFIX_CHECKS) +#if defined(MIDL_NS_PREFIX) +#define CHECK_NS_PREFIX_STATE "always" +#else +#define CHECK_NS_PREFIX_STATE "never" +#endif // MIDL_NS_PREFIX +#endif // !defined(DISABLE_NS_PREFIX_CHECKS) + + +#pragma push_macro("ABI_CONCAT") +#pragma push_macro("ABI_PARAMETER") +#pragma push_macro("ABI_NAMESPACE_BEGIN") +#pragma push_macro("ABI_NAMESPACE_END") +#pragma push_macro("C_IID") +#undef ABI_CONCAT +#undef ABI_PARAMETER +#undef ABI_NAMESPACE_BEGIN +#undef ABI_NAMESPACE_END +#undef C_IID +#define ABI_CONCAT(x,y) x##y + +// /ns_prefix optional state +#if defined(MIDL_NS_PREFIX) +#if defined(__cplusplus) +#define ABI_PARAMETER(x) ABI::x +#define ABI_NAMESPACE_BEGIN namespace ABI { +#define ABI_NAMESPACE_END } +#else // !defined(__cplusplus) +#define C_ABI_PARAMETER(x) ABI_CONCAT(__x_ABI_C, x) +#endif // !defined(__cplusplus) +#define C_IID(x) ABI_CONCAT(IID___x_ABI_C, x) +#else +#if defined(__cplusplus) +#define ABI_PARAMETER(x) x +#define ABI_NAMESPACE_BEGIN +#define ABI_NAMESPACE_END +#else // !defined(__cplusplus) +#define C_ABI_PARAMETER(x) ABI_CONCAT(__x_, x) +#endif // !defined(__cplusplus) +#define C_IID(x) ABI_CONCAT(IID___x_, x) +#endif // defined(MIDL_NS_PREFIX) + +#pragma push_macro("MIDL_CONST_ID") +#undef MIDL_CONST_ID +#define MIDL_CONST_ID const __declspec(selectany) + + +// API Contract Inclusion Definitions +#if !defined(SPECIFIC_API_CONTRACT_DEFINITIONS) +#if !defined(WINDOWS_APPLICATIONMODEL_CALLS_CALLSPHONECONTRACT_VERSION) +#define WINDOWS_APPLICATIONMODEL_CALLS_CALLSPHONECONTRACT_VERSION 0x60000 +#endif // defined(WINDOWS_APPLICATIONMODEL_CALLS_CALLSPHONECONTRACT_VERSION) + +#if !defined(WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION) +#define WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION 0x40000 +#endif // defined(WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION) + +#if !defined(WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION) +#define WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION 0xf0000 +#endif // defined(WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION) + +#if !defined(WINDOWS_NETWORKING_SOCKETS_CONTROLCHANNELTRIGGERCONTRACT_VERSION) +#define WINDOWS_NETWORKING_SOCKETS_CONTROLCHANNELTRIGGERCONTRACT_VERSION 0x30000 +#endif // defined(WINDOWS_NETWORKING_SOCKETS_CONTROLCHANNELTRIGGERCONTRACT_VERSION) + +#if !defined(WINDOWS_PHONE_PHONECONTRACT_VERSION) +#define WINDOWS_PHONE_PHONECONTRACT_VERSION 0x10000 +#endif // defined(WINDOWS_PHONE_PHONECONTRACT_VERSION) + +#if !defined(WINDOWS_PHONE_PHONEINTERNALCONTRACT_VERSION) +#define WINDOWS_PHONE_PHONEINTERNALCONTRACT_VERSION 0x10000 +#endif // defined(WINDOWS_PHONE_PHONEINTERNALCONTRACT_VERSION) + +#if !defined(WINDOWS_UI_WEBUI_CORE_WEBUICOMMANDBARCONTRACT_VERSION) +#define WINDOWS_UI_WEBUI_CORE_WEBUICOMMANDBARCONTRACT_VERSION 0x10000 +#endif // defined(WINDOWS_UI_WEBUI_CORE_WEBUICOMMANDBARCONTRACT_VERSION) + +#endif // defined(SPECIFIC_API_CONTRACT_DEFINITIONS) + + +// Header files for imported files +#include "oaidl.h" +#include "inspectable.h" +#include "Windows.Foundation.h" + +#if defined(__cplusplus) && !defined(CINTERFACE) +/* Forward Declarations */ +#ifndef ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ +#define ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ +ABI_NAMESPACE_BEGIN +namespace Microsoft { + namespace Internal { + namespace PushNotifications { + interface INotificationListener; + } /* PushNotifications */ + } /* Internal */ +} /* Microsoft */ +ABI_NAMESPACE_END +#define __x_Microsoft_CInternal_CPushNotifications_CINotificationListener ABI_PARAMETER(Microsoft::Internal::PushNotifications::INotificationListener) + +#endif // ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ + + + +#pragma warning (push) +#pragma warning (disable:4668) +#pragma warning (disable:4001) +#pragma once +#pragma warning (pop) + +/* + * + * Interface Microsoft.Internal.PushNotifications.INotificationListener + * + */ +#if !defined(____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__) +#define ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__ +extern const __declspec(selectany) _Null_terminated_ WCHAR InterfaceName_Microsoft_Internal_PushNotifications_INotificationListener[] = L"Microsoft.Internal.PushNotifications.INotificationListener"; +ABI_NAMESPACE_BEGIN +namespace Microsoft { + namespace Internal { + namespace PushNotifications { + /* [version, object, uuid("522D1AC5-A9B1-4DE9-9BFD-0B4C56459293")] */ + MIDL_INTERFACE("522D1AC5-A9B1-4DE9-9BFD-0B4C56459293") + INotificationListener : public IInspectable + { + public: + virtual HRESULT STDMETHODCALLTYPE OnRawNotificationReceived( + /* [in] */unsigned int payloadLength, + /* [size_is(payloadLength), in] */__RPC__in_ecount_full(payloadLength) ::byte * payload, + /* [in] */__RPC__in HSTRING correlationVector + ) = 0; + + }; + + MIDL_CONST_ID IID & IID_INotificationListener=_uuidof(INotificationListener); + + } /* PushNotifications */ + } /* Internal */ +} /* Microsoft */ +ABI_NAMESPACE_END + +EXTERN_C const IID C_IID(Microsoft_CInternal_CPushNotifications_CINotificationListener); +#endif /* !defined(____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__) */ + + +#else // !defined(__cplusplus) +/* Forward Declarations */ +#ifndef ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ +#define ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ +typedef interface C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener); + +#endif // ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ + + +#pragma warning (push) +#pragma warning (disable:4668) +#pragma warning (disable:4001) +#pragma once +#pragma warning (pop) + +/* + * + * Interface Microsoft.Internal.PushNotifications.INotificationListener + * + */ +#if !defined(____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__) +#define ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__ +extern const __declspec(selectany) _Null_terminated_ WCHAR InterfaceName_Microsoft_Internal_PushNotifications_INotificationListener[] = L"Microsoft.Internal.PushNotifications.INotificationListener"; +/* [version, object, uuid("522D1AC5-A9B1-4DE9-9BFD-0B4C56459293")] */ +typedef struct C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListenerVtbl) +{ + BEGIN_INTERFACE + HRESULT ( STDMETHODCALLTYPE *QueryInterface)( + __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject + ); + +ULONG ( STDMETHODCALLTYPE *AddRef )( + __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This + ); + +ULONG ( STDMETHODCALLTYPE *Release )( + __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This + ); + +HRESULT ( STDMETHODCALLTYPE *GetIids )( + __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This, + /* [out] */ __RPC__out ULONG *iidCount, + /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID **iids + ); + +HRESULT ( STDMETHODCALLTYPE *GetRuntimeClassName )( + __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This, + /* [out] */ __RPC__deref_out_opt HSTRING *className + ); + +HRESULT ( STDMETHODCALLTYPE *GetTrustLevel )( + __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This, + /* [OUT ] */ __RPC__out TrustLevel *trustLevel + ); +HRESULT ( STDMETHODCALLTYPE *OnRawNotificationReceived )( + C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This, + /* [in] */unsigned int payloadLength, + /* [size_is(payloadLength), in] */__RPC__in_ecount_full(payloadLength) byte * payload, + /* [in] */__RPC__in HSTRING correlationVector + ); + END_INTERFACE + +} C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListenerVtbl); + +interface C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) +{ + CONST_VTBL struct C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListenerVtbl) *lpVtbl; +}; + +#ifdef COBJMACROS +#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_QueryInterface(This,riid,ppvObject) \ +( (This)->lpVtbl->QueryInterface(This,riid,ppvObject) ) + +#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_AddRef(This) \ + ( (This)->lpVtbl->AddRef(This) ) + +#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_Release(This) \ + ( (This)->lpVtbl->Release(This) ) + +#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_GetIids(This,iidCount,iids) \ + ( (This)->lpVtbl->GetIids(This,iidCount,iids) ) + +#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_GetRuntimeClassName(This,className) \ + ( (This)->lpVtbl->GetRuntimeClassName(This,className) ) + +#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_GetTrustLevel(This,trustLevel) \ + ( (This)->lpVtbl->GetTrustLevel(This,trustLevel) ) + +#define __x_Microsoft_CInternal_CPushNotifications_CINotificationListener_OnRawNotificationReceived(This,payloadLength,payload,correlationVector) \ + ( (This)->lpVtbl->OnRawNotificationReceived(This,payloadLength,payload,correlationVector) ) + + +#endif /* COBJMACROS */ + + +EXTERN_C const IID C_IID(Microsoft_CInternal_CPushNotifications_CINotificationListener); +#endif /* !defined(____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__) */ + + +#endif // defined(__cplusplus) +#pragma pop_macro("MIDL_CONST_ID") +#pragma pop_macro("C_IID") +#pragma pop_macro("ABI_CONCAT") +#pragma pop_macro("ABI_PARAMETER") +#pragma pop_macro("ABI_NAMESPACE_BEGIN") +#pragma pop_macro("ABI_NAMESPACE_END") + + +#endif // __pushnotificationsrt_p_h__ + +#endif // __pushnotificationsrt_h__ From 78cb42f42adbeac623b5f854f83434161ce98c06 Mon Sep 17 00:00:00 2001 From: Paul Purifoy Date: Fri, 3 Sep 2021 12:27:23 -0700 Subject: [PATCH 31/50] Some nits --- dev/PushNotifications/PushNotificationChannel.cpp | 6 ++++-- dev/PushNotifications/PushNotificationManager.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/dev/PushNotifications/PushNotificationChannel.cpp b/dev/PushNotifications/PushNotificationChannel.cpp index 092b8d587b..de4009a992 100644 --- a/dev/PushNotifications/PushNotificationChannel.cpp +++ b/dev/PushNotifications/PushNotificationChannel.cpp @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. #include "pch.h" @@ -87,7 +87,9 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { if (auto strong = weak_self.get()) { - handler(*strong, winrt::make(args)); + auto pushArgs = winrt::make(args); + pushArgs.Handled(true); + handler(*strong, pushArgs); }; }); } diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index 5b7d7b0326..bdde42d634 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -118,7 +118,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { THROW_HR_IF(E_INVALIDARG, (remoteId == winrt::guid())); - auto cancellation{ co_await winrt::get_cancellation_token() }; + auto cancellation{ co_await winrt::get_cancellation_token() }; cancellation.enable_propagation(true); From 8496413880af62b7271fd16d5887ff6033c17574 Mon Sep 17 00:00:00 2001 From: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> Date: Fri, 3 Sep 2021 13:30:44 -0700 Subject: [PATCH 32/50] Addressed comments --- .../PushNotificationManager.cpp | 21 ++++++++----------- .../NotificationsLongRunningProcess.idl | 4 ++-- .../NotificationListener.cpp | 9 +++++--- .../NotificationListener.h | 2 +- .../NotificationListenerManager.cpp | 8 +++---- .../platform.cpp | 18 +++++++++------- .../platform.h | 6 +++--- .../winmain.cpp | 5 ++--- 8 files changed, 37 insertions(+), 36 deletions(-) diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index bdde42d634..277fbf8265 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -69,7 +69,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation const winrt::guid& remoteId, _Out_ wil::unique_cotaskmem_string &unpackagedAppUserModelId) { - auto coInitialize = wil::CoInitializeEx(); + //auto coInitialize = wil::CoInitializeEx(); auto notificationPlatform{ wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; @@ -145,13 +145,10 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation ChannelDetails channelInfo{}; winrt::hresult hr = CreateChannelWithRemoteIdHelper(remoteId, channelInfo); - /* - RemoteId APIs are not applicable for downlevel OS versions. - So we get error E_NOTIMPL and we fallback to calling into - Public WinRT API CreatePushNotificationChannelForApplicationAsync - to request for channels - */ - + // RemoteId APIs are not applicable for downlevel OS versions. + // So we get error E_NOTIMPL and we fallback to calling into + // public WinRT API CreatePushNotificationChannelForApplicationAsync + // to request a channel. if (SUCCEEDED(hr)) { co_return winrt::make( @@ -255,14 +252,14 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation if (isProtocolActivatorSet) { - auto coInitialize = wil::CoInitializeEx(); + //auto coInitialize = wil::CoInitializeEx(); wil::com_ptr notificationPlatform{ wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; wil::unique_cotaskmem_string processName; THROW_IF_FAILED(GetCurrentProcessPath(processName)); - THROW_IF_FAILED(notificationPlatform->RegisterActivator(processName.get())); + THROW_IF_FAILED(notificationPlatform->RegisterLongRunningActivator(processName.get())); } DWORD cookie = 0; @@ -390,14 +387,14 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation if (WI_IsFlagSet(options, PushNotificationRegistrationOptions::ProtocolActivator)) { - auto coInitialize = wil::CoInitializeEx(); + //auto coInitialize = wil::CoInitializeEx(); wil::com_ptr notificationPlatform{ wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; wil::unique_cotaskmem_string processName; THROW_IF_FAILED(GetCurrentProcessPath(processName)); - THROW_IF_FAILED(notificationPlatform->UnregisterActivator(processName.get())); + THROW_IF_FAILED(notificationPlatform->UnregisterLongRunningActivator(processName.get())); } } diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl index cfd8af1ddb..d28d1e3345 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl @@ -19,9 +19,9 @@ interface IWpnForegroundSink : IUnknown [pointer_default(unique)] interface INotificationsLongRunningPlatform : IUnknown { - HRESULT RegisterActivator([in] LPCWSTR processName); + HRESULT RegisterLongRunningActivator([in] LPCWSTR processName); - HRESULT UnregisterActivator([in] LPCWSTR processName); + HRESULT UnregisterLongRunningActivator([in] LPCWSTR processName); HRESULT RegisterFullTrustApplication([in] LPCWSTR processName, [in] GUID remoteId, [out] LPWSTR* appId); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp index aa6cc78305..1663ad7853 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp @@ -1,6 +1,9 @@ #include "pch.h" -HRESULT NotificationListener::RuntimeClassInitialize(std::shared_ptr foregroundSinkManager, std::wstring appId, std::wstring processName) +HRESULT NotificationListener::RuntimeClassInitialize( + std::shared_ptr foregroundSinkManager, + std::wstring appId, + std::wstring processName) { m_foregroundSinkManager = foregroundSinkManager; @@ -22,7 +25,7 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationListener::OnRawNotificationReceived commandLine.append(reinterpret_cast(payload), payloadLength); commandLine.append("\""); - std::string processNameAsUtf8String = ConvertProcessNameToUtf8String(); + const std::string processNameAsUtf8String = ConvertProcessNameToUtf8String(); SHELLEXECUTEINFOA shellExecuteInfo{}; shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOA); @@ -42,7 +45,7 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationListener::OnRawNotificationReceived } CATCH_RETURN() -std::string NotificationListener::ConvertProcessNameToUtf8String() +const std::string NotificationListener::ConvertProcessNameToUtf8String() { int size_needed = WideCharToMultiByte(CP_UTF8, 0, m_processName.c_str(), -1, NULL, 0, nullptr, nullptr); THROW_LAST_ERROR_IF(size_needed == 0); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h index e7872f8db4..07f576eb05 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h @@ -10,7 +10,7 @@ class NotificationListener : public Microsoft::WRL::RuntimeClass<::ABI::Microsof STDMETHOD(OnRawNotificationReceived)(unsigned int payloadLength, _In_ byte* payload, _In_ HSTRING correlationVector) noexcept; private: - std::string ConvertProcessNameToUtf8String(); + const std::string ConvertProcessNameToUtf8String(); std::shared_ptr m_foregroundSinkManager; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp index 2b830e8317..add441fc44 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp @@ -20,12 +20,12 @@ void NotificationListenerManager::AddListener(std::wstring appId, std::wstring p THROW_HR_IF(E_INVALIDARG, appId.empty()); THROW_HR_IF(E_INVALIDARG, processName.empty()); - ComPtr listener; - THROW_IF_FAILED(MakeAndInitialize(&listener, m_foregroundSinkManager, appId, processName)); - THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appId.c_str(), listener.Get())); - if (m_notificationListeners.find(appId) == std::end(m_notificationListeners)) { + ComPtr listener; + THROW_IF_FAILED(MakeAndInitialize(&listener, m_foregroundSinkManager, appId, processName)); + THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appId.c_str(), listener.Get())); + AgileRef agileListener; THROW_IF_FAILED(AsAgile(listener.Get(), &agileListener)); m_notificationListeners.insert({ appId, agileListener }); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index fbd95c491b..dac19cd621 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -60,7 +60,7 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterF auto lock = m_lock.lock_exclusive(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - std::wstring appIdentifier = GetAppIdentifier(processName); + const std::wstring appIdentifier = GetAppIdentifier(processName); THROW_IF_FAILED(PushNotifications_RegisterFullTrustApplication(appIdentifier.c_str(), remoteId)); wil::unique_cotaskmem_string outAppId = wil::make_unique_string(appIdentifier.c_str()); @@ -70,12 +70,12 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterF } CATCH_RETURN() -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterActivator(_In_ PCWSTR processName) noexcept try +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterLongRunningActivator(_In_ PCWSTR processName) noexcept try { auto lock = m_lock.lock_shared(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - std::wstring appId = GetAppIdentifier(processName); + const std::wstring appId = GetAppIdentifier(processName); m_notificationListenerManager.AddListener(appId, processName); m_lifetimeManager.Cancel(); @@ -84,12 +84,12 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterA } CATCH_RETURN() -STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterActivator(_In_ PCWSTR processName) noexcept try +STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::UnregisterLongRunningActivator(_In_ PCWSTR processName) noexcept try { auto lock = m_lock.lock_shared(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - std::wstring appId = GetAppIdentifier(processName); + const std::wstring appId = GetAppIdentifier(processName); m_notificationListenerManager.RemoveListener(appId); m_foregroundSinkManager->Remove(appId); @@ -109,11 +109,13 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::RegisterF auto lock = m_lock.lock_exclusive(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - std::wstring appId = GetAppIdentifier(processName); + const std::wstring appId = GetAppIdentifier(processName); m_notificationListenerManager.AddListener(appId, processName); m_foregroundSinkManager->Add(appId, sink); + m_lifetimeManager.Cancel(); + return S_OK; } CATCH_RETURN() @@ -123,7 +125,7 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationsLongRunningPlatformImpl::Unregiste auto lock = m_lock.lock_exclusive(); THROW_HR_IF(WPN_E_PLATFORM_UNAVAILABLE, m_shutdown); - std::wstring appId = GetAppIdentifier(processName); + const std::wstring appId = GetAppIdentifier(processName); m_foregroundSinkManager->Remove(appId); return S_OK; @@ -155,7 +157,7 @@ std::map NotificationsLongRunningPlatformImpl::GetFu return mapOfFullTrustApps; } -std::wstring NotificationsLongRunningPlatformImpl::GetAppIdentifier(std::wstring const& processName) +const std::wstring NotificationsLongRunningPlatformImpl::GetAppIdentifier(std::wstring const& processName) { auto values{ m_storage.Values() }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h index 9d2445e8a3..cd4a86a53d 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.h @@ -15,9 +15,9 @@ struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRu STDMETHOD(RegisterFullTrustApplication)(_In_ PCWSTR processName, GUID remoteId, _Out_ PWSTR* appId) noexcept; - STDMETHOD(RegisterActivator)(_In_ PCWSTR processName) noexcept; + STDMETHOD(RegisterLongRunningActivator)(_In_ PCWSTR processName) noexcept; - STDMETHOD(UnregisterActivator)(_In_ PCWSTR processName) noexcept; + STDMETHOD(UnregisterLongRunningActivator)(_In_ PCWSTR processName) noexcept; STDMETHOD(RegisterForegroundActivator)(_In_ IWpnForegroundSink* sink, _In_ PCWSTR processName) noexcept; @@ -26,7 +26,7 @@ struct __declspec(uuid(PUSHNOTIFICATIONS_IMPL_CLSID_STRING)) NotificationsLongRu private: std::map GetFullTrustApps(); - std::wstring GetAppIdentifier(std::wstring const& processName); + const std::wstring GetAppIdentifier(std::wstring const& processName); void RemoveAppIdentifier(std::wstring const& processName); winrt::Windows::Storage::ApplicationDataContainer m_storage{ nullptr }; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp index 00201be33e..fd6b5f5911 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/winmain.cpp @@ -21,7 +21,7 @@ using namespace Microsoft::WRL; int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /*lpCmdLine*/, int /*nCmdShow*/) { - RETURN_IF_FAILED(::CoInitializeEx(nullptr, COINITBASE_MULTITHREADED)); + auto coInitialize = wil::CoInitializeEx(); ComPtr platformFactory; RETURN_IF_FAILED(MakeAndInitialize(&platformFactory)); @@ -47,13 +47,12 @@ int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, PSTR /* // Wait returns if the platform realizes there are no more apps to be tracked. // It also returns if the timer initialized at the process start fires (see NotificationsLongRunningPlatformImpl::Initialize). platform->WaitForLifetimeEvent(); + platform->Shutdown(); RETURN_IF_FAILED(module.UnregisterCOMObject(nullptr, &cookie, 1)); module.Terminate(); - ::CoUninitialize(); - return 0; } From 3cab425288eedd7e609a66c9a95b0fcf1cca7272 Mon Sep 17 00:00:00 2001 From: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> Date: Fri, 3 Sep 2021 13:44:34 -0700 Subject: [PATCH 33/50] Fixed mistake - Removed comments --- dev/PushNotifications/PushNotificationManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index 277fbf8265..d4b0571bb9 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -69,7 +69,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation const winrt::guid& remoteId, _Out_ wil::unique_cotaskmem_string &unpackagedAppUserModelId) { - //auto coInitialize = wil::CoInitializeEx(); + auto coInitialize = wil::CoInitializeEx(); auto notificationPlatform{ wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; @@ -252,7 +252,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation if (isProtocolActivatorSet) { - //auto coInitialize = wil::CoInitializeEx(); + auto coInitialize = wil::CoInitializeEx(); wil::com_ptr notificationPlatform{ wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; @@ -387,7 +387,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation if (WI_IsFlagSet(options, PushNotificationRegistrationOptions::ProtocolActivator)) { - //auto coInitialize = wil::CoInitializeEx(); + auto coInitialize = wil::CoInitializeEx(); wil::com_ptr notificationPlatform{ wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; From 80469a43732919bea317db8efc4e3a58557a2f8b Mon Sep 17 00:00:00 2001 From: Paul Purifoy Date: Fri, 3 Sep 2021 14:17:20 -0700 Subject: [PATCH 34/50] Add LRP binaries to CopyFilestoStagingDir --- build/CopyFilesToStagingDir.ps1 | 14 ++++++-- .../PushNotifications-Constants.h | 4 +++ .../NotificationsLongRunningProcess.idl | 4 +-- tools/GeneratePushNotificationsOverrides.ps1 | 33 ++++++++++++------- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/build/CopyFilesToStagingDir.ps1 b/build/CopyFilesToStagingDir.ps1 index 0bc92e030f..0980e61dd9 100644 --- a/build/CopyFilesToStagingDir.ps1 +++ b/build/CopyFilesToStagingDir.ps1 @@ -89,11 +89,17 @@ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.p # MSIX Main package PublishFile $FullBuildOutput\DynamicDependency.DataStore\DynamicDependency.DataStore.exe $NugetDir\runtimes\win10-$Platform\native PublishFile $FullBuildOutput\DynamicDependency.DataStore\DynamicDependency.DataStore.pdb $NugetDir\runtimes\win10-$Platform\native -PublishFile $FullBuildOutput\PushNotificationsLongRunningTask\PushNotificationsLongRunningTask.exe $NugetDir\runtimes\win10-$Platform\native -PublishFile $FullBuildOutput\PushNotificationsLongRunningTask\PushNotificationsLongRunningTask.pdb $NugetDir\runtimes\win10-$Platform\native PublishFile $FullBuildOutput\DynamicDependency.DataStore.ProxyStub\DynamicDependency.DataStore.ProxyStub.dll $NugetDir\runtimes\win10-$Platform\native PublishFile $FullBuildOutput\DynamicDependency.DataStore.ProxyStub\DynamicDependency.DataStore.ProxyStub.pdb $NugetDir\runtimes\win10-$Platform\native # +# PushNotifications LRP +PublishFile $FullBuildOutput\PushNotificationsLongRunningTask\PushNotificationsLongRunningTask.exe $NugetDir\runtimes\win10-$Platform\native +PublishFile $FullBuildOutput\PushNotificationsLongRunningTask\PushNotificationsLongRunningTask.pdb $NugetDir\runtimes\win10-$Platform\native +PublishFile $FullBuildOutput\PushNotificationsLongRunningTask.StartupTask\PushNotificationsLongRunningTask.StartupTask.exe $NugetDir\runtimes\win10-$Platform\native +PublishFile $FullBuildOutput\PushNotificationsLongRunningTask.StartupTask\PushNotificationsLongRunningTask.StartupTask.pdb $NugetDir\runtimes\win10-$Platform\native +PublishFile $FullBuildOutput\PushNotificationsLongRunningTask.ProxyStub\PushNotificationsLongRunningTask.ProxyStub.dll $NugetDir\runtimes\win10-$Platform\native +PublishFile $FullBuildOutput\PushNotificationsLongRunningTask.ProxyStub\PushNotificationsLongRunningTask.ProxyStub.pdb $NugetDir\runtimes\win10-$Platform\native +# # MSIX DDLM package PublishFile $FullBuildOutput\DynamicDependencyLifetimeManager\DynamicDependencyLifetimeManager.exe $NugetDir\runtimes\win10-$Platform\native PublishFile $FullBuildOutput\DynamicDependencyLifetimeManager\DynamicDependencyLifetimeManager.pdb $NugetDir\runtimes\win10-$Platform\native @@ -120,5 +126,7 @@ PublishFile $FullBuildOutput\Microsoft.Windows.PushNotifications.Projection\Micr PublishFile $FullBuildOutput\Microsoft.Windows.System.Power.Projection\Microsoft.Windows.System.Power.Projection.dll $NugetDir\lib\net5.0-windows10.0.17763.0 PublishFile $FullBuildOutput\Microsoft.Windows.System.Power.Projection\Microsoft.Windows.System.Power.Projection.pdb $NugetDir\lib\net5.0-windows10.0.17763.0 # -# Dynamic Dependency build overrides +# Build overrides PublishFile $OverrideDir\DynamicDependency-Override.json $NugetDir\runtimes\win10-$Platform\native +PublishFile $OverrideDir\PushNotifications-Override.json $NugetDir\runtimes\win10-$Platform\native +# \ No newline at end of file diff --git a/dev/PushNotifications/PushNotifications-Constants.h b/dev/PushNotifications/PushNotifications-Constants.h index fe924ba682..fad7d21336 100644 --- a/dev/PushNotifications/PushNotifications-Constants.h +++ b/dev/PushNotifications/PushNotifications-Constants.h @@ -12,6 +12,10 @@ #define PUSHNOTIFICATIONS_IMPL_CLSID_UUID E739C755-0D09-48DF-A468-A5DF0B5422DC #define PUSHNOTIFICATIONS_IMPL_CLSID_STRING _STRINGIZE(PUSHNOTIFICATIONS_IMPL_CLSID_UUID) +#define PUSHNOTIFICATIONS_LRP_CLSID_UUID 60FC21B2-B396-4D49-94F0-7555869FB93C + +#define PUSHNOTIFICATIONS_FOREGROUNDSINK_CLSID_UUID 25604D55-9B17-426F-9D67-2B11B3A65598 + #if defined(WINDOWSAPPSDK_BUILD_PIPELINE) && (WINDOWSAPPSDK_BUILD_PIPELINE == 1) #include "PushNotifications-Override.h" #endif diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl index cfd8af1ddb..046fc61ab4 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/NotificationsLongRunningProcess.idl @@ -7,7 +7,7 @@ import "ocidl.idl"; #include "../PushNotifications-Constants.h" [object] -[uuid(25604D55-9B17-426F-9D67-2B11B3A65598)] +[uuid(PUSHNOTIFICATIONS_FOREGROUNDSINK_CLSID_UUID)] [pointer_default(unique)] interface IWpnForegroundSink : IUnknown { @@ -15,7 +15,7 @@ interface IWpnForegroundSink : IUnknown }; [object] -[uuid(60FC21B2-B396-4D49-94F0-7555869FB93C)] +[uuid(PUSHNOTIFICATIONS_LRP_CLSID_UUID)] [pointer_default(unique)] interface INotificationsLongRunningPlatform : IUnknown { diff --git a/tools/GeneratePushNotificationsOverrides.ps1 b/tools/GeneratePushNotificationsOverrides.ps1 index 896851e481..16d3393a1f 100644 --- a/tools/GeneratePushNotificationsOverrides.ps1 +++ b/tools/GeneratePushNotificationsOverrides.ps1 @@ -38,8 +38,6 @@ else Write-Output "$Path exists" } -$pushnotifications_clsid_uuid = New-Guid - # Generate the json file $content_json=@" { @@ -50,14 +48,27 @@ $content_json=@" "UUID": "E739C755-0D09-48DF-A468-A5DF0B5422DC" } }, - "Task": { + "ComInterfaces": { + "LRP": { + "CLSID": { + "UUID": "60FC21B2-B396-4D49-94F0-7555869FB93C" + } + }, + "ForegroundSink": { + "CLSID": { + "UUID": "25604D55-9B17-426F-9D67-2B11B3A65598" + } + } + }, + "ComServer": { "CLSID": { - "UUID": "$pushnotifications_clsid_uuid" + "UUID": "2DC0B845-A8FD-44D6-B79C-91152C2511EB" } - } + } } } "@ + $file_json = Join-Path $Path 'PushNotifications-Override.json' Write-Output "Writing $file_json..." "$content_json" | Out-File $file_json -Encoding utf8 @@ -88,14 +99,14 @@ $content_h=@" #define PUSHNOTIFICATIONS_IMPL_CLSID_STRING _STRINGIZE(PUSHNOTIFICATIONS_IMPL_CLSID_UUID) #endif -#ifdef PUSHNOTIFICATIONS_TASK_CLSID_UUID -#undef PUSHNOTIFICATIONS_TASK_CLSID_UUID -#define PUSHNOTIFICATIONS_TASK_CLSID_UUID $pushnotifications_clsid_uuid +#ifdef PUSHNOTIFICATIONS_LRP_CLSID_UUID +#undef PUSHNOTIFICATIONS_LRP_CLSID_UUID +#define PUSHNOTIFICATIONS_LRP_CLSID_UUID 60FC21B2-B396-4D49-94F0-7555869FB93C #endif -#ifdef PUSHNOTIFICATIONS_TASK_CLSID_STRING -#undef PUSHNOTIFICATIONS_TASK_CLSID_STRING -#define PUSHNOTIFICATIONS_TASK_CLSID_STRING _STRINGIZE(PUSHNOTIFICATIONS_TASK_CLSID_UUID) +#ifdef PUSHNOTIFICATIONS_FOREGROUNDSINK_CLSID_UUID +#undef PUSHNOTIFICATIONS_FOREGROUNDSINK_CLSID_UUID +#define PUSHNOTIFICATIONS_FOREGROUNDSINK_CLSID_UUID 25604D55-9B17-426F-9D67-2B11B3A65598 #endif "@ $file_h = Join-Path $Path 'PushNotifications-Override.h' From b7b98b9ef11a1a11b1d8a6a9620b322e7ec984aa Mon Sep 17 00:00:00 2001 From: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> Date: Fri, 3 Sep 2021 15:24:25 -0700 Subject: [PATCH 35/50] Addressed comments --- dev/AppLifecycle/AppInstance.cpp | 2 +- dev/PushNotifications/PushNotificationDummyDeferral.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dev/AppLifecycle/AppInstance.cpp b/dev/AppLifecycle/AppInstance.cpp index 0d129c4bd3..4cc58586e8 100644 --- a/dev/AppLifecycle/AppInstance.cpp +++ b/dev/AppLifecycle/AppInstance.cpp @@ -339,7 +339,7 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation // protocol, except the catch-all LaunchActivatedEventArgs case. if (!contractArgument.empty()) { - if (CompareStringOrdinal(contractArgument.data(), static_cast(contractArgument.size()), L"WindowsAppRuntimePushServer", -1, TRUE) == CSTR_EQUAL) + if (contractArgument == L"WindowsAppRuntimePushServer") { // Generate a basic encoded launch Uri for all Push activations. std::wstring tempContractData = GenerateEncodedLaunchUri(L"App", c_pushContractId); diff --git a/dev/PushNotifications/PushNotificationDummyDeferral.h b/dev/PushNotifications/PushNotificationDummyDeferral.h index 35a3e826ba..75e2ab06e8 100644 --- a/dev/PushNotifications/PushNotificationDummyDeferral.h +++ b/dev/PushNotifications/PushNotificationDummyDeferral.h @@ -15,11 +15,12 @@ struct PushNotificationDummyDeferral : winrt::implements { - HRESULT __stdcall CreateInstance(_In_opt_ IUnknown* aggregateInterface, _In_ REFIID interfaceId, _Outptr_ VOID** object) noexcept final + HRESULT __stdcall CreateInstance(_In_opt_ IUnknown* aggregateInterface, _In_ REFIID interfaceId, _Outptr_ VOID** object) noexcept final try { - RETURN_HR_IF(CLASS_E_NOAGGREGATION, aggregateInterface != nullptr); + THROW_HR_IF(CLASS_E_NOAGGREGATION, aggregateInterface != nullptr); return winrt::make().as(interfaceId, object); } + CATCH_RETURN() HRESULT __stdcall LockServer(BOOL) noexcept final { From f9f0abea82a224c974f0925a17ad142c1685e4bf Mon Sep 17 00:00:00 2001 From: Paul Purifoy Date: Tue, 7 Sep 2021 16:19:41 -0700 Subject: [PATCH 36/50] Merge main to LRP --- dev/PushNotifications/PushNotificationManager.cpp | 8 ++++---- dev/PushNotifications/PushNotificationManager.h | 4 ---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index 14ae5ea595..8c87f1007d 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -144,7 +144,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { try { - if (IsActivatorSupported(PushNotificationRegistrationOptions::PushTrigger)) + if (IsActivatorSupported(PushNotificationRegistrationActivators::PushTrigger)) { ChannelDetails channelInfo{}; winrt::hresult hr = CreateChannelWithRemoteIdHelper(remoteId, channelInfo); @@ -248,10 +248,10 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation auto registrationActivators{ details.Activators() }; - auto isBackgroundTaskFlagSet{ WI_IsAnyFlagSet(registrationActivators, PushNotificationRegistrationOptions::PushTrigger | PushNotificationRegistrationOptions::ComActivator) }; + auto isBackgroundTaskFlagSet{ WI_IsAnyFlagSet(registrationActivators, PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator) }; THROW_HR_IF(E_INVALIDARG, isBackgroundTaskFlagSet && !IsActivatorSupported(registrationActivators)); - auto isProtocolActivatorSet{ WI_IsFlagSet(registrationActivators, PushNotificationRegistrationOptions::ProtocolActivator) }; + auto isProtocolActivatorSet{ WI_IsFlagSet(registrationActivators, PushNotificationRegistrationActivators::ProtocolActivator) }; THROW_HR_IF(E_INVALIDARG, isProtocolActivatorSet && !IsActivatorSupported(registrationActivators)); if (isProtocolActivatorSet) @@ -393,7 +393,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation s_comActivatorRegistration.reset(); } - if (WI_IsFlagSet(options, PushNotificationRegistrationOptions::ProtocolActivator)) + if (WI_IsFlagSet(activators, PushNotificationRegistrationActivators::ProtocolActivator)) { auto coInitialize = wil::CoInitializeEx(); diff --git a/dev/PushNotifications/PushNotificationManager.h b/dev/PushNotifications/PushNotificationManager.h index aacc0caa0a..150f0ae4f8 100644 --- a/dev/PushNotifications/PushNotificationManager.h +++ b/dev/PushNotifications/PushNotificationManager.h @@ -19,10 +19,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation static winrt::Windows::Foundation::IAsyncOperationWithProgress CreateChannelAsync(winrt::guid const& remoteId); static bool IsActivatorSupported(Microsoft::Windows::PushNotifications::PushNotificationRegistrationActivators const& activators); - - private: - static bool IsChannelRequestRetryable(const winrt::hresult& hrException); - static bool IsBackgroundTaskBuilderAvailable(); }; } namespace winrt::Microsoft::Windows::PushNotifications::factory_implementation From 256155ee822b70b85cd55c8f9c3b3a496bef3c69 Mon Sep 17 00:00:00 2001 From: eric langlois Date: Tue, 14 Sep 2021 12:53:22 -0700 Subject: [PATCH 37/50] Telemetry Update for Unpackaged Apps (#1385) * Adding support for unpackaged apps * Using inline statics to cache data * Code cleanup * Code cleanup * Simplifying rethrow code * Addressing feedback * Distinguishing between legacy and modern impl * caching legacy status to it is also available when the call fails * Adding const to better express the intent * Code cleanup * Code cleanup * PR feedback Co-authored-by: Eric Langlois --- .../PushNotificationManager.cpp | 44 +++++----- .../PushNotificationTelemetry.h | 82 ++++++++++++++----- 2 files changed, 83 insertions(+), 43 deletions(-) diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index 8c87f1007d..905ac1f920 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -118,6 +118,8 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation winrt::IAsyncOperationWithProgress PushNotificationManager::CreateChannelAsync(const winrt::guid &remoteId) { + bool usingLegacyImplementation{ false }; + try { THROW_HR_IF(E_INVALIDARG, (remoteId == winrt::guid())); @@ -155,6 +157,8 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation // to request a channel. if (SUCCEEDED(hr)) { + PushNotificationTelemetry::ChannelRequestedByApi(S_OK, remoteId, usingLegacyImplementation); + co_return winrt::make( winrt::make(channelInfo), S_OK, @@ -162,15 +166,14 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation } else if (hr == E_NOTIMPL) { + usingLegacyImplementation = true; + PushNotificationChannelManager channelManager{}; winrt::PushNotificationChannel pushChannelReceived{ nullptr }; pushChannelReceived = co_await channelManager.CreatePushNotificationChannelForApplicationAsync(); - PushNotificationTelemetry::ChannelRequestedByApi( - S_OK, - AppModel::Identity::IsPackagedProcess(), - remoteId); + PushNotificationTelemetry::ChannelRequestedByApi(S_OK, remoteId, usingLegacyImplementation); co_return winrt::make( winrt::make(pushChannelReceived), @@ -189,6 +192,8 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation PushNotificationChannelManager channelManager{}; winrt::PushNotificationChannel pushChannelReceived{ co_await channelManager.CreatePushNotificationChannelForApplicationAsync(unpackagedAppUserModelId.get()) }; + PushNotificationTelemetry::ChannelRequestedByApi(S_OK, remoteId, usingLegacyImplementation); + co_return winrt::make( winrt::make(pushChannelReceived), S_OK, @@ -209,11 +214,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation } else { - - PushNotificationTelemetry::ChannelRequestedByApi( - channelRequestException.code(), - AppModel::Identity::IsPackagedProcess(), - remoteId); + PushNotificationTelemetry::ChannelRequestedByApi(channelRequestException.code(), remoteId, usingLegacyImplementation); co_return winrt::make( nullptr, @@ -227,13 +228,9 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation } catch (...) { - HRESULT hrError = wil::ResultFromCaughtException(); - PushNotificationTelemetry::ChannelRequestedByApi( - hrError, - AppModel::Identity::IsPackagedProcess(), - remoteId); + PushNotificationTelemetry::ChannelRequestedByApi(wil::ResultFromCaughtException(), remoteId, usingLegacyImplementation); - THROW_HR(hrError); + throw; } } @@ -366,11 +363,10 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation catch(...) { - HRESULT hrError = wil::ResultFromCaughtException(); - PushNotificationTelemetry::ActivatorRegisteredByApi(hrError, + PushNotificationTelemetry::ActivatorRegisteredByApi(wil::ResultFromCaughtException(), details == nullptr ? PushNotificationRegistrationActivators::Undefined : details.Activators()); - THROW_HR(hrError); + throw; } } @@ -407,9 +403,8 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation } catch (...) { - HRESULT hrError = wil::ResultFromCaughtException(); - PushNotificationTelemetry::ActivatorUnregisteredByApi(hrError, activators); - THROW_HR(hrError); + PushNotificationTelemetry::ActivatorUnregisteredByApi(wil::ResultFromCaughtException(), activators); + throw; } PushNotificationTelemetry::ActivatorUnregisteredByApi(S_OK, activators); @@ -430,9 +425,10 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation } catch(...) { - HRESULT hrError = wil::ResultFromCaughtException(); - PushNotificationTelemetry::ActivatorUnregisteredByApi(hrError, PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator); - THROW_HR(hrError); + PushNotificationTelemetry::ActivatorUnregisteredByApi(wil::ResultFromCaughtException(), + PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator); + + throw; } PushNotificationTelemetry::ActivatorUnregisteredByApi(S_OK, PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator); } diff --git a/dev/PushNotifications/PushNotificationTelemetry.h b/dev/PushNotifications/PushNotificationTelemetry.h index 4c8016a24b..fc62ca3606 100644 --- a/dev/PushNotifications/PushNotificationTelemetry.h +++ b/dev/PushNotifications/PushNotificationTelemetry.h @@ -21,8 +21,8 @@ class PushNotificationTelemetry : public wil::TraceLoggingProvider public: DEFINE_EVENT_METHOD(ChannelRequestedByApi)( winrt::hresult hr, - bool isAppPackaged, - const winrt::guid& remoteId) noexcept try + const winrt::guid& remoteId, + bool usingLegacyImplementation) noexcept try { if (c_maxEventLimit >= UpdateLogEventCount()) { @@ -31,9 +31,10 @@ class PushNotificationTelemetry : public wil::TraceLoggingProvider TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), _GENERIC_PARTB_FIELDS_ENABLED, TraceLoggingHexUInt32(hr, "OperationResult"), - TraceLoggingBool(isAppPackaged, "IsAppPackaged"), - TraceLoggingWideString(to_hstring(remoteId).data(), "RemoteId"), - TraceLoggingWideString(GetAppUserModelId(), "AppUserModelId")); + TraceLoggingGuid(remoteId, "RemoteId"), + TraceLoggingBool(usingLegacyImplementation, "usingLegacyImplementation"), + TraceLoggingBool(IsPackagedApp(), "IsAppPackaged"), + TraceLoggingWideString(GetAppName(), "AppName")); } } CATCH_LOG() @@ -48,7 +49,8 @@ class PushNotificationTelemetry : public wil::TraceLoggingProvider TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), _GENERIC_PARTB_FIELDS_ENABLED, TraceLoggingHexUInt32(hr, "OperationResult"), - TraceLoggingWideString(GetAppUserModelId(), "AppUserModelId")); + TraceLoggingBool(IsPackagedApp(), "IsAppPackaged"), + TraceLoggingWideString(GetAppName(), "AppName")); } } CATCH_LOG() @@ -66,7 +68,8 @@ class PushNotificationTelemetry : public wil::TraceLoggingProvider TraceLoggingHexUInt32(hr, "OperationResult"), TraceLoggingHexUInt32(static_cast>(activators), "RegistrationActivators"), - TraceLoggingWideString(GetAppUserModelId(), "AppUserModelId")); + TraceLoggingBool(IsPackagedApp(), "IsAppPackaged"), + TraceLoggingWideString(GetAppName(), "AppName")); } } CATCH_LOG() @@ -85,7 +88,8 @@ class PushNotificationTelemetry : public wil::TraceLoggingProvider TraceLoggingHexUInt32(hr, "OperationResult"), TraceLoggingHexUInt32(static_cast>(activators), "RegistrationActivators"), - TraceLoggingWideString(GetAppUserModelId(), "AppUserModelId")); + TraceLoggingBool(IsPackagedApp(), "IsAppPackaged"), + TraceLoggingWideString(GetAppName(), "AppName")); } } CATCH_LOG() @@ -116,21 +120,61 @@ class PushNotificationTelemetry : public wil::TraceLoggingProvider return m_eventCount; } - wchar_t m_appUserModelId[APPLICATION_USER_MODEL_ID_MAX_LENGTH] = {}; + inline bool IsPackagedApp() + { + static const bool isPackagedApp = AppModel::Identity::IsPackagedProcess(); + + return isPackagedApp; + } + + inline const wchar_t* GetAppName() + { + static const std::wstring appName = IsPackagedApp() ? GetAppNamePackaged() : GetAppNameUnpackaged(); + + return appName.c_str(); + } - wchar_t* GetAppUserModelId() + std::wstring GetAppNamePackaged() noexcept { - if (m_appUserModelId[0] == '\0') + wchar_t appUserModelId[APPLICATION_USER_MODEL_ID_MAX_LENGTH]{}; + + UINT32 appUserModelIdSize = ARRAYSIZE(appUserModelId); + auto result = GetCurrentApplicationUserModelId(&appUserModelIdSize, appUserModelId); + if (result != ERROR_SUCCESS) + { + wcscpy_s(appUserModelId, L"AppUserModelId not found"); + LOG_WIN32(result); + } + + return appUserModelId; + } + + PCWSTR CensorFilePath(PCWSTR path) noexcept + { + if (path) + { + path = !PathIsFileSpecW(path) ? PathFindFileNameW(path) : path; + } + + return path; + } + + std::wstring GetAppNameUnpackaged() + { + std::wstring appName; + + wil::unique_cotaskmem_string processName; + auto result = wil::GetModuleFileNameExW(GetCurrentProcess(), nullptr, processName); + if (result == ERROR_SUCCESS) + { + appName = CensorFilePath(processName.get()); + } + else { - UINT32 appUserModelIdSize = ARRAYSIZE(m_appUserModelId); - auto result = GetCurrentApplicationUserModelId(&appUserModelIdSize, m_appUserModelId); - if (result != ERROR_SUCCESS) - { - wcscpy_s(m_appUserModelId, L"AppUserModelId not found"); - LOG_WIN32(result); - } + appName = L"ModuleFileName not found"; + LOG_WIN32(result); } - return m_appUserModelId; + return appName; } }; From 0336f90be0ebcbf74d03fca928a46892543c8a71 Mon Sep 17 00:00:00 2001 From: eric langlois Date: Wed, 15 Sep 2021 12:13:03 -0700 Subject: [PATCH 38/50] Update to latest UDK and undo UDK hack (#1420) Co-authored-by: Eric Langlois --- .../PushNotificationsLongRunningTask.vcxproj | 24 +- .../packages.config | 6 +- dev/PushNotifications/PushNotificationsRT.h | 299 ------------------ 3 files changed, 15 insertions(+), 314 deletions(-) delete mode 100644 dev/PushNotifications/PushNotificationsRT.h diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index 499e213075..05f4d5485f 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -123,7 +123,7 @@ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp17 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -141,7 +141,7 @@ true stdcpp17 Guard - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -158,7 +158,7 @@ _DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp17 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -176,7 +176,7 @@ true stdcpp17 Guard - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -193,7 +193,7 @@ _DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp20 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -211,7 +211,7 @@ true Guard stdcpp20 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL;.. + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -252,9 +252,9 @@ - - - + + + @@ -263,8 +263,8 @@ - - - + + + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config b/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config index 27bcb8d80f..3f8ba0a1e3 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config @@ -1,8 +1,8 @@  - - - + + + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsRT.h b/dev/PushNotifications/PushNotificationsRT.h deleted file mode 100644 index f922f1f5f3..0000000000 --- a/dev/PushNotifications/PushNotificationsRT.h +++ /dev/null @@ -1,299 +0,0 @@ -/* Header file automatically generated from pushnotificationsrt.idl */ -/* - * File built with Microsoft(R) MIDLRT Compiler Engine Version 10.00.0231 - */ - -#pragma warning( disable: 4049 ) /* more than 64k source lines */ - -/* verify that the version is high enough to compile this file*/ -#ifndef __REQUIRED_RPCNDR_H_VERSION__ -#define __REQUIRED_RPCNDR_H_VERSION__ 500 -#endif - -/* verify that the version is high enough to compile this file*/ -#ifndef __REQUIRED_RPCSAL_H_VERSION__ -#define __REQUIRED_RPCSAL_H_VERSION__ 100 -#endif - -#include -#include - -#ifndef __RPCNDR_H_VERSION__ -#error this stub requires an updated version of -#endif /* __RPCNDR_H_VERSION__ */ - -#ifndef COM_NO_WINDOWS_H -#include -#include -#endif /*COM_NO_WINDOWS_H*/ -#ifndef __pushnotificationsrt_h__ -#define __pushnotificationsrt_h__ -#ifndef __pushnotificationsrt_p_h__ -#define __pushnotificationsrt_p_h__ - - -#pragma once - -// Ensure that the setting of the /ns_prefix command line switch is consistent for all headers. -// If you get an error from the compiler indicating "warning C4005: 'CHECK_NS_PREFIX_STATE': macro redefinition", this -// indicates that you have included two different headers with different settings for the /ns_prefix MIDL command line switch -#if !defined(DISABLE_NS_PREFIX_CHECKS) -#if defined(MIDL_NS_PREFIX) -#define CHECK_NS_PREFIX_STATE "always" -#else -#define CHECK_NS_PREFIX_STATE "never" -#endif // MIDL_NS_PREFIX -#endif // !defined(DISABLE_NS_PREFIX_CHECKS) - - -#pragma push_macro("ABI_CONCAT") -#pragma push_macro("ABI_PARAMETER") -#pragma push_macro("ABI_NAMESPACE_BEGIN") -#pragma push_macro("ABI_NAMESPACE_END") -#pragma push_macro("C_IID") -#undef ABI_CONCAT -#undef ABI_PARAMETER -#undef ABI_NAMESPACE_BEGIN -#undef ABI_NAMESPACE_END -#undef C_IID -#define ABI_CONCAT(x,y) x##y - -// /ns_prefix optional state -#if defined(MIDL_NS_PREFIX) -#if defined(__cplusplus) -#define ABI_PARAMETER(x) ABI::x -#define ABI_NAMESPACE_BEGIN namespace ABI { -#define ABI_NAMESPACE_END } -#else // !defined(__cplusplus) -#define C_ABI_PARAMETER(x) ABI_CONCAT(__x_ABI_C, x) -#endif // !defined(__cplusplus) -#define C_IID(x) ABI_CONCAT(IID___x_ABI_C, x) -#else -#if defined(__cplusplus) -#define ABI_PARAMETER(x) x -#define ABI_NAMESPACE_BEGIN -#define ABI_NAMESPACE_END -#else // !defined(__cplusplus) -#define C_ABI_PARAMETER(x) ABI_CONCAT(__x_, x) -#endif // !defined(__cplusplus) -#define C_IID(x) ABI_CONCAT(IID___x_, x) -#endif // defined(MIDL_NS_PREFIX) - -#pragma push_macro("MIDL_CONST_ID") -#undef MIDL_CONST_ID -#define MIDL_CONST_ID const __declspec(selectany) - - -// API Contract Inclusion Definitions -#if !defined(SPECIFIC_API_CONTRACT_DEFINITIONS) -#if !defined(WINDOWS_APPLICATIONMODEL_CALLS_CALLSPHONECONTRACT_VERSION) -#define WINDOWS_APPLICATIONMODEL_CALLS_CALLSPHONECONTRACT_VERSION 0x60000 -#endif // defined(WINDOWS_APPLICATIONMODEL_CALLS_CALLSPHONECONTRACT_VERSION) - -#if !defined(WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION) -#define WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION 0x40000 -#endif // defined(WINDOWS_FOUNDATION_FOUNDATIONCONTRACT_VERSION) - -#if !defined(WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION) -#define WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION 0xf0000 -#endif // defined(WINDOWS_FOUNDATION_UNIVERSALAPICONTRACT_VERSION) - -#if !defined(WINDOWS_NETWORKING_SOCKETS_CONTROLCHANNELTRIGGERCONTRACT_VERSION) -#define WINDOWS_NETWORKING_SOCKETS_CONTROLCHANNELTRIGGERCONTRACT_VERSION 0x30000 -#endif // defined(WINDOWS_NETWORKING_SOCKETS_CONTROLCHANNELTRIGGERCONTRACT_VERSION) - -#if !defined(WINDOWS_PHONE_PHONECONTRACT_VERSION) -#define WINDOWS_PHONE_PHONECONTRACT_VERSION 0x10000 -#endif // defined(WINDOWS_PHONE_PHONECONTRACT_VERSION) - -#if !defined(WINDOWS_PHONE_PHONEINTERNALCONTRACT_VERSION) -#define WINDOWS_PHONE_PHONEINTERNALCONTRACT_VERSION 0x10000 -#endif // defined(WINDOWS_PHONE_PHONEINTERNALCONTRACT_VERSION) - -#if !defined(WINDOWS_UI_WEBUI_CORE_WEBUICOMMANDBARCONTRACT_VERSION) -#define WINDOWS_UI_WEBUI_CORE_WEBUICOMMANDBARCONTRACT_VERSION 0x10000 -#endif // defined(WINDOWS_UI_WEBUI_CORE_WEBUICOMMANDBARCONTRACT_VERSION) - -#endif // defined(SPECIFIC_API_CONTRACT_DEFINITIONS) - - -// Header files for imported files -#include "oaidl.h" -#include "inspectable.h" -#include "Windows.Foundation.h" - -#if defined(__cplusplus) && !defined(CINTERFACE) -/* Forward Declarations */ -#ifndef ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ -#define ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ -ABI_NAMESPACE_BEGIN -namespace Microsoft { - namespace Internal { - namespace PushNotifications { - interface INotificationListener; - } /* PushNotifications */ - } /* Internal */ -} /* Microsoft */ -ABI_NAMESPACE_END -#define __x_Microsoft_CInternal_CPushNotifications_CINotificationListener ABI_PARAMETER(Microsoft::Internal::PushNotifications::INotificationListener) - -#endif // ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ - - - -#pragma warning (push) -#pragma warning (disable:4668) -#pragma warning (disable:4001) -#pragma once -#pragma warning (pop) - -/* - * - * Interface Microsoft.Internal.PushNotifications.INotificationListener - * - */ -#if !defined(____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__) -#define ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__ -extern const __declspec(selectany) _Null_terminated_ WCHAR InterfaceName_Microsoft_Internal_PushNotifications_INotificationListener[] = L"Microsoft.Internal.PushNotifications.INotificationListener"; -ABI_NAMESPACE_BEGIN -namespace Microsoft { - namespace Internal { - namespace PushNotifications { - /* [version, object, uuid("522D1AC5-A9B1-4DE9-9BFD-0B4C56459293")] */ - MIDL_INTERFACE("522D1AC5-A9B1-4DE9-9BFD-0B4C56459293") - INotificationListener : public IInspectable - { - public: - virtual HRESULT STDMETHODCALLTYPE OnRawNotificationReceived( - /* [in] */unsigned int payloadLength, - /* [size_is(payloadLength), in] */__RPC__in_ecount_full(payloadLength) ::byte * payload, - /* [in] */__RPC__in HSTRING correlationVector - ) = 0; - - }; - - MIDL_CONST_ID IID & IID_INotificationListener=_uuidof(INotificationListener); - - } /* PushNotifications */ - } /* Internal */ -} /* Microsoft */ -ABI_NAMESPACE_END - -EXTERN_C const IID C_IID(Microsoft_CInternal_CPushNotifications_CINotificationListener); -#endif /* !defined(____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__) */ - - -#else // !defined(__cplusplus) -/* Forward Declarations */ -#ifndef ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ -#define ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ -typedef interface C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener); - -#endif // ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_FWD_DEFINED__ - - -#pragma warning (push) -#pragma warning (disable:4668) -#pragma warning (disable:4001) -#pragma once -#pragma warning (pop) - -/* - * - * Interface Microsoft.Internal.PushNotifications.INotificationListener - * - */ -#if !defined(____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__) -#define ____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__ -extern const __declspec(selectany) _Null_terminated_ WCHAR InterfaceName_Microsoft_Internal_PushNotifications_INotificationListener[] = L"Microsoft.Internal.PushNotifications.INotificationListener"; -/* [version, object, uuid("522D1AC5-A9B1-4DE9-9BFD-0B4C56459293")] */ -typedef struct C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListenerVtbl) -{ - BEGIN_INTERFACE - HRESULT ( STDMETHODCALLTYPE *QueryInterface)( - __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This, - /* [in] */ __RPC__in REFIID riid, - /* [annotation][iid_is][out] */ - _COM_Outptr_ void **ppvObject - ); - -ULONG ( STDMETHODCALLTYPE *AddRef )( - __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This - ); - -ULONG ( STDMETHODCALLTYPE *Release )( - __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This - ); - -HRESULT ( STDMETHODCALLTYPE *GetIids )( - __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This, - /* [out] */ __RPC__out ULONG *iidCount, - /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID **iids - ); - -HRESULT ( STDMETHODCALLTYPE *GetRuntimeClassName )( - __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This, - /* [out] */ __RPC__deref_out_opt HSTRING *className - ); - -HRESULT ( STDMETHODCALLTYPE *GetTrustLevel )( - __RPC__in C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This, - /* [OUT ] */ __RPC__out TrustLevel *trustLevel - ); -HRESULT ( STDMETHODCALLTYPE *OnRawNotificationReceived )( - C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) * This, - /* [in] */unsigned int payloadLength, - /* [size_is(payloadLength), in] */__RPC__in_ecount_full(payloadLength) byte * payload, - /* [in] */__RPC__in HSTRING correlationVector - ); - END_INTERFACE - -} C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListenerVtbl); - -interface C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener) -{ - CONST_VTBL struct C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListenerVtbl) *lpVtbl; -}; - -#ifdef COBJMACROS -#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_QueryInterface(This,riid,ppvObject) \ -( (This)->lpVtbl->QueryInterface(This,riid,ppvObject) ) - -#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_AddRef(This) \ - ( (This)->lpVtbl->AddRef(This) ) - -#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_Release(This) \ - ( (This)->lpVtbl->Release(This) ) - -#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_GetIids(This,iidCount,iids) \ - ( (This)->lpVtbl->GetIids(This,iidCount,iids) ) - -#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_GetRuntimeClassName(This,className) \ - ( (This)->lpVtbl->GetRuntimeClassName(This,className) ) - -#define C_ABI_PARAMETER(Microsoft_CInternal_CPushNotifications_CINotificationListener)_GetTrustLevel(This,trustLevel) \ - ( (This)->lpVtbl->GetTrustLevel(This,trustLevel) ) - -#define __x_Microsoft_CInternal_CPushNotifications_CINotificationListener_OnRawNotificationReceived(This,payloadLength,payload,correlationVector) \ - ( (This)->lpVtbl->OnRawNotificationReceived(This,payloadLength,payload,correlationVector) ) - - -#endif /* COBJMACROS */ - - -EXTERN_C const IID C_IID(Microsoft_CInternal_CPushNotifications_CINotificationListener); -#endif /* !defined(____x_Microsoft_CInternal_CPushNotifications_CINotificationListener_INTERFACE_DEFINED__) */ - - -#endif // defined(__cplusplus) -#pragma pop_macro("MIDL_CONST_ID") -#pragma pop_macro("C_IID") -#pragma pop_macro("ABI_CONCAT") -#pragma pop_macro("ABI_PARAMETER") -#pragma pop_macro("ABI_NAMESPACE_BEGIN") -#pragma pop_macro("ABI_NAMESPACE_END") - - -#endif // __pushnotificationsrt_p_h__ - -#endif // __pushnotificationsrt_h__ From 401b47c919d5b038246a396a51b4480a8e35da2f Mon Sep 17 00:00:00 2001 From: Paul Purifoy <33183370+pmpurifoy@users.noreply.github.com> Date: Wed, 15 Sep 2021 16:16:53 -0700 Subject: [PATCH 39/50] Fixing WNP_LRP tests (#1401) * Working on tests * Call ReigsterFullTrust in RegisterLongRunningActivator * Removed g_isPackaged with IsActivatorSupported * Addressing nits --- .../PushNotificationManager.cpp | 41 +++++++- .../NotificationListenerManager.cpp | 1 + test/PushNotificationTests/APITests.cpp | 5 + .../PushNotificationsTestApp/main.cpp | 97 ++++++++++++------- 4 files changed, 103 insertions(+), 41 deletions(-) diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index 905ac1f920..e350362c08 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -43,6 +43,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { static winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration s_pushTriggerRegistration{ nullptr }; static wil::unique_com_class_object_cookie s_comActivatorRegistration; + static bool s_protocolRegistration{ false }; static wil::srwlock s_activatorInfoLock; inline constexpr auto c_maxBackoff{ 5min }; @@ -240,9 +241,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { THROW_HR_IF_NULL(E_INVALIDARG, details); - GUID taskClsid = details.TaskClsid(); - THROW_HR_IF(E_INVALIDARG, taskClsid == GUID_NULL); - auto registrationActivators{ details.Activators() }; auto isBackgroundTaskFlagSet{ WI_IsAnyFlagSet(registrationActivators, PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator) }; @@ -253,6 +251,11 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation if (isProtocolActivatorSet) { + { + auto lock = s_activatorInfoLock.lock_shared(); + THROW_HR_IF(E_INVALIDARG, s_protocolRegistration); + } + auto coInitialize = wil::CoInitializeEx(); wil::com_ptr notificationPlatform{ @@ -261,14 +264,22 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation wil::unique_cotaskmem_string processName; THROW_IF_FAILED(GetCurrentProcessPath(processName)); THROW_IF_FAILED(notificationPlatform->RegisterLongRunningActivator(processName.get())); + + { + auto lock = s_activatorInfoLock.lock_exclusive(); + s_protocolRegistration = true; + } } BackgroundTaskBuilder builder{ nullptr }; if (WI_IsFlagSet(registrationActivators, PushNotificationRegistrationActivators::PushTrigger)) { + GUID taskClsid = details.TaskClsid(); + THROW_HR_IF(E_INVALIDARG, taskClsid == GUID_NULL); + { - auto lock = s_activatorInfoLock.lock_exclusive(); + auto lock = s_activatorInfoLock.lock_shared(); THROW_HR_IF(E_INVALIDARG, s_pushTriggerRegistration); } @@ -333,8 +344,11 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation if (WI_IsFlagSet(registrationActivators, PushNotificationRegistrationActivators::ComActivator)) { + GUID taskClsid = details.TaskClsid(); + THROW_HR_IF(E_INVALIDARG, taskClsid == GUID_NULL); + { - auto lock = s_activatorInfoLock.lock_exclusive(); + auto lock = s_activatorInfoLock.lock_shared(); THROW_HR_IF_MSG(E_INVALIDARG, s_comActivatorRegistration, "ComActivator already registered."); } @@ -391,6 +405,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation if (WI_IsFlagSet(activators, PushNotificationRegistrationActivators::ProtocolActivator)) { + THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), !s_protocolRegistration); auto coInitialize = wil::CoInitializeEx(); wil::com_ptr notificationPlatform{ @@ -399,6 +414,8 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation wil::unique_cotaskmem_string processName; THROW_IF_FAILED(GetCurrentProcessPath(processName)); THROW_IF_FAILED(notificationPlatform->UnregisterLongRunningActivator(processName.get())); + + s_protocolRegistration = false; } } catch (...) @@ -422,6 +439,20 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation } s_comActivatorRegistration.reset(); + + if (s_protocolRegistration) + { + auto coInitialize = wil::CoInitializeEx(); + + wil::com_ptr notificationPlatform{ + wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + + wil::unique_cotaskmem_string processName; + THROW_IF_FAILED(GetCurrentProcessPath(processName)); + THROW_IF_FAILED(notificationPlatform->UnregisterLongRunningActivator(processName.get())); + + s_protocolRegistration = false; + } } catch(...) { diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp index add441fc44..75bc1c4893 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp @@ -24,6 +24,7 @@ void NotificationListenerManager::AddListener(std::wstring appId, std::wstring p { ComPtr listener; THROW_IF_FAILED(MakeAndInitialize(&listener, m_foregroundSinkManager, appId, processName)); + THROW_IF_FAILED(PushNotifications_RegisterFullTrustApplication(appId.c_str(), GUID_NULL)); THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appId.c_str(), listener.Get())); AgileRef agileListener; diff --git a/test/PushNotificationTests/APITests.cpp b/test/PushNotificationTests/APITests.cpp index 82cda17c4c..892c483920 100644 --- a/test/PushNotificationTests/APITests.cpp +++ b/test/PushNotificationTests/APITests.cpp @@ -262,6 +262,11 @@ namespace Test::PushNotifications RunTest(L"ActivatorTest", testWaitTime()); } + TEST_METHOD(ActivatorTest_Unpackaged) + { + RunTestUnpackaged(L"ActivatorTest", channelTestWaitTime()); + } + TEST_METHOD(RegisterActivatorNullDetails) { RunTest(L"RegisterActivatorNullDetails", testWaitTime()); diff --git a/test/TestApps/PushNotificationsTestApp/main.cpp b/test/TestApps/PushNotificationsTestApp/main.cpp index bbfd1bdc24..a8fabd0728 100644 --- a/test/TestApps/PushNotificationsTestApp/main.cpp +++ b/test/TestApps/PushNotificationsTestApp/main.cpp @@ -15,8 +15,6 @@ using namespace winrt::Windows::Foundation; using namespace winrt::Windows::Storage; using namespace winrt::Windows::Storage::Streams; -bool g_registeredActivator = false; - winrt::guid remoteId1(L"a2e4a323-b518-4799-9e80-0b37aeb0d225"); // Generated from ms.portal.azure.com winrt::guid remoteId2(L"CA1A4AB2-AC1D-4EFC-A132-E5A191CA285A"); // Dummy guid from visual studio guid tool generator @@ -114,17 +112,26 @@ bool MultipleChannelRequestUsingMultipleRemoteId() bool ActivatorTest() { - PushNotificationManager::UnregisterActivator(PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator); - g_registeredActivator = false; - + PushNotificationManager::UnregisterAllActivators(); try { - PushNotificationActivationInfo info( - PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator, - c_fakeComServerId); + if(PushNotificationManager::IsActivatorSupported(PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator)) + { + PushNotificationActivationInfo info( + PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator, + c_fakeComServerId); + + PushNotificationManager::RegisterActivator(info); + PushNotificationManager::UnregisterActivator(PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator); + } + else + { + PushNotificationActivationInfo info(PushNotificationRegistrationActivators::ProtocolActivator); + + PushNotificationManager::RegisterActivator(info); + PushNotificationManager::UnregisterActivator(PushNotificationRegistrationActivators::ProtocolActivator); + } - PushNotificationManager::RegisterActivator(info); - PushNotificationManager::UnregisterActivator(PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator); } catch (...) { @@ -136,9 +143,7 @@ bool ActivatorTest() // Verify calling register activator with null PushNotificationActivationInfo is not allowed. bool RegisterActivatorNullDetails() { - PushNotificationManager::UnregisterActivator(PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator); - g_registeredActivator = false; - + PushNotificationManager::UnregisterAllActivators(); try { PushNotificationManager::RegisterActivator(nullptr); @@ -153,22 +158,39 @@ bool RegisterActivatorNullDetails() // Verify calling register activator with null clsid is not allowed. bool RegisterActivatorNullClsid() { - PushNotificationManager::UnregisterActivator(PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator); - g_registeredActivator = false; - - try + PushNotificationManager::UnregisterAllActivators(); + if(PushNotificationManager::IsActivatorSupported(PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator)) { - PushNotificationActivationInfo info( - PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator, - winrt::guid()); // Null guid + try + { + PushNotificationActivationInfo info( + PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator, + winrt::guid()); - PushNotificationManager::RegisterActivator(info); + PushNotificationManager::RegisterActivator(info); + } + catch(...) + { + return to_hresult() == E_INVALIDARG; + } + return false; } - catch (...) + else { - return to_hresult() == E_INVALIDARG; + try + { + PushNotificationActivationInfo info( + PushNotificationRegistrationActivators::ProtocolActivator, + winrt::guid()); + + PushNotificationManager::RegisterActivator(info); + } + catch(...) + { + return false; + } + return true; } - return false; } // Verify registering multiple activators is not allowed. @@ -176,11 +198,19 @@ bool MultipleRegisterActivatorTest() { try { - PushNotificationActivationInfo info( - PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator, - c_fakeComServerId); // Fake clsid to test multiple activators + if(PushNotificationManager::IsActivatorSupported(PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator)) + { + PushNotificationActivationInfo info( + PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator, + c_fakeComServerId); // Fake clsid to test multiple activators - PushNotificationManager::RegisterActivator(info); + PushNotificationManager::RegisterActivator(info); + } + else + { + PushNotificationActivationInfo info(PushNotificationRegistrationActivators::ProtocolActivator); + PushNotificationManager::RegisterActivator(info); + } } catch (...) { @@ -291,10 +321,7 @@ int main() try { bool testResult = false; auto scope_exit = wil::scope_exit([&] { - if (g_registeredActivator) - { - PushNotificationManager::UnregisterActivator(PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator); - } + PushNotificationManager::UnregisterAllActivators(); ::Test::Bootstrap::CleanupBootstrap(); }); @@ -308,15 +335,13 @@ int main() try winrt::guid(c_comServerId)); // same clsid as app manifest PushNotificationManager::RegisterActivator(info); - g_registeredActivator = true; } - /* TODO: Register ProtocolActivator for unpackaged applications else { - PushNotificationActivationInfo info(PushNotificationRegistrationActivators::ProtocolActivator, nullptr); + PushNotificationActivationInfo info(PushNotificationRegistrationActivators::ProtocolActivator); PushNotificationManager::RegisterActivator(info); } - */ + auto args = AppInstance::GetCurrent().GetActivatedEventArgs(); auto kind = args.Kind(); From b25c2f870e652e44fa41e6b8dbb59286fbf5c8f9 Mon Sep 17 00:00:00 2001 From: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> Date: Fri, 17 Sep 2021 17:41:36 -0700 Subject: [PATCH 40/50] Protocol Activation bug fixes (#1406) This PR fixes a couple of issues: - Truncated payloads delivered to the app: the Push payload is now processed correctly to comply with AppLifecycle command line expectations (i.e. truncation happened at the first space character - other activation types are already escaping such characters, now we do it too. Then, the payload is unescaped at GetRawNotificationEventArgs.h). - Payloads with special characters crashed the app: Special characters weren't playing okay with wstring->string conversion at PushNotificationReceivedEventArgs, because WideCharToMultiByte was erroring out with ERROR_INSUFFICIENT_BUFFER. --- .../GetRawNotificationEventArgs.h | 5 ++- .../PushNotificationReceivedEventArgs.cpp | 16 ++------ .../PushNotificationReceivedEventArgs.h | 2 - .../PushNotifications.vcxitems | 1 + .../NotificationListener.cpp | 34 +++++++---------- .../NotificationListener.h | 2 - .../PushNotificationsLongRunningTask.vcxproj | 1 + ...tificationsLongRunningTask.vcxproj.filters | 3 ++ .../PushNotificationsLongRunningTask/utils.h | 27 +++++++++++++ dev/PushNotifications/utils.h | 38 +++++++++++++++++++ 10 files changed, 91 insertions(+), 38 deletions(-) create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/utils.h create mode 100644 dev/PushNotifications/utils.h diff --git a/dev/PushNotifications/GetRawNotificationEventArgs.h b/dev/PushNotifications/GetRawNotificationEventArgs.h index 2e2a814fa7..2bf1bdd683 100644 --- a/dev/PushNotifications/GetRawNotificationEventArgs.h +++ b/dev/PushNotifications/GetRawNotificationEventArgs.h @@ -18,7 +18,10 @@ namespace winrt::Microsoft::Windows::PushNotifications { if (pair.Name() == L"payload") { - std::wstring payloadAsWstring{pair.Value()}; + // Convert escaped components to its normal content + // from the conversion done in the LRP (see NotificationListener.cpp) + std::wstring payloadAsEscapedWstring{ pair.Value() }; + std::wstring payloadAsWstring{ winrt::Windows::Foundation::Uri::UnescapeComponent(payloadAsEscapedWstring) }; return winrt::make(payloadAsWstring); } } diff --git a/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp b/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp index 9460599d77..e2fc64dd3d 100644 --- a/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp +++ b/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp @@ -15,6 +15,8 @@ #include #include "ValueMarshaling.h" +#include "utils.h" + namespace winrt { using namespace Windows::ApplicationModel::Background; @@ -67,7 +69,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation std::vector PushNotificationReceivedEventArgs::BuildPayload(std::wstring const& payload) { - std::string payloadToSimpleString = Utf16ToUtf8(payload.c_str()); + std::string payloadToSimpleString = ConvertWideStringToUtf8String(payload); return { payloadToSimpleString.c_str(), payloadToSimpleString.c_str() + (payloadToSimpleString.length() * sizeof(uint8_t)) }; } @@ -143,17 +145,5 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation m_handledUnpackaged = value; } } - - std::string PushNotificationReceivedEventArgs::Utf16ToUtf8(_In_z_ PCWSTR utf16) - { - int size_needed = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, nullptr, nullptr); - THROW_LAST_ERROR_IF(size_needed == 0); - - // size_needed minus the null character - std::string utf8(size_needed - 1, 0); - int size = WideCharToMultiByte(CP_UTF8, 0, utf16, size_needed - 1, &utf8[0], size_needed - 1, nullptr, nullptr); - THROW_LAST_ERROR_IF(size == 0); - return utf8; - } } diff --git a/dev/PushNotifications/PushNotificationReceivedEventArgs.h b/dev/PushNotifications/PushNotificationReceivedEventArgs.h index 5b2774ea3b..61b8a7e286 100644 --- a/dev/PushNotifications/PushNotificationReceivedEventArgs.h +++ b/dev/PushNotifications/PushNotificationReceivedEventArgs.h @@ -24,8 +24,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation void Handled(bool value); private: - std::string Utf16ToUtf8(_In_z_ PCWSTR utf16); - const winrt::Windows::Storage::Streams::IBuffer m_rawNotification{}; std::vector BuildPayload(winrt::Windows::Storage::Streams::IBuffer const& buffer); diff --git a/dev/PushNotifications/PushNotifications.vcxitems b/dev/PushNotifications/PushNotifications.vcxitems index bd5fbdf948..118587af45 100644 --- a/dev/PushNotifications/PushNotifications.vcxitems +++ b/dev/PushNotifications/PushNotifications.vcxitems @@ -36,5 +36,6 @@ + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp index 1663ad7853..c23ebfd3a1 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp @@ -1,4 +1,5 @@ #include "pch.h" +#include "utils.h" HRESULT NotificationListener::RuntimeClassInitialize( std::shared_ptr foregroundSinkManager, @@ -21,21 +22,26 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationListener::OnRawNotificationReceived if (!m_foregroundSinkManager->InvokeForegroundHandlers(m_appId, payloadArray, payloadLength)) { - std::string commandLine = "----WindowsAppSDKPushServer:-Payload:\""; - commandLine.append(reinterpret_cast(payload), payloadLength); - commandLine.append("\""); + // Command line format: ----WindowsAppRuntimePushServer:-Payload:"" + std::wstring commandLine = L"----WindowsAppRuntimePushServer:-Payload:\""; - const std::string processNameAsUtf8String = ConvertProcessNameToUtf8String(); + // Escape special characters to follow command line standards for any app activation type in AppLifecycle + // (See AppInstance.cpp and Serialize() from other activation types) + std::wstring payloadAsWideString = ConvertByteArrayToWideString(payloadLength, payload); + auto payloadAsEscapedUriFormat = winrt::Windows::Foundation::Uri::EscapeComponent(payloadAsWideString.c_str()); - SHELLEXECUTEINFOA shellExecuteInfo{}; - shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFOA); + commandLine.append(payloadAsEscapedUriFormat); + commandLine.append(L"\""); + + SHELLEXECUTEINFO shellExecuteInfo{}; + shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO); shellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_DOENVSUBST; - shellExecuteInfo.lpFile = processNameAsUtf8String.c_str(); + shellExecuteInfo.lpFile = m_processName.c_str(); shellExecuteInfo.lpParameters = commandLine.c_str(); shellExecuteInfo.nShow = SW_NORMAL; - if (!ShellExecuteExA(&shellExecuteInfo)) + if (!ShellExecuteEx(&shellExecuteInfo)) { THROW_IF_WIN32_ERROR(GetLastError()); } @@ -44,15 +50,3 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationListener::OnRawNotificationReceived return S_OK; } CATCH_RETURN() - -const std::string NotificationListener::ConvertProcessNameToUtf8String() -{ - int size_needed = WideCharToMultiByte(CP_UTF8, 0, m_processName.c_str(), -1, NULL, 0, nullptr, nullptr); - THROW_LAST_ERROR_IF(size_needed == 0); - - // size_needed minus the null character - std::string utf8(size_needed - 1, 0); - int size = WideCharToMultiByte(CP_UTF8, 0, m_processName.c_str(), size_needed - 1, &utf8[0], size_needed - 1, nullptr, nullptr); - THROW_LAST_ERROR_IF(size == 0); - return utf8; -} diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h index 07f576eb05..a02dc7525b 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.h @@ -10,8 +10,6 @@ class NotificationListener : public Microsoft::WRL::RuntimeClass<::ABI::Microsof STDMETHOD(OnRawNotificationReceived)(unsigned int payloadLength, _In_ byte* payload, _In_ HSTRING correlationVector) noexcept; private: - const std::string ConvertProcessNameToUtf8String(); - std::shared_ptr m_foregroundSinkManager; std::wstring m_appId; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index 05f4d5485f..f7fb2babb1 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -239,6 +239,7 @@ + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters index 53d4e755e9..3cc03ec1a1 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters @@ -36,6 +36,9 @@ Header Files + + Source Files + diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/utils.h b/dev/PushNotifications/PushNotificationsLongRunningTask/utils.h new file mode 100644 index 0000000000..88bbedbbe7 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/utils.h @@ -0,0 +1,27 @@ +#pragma once + +#include "pch.h" + +const std::wstring ConvertByteArrayToWideString(unsigned int payloadLength, byte* payload) +{ + int size = MultiByteToWideChar( + CP_UTF8, + 0, + reinterpret_cast(payload), + payloadLength, + nullptr, + 0); + THROW_LAST_ERROR_IF(size == 0); + + std::wstring payloadAsWideString(size, 0); + size = MultiByteToWideChar( + CP_UTF8, + 0, + reinterpret_cast(payload), + payloadLength, + &payloadAsWideString[0], + size); + THROW_LAST_ERROR_IF(size == 0); + + return payloadAsWideString; +} diff --git a/dev/PushNotifications/utils.h b/dev/PushNotifications/utils.h new file mode 100644 index 0000000000..187fbf84cc --- /dev/null +++ b/dev/PushNotifications/utils.h @@ -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. + +#pragma once + +#include "pch.h" + +std::string ConvertWideStringToUtf8String(_In_ std::wstring const& utf16string) +{ + int size = WideCharToMultiByte( + CP_UTF8, + 0, + utf16string.data(), + static_cast(utf16string.length()), + nullptr, + 0, + nullptr, + nullptr); + + THROW_LAST_ERROR_IF(size == 0); + + std::string utf8string; + utf8string.resize(size); + + size = WideCharToMultiByte( + CP_UTF8, + 0, + utf16string.data(), + static_cast(utf16string.length()), + &utf8string[0], + size, + nullptr, + nullptr); + + THROW_LAST_ERROR_IF(size == 0); + + return utf8string; +} From d170ce3f57543090940e1ae42de426dea33c9da0 Mon Sep 17 00:00:00 2001 From: Sharath Manchala <10109130+sharath2727@users.noreply.github.com> Date: Mon, 20 Sep 2021 11:02:09 -0700 Subject: [PATCH 41/50] Use remoteId as const value (#1435) --- dev/PushNotifications/PushNotificationManager.cpp | 2 +- dev/PushNotifications/PushNotificationManager.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index 5f02763555..305ace44f1 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -118,7 +118,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation } CATCH_RETURN() - winrt::IAsyncOperationWithProgress PushNotificationManager::CreateChannelAsync(const winrt::guid &remoteId) + winrt::IAsyncOperationWithProgress PushNotificationManager::CreateChannelAsync(const winrt::guid remoteId) { THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::PushNotifications::Feature_PushNotifications::IsEnabled()); diff --git a/dev/PushNotifications/PushNotificationManager.h b/dev/PushNotifications/PushNotificationManager.h index 150f0ae4f8..56c1f537d9 100644 --- a/dev/PushNotifications/PushNotificationManager.h +++ b/dev/PushNotifications/PushNotificationManager.h @@ -16,7 +16,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation static void UnregisterActivator(Microsoft::Windows::PushNotifications::PushNotificationRegistrationActivators const& activators); static void UnregisterAllActivators(); - static winrt::Windows::Foundation::IAsyncOperationWithProgress CreateChannelAsync(winrt::guid const& remoteId); + static winrt::Windows::Foundation::IAsyncOperationWithProgress CreateChannelAsync(winrt::guid const remoteId); static bool IsActivatorSupported(Microsoft::Windows::PushNotifications::PushNotificationRegistrationActivators const& activators); }; From fbfcf49e1ac89f27d564d3d2fa3a15c88abc0ee6 Mon Sep 17 00:00:00 2001 From: eric langlois Date: Wed, 22 Sep 2021 12:23:28 -0700 Subject: [PATCH 42/50] Upgrade LRP to latest UDK (#1459) * Upgrade LRP to latest UDK * Missed a few checks in the vcproj Co-authored-by: Eric Langlois --- .../PushNotificationsLongRunningTask.vcxproj | 12 ++++++------ .../PushNotificationsLongRunningTask/packages.config | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index f7fb2babb1..7f1a18296a 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -253,9 +253,9 @@ - - - + + + @@ -264,8 +264,8 @@ - - - + + + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config b/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config index 3f8ba0a1e3..db75f467d8 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config @@ -1,8 +1,8 @@  - - - + + + \ No newline at end of file From 2a7fae8ba4889c1e2ae2f69b37b14b08caedaf08 Mon Sep 17 00:00:00 2001 From: Eric Langlois Date: Wed, 29 Sep 2021 07:01:21 -0700 Subject: [PATCH 43/50] fix bad merge --- .../PushNotificationsLongRunningTask.vcxproj | 3 --- 1 file changed, 3 deletions(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index 39a0b1786c..b66e18f5f2 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -252,9 +252,6 @@ {bf3fced0-cadb-490a-93a7-4d90e1f45ab0} - - - From a732c1d908c03378f8dc38d728a9a56f13526540 Mon Sep 17 00:00:00 2001 From: Paul Purifoy Date: Wed, 29 Sep 2021 15:47:28 -0700 Subject: [PATCH 44/50] Update CopyFilesToStagingDir.ps1 --- build/CopyFilesToStagingDir.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/CopyFilesToStagingDir.ps1 b/build/CopyFilesToStagingDir.ps1 index 5a6736fa3e..b167ea32d3 100644 --- a/build/CopyFilesToStagingDir.ps1 +++ b/build/CopyFilesToStagingDir.ps1 @@ -34,6 +34,7 @@ function PublishFile { } PublishFile $OverrideDir\DynamicDependency-Override.json $FullPublishDir\ +PublishFile $OverrideDir\PushNotifications-Override.json $FullPublishDir\ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.dll $FullPublishDir\Microsoft.WindowsAppRuntime\ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.lib $FullPublishDir\Microsoft.WindowsAppRuntime\ @@ -87,6 +88,9 @@ PublishFile $FullBuildOutput\Microsoft.Windows.System.Power.Projection\Microsoft # Dynamic Dependency build overrides PublishFile $OverrideDir\DynamicDependency-Override.json $NugetDir\runtimes\win10-$Platform\native # +# Push Notifications build overrides +PublishFile $OverrideDir\PushNotifications-Override.json $NugetDir\runtimes\win10-$Platform\native +# # Includes (*.h) PublishFile $FullBuildOutput\WindowsAppRuntime_BootstrapDLL\MddBootstrap.h $NugetDir\include PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\MsixDynamicDependency.h $NugetDir\include From e0f1df96a6c3ec9ed4bf2da3f1187123d8a3f4cf Mon Sep 17 00:00:00 2001 From: Paul Purifoy Date: Thu, 30 Sep 2021 10:26:40 -0700 Subject: [PATCH 45/50] Remove PushNotifications from outer layer of JSON --- tools/GeneratePushNotificationsOverrides.ps1 | 43 ++++++++------------ 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/tools/GeneratePushNotificationsOverrides.ps1 b/tools/GeneratePushNotificationsOverrides.ps1 index 16d3393a1f..cdce32bc72 100644 --- a/tools/GeneratePushNotificationsOverrides.ps1 +++ b/tools/GeneratePushNotificationsOverrides.ps1 @@ -41,31 +41,24 @@ else # Generate the json file $content_json=@" { - "PushNotifications": { - "LIBID": "CE96C745-3017-460E-895B-4FD98E1194F2", - "Impl": { - "CLSID": { - "UUID": "E739C755-0D09-48DF-A468-A5DF0B5422DC" - } - }, - "ComInterfaces": { - "LRP": { - "CLSID": { - "UUID": "60FC21B2-B396-4D49-94F0-7555869FB93C" - } - }, - "ForegroundSink": { - "CLSID": { - "UUID": "25604D55-9B17-426F-9D67-2B11B3A65598" - } - } - }, - "ComServer": { - "CLSID": { - "UUID": "2DC0B845-A8FD-44D6-B79C-91152C2511EB" - } - } - } + "LIBID": "CE96C745-3017-460E-895B-4FD98E1194F2", + "ComServer": { + "CLSID": { + "UUID": "E739C755-0D09-48DF-A468-A5DF0B5422DC" + } + }, + "ComInterfaces": { + "LRP": { + "CLSID": { + "UUID": "60FC21B2-B396-4D49-94F0-7555869FB93C" + } + }, + "ForegroundSink": { + "CLSID": { + "UUID": "25604D55-9B17-426F-9D67-2B11B3A65598" + } + } + } } "@ From 493a468e2bafcdeff52aa7bdad50a08b8808091e Mon Sep 17 00:00:00 2001 From: eric langlois Date: Thu, 30 Sep 2021 18:44:17 -0700 Subject: [PATCH 46/50] Adding source link to projects not in main yet (#1515) Co-authored-by: Eric Langlois --- ...ificationsLongRunningTask.ProxyStub.vcxproj | 18 ++++++++++++++++++ ...nsLongRunningTask.ProxyStub.vcxproj.filters | 7 ++++--- .../packages.config | 6 ++++++ ...icationsLongRunningTask.StartupTask.vcxproj | 13 ++++++++++++- .../packages.config | 6 ++++++ 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/packages.config create mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/packages.config diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj index 0b05d19fb6..f19a675cf6 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj @@ -1,5 +1,8 @@ + + + @@ -441,10 +444,14 @@ + + + + @@ -454,4 +461,15 @@ + + + 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/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters index 4fb8c588f6..8eb19e2809 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/PushNotificationsLongRunningTask.ProxyStub.vcxproj.filters @@ -23,13 +23,13 @@ Source Files - + Source Files - + Source Files - + Source Files @@ -45,5 +45,6 @@ Source Files + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/packages.config b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/packages.config new file mode 100644 index 0000000000..390175e9d3 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.ProxyStub/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj index 320ef953d5..522bf2a842 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/PushNotificationsLongRunningTask.StartupTask.vcxproj @@ -1,5 +1,8 @@ + + + @@ -233,6 +236,9 @@ + + + @@ -241,6 +247,11 @@ + + + + + + - \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/packages.config b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/packages.config new file mode 100644 index 0000000000..390175e9d3 --- /dev/null +++ b/dev/PushNotifications/PushNotificationsLongRunningTask.StartupTask/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From 2acab7cbf7b4b037b9201e38d7edb783e8502ea5 Mon Sep 17 00:00:00 2001 From: eric langlois Date: Tue, 5 Oct 2021 09:46:05 -0700 Subject: [PATCH 47/50] Support foregroundtask registration for packaged applications (#1521) * Support foregroundtask registration for packaged applications * Address comments * Address comments2 * Introduce PushNotificationsUtility.h/cpp * Address comments * Mark PushNotificationUtility.h file to be shared across the PushNotifications directory * Add try/catch around onRawNotificationRecveived * Set foregroundhandled to true by default * Address comments for getappusermodelId API * Address nits * Adress one more nit Co-authored-by: Venkata Sharath Chandra Manchala --- .../PushNotificationChannel.cpp | 68 +++++++++++++++--- .../PushNotificationChannel.h | 6 +- .../PushNotificationUtility.cpp | 69 +++++++++++++++++++ .../PushNotificationUtility.h | 9 +++ .../PushNotifications.vcxitems | 5 ++ .../PushNotificationsLongRunningTask.vcxproj | 12 ++-- dev/PushNotifications/externs.h | 1 - .../PushNotificationsDemoApp/main.cpp | 2 +- 8 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 dev/PushNotifications/PushNotificationUtility.cpp create mode 100644 dev/PushNotifications/PushNotificationUtility.h diff --git a/dev/PushNotifications/PushNotificationChannel.cpp b/dev/PushNotifications/PushNotificationChannel.cpp index 2c1c166271..2b36467e98 100644 --- a/dev/PushNotifications/PushNotificationChannel.cpp +++ b/dev/PushNotifications/PushNotificationChannel.cpp @@ -12,7 +12,7 @@ #include "externs.h" #include "PushNotificationTelemetry.h" #include - +#include "PushNotificationUtility.h" namespace winrt::Windows { @@ -89,15 +89,34 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { if (IsPackagedAppScenario()) { - return m_channel.PushNotificationReceived([weak_self = get_weak(), handler](auto&&, auto&& args) + if (m_channel) + { + return m_channel.PushNotificationReceived([weak_self = get_weak(), handler](auto&&, auto&& args) + { + if (auto strong = weak_self.get()) + { + auto pushArgs = winrt::make(args); + pushArgs.Handled(true); + handler(*strong, pushArgs); + }; + }); + } + else { - if (auto strong = weak_self.get()) + // The channelUri is directly obtained when we request Channel from UDK using RemoteId + auto lock = m_lock.lock_exclusive(); + + if (!m_foregroundHandlerCount) { - auto pushArgs = winrt::make(args); - pushArgs.Handled(true); - handler(*strong, pushArgs); - }; - }); + auto appUserModelId = GetAppUserModelId(); + + THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appUserModelId.get(), this)); + } + + ++m_foregroundHandlerCount; + + return m_foregroundHandlers.add(handler); + } } else { @@ -120,7 +139,24 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { if (IsPackagedAppScenario()) { - m_channel.PushNotificationReceived(token); + if (m_channel) + { + m_channel.PushNotificationReceived(token); + } + else + { + auto lock = m_lock.lock_exclusive(); + + if (m_foregroundHandlerCount == 1) + { + auto appUserModelId = GetAppUserModelId(); + + THROW_IF_FAILED(PushNotifications_UnregisterNotificationSinkForFullTrustApplication(appUserModelId.get())); + } + + m_foregroundHandlers.remove(token); + --m_foregroundHandlerCount; + } } else { @@ -148,6 +184,20 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation } CATCH_RETURN() + HRESULT __stdcall PushNotificationChannel::OnRawNotificationReceived(unsigned int payloadLength, _In_ byte* payload, _In_ HSTRING /*correlationVector */) noexcept try + { + BOOL foregroundHandled = true; + THROW_IF_FAILED(InvokeAll(payloadLength, payload, &foregroundHandled)); + + if (!foregroundHandled) + { + ProtocolLaunchHelper(payloadLength, payload); + } + + return S_OK; + } + CATCH_RETURN(); + bool PushNotificationChannel::IsBackgroundTaskBuilderAvailable() { return winrt::Windows::ApiInformation::IsMethodPresent(L"Windows.ApplicationModel.Background.BackgroundTaskBuilder", L"SetTaskEntryPointClsid"); diff --git a/dev/PushNotifications/PushNotificationChannel.h b/dev/PushNotifications/PushNotificationChannel.h index cb02cb6e68..1a1595acd1 100644 --- a/dev/PushNotifications/PushNotificationChannel.h +++ b/dev/PushNotifications/PushNotificationChannel.h @@ -5,6 +5,7 @@ #include "Microsoft.Windows.PushNotifications.PushNotificationChannel.g.h" #include #include "winrt/Windows.Networking.PushNotifications.h" +#include #include "externs.h" namespace winrt::Microsoft::Windows::PushNotifications::implementation @@ -13,7 +14,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation winrt::Microsoft::Windows::PushNotifications::PushNotificationChannel, winrt::Microsoft::Windows::PushNotifications::PushNotificationReceivedEventArgs> PushNotificationEventHandler; - struct PushNotificationChannel : PushNotificationChannelT + struct PushNotificationChannel : PushNotificationChannelT { PushNotificationChannel(winrt::Windows::Networking::PushNotifications::PushNotificationChannel const& channel); @@ -29,6 +30,9 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation // IWpnForegroundSink HRESULT __stdcall InvokeAll(_In_ ULONG length, _In_ byte* payload, _Out_ BOOL* foregroundHandled) noexcept; + // INotificationHandler + HRESULT __stdcall OnRawNotificationReceived(unsigned int payloadLength, _In_ byte* payload, _In_ HSTRING /*correlationVector */) noexcept; + private: bool IsPackagedAppScenario(); bool IsBackgroundTaskBuilderAvailable(); diff --git a/dev/PushNotifications/PushNotificationUtility.cpp b/dev/PushNotifications/PushNotificationUtility.cpp new file mode 100644 index 0000000000..081800b8fe --- /dev/null +++ b/dev/PushNotifications/PushNotificationUtility.cpp @@ -0,0 +1,69 @@ +// 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 "externs.h" +#include "PushNotificationUtility.h" + +wil::unique_cotaskmem_string GetAppUserModelId() +{ + wchar_t appId[APPLICATION_USER_MODEL_ID_MAX_LENGTH] = {}; + UINT32 appIdSize{ ARRAYSIZE(appId) }; + + THROW_IF_FAILED(::GetCurrentApplicationUserModelId(&appIdSize, appId)); + + return wil::make_unique_string(appId); +} + +std::wstring Utf8BytesToWideString(unsigned int payloadLength, _In_reads_(payloadLength) byte* payload) +{ + int size = MultiByteToWideChar( + CP_UTF8, + 0, + reinterpret_cast(payload), + payloadLength, + nullptr, + 0); + THROW_LAST_ERROR_IF(size == 0); + + std::wstring payloadAsWideString(size, 0); + size = MultiByteToWideChar( + CP_UTF8, + 0, + reinterpret_cast(payload), + payloadLength, + &payloadAsWideString[0], + size); + THROW_LAST_ERROR_IF(size == 0); + + return payloadAsWideString; +} + +void ProtocolLaunchHelper(unsigned int payloadLength, _In_reads_(payloadLength) byte* payload) +{ + // Command line format: ----WindowsAppRuntimePushServer:-Payload:"" + std::wstring commandLine = L"----WindowsAppRuntimePushServer:-Payload:\""; + + // Escape special characters to follow command line standards for any app activation type in AppLifecycle + // (See AppInstance.cpp and Serialize() from other activation types) + std::wstring payloadAsWideString = Utf8BytesToWideString(payloadLength, payload); + auto payloadAsEscapedUriFormat = winrt::Windows::Foundation::Uri::EscapeComponent(payloadAsWideString.c_str()); + + commandLine.append(payloadAsEscapedUriFormat); + commandLine.append(L"\""); + + wil::unique_cotaskmem_string processName; + THROW_IF_FAILED(GetCurrentProcessPath(processName)); + + SHELLEXECUTEINFO shellExecuteInfo{}; + shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO); + shellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_DOENVSUBST; + shellExecuteInfo.lpFile = processName.get(); + shellExecuteInfo.lpParameters = commandLine.c_str(); + + shellExecuteInfo.nShow = SW_NORMAL; + + if (!ShellExecuteEx(&shellExecuteInfo)) + { + THROW_IF_WIN32_ERROR(GetLastError()); + } +} diff --git a/dev/PushNotifications/PushNotificationUtility.h b/dev/PushNotifications/PushNotificationUtility.h new file mode 100644 index 0000000000..69475daa1d --- /dev/null +++ b/dev/PushNotifications/PushNotificationUtility.h @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +#pragma once +#include "pch.h" + +const std::wstring ConvertByteArrayToWideString(unsigned int payloadLength, _In_reads_(payloadLength) byte* payload); +void ProtocolLaunchHelper(unsigned int payloadLength, _In_reads_(payloadLength) byte* payload); +wil::unique_cotaskmem_string GetAppUserModelId(); diff --git a/dev/PushNotifications/PushNotifications.vcxitems b/dev/PushNotifications/PushNotifications.vcxitems index 118587af45..acf9dce25e 100644 --- a/dev/PushNotifications/PushNotifications.vcxitems +++ b/dev/PushNotifications/PushNotifications.vcxitems @@ -23,6 +23,7 @@ + @@ -36,6 +37,10 @@ + + + + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index b66e18f5f2..08a90202a6 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -126,7 +126,7 @@ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp17 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -144,7 +144,7 @@ true stdcpp17 Guard - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -161,7 +161,7 @@ _DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp17 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -179,7 +179,7 @@ true stdcpp17 Guard - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -196,7 +196,7 @@ _DEBUG;_WINDOWS;%(PreprocessorDefinitions) true stdcpp20 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows @@ -214,7 +214,7 @@ true Guard stdcpp20 - %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)..\WindowsAppSDK_BootstrapDLL + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory);$(OutDir)..\PushNotificationsLongRunningTask.ProxyStub;$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)..\WindowsAppSDK_BootstrapDLL Windows diff --git a/dev/PushNotifications/externs.h b/dev/PushNotifications/externs.h index 090418cb8b..2217362df3 100644 --- a/dev/PushNotifications/externs.h +++ b/dev/PushNotifications/externs.h @@ -20,4 +20,3 @@ inline HRESULT GetCurrentProcessPath(wil::unique_cotaskmem_string& processName) { return wil::GetModuleFileNameExW(GetCurrentProcess(), nullptr, processName); }; - diff --git a/test/TestApps/PushNotificationsDemoApp/main.cpp b/test/TestApps/PushNotificationsDemoApp/main.cpp index ccdf58a866..2ad3518336 100644 --- a/test/TestApps/PushNotificationsDemoApp/main.cpp +++ b/test/TestApps/PushNotificationsDemoApp/main.cpp @@ -18,7 +18,7 @@ winrt::Windows::Foundation::IAsyncOperation RequestChan // To obtain an AAD RemoteIdentifier for your app, // follow the instructions on https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app auto channelOperation = PushNotificationManager::CreateChannelAsync( - winrt::guid("ccd2ae3f-764f-4ae3-be45-9804761b28b2")); + winrt::guid("0160ee84-0c53-4851-9ff2-d7f5a87ed914")); // Setup the inprogress event handler channelOperation.Progress( From 5d4dd661dd15e2468af8a6a7a361b7411689c1c0 Mon Sep 17 00:00:00 2001 From: eric langlois Date: Thu, 7 Oct 2021 18:01:37 -0700 Subject: [PATCH 48/50] Fix for regression in protocol activation in AppLifecycle (#1558) * Hack to address AppLifecycle regression introduced in main * Code cleanup * Code cleanup * Addressing PR feedback * Adding bare bone unit test to avoid future regression Co-authored-by: Eric Langlois --- .../ActivationRegistrationManager.cpp | 2 +- .../ActivationRegistrationManager.h | 3 +- dev/AppLifecycle/AppInstance.cpp | 38 +++++++++++++------ .../API/DynamicDependency.vcxitems.filters | 1 - test/AppLifecycle/FunctionalTests.cpp | 12 ++++++ test/TestApps/AppLifecycleTestApp/main.cpp | 9 +++++ .../Package.appxmanifest | 2 +- .../Package.appxmanifest | 2 +- test/inc/TestDef.h | 1 + 9 files changed, 54 insertions(+), 16 deletions(-) diff --git a/dev/AppLifecycle/ActivationRegistrationManager.cpp b/dev/AppLifecycle/ActivationRegistrationManager.cpp index 2fa802efc3..e6889722c0 100644 --- a/dev/AppLifecycle/ActivationRegistrationManager.cpp +++ b/dev/AppLifecycle/ActivationRegistrationManager.cpp @@ -21,7 +21,7 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation // Example: C:\some\path\App.exe "----ms-protocol:myscheme:some=data&some=other" return wil::str_printf(L"%s \"%s%s%s%s\"", exePath.c_str(), c_argumentPrefix, - c_protocolArgumentString, c_argumentSuffix, argumentData.c_str()); + c_msProtocolArgumentString, c_argumentSuffix, argumentData.c_str()); } void ActivationRegistrationManager::RegisterForFileTypeActivation( diff --git a/dev/AppLifecycle/ActivationRegistrationManager.h b/dev/AppLifecycle/ActivationRegistrationManager.h index c675a5e285..b8b6fc8826 100644 --- a/dev/AppLifecycle/ActivationRegistrationManager.h +++ b/dev/AppLifecycle/ActivationRegistrationManager.h @@ -9,7 +9,8 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation // Registration constant values. static PCWSTR c_argumentPrefix{ L"----" }; static PCWSTR c_argumentSuffix{ L":" }; - static PCWSTR c_protocolArgumentString{ L"ms-protocol" }; + static PCWSTR c_msProtocolArgumentString{ L"ms-protocol" }; + static PCWSTR c_pushProtocolArgumentString{ L"WindowsAppRuntimePushServer" }; static PCWSTR c_runKeyPath{ LR"(Software\Microsoft\Windows\CurrentVersion\Run\)" }; struct ActivationRegistrationManager diff --git a/dev/AppLifecycle/AppInstance.cpp b/dev/AppLifecycle/AppInstance.cpp index 9dec948483..2abec8eaf9 100644 --- a/dev/AppLifecycle/AppInstance.cpp +++ b/dev/AppLifecycle/AppInstance.cpp @@ -25,16 +25,12 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation INIT_ONCE AppInstance::s_initOnce{}; winrt::com_ptr AppInstance::s_current; - std::tuple ParseCommandLine(const std::wstring& commandLine) + std::tuple GetActivationArguments(PWSTR argv[], int argc, PCWSTR activationKind) { - int argc{}; - wil::unique_hlocal_ptr argv{ CommandLineToArgvW(commandLine.c_str(), &argc) }; - - // Search for ----ms-protocol: for (int index = 0; index < argc; index++) { std::wstring_view fullArgument = argv[index]; - auto protocolQualifier = wil::str_printf(L"%s%s%s", c_argumentPrefix, c_protocolArgumentString, c_argumentSuffix); + auto protocolQualifier = wil::str_printf(L"%s%s%s", c_argumentPrefix, activationKind, c_argumentSuffix); auto argStart = fullArgument.find(protocolQualifier); if (argStart == std::wstring::npos) @@ -57,6 +53,25 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation return { argument.substr(0, argsDelim), argument.substr(argsDelim + 1) }; } + return { L"", L""}; + } + + std::tuple ParseCommandLine(const std::wstring& commandLine) + { + int argc{}; + + wil::unique_hlocal_ptr argv{ CommandLineToArgvW(commandLine.c_str(), &argc) }; + + PCWSTR activationKinds[] = { c_msProtocolArgumentString, c_pushProtocolArgumentString }; + for (auto activationKind : activationKinds) + { + auto [ kind, data ] = GetActivationArguments(argv.get(), argc, activationKind); + if (kind != L"") + { + return { kind, data }; + } + } + return { L"", L"" }; } @@ -343,11 +358,11 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation // protocol, except the catch-all LaunchActivatedEventArgs case. if (!contractArgument.empty()) { - if (contractArgument == L"WindowsAppRuntimePushServer") + if (contractArgument == c_pushProtocolArgumentString) { // Generate a basic encoded launch Uri for all Push activations. std::wstring tempContractData = GenerateEncodedLaunchUri(L"App", c_pushContractId); - contractArgument = c_protocolArgumentString; + contractArgument = c_msProtocolArgumentString; // A non-empty contractData means we have a payload. // This contains a background notification. It is specific to unpackaged apps. @@ -358,14 +373,15 @@ namespace winrt::Microsoft::Windows::AppLifecycle::implementation if (!contractData.empty() && index == 0) { tempContractData += L"&payload="; - // 11 -> the size of &payload= + starting quote + ending quote. - tempContractData += contractData.substr(10, contractData.size() - 11); + // 9 -> the size of &payload= as quotes in the contrat data will + // have been tripped in the call to ParseCommandLine. + tempContractData += contractData.substr(9, contractData.size() - 9); } contractData = tempContractData; } - if (CompareStringOrdinal(contractArgument.c_str(), static_cast(contractArgument.size()), c_protocolArgumentString, -1, TRUE) == CSTR_EQUAL) + if (CompareStringOrdinal(contractArgument.c_str(), static_cast(contractArgument.size()), c_msProtocolArgumentString, -1, TRUE) == CSTR_EQUAL) { kind = ExtendedActivationKind::Protocol; auto args = make(contractData.c_str()); diff --git a/dev/DynamicDependency/API/DynamicDependency.vcxitems.filters b/dev/DynamicDependency/API/DynamicDependency.vcxitems.filters index 1226846aae..260a4139fd 100644 --- a/dev/DynamicDependency/API/DynamicDependency.vcxitems.filters +++ b/dev/DynamicDependency/API/DynamicDependency.vcxitems.filters @@ -49,7 +49,6 @@ - diff --git a/test/AppLifecycle/FunctionalTests.cpp b/test/AppLifecycle/FunctionalTests.cpp index a727b21825..db8dac3d19 100644 --- a/test/AppLifecycle/FunctionalTests.cpp +++ b/test/AppLifecycle/FunctionalTests.cpp @@ -188,6 +188,18 @@ namespace Test::AppLifecycle WaitForEvent(event, m_failed); } + TEST_METHOD(GetActivatedEventArgsForPush_Win32) + { + // Create a named event for communicating with test app. + auto event = CreateTestEvent(c_testPushPhaseEventName); + + // Launch the test app using the push activationprotocol. + Execute(L"AppLifecycleTestApp.exe", L"----WindowsAppRuntimePushServer:-Payload:\"\"", g_deploymentDir); + + // Wait for the protocol activation. + WaitForEvent(event, m_failed); + } + TEST_METHOD(GetActivatedEventArgsForStartup_Win32) { // Create a named event for communicating with test app. diff --git a/test/TestApps/AppLifecycleTestApp/main.cpp b/test/TestApps/AppLifecycleTestApp/main.cpp index ac7170b213..5f6e446169 100644 --- a/test/TestApps/AppLifecycleTestApp/main.cpp +++ b/test/TestApps/AppLifecycleTestApp/main.cpp @@ -165,6 +165,15 @@ int main() succeeded = true; } } + else if (kind == ExtendedActivationKind::Push) + { + if (args.Data() != nullptr) + { + // Signal event that the was correctly activated through push. + SignalPhase(c_testPushPhaseEventName); + succeeded = true; + } + } if (!succeeded) { diff --git a/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest b/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest index 71a2571567..65d30def92 100644 --- a/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest +++ b/test/TestApps/PushNotificationsDemoPackage/Package.appxmanifest @@ -49,7 +49,7 @@ - + diff --git a/test/TestApps/PushNotificationsTestAppPackage/Package.appxmanifest b/test/TestApps/PushNotificationsTestAppPackage/Package.appxmanifest index 60ff7a1919..834df05340 100644 --- a/test/TestApps/PushNotificationsTestAppPackage/Package.appxmanifest +++ b/test/TestApps/PushNotificationsTestAppPackage/Package.appxmanifest @@ -49,7 +49,7 @@ - + diff --git a/test/inc/TestDef.h b/test/inc/TestDef.h index cd5b200582..93a41cbb2a 100644 --- a/test/inc/TestDef.h +++ b/test/inc/TestDef.h @@ -17,6 +17,7 @@ static const std::wstring c_testFilePhaseEventName = L"WindowsAppRuntimeTestFile static const std::wstring c_testStartupPhaseEventName = L"WindowsAppRuntimeTestStartupPhaseEventName"; static const std::wstring c_testInstanceRedirectedPhaseEventName = L"WindowsAppRuntimeTestInstanceRedirectedPhaseEventName"; +static const std::wstring c_testPushPhaseEventName = L"WindowsAppRuntimeTestPushPhaseEventName"; inline const winrt::hstring c_rawNotificationPayload = L""; inline IID c_comServerId = winrt::guid("ccd2ae3f-764f-4ae3-be45-9804761b28b2"); // Value from PushNotificationsTestAppPackage ComActivator in appxmanifest. inline IID c_fakeComServerId = winrt::guid("00000000-0000-0000-0000-000000000001"); From 364bb413301e10496a78fb20cdd69ed2810449cb Mon Sep 17 00:00:00 2001 From: Paul Purifoy <33183370+pmpurifoy@users.noreply.github.com> Date: Fri, 8 Oct 2021 15:50:49 -0700 Subject: [PATCH 49/50] LRP E2E Scenario fixes (#1543) * LRP fixes * In progress * Revert "In progress" This reverts commit d5d021acf847f8f84dbb87557aae72ffc1754758. * Add fixes to E2E testing * Address nits * Added nits from other PR and fixed PushNotificationUtiilty * Use string converter with payload length * Update APITests.cpp * Include AppLifecycle fix for PushArgs * Revert "Include AppLifecycle fix for PushArgs" This reverts commit 33994da986b08c579590fe9a6ef0e0a9d583a712. * Addressing nits * Add Verify.h to demo app for helper function * Added TAEF dependencies to Demo/TestApp Co-authored-by: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> --- WindowsAppRuntime.sln | 1 + .../PushNotificationChannel.cpp | 14 +-- .../PushNotificationManager.cpp | 37 +++--- .../PushNotificationReceivedEventArgs.cpp | 6 +- .../PushNotificationUtility.cpp | 69 ------------ .../PushNotificationUtility.h | 106 +++++++++++++++++- .../PushNotifications.vcxitems | 5 - .../NotificationListener.cpp | 26 +---- .../NotificationListenerManager.cpp | 34 +++--- .../NotificationListenerManager.h | 7 +- .../PushNotificationsLongRunningTask.vcxproj | 5 +- ...tificationsLongRunningTask.vcxproj.filters | 3 - .../platform.cpp | 5 +- .../PushNotificationsLongRunningTask/utils.h | 27 ----- dev/PushNotifications/utils.h | 38 ------- .../PushNotificationsDemoApp.vcxproj | 8 ++ .../PushNotificationsDemoApp/main.cpp | 38 ++++++- .../PushNotificationsDemoApp/packages.config | 1 + .../PushNotificationsTestApp.vcxproj | 2 +- .../PushNotificationsTestApp/packages.config | 1 + 20 files changed, 203 insertions(+), 230 deletions(-) delete mode 100644 dev/PushNotifications/PushNotificationUtility.cpp delete mode 100644 dev/PushNotifications/PushNotificationsLongRunningTask/utils.h delete mode 100644 dev/PushNotifications/utils.h diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index d53e2adfeb..0199bf2073 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -251,6 +251,7 @@ Global dev\EnvironmentManager\API\Microsoft.Process.Environment.vcxitems*{2f3fad1b-d3df-4866-a3a3-c2c777d55638}*SharedItemsImports = 9 dev\UndockedRegFreeWinRT\UndockedRegFreeWinRT.vcxitems*{56371ca6-144b-4989-a4e9-391ad4fa7651}*SharedItemsImports = 9 test\inc\inc.vcxitems*{56a1d696-feda-4333-bf37-772ebececb10}*SharedItemsImports = 4 + test\inc\inc.vcxitems*{5b2d17fe-c371-417f-860c-3d32397c2404}*SharedItemsImports = 4 test\inc\inc.vcxitems*{7c502995-59c3-483b-86ba-815985353633}*SharedItemsImports = 4 test\inc\inc.vcxitems*{8e52d7ea-a200-4a6b-ba74-8efb49468caf}*SharedItemsImports = 4 test\inc\inc.vcxitems*{b567fe2e-3a03-48d0-b2b5-760cdec35891}*SharedItemsImports = 9 diff --git a/dev/PushNotifications/PushNotificationChannel.cpp b/dev/PushNotifications/PushNotificationChannel.cpp index 2b36467e98..73c5395eee 100644 --- a/dev/PushNotifications/PushNotificationChannel.cpp +++ b/dev/PushNotifications/PushNotificationChannel.cpp @@ -108,7 +108,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation if (!m_foregroundHandlerCount) { - auto appUserModelId = GetAppUserModelId(); + auto appUserModelId{ winrt::Microsoft::Helpers::GetAppUserModelId() }; THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appUserModelId.get(), this)); } @@ -123,8 +123,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation auto lock = m_lock.lock_exclusive(); if (!m_foregroundHandlerCount++) { - wil::com_ptr notificationsLongRunningPlatform{ - wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + auto notificationsLongRunningPlatform{ winrt::Microsoft::Helpers::GetNotificationPlatform() }; wil::unique_cotaskmem_string processName; THROW_IF_FAILED(GetCurrentProcessPath(processName)); @@ -149,7 +148,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation if (m_foregroundHandlerCount == 1) { - auto appUserModelId = GetAppUserModelId(); + auto appUserModelId{ winrt::Microsoft::Helpers::GetAppUserModelId() }; THROW_IF_FAILED(PushNotifications_UnregisterNotificationSinkForFullTrustApplication(appUserModelId.get())); } @@ -164,8 +163,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation m_foregroundHandlers.remove(token); if (!--m_foregroundHandlerCount) { - wil::com_ptr notificationsLongRunningPlatform{ - wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + auto notificationsLongRunningPlatform{ winrt::Microsoft::Helpers::GetNotificationPlatform() }; wil::unique_cotaskmem_string processName; THROW_IF_FAILED(GetCurrentProcessPath(processName)); @@ -191,7 +189,9 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation if (!foregroundHandled) { - ProtocolLaunchHelper(payloadLength, payload); + wil::unique_cotaskmem_string processName; + THROW_IF_FAILED(GetCurrentProcessPath(processName)); + THROW_IF_FAILED(winrt::Microsoft::Helpers::ProtocolLaunchHelper(processName.get(), payloadLength, payload)); } return S_OK; diff --git a/dev/PushNotifications/PushNotificationManager.cpp b/dev/PushNotifications/PushNotificationManager.cpp index 305ace44f1..44d207e3ac 100644 --- a/dev/PushNotifications/PushNotificationManager.cpp +++ b/dev/PushNotifications/PushNotificationManager.cpp @@ -19,8 +19,8 @@ #include #include #include "NotificationsLongRunningProcess_h.h" -#include "PushNotificationTelemetry.h" #include +#include "PushNotificationUtility.h" using namespace std::literals; @@ -40,6 +40,10 @@ namespace winrt using namespace Windows::Foundation; } +namespace PushNotificationHelpers +{ + using namespace winrt::Microsoft::Windows::PushNotifications::Helpers; +} namespace winrt::Microsoft::Windows::PushNotifications::implementation { static winrt::Windows::ApplicationModel::Background::IBackgroundTaskRegistration s_pushTriggerRegistration{ nullptr }; @@ -77,7 +81,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { auto coInitialize = wil::CoInitializeEx(); - auto notificationPlatform{ wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + auto notificationPlatform{ PushNotificationHelpers::GetNotificationPlatform() }; wil::unique_cotaskmem_string processName; THROW_IF_FAILED(GetCurrentProcessPath(processName)); @@ -196,6 +200,12 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation PushNotificationChannelManager channelManager{}; winrt::PushNotificationChannel pushChannelReceived{ co_await channelManager.CreatePushNotificationChannelForApplicationAsync(unpackagedAppUserModelId.get()) }; + auto notificationPlatform{ PushNotificationHelpers::GetNotificationPlatform() }; + + wil::unique_cotaskmem_string processName; + THROW_IF_FAILED(GetCurrentProcessPath(processName)); + THROW_IF_FAILED(notificationPlatform->RegisterLongRunningActivator(processName.get())); + PushNotificationTelemetry::ChannelRequestedByApi(S_OK, remoteId, usingLegacyImplementation); co_return winrt::make( @@ -233,7 +243,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation catch (...) { PushNotificationTelemetry::ChannelRequestedByApi(wil::ResultFromCaughtException(), remoteId, usingLegacyImplementation); - throw; } } @@ -261,14 +270,8 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation THROW_HR_IF(E_INVALIDARG, s_protocolRegistration); } - auto coInitialize = wil::CoInitializeEx(); - - wil::com_ptr notificationPlatform{ - wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; - - wil::unique_cotaskmem_string processName; - THROW_IF_FAILED(GetCurrentProcessPath(processName)); - THROW_IF_FAILED(notificationPlatform->RegisterLongRunningActivator(processName.get())); + wil::unique_cotaskmem_string unpackagedAppUserModelId; + RegisterUnpackagedApplicationHelper(GUID_NULL, unpackagedAppUserModelId); // create default registration for app { auto lock = s_activatorInfoLock.lock_exclusive(); @@ -384,7 +387,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { PushNotificationTelemetry::ActivatorRegisteredByApi(wil::ResultFromCaughtException(), details == nullptr ? PushNotificationRegistrationActivators::Undefined : details.Activators()); - throw; } } @@ -415,12 +417,11 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_NOT_FOUND), !s_protocolRegistration); auto coInitialize = wil::CoInitializeEx(); - wil::com_ptr notificationPlatform{ - wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + auto notificationPlatform{ PushNotificationHelpers::GetNotificationPlatform() }; wil::unique_cotaskmem_string processName; THROW_IF_FAILED(GetCurrentProcessPath(processName)); - THROW_IF_FAILED(notificationPlatform->UnregisterLongRunningActivator(processName.get())); + LOG_IF_FAILED(notificationPlatform->UnregisterLongRunningActivator(processName.get())); s_protocolRegistration = false; } @@ -453,12 +454,11 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { auto coInitialize = wil::CoInitializeEx(); - wil::com_ptr notificationPlatform{ - wil::CoCreateInstance(CLSCTX_LOCAL_SERVER) }; + auto notificationPlatform{ PushNotificationHelpers::GetNotificationPlatform() }; wil::unique_cotaskmem_string processName; THROW_IF_FAILED(GetCurrentProcessPath(processName)); - THROW_IF_FAILED(notificationPlatform->UnregisterLongRunningActivator(processName.get())); + LOG_IF_FAILED(notificationPlatform->UnregisterLongRunningActivator(processName.get())); s_protocolRegistration = false; } @@ -467,7 +467,6 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation { PushNotificationTelemetry::ActivatorUnregisteredByApi(wil::ResultFromCaughtException(), PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator); - throw; } PushNotificationTelemetry::ActivatorUnregisteredByApi(S_OK, PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator); diff --git a/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp b/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp index e2fc64dd3d..94877d115a 100644 --- a/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp +++ b/dev/PushNotifications/PushNotificationReceivedEventArgs.cpp @@ -14,8 +14,7 @@ #include #include #include "ValueMarshaling.h" - -#include "utils.h" +#include "PushNotificationUtility.h" namespace winrt { @@ -69,8 +68,7 @@ namespace winrt::Microsoft::Windows::PushNotifications::implementation std::vector PushNotificationReceivedEventArgs::BuildPayload(std::wstring const& payload) { - std::string payloadToSimpleString = ConvertWideStringToUtf8String(payload); - + std::string payloadToSimpleString{ ::winrt::Microsoft::Windows::PushNotifications::Helpers::WideStringToUtf8String(payload) }; return { payloadToSimpleString.c_str(), payloadToSimpleString.c_str() + (payloadToSimpleString.length() * sizeof(uint8_t)) }; } diff --git a/dev/PushNotifications/PushNotificationUtility.cpp b/dev/PushNotifications/PushNotificationUtility.cpp deleted file mode 100644 index 081800b8fe..0000000000 --- a/dev/PushNotifications/PushNotificationUtility.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// 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 "externs.h" -#include "PushNotificationUtility.h" - -wil::unique_cotaskmem_string GetAppUserModelId() -{ - wchar_t appId[APPLICATION_USER_MODEL_ID_MAX_LENGTH] = {}; - UINT32 appIdSize{ ARRAYSIZE(appId) }; - - THROW_IF_FAILED(::GetCurrentApplicationUserModelId(&appIdSize, appId)); - - return wil::make_unique_string(appId); -} - -std::wstring Utf8BytesToWideString(unsigned int payloadLength, _In_reads_(payloadLength) byte* payload) -{ - int size = MultiByteToWideChar( - CP_UTF8, - 0, - reinterpret_cast(payload), - payloadLength, - nullptr, - 0); - THROW_LAST_ERROR_IF(size == 0); - - std::wstring payloadAsWideString(size, 0); - size = MultiByteToWideChar( - CP_UTF8, - 0, - reinterpret_cast(payload), - payloadLength, - &payloadAsWideString[0], - size); - THROW_LAST_ERROR_IF(size == 0); - - return payloadAsWideString; -} - -void ProtocolLaunchHelper(unsigned int payloadLength, _In_reads_(payloadLength) byte* payload) -{ - // Command line format: ----WindowsAppRuntimePushServer:-Payload:"" - std::wstring commandLine = L"----WindowsAppRuntimePushServer:-Payload:\""; - - // Escape special characters to follow command line standards for any app activation type in AppLifecycle - // (See AppInstance.cpp and Serialize() from other activation types) - std::wstring payloadAsWideString = Utf8BytesToWideString(payloadLength, payload); - auto payloadAsEscapedUriFormat = winrt::Windows::Foundation::Uri::EscapeComponent(payloadAsWideString.c_str()); - - commandLine.append(payloadAsEscapedUriFormat); - commandLine.append(L"\""); - - wil::unique_cotaskmem_string processName; - THROW_IF_FAILED(GetCurrentProcessPath(processName)); - - SHELLEXECUTEINFO shellExecuteInfo{}; - shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO); - shellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_DOENVSUBST; - shellExecuteInfo.lpFile = processName.get(); - shellExecuteInfo.lpParameters = commandLine.c_str(); - - shellExecuteInfo.nShow = SW_NORMAL; - - if (!ShellExecuteEx(&shellExecuteInfo)) - { - THROW_IF_WIN32_ERROR(GetLastError()); - } -} diff --git a/dev/PushNotifications/PushNotificationUtility.h b/dev/PushNotifications/PushNotificationUtility.h index 69475daa1d..6fd8d95bad 100644 --- a/dev/PushNotifications/PushNotificationUtility.h +++ b/dev/PushNotifications/PushNotificationUtility.h @@ -3,7 +3,107 @@ #pragma once #include "pch.h" +#include "NotificationsLongRunningProcess_h.h" -const std::wstring ConvertByteArrayToWideString(unsigned int payloadLength, _In_reads_(payloadLength) byte* payload); -void ProtocolLaunchHelper(unsigned int payloadLength, _In_reads_(payloadLength) byte* payload); -wil::unique_cotaskmem_string GetAppUserModelId(); +namespace winrt::Microsoft::Windows::PushNotifications::Helpers +{ + inline std::string WideStringToUtf8String(_In_ std::wstring const& utf16string) + { + int size = WideCharToMultiByte( + CP_UTF8, + 0, + utf16string.data(), + static_cast(utf16string.length()), + nullptr, + 0, + nullptr, + nullptr); + + THROW_LAST_ERROR_IF(size == 0); + + std::string utf8string; + utf8string.resize(size); + + size = WideCharToMultiByte( + CP_UTF8, + 0, + utf16string.data(), + static_cast(utf16string.length()), + &utf8string[0], + size, + nullptr, + nullptr); + + THROW_LAST_ERROR_IF(size == 0); + + return utf8string; + } + + inline std::wstring Utf8BytesToWideString(unsigned int payloadLength, _In_reads_(payloadLength) byte* payload) + { + int size = MultiByteToWideChar( + CP_UTF8, + 0, + reinterpret_cast(payload), + payloadLength, + nullptr, + 0); + THROW_LAST_ERROR_IF(size == 0); + + std::wstring payloadAsWideString(size, 0); + size = MultiByteToWideChar( + CP_UTF8, + 0, + reinterpret_cast(payload), + payloadLength, + &payloadAsWideString[0], + size); + THROW_LAST_ERROR_IF(size == 0); + + return payloadAsWideString; + } + + inline wil::unique_cotaskmem_string GetAppUserModelId() + { + wchar_t appId[APPLICATION_USER_MODEL_ID_MAX_LENGTH] = {}; + UINT32 appIdSize{ ARRAYSIZE(appId) }; + + THROW_IF_FAILED(::GetCurrentApplicationUserModelId(&appIdSize, appId)); + + return wil::make_unique_string(appId); + } + + inline HRESULT ProtocolLaunchHelper(std::wstring processName, unsigned int payloadLength, _In_reads_(payloadLength) byte* payload) noexcept try + { + // Command line format: ----WindowsAppRuntimePushServer:-Payload:"" + std::wstring commandLine = L"----WindowsAppRuntimePushServer:-Payload:\""; + + // Escape special characters to follow command line standards for any app activation type in AppLifecycle + // (See AppInstance.cpp and Serialize() from other activation types) + auto payloadAsWideString{ Utf8BytesToWideString(payloadLength, payload) }; + auto payloadAsEscapedUriFormat = winrt::Windows::Foundation::Uri::EscapeComponent(payloadAsWideString.c_str()); + + commandLine.append(payloadAsEscapedUriFormat); + commandLine.append(L"\""); + + SHELLEXECUTEINFO shellExecuteInfo{}; + shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO); + shellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_DOENVSUBST; + shellExecuteInfo.lpFile = processName.c_str(); + shellExecuteInfo.lpParameters = commandLine.c_str(); + + shellExecuteInfo.nShow = SW_NORMAL; + + if (!ShellExecuteEx(&shellExecuteInfo)) + { + THROW_IF_WIN32_ERROR(GetLastError()); + } + return S_OK; + } + CATCH_RETURN() + + inline wil::com_ptr GetNotificationPlatform() + { + return wil::CoCreateInstance(CLSCTX_LOCAL_SERVER); + } +} diff --git a/dev/PushNotifications/PushNotifications.vcxitems b/dev/PushNotifications/PushNotifications.vcxitems index acf9dce25e..5f0fb92680 100644 --- a/dev/PushNotifications/PushNotifications.vcxitems +++ b/dev/PushNotifications/PushNotifications.vcxitems @@ -23,7 +23,6 @@ - @@ -38,9 +37,5 @@ - - - - \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp index c23ebfd3a1..f2d2050e47 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListener.cpp @@ -1,5 +1,5 @@ #include "pch.h" -#include "utils.h" +#include "../PushNotificationUtility.h" HRESULT NotificationListener::RuntimeClassInitialize( std::shared_ptr foregroundSinkManager, @@ -22,29 +22,7 @@ STDMETHODIMP_(HRESULT __stdcall) NotificationListener::OnRawNotificationReceived if (!m_foregroundSinkManager->InvokeForegroundHandlers(m_appId, payloadArray, payloadLength)) { - // Command line format: ----WindowsAppRuntimePushServer:-Payload:"" - std::wstring commandLine = L"----WindowsAppRuntimePushServer:-Payload:\""; - - // Escape special characters to follow command line standards for any app activation type in AppLifecycle - // (See AppInstance.cpp and Serialize() from other activation types) - std::wstring payloadAsWideString = ConvertByteArrayToWideString(payloadLength, payload); - auto payloadAsEscapedUriFormat = winrt::Windows::Foundation::Uri::EscapeComponent(payloadAsWideString.c_str()); - - commandLine.append(payloadAsEscapedUriFormat); - commandLine.append(L"\""); - - SHELLEXECUTEINFO shellExecuteInfo{}; - shellExecuteInfo.cbSize = sizeof(SHELLEXECUTEINFO); - shellExecuteInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_DOENVSUBST; - shellExecuteInfo.lpFile = m_processName.c_str(); - shellExecuteInfo.lpParameters = commandLine.c_str(); - - shellExecuteInfo.nShow = SW_NORMAL; - - if (!ShellExecuteEx(&shellExecuteInfo)) - { - THROW_IF_WIN32_ERROR(GetLastError()); - } + THROW_IF_FAILED(winrt::Microsoft::Windows::PushNotifications::Helpers::ProtocolLaunchHelper(m_processName, payloadLength, payload)); }; return S_OK; diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp index 75bc1c4893..642d161c30 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.cpp @@ -3,42 +3,42 @@ using namespace Microsoft::WRL; using namespace ::ABI::Microsoft::Internal::PushNotifications; -void NotificationListenerManager::Initialize(std::shared_ptr foregroundSinkManager, std::map& appIdList) +void NotificationListenerManager::Initialize(std::shared_ptr foregroundSinkManager) { m_foregroundSinkManager = foregroundSinkManager; +} +void NotificationListenerManager::SetAppIdMapping(std::map& appIdList) +{ for (auto appData : appIdList) { AddListener(appData.first, appData.second); } } -void NotificationListenerManager::AddListener(std::wstring appId, std::wstring processName) +void NotificationListenerManager::AddListener(std::wstring const& appId, std::wstring const& processName) { - auto lock = m_lock.lock_exclusive(); - THROW_HR_IF(E_INVALIDARG, appId.empty()); THROW_HR_IF(E_INVALIDARG, processName.empty()); - if (m_notificationListeners.find(appId) == std::end(m_notificationListeners)) - { - ComPtr listener; - THROW_IF_FAILED(MakeAndInitialize(&listener, m_foregroundSinkManager, appId, processName)); - THROW_IF_FAILED(PushNotifications_RegisterFullTrustApplication(appId.c_str(), GUID_NULL)); - THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appId.c_str(), listener.Get())); - - AgileRef agileListener; - THROW_IF_FAILED(AsAgile(listener.Get(), &agileListener)); - m_notificationListeners.insert({ appId, agileListener }); - } + auto lock = m_lock.lock_exclusive(); + + // Make sure we keep the long running sink up-to-date with wpncore. + ComPtr newListener; + THROW_IF_FAILED(MakeAndInitialize(&newListener, m_foregroundSinkManager, appId, processName)); + THROW_IF_FAILED(PushNotifications_RegisterNotificationSinkForFullTrustApplication(appId.c_str(), newListener.Get())); + + AgileRef newListenerAsAgile; + THROW_IF_FAILED(AsAgile(newListener.Get(), &newListenerAsAgile)); + m_notificationListeners[appId] = newListenerAsAgile; } void NotificationListenerManager::RemoveListener(std::wstring appId) { - auto lock = m_lock.lock_exclusive(); - THROW_HR_IF(E_INVALIDARG, appId.empty()); + auto lock = m_lock.lock_exclusive(); + LOG_IF_FAILED(PushNotifications_UnregisterNotificationSinkForFullTrustApplication(appId.c_str())); m_notificationListeners.erase(appId); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h index 63d63ba0b0..46502cc123 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/NotificationListenerManager.h @@ -9,9 +9,12 @@ class NotificationListenerManager public: NotificationListenerManager() {}; - void Initialize(std::shared_ptr foregroundSinkManager, std::map& appIdList); + // This function has to be called after initializing the ForegroundSinkManager during Platform initialization + void Initialize(std::shared_ptr foregroundSinkManager); - void AddListener(std::wstring appId, std::wstring processName); + void SetAppIdMapping(std::map& appIdList); + + void AddListener(std::wstring const& appId, std::wstring const& processName); void RemoveListener(std::wstring appId); bool IsEmpty(); diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index 08a90202a6..e41907b36c 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -242,7 +242,6 @@ - @@ -262,7 +261,7 @@ - + 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}. @@ -279,5 +278,5 @@ - + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters index 3cc03ec1a1..53d4e755e9 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj.filters @@ -36,9 +36,6 @@ Header Files - - Source Files - diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp index dac19cd621..c590fadc15 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/platform.cpp @@ -24,6 +24,7 @@ void NotificationsLongRunningPlatformImpl::Initialize() L"LRP", Storage::ApplicationDataCreateDisposition::Always); m_foregroundSinkManager = std::make_shared(); + m_notificationListenerManager.Initialize(m_foregroundSinkManager); auto fullTrustApps = GetFullTrustApps(); @@ -32,7 +33,7 @@ void NotificationsLongRunningPlatformImpl::Initialize() // We have at least one app that could receive notifications. // Cancel the timer to persist the LRP. m_lifetimeManager.Cancel(); - m_notificationListenerManager.Initialize(m_foregroundSinkManager, fullTrustApps); + m_notificationListenerManager.SetAppIdMapping(fullTrustApps); } m_initialized = true; @@ -139,7 +140,7 @@ std::map NotificationsLongRunningPlatformImpl::GetFu std::map mapOfFullTrustApps; // Get list of full trust apps with valid channels from wpncore - wil::unique_cotaskmem_array_ptr appIds; + wil::unique_cotaskmem_array_ptr appIds; PushNotifications_GetFullTrustApplicationsWithChannels(appIds.addressof(), appIds.size_address()); // Get list of apps from Storage diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/utils.h b/dev/PushNotifications/PushNotificationsLongRunningTask/utils.h deleted file mode 100644 index 88bbedbbe7..0000000000 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/utils.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "pch.h" - -const std::wstring ConvertByteArrayToWideString(unsigned int payloadLength, byte* payload) -{ - int size = MultiByteToWideChar( - CP_UTF8, - 0, - reinterpret_cast(payload), - payloadLength, - nullptr, - 0); - THROW_LAST_ERROR_IF(size == 0); - - std::wstring payloadAsWideString(size, 0); - size = MultiByteToWideChar( - CP_UTF8, - 0, - reinterpret_cast(payload), - payloadLength, - &payloadAsWideString[0], - size); - THROW_LAST_ERROR_IF(size == 0); - - return payloadAsWideString; -} diff --git a/dev/PushNotifications/utils.h b/dev/PushNotifications/utils.h deleted file mode 100644 index 187fbf84cc..0000000000 --- a/dev/PushNotifications/utils.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -#pragma once - -#include "pch.h" - -std::string ConvertWideStringToUtf8String(_In_ std::wstring const& utf16string) -{ - int size = WideCharToMultiByte( - CP_UTF8, - 0, - utf16string.data(), - static_cast(utf16string.length()), - nullptr, - 0, - nullptr, - nullptr); - - THROW_LAST_ERROR_IF(size == 0); - - std::string utf8string; - utf8string.resize(size); - - size = WideCharToMultiByte( - CP_UTF8, - 0, - utf16string.data(), - static_cast(utf16string.length()), - &utf8string[0], - size, - nullptr, - nullptr); - - THROW_LAST_ERROR_IF(size == 0); - - return utf8string; -} diff --git a/test/TestApps/PushNotificationsDemoApp/PushNotificationsDemoApp.vcxproj b/test/TestApps/PushNotificationsDemoApp/PushNotificationsDemoApp.vcxproj index 0d42ca9266..d6fddb0f58 100644 --- a/test/TestApps/PushNotificationsDemoApp/PushNotificationsDemoApp.vcxproj +++ b/test/TestApps/PushNotificationsDemoApp/PushNotificationsDemoApp.vcxproj @@ -80,6 +80,7 @@ + @@ -250,10 +251,16 @@ $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.WindowsAppRuntime.dll + + + {f76b776e-86f5-48c5-8fc7-d2795ecc9746} + + + @@ -262,6 +269,7 @@ + diff --git a/test/TestApps/PushNotificationsDemoApp/main.cpp b/test/TestApps/PushNotificationsDemoApp/main.cpp index 2ad3518336..8d82381432 100644 --- a/test/TestApps/PushNotificationsDemoApp/main.cpp +++ b/test/TestApps/PushNotificationsDemoApp/main.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include "WindowsAppRuntime.Test.AppModel.h" using namespace winrt::Microsoft::Windows::AppLifecycle; using namespace winrt::Microsoft::Windows::PushNotifications; @@ -89,11 +91,27 @@ winrt::Microsoft::Windows::PushNotifications::PushNotificationChannel RequestCha int main() { - PushNotificationActivationInfo info( - PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator, - winrt::guid("ccd2ae3f-764f-4ae3-be45-9804761b28b2")); // same clsid as app manifest + if (!Test::AppModel::IsPackagedProcess()) + { + // Major.Minor version, MinVersion=0 to find any framework package for this major.minor version + const UINT32 c_Version_MajorMinor{ 0x00040001 }; + const PACKAGE_VERSION minVersion{}; + RETURN_IF_FAILED(MddBootstrapInitialize(c_Version_MajorMinor, nullptr, minVersion)); + } - PushNotificationManager::RegisterActivator(info); + if (PushNotificationManager::IsActivatorSupported(PushNotificationRegistrationActivators::ComActivator)) + { + PushNotificationActivationInfo info( + PushNotificationRegistrationActivators::PushTrigger | PushNotificationRegistrationActivators::ComActivator, + winrt::guid("ccd2ae3f-764f-4ae3-be45-9804761b28b2")); // same clsid as app manifest + + PushNotificationManager::RegisterActivator(info); + } + else + { + PushNotificationActivationInfo info(PushNotificationRegistrationActivators::ProtocolActivator); + PushNotificationManager::RegisterActivator(info); + } auto args = AppInstance::GetCurrent().GetActivatedEventArgs(); auto kind = args.Kind(); @@ -129,7 +147,15 @@ int main() std::cin.ignore(); } - // Don't unregister PushTrigger because we still want to receive push notifications from background infrastructure. - PushNotificationManager::UnregisterActivator(PushNotificationRegistrationActivators::ComActivator); + if (PushNotificationManager::IsActivatorSupported(PushNotificationRegistrationActivators::ComActivator)) + { + // Don't unregister PushTrigger because we still want to receive push notifications from background infrastructure. + PushNotificationManager::UnregisterActivator(PushNotificationRegistrationActivators::ComActivator); + } + + if (!Test::AppModel::IsPackagedProcess()) + { + MddBootstrapShutdown(); + } return 0; } diff --git a/test/TestApps/PushNotificationsDemoApp/packages.config b/test/TestApps/PushNotificationsDemoApp/packages.config index fc20b89bf7..6a9200b4c2 100644 --- a/test/TestApps/PushNotificationsDemoApp/packages.config +++ b/test/TestApps/PushNotificationsDemoApp/packages.config @@ -1,5 +1,6 @@  + \ No newline at end of file diff --git a/test/TestApps/PushNotificationsTestApp/PushNotificationsTestApp.vcxproj b/test/TestApps/PushNotificationsTestApp/PushNotificationsTestApp.vcxproj index bf5aabc79b..4b2ebc71ae 100644 --- a/test/TestApps/PushNotificationsTestApp/PushNotificationsTestApp.vcxproj +++ b/test/TestApps/PushNotificationsTestApp/PushNotificationsTestApp.vcxproj @@ -280,4 +280,4 @@ - + \ No newline at end of file diff --git a/test/TestApps/PushNotificationsTestApp/packages.config b/test/TestApps/PushNotificationsTestApp/packages.config index fc20b89bf7..6a9200b4c2 100644 --- a/test/TestApps/PushNotificationsTestApp/packages.config +++ b/test/TestApps/PushNotificationsTestApp/packages.config @@ -1,5 +1,6 @@  + \ No newline at end of file From da6fe4d4c429b9ef8875c4e899b4ab9a558ce5bd Mon Sep 17 00:00:00 2001 From: eric langlois Date: Wed, 13 Oct 2021 06:02:25 -0700 Subject: [PATCH 50/50] Updating LRP to use latest FrameworkUDK (#1587) Co-authored-by: Eric Langlois --- .../PushNotificationsLongRunningTask.vcxproj | 8 ++------ .../PushNotificationsLongRunningTask/packages.config | 8 +++----- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj index e41907b36c..6ccf99c489 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/PushNotificationsLongRunningTask.vcxproj @@ -258,9 +258,7 @@ - - - + @@ -275,8 +273,6 @@ - - - + \ No newline at end of file diff --git a/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config b/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config index 143c38ff8d..7bcf3cf398 100644 --- a/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config +++ b/dev/PushNotifications/PushNotificationsLongRunningTask/packages.config @@ -1,11 +1,9 @@  - - - - - + + + \ No newline at end of file