From f91f9b37d0e9fd2002e73af3d2c862431c925769 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Mon, 13 May 2019 10:42:08 +0200 Subject: [PATCH] windows: add basic WTS functions for windows/svc usage The svc package exposes svc.SessionChange, but it's impossible to do anything with them without these structures, and without being able to enumerate them prior to events, the events themselves aren't useful, so we add the enumeration functions as well. Change-Id: I14c932dfe97c6712fd4868c1b3a0e3a61a6a562c Reviewed-on: https://go-review.googlesource.com/c/sys/+/176623 Run-TryBot: Jason Donenfeld TryBot-Result: Gobot Gobot Reviewed-by: Alex Brainman --- windows/security_windows.go | 42 +++++++++++++++++++++++++++++++++++++ windows/zsyscall_windows.go | 33 +++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/windows/security_windows.go b/windows/security_windows.go index 2ba1a313..68e33caa 100644 --- a/windows/security_windows.go +++ b/windows/security_windows.go @@ -717,3 +717,45 @@ func (t Token) IsMember(sid *SID) (bool, error) { } return b != 0, nil } + +const ( + WTS_CONSOLE_CONNECT = 0x1 + WTS_CONSOLE_DISCONNECT = 0x2 + WTS_REMOTE_CONNECT = 0x3 + WTS_REMOTE_DISCONNECT = 0x4 + WTS_SESSION_LOGON = 0x5 + WTS_SESSION_LOGOFF = 0x6 + WTS_SESSION_LOCK = 0x7 + WTS_SESSION_UNLOCK = 0x8 + WTS_SESSION_REMOTE_CONTROL = 0x9 + WTS_SESSION_CREATE = 0xa + WTS_SESSION_TERMINATE = 0xb +) + +const ( + WTSActive = 0 + WTSConnected = 1 + WTSConnectQuery = 2 + WTSShadow = 3 + WTSDisconnected = 4 + WTSIdle = 5 + WTSListen = 6 + WTSReset = 7 + WTSDown = 8 + WTSInit = 9 +) + +type WTSSESSION_NOTIFICATION struct { + Size uint32 + SessionID uint32 +} + +type WTS_SESSION_INFO struct { + SessionID uint32 + WindowStationName *uint16 + State uint32 +} + +//sys WTSQueryUserToken(session uint32, token *Token) (err error) = wtsapi32.WTSQueryUserToken +//sys WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) = wtsapi32.WTSEnumerateSessionsW +//sys WTSFreeMemory(ptr uintptr) = wtsapi32.WTSFreeMemory diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go index 02f27995..99cbf3e9 100644 --- a/windows/zsyscall_windows.go +++ b/windows/zsyscall_windows.go @@ -46,6 +46,7 @@ var ( modsecur32 = NewLazySystemDLL("secur32.dll") modnetapi32 = NewLazySystemDLL("netapi32.dll") moduserenv = NewLazySystemDLL("userenv.dll") + modwtsapi32 = NewLazySystemDLL("wtsapi32.dll") procRegisterEventSourceW = modadvapi32.NewProc("RegisterEventSourceW") procDeregisterEventSource = modadvapi32.NewProc("DeregisterEventSource") @@ -269,6 +270,9 @@ var ( procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW") procGetSystemDirectoryW = modkernel32.NewProc("GetSystemDirectoryW") + procWTSQueryUserToken = modwtsapi32.NewProc("WTSQueryUserToken") + procWTSEnumerateSessionsW = modwtsapi32.NewProc("WTSEnumerateSessionsW") + procWTSFreeMemory = modwtsapi32.NewProc("WTSFreeMemory") ) func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) { @@ -2943,3 +2947,32 @@ func getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) { } return } + +func WTSQueryUserToken(session uint32, token *Token) (err error) { + r1, _, e1 := syscall.Syscall(procWTSQueryUserToken.Addr(), 2, uintptr(session), uintptr(unsafe.Pointer(token)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WTSEnumerateSessions(handle Handle, reserved uint32, version uint32, sessions **WTS_SESSION_INFO, count *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procWTSEnumerateSessionsW.Addr(), 5, uintptr(handle), uintptr(reserved), uintptr(version), uintptr(unsafe.Pointer(sessions)), uintptr(unsafe.Pointer(count)), 0) + if r1 == 0 { + if e1 != 0 { + err = errnoErr(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func WTSFreeMemory(ptr uintptr) { + syscall.Syscall(procWTSFreeMemory.Addr(), 1, uintptr(ptr), 0, 0) + return +}