From adbc273bcf505a2e520ac639adf19293c76fd652 Mon Sep 17 00:00:00 2001
From: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com>
Date: Fri, 4 Aug 2023 09:59:33 +0200
Subject: [PATCH] =?UTF-8?q?[installer]=20Auto-start=20PowerToys=20as=20log?=
=?UTF-8?q?ged-in=20user=20from=20installer=20run=E2=80=A6=20(#27793)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* [installer] Auto-start PowerToys as logged-in user from installer running as SYSTEM
* spellcheck
* Address feedback
* spellcheck
---
.github/actions/spell-check/expect.txt | 186 +-----------------
installer/PowerToysSetup/Product.wxs | 16 +-
.../CustomAction.cpp | 160 ++++++++++++++-
.../CustomAction.def | 1 +
.../PowerToysSetupCustomActions.vcxproj | 2 +-
5 files changed, 176 insertions(+), 189 deletions(-)
diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt
index a40869a56b..204e9b162d 100644
--- a/.github/actions/spell-check/expect.txt
+++ b/.github/actions/spell-check/expect.txt
@@ -1,28 +1,15 @@
aaaa
-AAAAEF
-AAB
-AABAD
-AACB
-AACD
-AAD
-AADF
-abap
abcdefghjkmnpqrstuvxyz
-ABE
abgr
abi
ABlocked
ABOUTBOX
Abug
-ACA
accctrl
Acceleratorkeys
ACCEPTFILES
ACCESSDENIED
accessibilityinsights
-ACDB
-ACFC
-ACFF
Acl
aclapi
AClient
@@ -40,18 +27,7 @@ adml
admx
advapi
advfirewall
-AEAA
-AEAD
-AECC
-AED
-AEE
-AEEB
-AFAE
-AFAEFC
-AFDA
-AFE
AFeature
-AFFE
AFFINETRANSFORM
AFX
AGGREGATABLE
@@ -77,7 +53,6 @@ ansicolor
ANull
AOC
aocfnapldcnfbofgmbbllojgocaelgdd
-AOT
APARTMENTTHREADED
APeriod
apidl
@@ -143,36 +118,13 @@ AValid
awakeness
AWAYMODE
AYUV
-azcli
azman
-azor
backtracer
-BAF
bak
-BBE
bbwe
-BCA
-BCB
-BCCE
-BCCEA
bck
-BDB
-BDBAD
-BDCC
-BDDF
-BDFB
-BEAA
-BEB
-BEEAADF
-BEEC
-BEFA
betadele
betsegaw
-BFC
-BFDE
-BFEB
-BFF
-BFFA
BGR
bgra
bhid
@@ -227,48 +179,28 @@ BValue
byapp
BYPOSITION
bytearray
-CABD
CALG
callbackptr
calpwstr
-cameligo
Cangjie
CANRENAME
CAPTUREBLT
CAPTURECHANGED
CAtl
-CBA
-CBB
-CBF
-CCCCDE
cch
CCHDEVICENAME
CCHFORMNAME
CCom
CContext
-CDAC
-CDBF
-CDCE
-CDD
-CDE
cdecl
CDeclaration
CDEF
cdpx
-CEAF
-CEBAC
-CEBD
-CECB
CElems
CENTERALIGN
ceq
certlm
certmgr
-CFAADB
-CFBBF
-CFEE
-CFFEE
-CFFF
cguid
CHANGECBCHAIN
changecursor
@@ -346,7 +278,6 @@ comsupp
comsuppw
comsuppwd
comutil
-concrt
CONFIGW
CONFLICTINGMODIFIERKEY
CONFLICTINGMODIFIERSHORTCUT
@@ -414,10 +345,8 @@ CYSCREEN
CYSMICON
CYVIRTUALSCREEN
cziplib
-DAA
Dac
dacl
-DAF
damienleroy
DARKPURPLE
DARKTEAL
@@ -429,30 +358,18 @@ dataversion
DATAW
davidegiacometti
Dayof
-DBAE
-DBB
-DBBDA
-DBDE
Dbg
Dbghelp
DBLCLKS
DBLEPSILON
-DCAB
DCapture
DCBA
-DCBC
-DCCB
-DCEFCB
-DCF
DCOM
dcommon
dcomp
-dcompi
DComposition
dcr
dcs
-DDCDD
-DDCE
DDEIf
DDevice
ddf
@@ -463,7 +380,6 @@ debugbreak
DECLAR
declspec
decryptor
-DED
Dedup
DEFAULTBOOTSTRAPPERINSTALLFOLDER
DEFAULTCOLOR
@@ -485,7 +401,6 @@ DENORMAL
Deondre
depersist
deprioritized
-depsfileslistspath
deref
DESKTOPABSOLUTEEDITING
DESKTOPABSOLUTEPARSING
@@ -500,9 +415,6 @@ DEVMODEW
DEVMON
devpkey
DEVSOURCE
-DFAB
-DFB
-DFBEA
DIIRFLAG
dimm
directshow
@@ -549,13 +461,11 @@ dvr
DVSD
DVSL
DVTARGETDEVICE
-DWINRT
dwl
dwm
dwmapi
DWMCOLORIZATIONCOLORCHANGED
DWMCOMPOSITIONCHANGED
-dwmcorei
DWMNCRENDERINGCHANGED
Dwmp
DWMSENDICONICLIVEPREVIEWBITMAP
@@ -571,41 +481,13 @@ dxgi
dxgidebug
dxgiformat
dxguid
-EAAFE
-EABF
-EAC
-EADC
-EAF
-EBCF
-EBD
-EBE
-ecl
ecount
EData
-EDB
-EDCCC
-EDFAE
Edid
-edis
EDITKEYBOARD
editkeyboardwindow
EDITSHORTCUTS
editshortcutswindow
-edshift
-EEA
-EEB
-EEBBE
-EEBD
-EED
-EEDA
-EEEE
-EEF
-EEFA
-EFB
-EFC
-EFDD
-EFE
-EFFEFC
EFile
eip
ekus
@@ -634,7 +516,6 @@ ERRORTITLE
ESettings
esize
esrp
-estructuredtext
etl
etstat
etw
@@ -672,45 +553,14 @@ EXTENDEDKEY
EXTENDEDVERBS
EXTRINSICPROPERTIES
eyetracker
-FABC
-FAEDDA
-FAF
-FAFD
fancymouse
fancyzone
FANCYZONESDRAWLAYOUTTEST
FANCYZONESEDITOR
Farbraum
FARPROC
-FBB
-FBC
-FBDE
-FBF
-FCAE
-FCB
-FCCFF
-FCD
-FCDB
-FCDD
-FCE
-FDB
-FDBF
-FDC
-FDCD
-FDE
-FDEF
-FDF
fdw
-FECF
-FEDF
-FEEF
feimage
-FFB
-FFBCF
-FFBE
-FFDDD
-FFEB
-FFEBEF
fff
fileapi
FILEEXPLORER
@@ -787,14 +637,12 @@ GPOCA
gpp
GPT
gpu
-graphql
GSM
gtm
gui
guiddata
guiddef
guidgenerator
-GUIDv
GUITHREADINFO
GValue
gwl
@@ -1022,7 +870,6 @@ JPN
jpnime
Jsons
jsonval
-julia
junja
jxr
jyuwono
@@ -1047,11 +894,9 @@ keynum
keyremaps
Keytool
keyup
-Kfiles
KILLFOCUS
killrunner
Knownfolders
-kotlin
KSPROPERTY
Kybd
LAlt
@@ -1083,7 +928,6 @@ LError
Lessthan
LEVELID
LExit
-lexon
lhs
lhwnd
LIBID
@@ -1283,7 +1127,6 @@ msc
msclr
mscorlib
msdata
-msdax
msedge
MSGFLT
MSIFASTINSTALL
@@ -1300,7 +1143,6 @@ msrc
msstore
mst
msvc
-msvcp
MTND
Mul
MULTIPLEUSE
@@ -1310,7 +1152,6 @@ mwb
MWBEx
myfile
MYICON
-mysql
NAMECHANGE
nameof
namespaceanddescendants
@@ -1360,7 +1201,6 @@ NIF
nint
NLD
NLog
-nls
NLSTEXT
NNN
NOACTIVATE
@@ -1490,7 +1330,6 @@ PARENTRELATIVEPARSING
PArgb
parray
PARTIALCONFIRMATIONDIALOGTITLE
-pascaligo
pasteplain
PATCOPY
pathcch
@@ -1532,7 +1371,6 @@ pfn
pfo
pft
pgp
-pgsql
pguid
PHANDLE
phbm
@@ -1560,12 +1398,10 @@ Pnp
Popups
POPUPWINDOW
posix
-postiats
poweraccent
powerlauncher
POWEROCR
powerpreview
-powerquery
powerrename
POWERRENAMECONTEXTMENU
powerrenameinput
@@ -1607,9 +1443,9 @@ printmanagement
prm
proactively
PROCESSKEY
+processthreadsapi
PRODEXT
PRODUCTVERSION
-productwxspath
Progman
programdata
PROGRAMFILES
@@ -1686,7 +1522,6 @@ RECTL
rectp
rects
redirectedfrom
-redis
Redist
redistributable
reencode
@@ -1719,7 +1554,6 @@ REMAPSUCCESSFUL
REMAPUNSUCCESSFUL
Remotable
remoteip
-Removedir
Removelnk
renamable
RENAMEONCOLLISION
@@ -1786,7 +1620,6 @@ rungameid
RUNLEVEL
runsettings
runtimeclass
-runtimedepsjsonpath
runtimeobject
runtimepack
runtimes
@@ -1894,6 +1727,7 @@ SHOWNOACTIVATE
SHOWNORMAL
SHOWWINDOW
shtypes
+sia
SIATTRIBFLAGS
SICHINT
sid
@@ -2028,7 +1862,6 @@ SYSMENU
SYSTEMAPPS
systemroot
SYSTEMTIME
-systemverilog
sysvol
Tadele
talynone
@@ -2048,7 +1881,6 @@ taskkill
tasklist
taskschd
tchar
-tcl
Tcollab
tcp
tcs
@@ -2071,7 +1903,6 @@ textblock
TEXTEXTRACTOR
TEXTINCLUDE
tgz
-themeresources
THH
THICKFRAME
THISCOMPONENT
@@ -2122,9 +1953,7 @@ TYPESHORTCUT
UAC
UAL
uap
-uby
udit
-Udk
Udp
uefi
UHash
@@ -2169,6 +1998,7 @@ USEDEFAULT
USEFILEATTRIBUTES
USERDATA
USERDOMAIN
+Userenv
userprofile
USESHOWWINDOW
USESTDHANDLES
@@ -2186,16 +2016,12 @@ valuegenerator
Vanara
variantassignment
vcamp
-vccorlib
vcdl
vcgtq
VCINSTALLDIR
vcm
-vcomp
Vcpkg
-vcproj
VCRT
-vcruntime
vcvars
VDesktop
vdi
@@ -2308,7 +2134,7 @@ WINL
winlogon
winmd
winmm
-WINNT
+winnt
winres
winrt
winsdk
@@ -2353,7 +2179,6 @@ workspaces
wox
wparam
wpf
-wpfdepsjsonpath
wpftmp
wpr
wprp
@@ -2380,7 +2205,6 @@ WTS
wtsapi
WTSAT
Wubi
-wuceffectsi
WVC
Wwan
Wwanpp
@@ -2392,7 +2216,6 @@ XBUTTON
XBUTTONDBLCLK
XBUTTONDOWN
XBUTTONUP
-xcopy
XDocument
XDOWN
XElement
@@ -2417,7 +2240,6 @@ yinwang
yinyue
YOffset
YPels
-ypescript
YResolution
YStr
YUY
diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs
index 0263b243c4..34fb32bd4b 100644
--- a/installer/PowerToysSetup/Product.wxs
+++ b/installer/PowerToysSetup/Product.wxs
@@ -133,6 +133,7 @@
+
@@ -171,17 +172,22 @@
-->
- NOT Installed
+ NOT Installed
+
+
+ Execute="deferred"
+ BinaryKey="PTCustomActions"
+ DllEntry="LaunchPowerToysCA"
+ />
-
#include
#include "../../src/common/logger/logger.h"
@@ -16,6 +15,11 @@
#include
#include
+#include
+#include
+#include
+#include
+
using namespace std;
HINSTANCE DLL_HANDLE = nullptr;
@@ -50,6 +54,160 @@ LExit:
return hr;
}
+BOOL IsLocalSystem()
+{
+ HANDLE hToken;
+ UCHAR bTokenUser[sizeof(TOKEN_USER) + 8 + 4 * SID_MAX_SUB_AUTHORITIES];
+ PTOKEN_USER pTokenUser = (PTOKEN_USER)bTokenUser;
+ ULONG cbTokenUser;
+ SID_IDENTIFIER_AUTHORITY siaNT = SECURITY_NT_AUTHORITY;
+ PSID pSystemSid;
+ BOOL bSystem;
+
+ // open process token
+ if (!OpenProcessToken(GetCurrentProcess(),
+ TOKEN_QUERY,
+ &hToken))
+ return FALSE;
+
+ // retrieve user SID
+ if (!GetTokenInformation(hToken, TokenUser, pTokenUser,
+ sizeof(bTokenUser), &cbTokenUser))
+ {
+ CloseHandle(hToken);
+ return FALSE;
+ }
+
+ CloseHandle(hToken);
+
+ // allocate LocalSystem well-known SID
+ if (!AllocateAndInitializeSid(&siaNT, 1, SECURITY_LOCAL_SYSTEM_RID,
+ 0, 0, 0, 0, 0, 0, 0, &pSystemSid))
+ return FALSE;
+
+ // compare the user SID from the token with the LocalSystem SID
+ bSystem = EqualSid(pTokenUser->User.Sid, pSystemSid);
+
+ FreeSid(pSystemSid);
+
+ return bSystem;
+}
+
+UINT __stdcall LaunchPowerToysCA(MSIHANDLE hInstall)
+{
+ HRESULT hr = S_OK;
+ UINT er = ERROR_SUCCESS;
+ std::wstring installationFolder, path, args;
+ std::wstring commandLine;
+
+ hr = WcaInitialize(hInstall, "LaunchPowerToys");
+ ExitOnFailure(hr, "Failed to initialize");
+ hr = getInstallFolder(hInstall, installationFolder);
+ ExitOnFailure(hr, "Failed to get installFolder.");
+
+ path = installationFolder;
+ path += L"\\PowerToys.exe";
+
+ args = L"--dont-elevate";
+
+ commandLine = L"\"" + path + L"\" ";
+ commandLine += args;
+
+ BOOL isSystemUser = IsLocalSystem();
+
+ if (isSystemUser) {
+
+ HANDLE hUserToken = NULL;
+ DWORD dwSessionId;
+ ProcessIdToSessionId(GetCurrentProcessId(), &dwSessionId);
+ auto rv = WTSQueryUserToken(dwSessionId, &hUserToken);
+
+ if (rv == 0)
+ {
+ ExitOnFailure(hr, "Failed to query user token");
+ }
+
+ HANDLE hUserTokenDup;
+ if (DuplicateTokenEx(hUserToken, TOKEN_ALL_ACCESS, NULL, SECURITY_IMPERSONATION_LEVEL::SecurityImpersonation, TOKEN_TYPE::TokenPrimary, &hUserTokenDup) == 0)
+ {
+ CloseHandle(hUserToken);
+ CloseHandle(hUserTokenDup);
+ ExitOnFailure(hr, "Failed to duplicate user token");
+ }
+
+ if (ImpersonateLoggedOnUser(hUserTokenDup))
+ {
+ STARTUPINFO startupInfo{ .cb = sizeof(STARTUPINFO), .wShowWindow = SW_SHOWNORMAL };
+ PROCESS_INFORMATION processInformation;
+
+ PVOID lpEnvironment = NULL;
+ CreateEnvironmentBlock(&lpEnvironment, hUserTokenDup, FALSE);
+
+ CreateProcessAsUser(
+ hUserTokenDup,
+ NULL,
+ commandLine.data(),
+ NULL,
+ NULL,
+ FALSE,
+ CREATE_DEFAULT_ERROR_MODE | CREATE_UNICODE_ENVIRONMENT,
+ lpEnvironment,
+ NULL,
+ &startupInfo,
+ &processInformation);
+
+ if (!CloseHandle(processInformation.hProcess))
+ {
+ er = ERROR_INSTALL_FAILURE;
+ }
+ if (!CloseHandle(processInformation.hThread))
+ {
+ er = ERROR_INSTALL_FAILURE;
+ }
+
+ RevertToSelf();
+ CloseHandle(hUserToken);
+ CloseHandle(hUserTokenDup);
+ }
+ else
+ {
+ ExitOnFailure(hr, "Failed to duplicate user token");
+ }
+ }
+ else
+ {
+ STARTUPINFO startupInfo{ .cb = sizeof(STARTUPINFO), .wShowWindow = SW_SHOWNORMAL };
+
+ PROCESS_INFORMATION processInformation;
+
+ // Start the resizer
+ CreateProcess(
+ NULL,
+ commandLine.data(),
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ NULL,
+ &startupInfo,
+ &processInformation);
+
+ if (!CloseHandle(processInformation.hProcess))
+ {
+ ExitOnFailure(hr, "Failed to close process handle");
+ }
+ if (!CloseHandle(processInformation.hThread))
+ {
+ ExitOnFailure(hr, "Failed to close thread handle");
+ }
+ }
+
+LExit:
+ er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
+ return WcaFinalize(er);
+}
+
UINT __stdcall CheckGPOCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
diff --git a/installer/PowerToysSetupCustomActions/CustomAction.def b/installer/PowerToysSetupCustomActions/CustomAction.def
index 65b7b1faf2..697ceaba84 100644
--- a/installer/PowerToysSetupCustomActions/CustomAction.def
+++ b/installer/PowerToysSetupCustomActions/CustomAction.def
@@ -1,6 +1,7 @@
LIBRARY "PowerToysSetupCustomActions"
EXPORTS
+ LaunchPowerToysCA
CheckGPOCA
ApplyModulesRegistryChangeSetsCA
CreateScheduledTaskCA
diff --git a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj
index ecdccaac57..706b93e8ac 100644
--- a/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj
+++ b/installer/PowerToysSetupCustomActions/PowerToysSetupCustomActions.vcxproj
@@ -88,7 +88,7 @@
ProgramDatabase
- WindowsApp.lib;Newdev.lib;Crypt32.lib;msi.lib;wcautil.lib;Psapi.lib;Pathcch.lib;comsupp.lib;taskschd.lib;Secur32.lib;msi.lib;dutil.lib;wcautil.lib;Version.lib;Shlwapi.lib;%(AdditionalDependencies)
+ Userenv.lib;Wtsapi32.lib;WindowsApp.lib;Newdev.lib;Crypt32.lib;msi.lib;wcautil.lib;Psapi.lib;Pathcch.lib;comsupp.lib;taskschd.lib;Secur32.lib;msi.lib;dutil.lib;wcautil.lib;Version.lib;Shlwapi.lib;%(AdditionalDependencies)
CustomAction.def