From 479acdf4ea4619172c0a5938370cfa54e52d3704 Mon Sep 17 00:00:00 2001 From: Tobias Kohlbau Date: Sat, 6 Feb 2021 08:58:28 +0100 Subject: [PATCH] windows: add support for CommTimeouts CommTimeouts allows the user to set the timeout on Comm devices: docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setcommtimeouts docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getcommtimeouts Change-Id: I756dc93b1b01412a496c6eccab22c9ff7e5f4b83 Reviewed-on: https://go-review.googlesource.com/c/sys/+/290209 Reviewed-by: Jason A. Donenfeld Reviewed-by: Alex Brainman Trust: Jason A. Donenfeld Trust: Alex Brainman Run-TryBot: Jason A. Donenfeld TryBot-Result: Go Bot --- windows/syscall_windows.go | 2 ++ windows/types_windows.go | 8 ++++++++ windows/zsyscall_windows.go | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index ae380007..23238fad 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -344,6 +344,8 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetProcessPriorityBoost(process Handle, disable bool) (err error) = kernel32.SetProcessPriorityBoost //sys GetProcessWorkingSetSizeEx(hProcess Handle, lpMinimumWorkingSetSize *uintptr, lpMaximumWorkingSetSize *uintptr, flags *uint32) //sys SetProcessWorkingSetSizeEx(hProcess Handle, dwMinimumWorkingSetSize uintptr, dwMaximumWorkingSetSize uintptr, flags uint32) (err error) +//sys GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) +//sys SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) // Volume Management Functions //sys DefineDosDevice(flags uint32, deviceName *uint16, targetPath *uint16) (err error) = DefineDosDeviceW diff --git a/windows/types_windows.go b/windows/types_windows.go index f14bf05a..c2608898 100644 --- a/windows/types_windows.go +++ b/windows/types_windows.go @@ -2260,3 +2260,11 @@ const ( // REG_NOTIFY_THREAD_AGNOSTIC indicates that the lifetime of the registration must not be tied to the lifetime of the thread issuing the RegNotifyChangeKeyValue call. Note: This flag value is only supported in Windows 8 and later. REG_NOTIFY_THREAD_AGNOSTIC = 0x10000000 ) + +type CommTimeouts struct { + ReadIntervalTimeout uint32 + ReadTotalTimeoutMultiplier uint32 + ReadTotalTimeoutConstant uint32 + WriteTotalTimeoutMultiplier uint32 + WriteTotalTimeoutConstant uint32 +} diff --git a/windows/zsyscall_windows.go b/windows/zsyscall_windows.go index 8d6a4da0..aa768631 100644 --- a/windows/zsyscall_windows.go +++ b/windows/zsyscall_windows.go @@ -212,6 +212,7 @@ var ( procFreeLibrary = modkernel32.NewProc("FreeLibrary") procGenerateConsoleCtrlEvent = modkernel32.NewProc("GenerateConsoleCtrlEvent") procGetACP = modkernel32.NewProc("GetACP") + procGetCommTimeouts = modkernel32.NewProc("GetCommTimeouts") procGetCommandLineW = modkernel32.NewProc("GetCommandLineW") procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW") procGetComputerNameW = modkernel32.NewProc("GetComputerNameW") @@ -296,6 +297,7 @@ var ( procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW") procResetEvent = modkernel32.NewProc("ResetEvent") procResumeThread = modkernel32.NewProc("ResumeThread") + procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts") procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition") procSetConsoleMode = modkernel32.NewProc("SetConsoleMode") procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW") @@ -1787,6 +1789,14 @@ func GetACP() (acp uint32) { return } +func GetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { + r1, _, e1 := syscall.Syscall(procGetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func GetCommandLine() (cmd *uint16) { r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0) cmd = (*uint16)(unsafe.Pointer(r0)) @@ -2537,6 +2547,14 @@ func ResumeThread(thread Handle) (ret uint32, err error) { return } +func SetCommTimeouts(handle Handle, timeouts *CommTimeouts) (err error) { + r1, _, e1 := syscall.Syscall(procSetCommTimeouts.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(timeouts)), 0) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func setConsoleCursorPosition(console Handle, position uint32) (err error) { r1, _, e1 := syscall.Syscall(procSetConsoleCursorPosition.Addr(), 2, uintptr(console), uintptr(position), 0) if r1 == 0 {