mirror of
https://github.com/golang/sys.git
synced 2026-01-29 07:02:06 +03:00
windows: add console ConPTY API
Add Windows ConPTY API, specifically CreatePseudoConsole, ClosePseudoConsole, and ResizePseudoConsole.
See https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/
See https://learn.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session
Updates #62708
Change-Id: I433c4d9d8716dd75fa44291ab0cf6ef3c5f6a913
GitHub-Last-Rev: 21cda7e648
GitHub-Pull-Request: golang/sys#175
Reviewed-on: https://go-review.googlesource.com/c/sys/+/528915
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
Reviewed-by: Than McIntosh <thanm@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
committed by
Quim Muntal
parent
aa9470e40d
commit
71c9d8730f
@@ -297,12 +297,15 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
||||
//sys RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, event Handle, asynchronous bool) (regerrno error) = advapi32.RegNotifyChangeKeyValue
|
||||
//sys GetCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
|
||||
//sys ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) = kernel32.ProcessIdToSessionId
|
||||
//sys ClosePseudoConsole(console Handle) = kernel32.ClosePseudoConsole
|
||||
//sys createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pconsole *Handle) (hr error) = kernel32.CreatePseudoConsole
|
||||
//sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
|
||||
//sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode
|
||||
//sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo
|
||||
//sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition
|
||||
//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
|
||||
//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
|
||||
//sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole
|
||||
//sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
|
||||
//sys Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW
|
||||
//sys Module32Next(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32NextW
|
||||
@@ -1813,3 +1816,17 @@ type PSAPI_WORKING_SET_EX_INFORMATION struct {
|
||||
// A PSAPI_WORKING_SET_EX_BLOCK union that indicates the attributes of the page at VirtualAddress.
|
||||
VirtualAttributes PSAPI_WORKING_SET_EX_BLOCK
|
||||
}
|
||||
|
||||
// CreatePseudoConsole creates a windows pseudo console.
|
||||
func CreatePseudoConsole(size Coord, in Handle, out Handle, flags uint32, pconsole *Handle) error {
|
||||
// We need this wrapper to manually cast Coord to uint32. The autogenerated wrappers only
|
||||
// accept arguments that can be casted to uintptr, and Coord can't.
|
||||
return createPseudoConsole(*((*uint32)(unsafe.Pointer(&size))), in, out, flags, pconsole)
|
||||
}
|
||||
|
||||
// ResizePseudoConsole resizes the internal buffers of the pseudo console to the width and height specified in `size`.
|
||||
func ResizePseudoConsole(pconsole Handle, size Coord) error {
|
||||
// We need this wrapper to manually cast Coord to uint32. The autogenerated wrappers only
|
||||
// accept arguments that can be casted to uintptr, and Coord can't.
|
||||
return resizePseudoConsole(pconsole, *((*uint32)(unsafe.Pointer(&size))))
|
||||
}
|
||||
|
||||
@@ -247,6 +247,7 @@ const (
|
||||
PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = 0x00020007
|
||||
PROC_THREAD_ATTRIBUTE_UMS_THREAD = 0x00030006
|
||||
PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL = 0x0002000b
|
||||
PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x00020016
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -2139,6 +2140,12 @@ const (
|
||||
ENABLE_LVB_GRID_WORLDWIDE = 0x10
|
||||
)
|
||||
|
||||
// Pseudo console related constants used for the flags parameter to
|
||||
// CreatePseudoConsole. See: https://learn.microsoft.com/en-us/windows/console/createpseudoconsole
|
||||
const (
|
||||
PSEUDOCONSOLE_INHERIT_CURSOR = 0x1
|
||||
)
|
||||
|
||||
type Coord struct {
|
||||
X int16
|
||||
Y int16
|
||||
|
||||
@@ -188,6 +188,7 @@ var (
|
||||
procCancelIo = modkernel32.NewProc("CancelIo")
|
||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
||||
procCloseHandle = modkernel32.NewProc("CloseHandle")
|
||||
procClosePseudoConsole = modkernel32.NewProc("ClosePseudoConsole")
|
||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||
procCreateDirectoryW = modkernel32.NewProc("CreateDirectoryW")
|
||||
procCreateEventExW = modkernel32.NewProc("CreateEventExW")
|
||||
@@ -202,6 +203,7 @@ var (
|
||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
||||
procCreatePipe = modkernel32.NewProc("CreatePipe")
|
||||
procCreateProcessW = modkernel32.NewProc("CreateProcessW")
|
||||
procCreatePseudoConsole = modkernel32.NewProc("CreatePseudoConsole")
|
||||
procCreateSymbolicLinkW = modkernel32.NewProc("CreateSymbolicLinkW")
|
||||
procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot")
|
||||
procDefineDosDeviceW = modkernel32.NewProc("DefineDosDeviceW")
|
||||
@@ -328,6 +330,7 @@ var (
|
||||
procReleaseMutex = modkernel32.NewProc("ReleaseMutex")
|
||||
procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW")
|
||||
procResetEvent = modkernel32.NewProc("ResetEvent")
|
||||
procResizePseudoConsole = modkernel32.NewProc("ResizePseudoConsole")
|
||||
procResumeThread = modkernel32.NewProc("ResumeThread")
|
||||
procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts")
|
||||
procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition")
|
||||
@@ -1633,6 +1636,11 @@ func CloseHandle(handle Handle) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func ClosePseudoConsole(console Handle) {
|
||||
syscall.Syscall(procClosePseudoConsole.Addr(), 1, uintptr(console), 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(overlapped)), 0)
|
||||
if r1 == 0 {
|
||||
@@ -1762,6 +1770,14 @@ func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityA
|
||||
return
|
||||
}
|
||||
|
||||
func createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pconsole *Handle) (hr error) {
|
||||
r0, _, _ := syscall.Syscall6(procCreatePseudoConsole.Addr(), 5, uintptr(size), uintptr(in), uintptr(out), uintptr(flags), uintptr(unsafe.Pointer(pconsole)), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags))
|
||||
if r1&0xff == 0 {
|
||||
@@ -2862,6 +2878,14 @@ func ResetEvent(event Handle) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func resizePseudoConsole(pconsole Handle, size uint32) (hr error) {
|
||||
r0, _, _ := syscall.Syscall(procResizePseudoConsole.Addr(), 2, uintptr(pconsole), uintptr(size), 0)
|
||||
if r0 != 0 {
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ResumeThread(thread Handle) (ret uint32, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procResumeThread.Addr(), 1, uintptr(thread), 0, 0)
|
||||
ret = uint32(r0)
|
||||
|
||||
Reference in New Issue
Block a user