Skip to content

Instantly share code, notes, and snippets.

@char101
Created May 18, 2023 07:57
Show Gist options
  • Save char101/2a56fdcdd9f755121b8c063021a0f37e to your computer and use it in GitHub Desktop.
Save char101/2a56fdcdd9f755121b8c063021a0f37e to your computer and use it in GitHub Desktop.
[AutoHotkey v2] RunWithShellToken
RunWithShellToken(cmd, args := '', workingDir := '') {
static token := 0
static startupInfo := 0
static processInfo := 0
if !startupInfo {
startupInfo := Buffer(7 * A_PtrSize + 9 * 4 + 2 * 2, 0)
NumPut('Int', startupInfo.Size, startupInfo) ; cb
NumPut('Int', 1, startupInfo, 4 + 3 * A_PtrSize + 4 * 7) ; dwFlags STARTF_USESHOWWINDOW
NumPut('UShort', 5, startupInfo, 4 + 3 * A_PtrSize + 5 * 7) ; wShowWindow SW_SHOW
}
if !processInfo {
processInfo := Buffer(2 * A_PtrSize + 2 * 4, 0)
}
if !token {
shellWindow := DllCall('user32.dll\GetShellWindow')
if !shellWindow
throw
DllCall('user32.dll\GetWindowThreadProcessId', 'Ptr', shellWindow, 'UInt*', &shellPid := 0)
if !shellPid
throw
shellProcess := DllCall('kernel32.dll\OpenProcess', 'UInt', 0x400, 'Int', 0, 'UInt', shellPid, 'Ptr')
if !shellProcess
throw
if !DllCall('advapi32.dll\OpenProcessToken', 'Ptr', shellProcess, 'Int', 2, 'Ptr*', &shellToken := 0) {
DllCall('kernel32.dll\CloseHandle', 'Ptr', shellProcess)
throw
}
; 0xF01FF = TOKEN_ALL_ACCESS
if !DllCall('advapi32\DuplicateTokenEx', 'Ptr', shellToken, 'Int', 0xF01FF, 'Ptr', 0, 'Int', 2, 'Int', 1, 'Ptr*', &token) {
DllCall('kernel32.dll\CloseHandle', 'Ptr', shellToken)
DllCall('kernel32.dll\CloseHandle', 'Ptr', shellProcess)
throw
}
DllCall('CloseHandle', 'Ptr', shellToken)
DllCall('CloseHandle', 'Ptr', shellProcess)
OnExit((*) => (DllCall('kernel32.dll\CloseHandle', 'Ptr', token), 0))
}
if !workingDir
workingDir := A_ScriptDir
cmd := '"' cmd '"'
if args
cmd := cmd ' ' args
env := DllCall('kernel32.dll\GetEnvironmentStrings')
if !DllCall('advapi32.dll\CreateProcessWithTokenW',
'Ptr', token, ; hToken
'Int', 0, ; dwLogonFlags
'Ptr', 0, ; lpApplicationName,
'WStr', cmd, ; lpCommandLine
'Int', 0, ; dwCreationFlags
'Ptr', env, ; lpEnvironment
'WStr', workingDir, ; lpCurrentDirectory
'Ptr', startupInfo, ; lpStartupInfo
'Ptr', processInfo ; lpProcessInformation
) {
DllCall('kernel32.dll\FreeEnvironmentStrings', 'Ptr', env)
throw DllCall('kernel32.dll\GetLastError')
}
DllCall('kernel32.dll\CloseHandle', 'Ptr', NumGet(processInfo, A_PtrSize, 'Ptr')) ; close hThread
DllCall('kernel32.dll\CloseHandle', 'Ptr', NumGet(processInfo, 0, 'Ptr')) ; close hProcess
DllCall('kernel32.dll\FreeEnvironmentStrings', 'Ptr', env)
return NumGet(processInfo, 2 * A_PtrSize, 'Int')
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment