Use Windows serial comm functions from golang.org/x/sys/windows
This commit is contained in:
2
go.mod
2
go.mod
@@ -5,7 +5,7 @@ go 1.17
|
||||
require (
|
||||
github.com/creack/goselect v0.1.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
golang.org/x/sys v0.17.0
|
||||
golang.org/x/sys v0.19.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
4
go.sum
4
go.sum
@@ -12,8 +12,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -19,46 +19,29 @@ package serial
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
type windowsPort struct {
|
||||
mu sync.Mutex
|
||||
handle syscall.Handle
|
||||
handle windows.Handle
|
||||
}
|
||||
|
||||
func nativeGetPortsList() ([]string, error) {
|
||||
subKey, err := syscall.UTF16PtrFromString("HARDWARE\\DEVICEMAP\\SERIALCOMM\\")
|
||||
key, err := registry.OpenKey(windows.HKEY_LOCAL_MACHINE, `HARDWARE\DEVICEMAP\SERIALCOMM\`, windows.KEY_READ)
|
||||
if err != nil {
|
||||
return nil, &PortError{code: ErrorEnumeratingPorts}
|
||||
return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err}
|
||||
}
|
||||
defer key.Close()
|
||||
|
||||
list, err := key.ReadValueNames(0)
|
||||
if err != nil {
|
||||
return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err}
|
||||
}
|
||||
|
||||
var h syscall.Handle
|
||||
if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, subKey, 0, syscall.KEY_READ, &h); err != nil {
|
||||
if errno, isErrno := err.(syscall.Errno); isErrno && errno == syscall.ERROR_FILE_NOT_FOUND {
|
||||
return []string{}, nil
|
||||
}
|
||||
return nil, &PortError{code: ErrorEnumeratingPorts}
|
||||
}
|
||||
defer syscall.RegCloseKey(h)
|
||||
|
||||
var valuesCount uint32
|
||||
if syscall.RegQueryInfoKey(h, nil, nil, nil, nil, nil, nil, &valuesCount, nil, nil, nil, nil) != nil {
|
||||
return nil, &PortError{code: ErrorEnumeratingPorts}
|
||||
}
|
||||
|
||||
list := make([]string, valuesCount)
|
||||
for i := range list {
|
||||
var data [1024]uint16
|
||||
dataSize := uint32(len(data))
|
||||
var name [1024]uint16
|
||||
nameSize := uint32(len(name))
|
||||
if regEnumValue(h, uint32(i), &name[0], &nameSize, nil, nil, &data[0], &dataSize) != nil {
|
||||
return nil, &PortError{code: ErrorEnumeratingPorts}
|
||||
}
|
||||
list[i] = syscall.UTF16ToString(data[:])
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
@@ -71,7 +54,7 @@ func (port *windowsPort) Close() error {
|
||||
if port.handle == 0 {
|
||||
return nil
|
||||
}
|
||||
return syscall.CloseHandle(port.handle)
|
||||
return windows.CloseHandle(port.handle)
|
||||
}
|
||||
|
||||
func (port *windowsPort) Read(p []byte) (int, error) {
|
||||
@@ -80,16 +63,16 @@ func (port *windowsPort) Read(p []byte) (int, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer syscall.CloseHandle(ev.HEvent)
|
||||
defer windows.CloseHandle(ev.HEvent)
|
||||
|
||||
err = syscall.ReadFile(port.handle, p, &readed, ev)
|
||||
if err == syscall.ERROR_IO_PENDING {
|
||||
err = getOverlappedResult(port.handle, ev, &readed, true)
|
||||
err = windows.ReadFile(port.handle, p, &readed, ev)
|
||||
if err == windows.ERROR_IO_PENDING {
|
||||
err = windows.GetOverlappedResult(port.handle, ev, &readed, true)
|
||||
}
|
||||
switch err {
|
||||
case nil:
|
||||
// operation completed successfully
|
||||
case syscall.ERROR_OPERATION_ABORTED:
|
||||
case windows.ERROR_OPERATION_ABORTED:
|
||||
// port may have been closed
|
||||
return int(readed), &PortError{code: PortClosed, causedBy: err}
|
||||
default:
|
||||
@@ -110,32 +93,25 @@ func (port *windowsPort) Write(p []byte) (int, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer syscall.CloseHandle(ev.HEvent)
|
||||
err = syscall.WriteFile(port.handle, p, &writed, ev)
|
||||
if err == syscall.ERROR_IO_PENDING {
|
||||
defer windows.CloseHandle(ev.HEvent)
|
||||
err = windows.WriteFile(port.handle, p, &writed, ev)
|
||||
if err == windows.ERROR_IO_PENDING {
|
||||
// wait for write to complete
|
||||
err = getOverlappedResult(port.handle, ev, &writed, true)
|
||||
err = windows.GetOverlappedResult(port.handle, ev, &writed, true)
|
||||
}
|
||||
return int(writed), err
|
||||
}
|
||||
|
||||
func (port *windowsPort) Drain() (err error) {
|
||||
return syscall.FlushFileBuffers(port.handle)
|
||||
return windows.FlushFileBuffers(port.handle)
|
||||
}
|
||||
|
||||
const (
|
||||
purgeRxAbort uint32 = 0x0002
|
||||
purgeRxClear = 0x0008
|
||||
purgeTxAbort = 0x0001
|
||||
purgeTxClear = 0x0004
|
||||
)
|
||||
|
||||
func (port *windowsPort) ResetInputBuffer() error {
|
||||
return purgeComm(port.handle, purgeRxClear|purgeRxAbort)
|
||||
return windows.PurgeComm(port.handle, windows.PURGE_RXCLEAR|windows.PURGE_RXABORT)
|
||||
}
|
||||
|
||||
func (port *windowsPort) ResetOutputBuffer() error {
|
||||
return purgeComm(port.handle, purgeTxClear|purgeTxAbort)
|
||||
return windows.PurgeComm(port.handle, windows.PURGE_TXCLEAR|windows.PURGE_TXABORT)
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -159,112 +135,37 @@ const (
|
||||
dcbAbortOnError = 0x00004000
|
||||
)
|
||||
|
||||
type dcb struct {
|
||||
DCBlength uint32
|
||||
BaudRate uint32
|
||||
|
||||
// Flags field is a bitfield
|
||||
// fBinary :1
|
||||
// fParity :1
|
||||
// fOutxCtsFlow :1
|
||||
// fOutxDsrFlow :1
|
||||
// fDtrControl :2
|
||||
// fDsrSensitivity :1
|
||||
// fTXContinueOnXoff :1
|
||||
// fOutX :1
|
||||
// fInX :1
|
||||
// fErrorChar :1
|
||||
// fNull :1
|
||||
// fRtsControl :2
|
||||
// fAbortOnError :1
|
||||
// fDummy2 :17
|
||||
Flags uint32
|
||||
|
||||
wReserved uint16
|
||||
XonLim uint16
|
||||
XoffLim uint16
|
||||
ByteSize byte
|
||||
Parity byte
|
||||
StopBits byte
|
||||
XonChar byte
|
||||
XoffChar byte
|
||||
ErrorChar byte
|
||||
EOFChar byte
|
||||
EvtChar byte
|
||||
wReserved1 uint16
|
||||
}
|
||||
|
||||
type commTimeouts struct {
|
||||
ReadIntervalTimeout uint32
|
||||
ReadTotalTimeoutMultiplier uint32
|
||||
ReadTotalTimeoutConstant uint32
|
||||
WriteTotalTimeoutMultiplier uint32
|
||||
WriteTotalTimeoutConstant uint32
|
||||
}
|
||||
|
||||
const (
|
||||
noParity = 0
|
||||
oddParity = 1
|
||||
evenParity = 2
|
||||
markParity = 3
|
||||
spaceParity = 4
|
||||
)
|
||||
|
||||
var parityMap = map[Parity]byte{
|
||||
NoParity: noParity,
|
||||
OddParity: oddParity,
|
||||
EvenParity: evenParity,
|
||||
MarkParity: markParity,
|
||||
SpaceParity: spaceParity,
|
||||
NoParity: windows.NOPARITY,
|
||||
OddParity: windows.ODDPARITY,
|
||||
EvenParity: windows.EVENPARITY,
|
||||
MarkParity: windows.MARKPARITY,
|
||||
SpaceParity: windows.SPACEPARITY,
|
||||
}
|
||||
|
||||
const (
|
||||
oneStopBit = 0
|
||||
one5StopBits = 1
|
||||
twoStopBits = 2
|
||||
)
|
||||
|
||||
var stopBitsMap = map[StopBits]byte{
|
||||
OneStopBit: oneStopBit,
|
||||
OnePointFiveStopBits: one5StopBits,
|
||||
TwoStopBits: twoStopBits,
|
||||
OneStopBit: windows.ONESTOPBIT,
|
||||
OnePointFiveStopBits: windows.ONE5STOPBITS,
|
||||
TwoStopBits: windows.TWOSTOPBITS,
|
||||
}
|
||||
|
||||
const (
|
||||
commFunctionSetXOFF = 1
|
||||
commFunctionSetXON = 2
|
||||
commFunctionSetRTS = 3
|
||||
commFunctionClrRTS = 4
|
||||
commFunctionSetDTR = 5
|
||||
commFunctionClrDTR = 6
|
||||
commFunctionSetBreak = 8
|
||||
commFunctionClrBreak = 9
|
||||
)
|
||||
|
||||
const (
|
||||
msCTSOn = 0x0010
|
||||
msDSROn = 0x0020
|
||||
msRingOn = 0x0040
|
||||
msRLSDOn = 0x0080
|
||||
)
|
||||
|
||||
func (port *windowsPort) SetMode(mode *Mode) error {
|
||||
params := dcb{}
|
||||
if getCommState(port.handle, ¶ms) != nil {
|
||||
params := windows.DCB{}
|
||||
if windows.GetCommState(port.handle, ¶ms) != nil {
|
||||
port.Close()
|
||||
return &PortError{code: InvalidSerialPort}
|
||||
}
|
||||
port.setModeParams(mode, ¶ms)
|
||||
if setCommState(port.handle, ¶ms) != nil {
|
||||
if windows.SetCommState(port.handle, ¶ms) != nil {
|
||||
port.Close()
|
||||
return &PortError{code: InvalidSerialPort}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (port *windowsPort) setModeParams(mode *Mode, params *dcb) {
|
||||
func (port *windowsPort) setModeParams(mode *Mode, params *windows.DCB) {
|
||||
if mode.BaudRate == 0 {
|
||||
params.BaudRate = 9600 // Default to 9600
|
||||
params.BaudRate = windows.CBR_9600 // Default to 9600
|
||||
} else {
|
||||
params.BaudRate = uint32(mode.BaudRate)
|
||||
}
|
||||
@@ -278,22 +179,22 @@ func (port *windowsPort) setModeParams(mode *Mode, params *dcb) {
|
||||
}
|
||||
|
||||
func (port *windowsPort) SetDTR(dtr bool) error {
|
||||
// Like for RTS there are problems with the escapeCommFunction
|
||||
// Like for RTS there are problems with the windows.EscapeCommFunction
|
||||
// observed behaviour was that DTR is set from false -> true
|
||||
// when setting RTS from true -> false
|
||||
// 1) Connect -> RTS = true (low) DTR = true (low) OKAY
|
||||
// 2) SetDTR(false) -> RTS = true (low) DTR = false (high) OKAY
|
||||
// 3) SetRTS(false) -> RTS = false (high) DTR = true (low) ERROR: DTR toggled
|
||||
// 2) SetDTR(false) -> RTS = true (low) DTR = false (heigh) OKAY
|
||||
// 3) SetRTS(false) -> RTS = false (heigh) DTR = true (low) ERROR: DTR toggled
|
||||
//
|
||||
// In addition this way the CommState Flags are not updated
|
||||
/*
|
||||
var res bool
|
||||
var err error
|
||||
if dtr {
|
||||
res = escapeCommFunction(port.handle, commFunctionSetDTR)
|
||||
err = windows.EscapeCommFunction(port.handle, windows.SETDTR)
|
||||
} else {
|
||||
res = escapeCommFunction(port.handle, commFunctionClrDTR)
|
||||
err = windows.EscapeCommFunction(port.handle, windows.CLTDTR)
|
||||
}
|
||||
if !res {
|
||||
if err != nil {
|
||||
return &PortError{}
|
||||
}
|
||||
return nil
|
||||
@@ -301,15 +202,15 @@ func (port *windowsPort) SetDTR(dtr bool) error {
|
||||
|
||||
// The following seems a more reliable way to do it
|
||||
|
||||
params := &dcb{}
|
||||
if err := getCommState(port.handle, params); err != nil {
|
||||
params := &windows.DCB{}
|
||||
if err := windows.GetCommState(port.handle, params); err != nil {
|
||||
return &PortError{causedBy: err}
|
||||
}
|
||||
params.Flags &= dcbDTRControlDisableMask
|
||||
if dtr {
|
||||
params.Flags |= dcbDTRControlEnable
|
||||
params.Flags |= windows.DTR_CONTROL_ENABLE
|
||||
}
|
||||
if err := setCommState(port.handle, params); err != nil {
|
||||
if err := windows.SetCommState(port.handle, params); err != nil {
|
||||
return &PortError{causedBy: err}
|
||||
}
|
||||
|
||||
@@ -325,13 +226,13 @@ func (port *windowsPort) SetRTS(rts bool) error {
|
||||
// In addition this way the CommState Flags are not updated
|
||||
|
||||
/*
|
||||
var res bool
|
||||
var err error
|
||||
if rts {
|
||||
res = escapeCommFunction(port.handle, commFunctionSetRTS)
|
||||
err = windows.EscapeCommFunction(port.handle, windows.SETRTS)
|
||||
} else {
|
||||
res = escapeCommFunction(port.handle, commFunctionClrRTS)
|
||||
err = windows.EscapeCommFunction(port.handle, windows.CLRRTS)
|
||||
}
|
||||
if !res {
|
||||
if err != nil {
|
||||
return &PortError{}
|
||||
}
|
||||
return nil
|
||||
@@ -339,15 +240,15 @@ func (port *windowsPort) SetRTS(rts bool) error {
|
||||
|
||||
// The following seems a more reliable way to do it
|
||||
|
||||
params := &dcb{}
|
||||
if err := getCommState(port.handle, params); err != nil {
|
||||
params := &windows.DCB{}
|
||||
if err := windows.GetCommState(port.handle, params); err != nil {
|
||||
return &PortError{causedBy: err}
|
||||
}
|
||||
params.Flags &= dcbRTSControlDisableMask
|
||||
if rts {
|
||||
params.Flags |= dcbRTSControlEnable
|
||||
params.Flags |= windows.RTS_CONTROL_ENABLE
|
||||
}
|
||||
if err := setCommState(port.handle, params); err != nil {
|
||||
if err := windows.SetCommState(port.handle, params); err != nil {
|
||||
return &PortError{causedBy: err}
|
||||
}
|
||||
return nil
|
||||
@@ -355,19 +256,19 @@ func (port *windowsPort) SetRTS(rts bool) error {
|
||||
|
||||
func (port *windowsPort) GetModemStatusBits() (*ModemStatusBits, error) {
|
||||
var bits uint32
|
||||
if !getCommModemStatus(port.handle, &bits) {
|
||||
if err := windows.GetCommModemStatus(port.handle, &bits); err != nil {
|
||||
return nil, &PortError{}
|
||||
}
|
||||
return &ModemStatusBits{
|
||||
CTS: (bits & msCTSOn) != 0,
|
||||
DCD: (bits & msRLSDOn) != 0,
|
||||
DSR: (bits & msDSROn) != 0,
|
||||
RI: (bits & msRingOn) != 0,
|
||||
CTS: (bits & windows.EV_CTS) != 0,
|
||||
DCD: (bits & windows.EV_RLSD) != 0,
|
||||
DSR: (bits & windows.EV_DSR) != 0,
|
||||
RI: (bits & windows.EV_RING) != 0,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (port *windowsPort) SetReadTimeout(timeout time.Duration) error {
|
||||
commTimeouts := &commTimeouts{
|
||||
commTimeouts := &windows.CommTimeouts{
|
||||
ReadIntervalTimeout: 0xFFFFFFFF,
|
||||
ReadTotalTimeoutMultiplier: 0xFFFFFFFF,
|
||||
ReadTotalTimeoutConstant: 0xFFFFFFFE,
|
||||
@@ -382,7 +283,7 @@ func (port *windowsPort) SetReadTimeout(timeout time.Duration) error {
|
||||
commTimeouts.ReadTotalTimeoutConstant = uint32(ms)
|
||||
}
|
||||
|
||||
if err := setCommTimeouts(port.handle, commTimeouts); err != nil {
|
||||
if err := windows.SetCommTimeouts(port.handle, commTimeouts); err != nil {
|
||||
return &PortError{code: InvalidTimeoutValue, causedBy: err}
|
||||
}
|
||||
|
||||
@@ -390,42 +291,42 @@ func (port *windowsPort) SetReadTimeout(timeout time.Duration) error {
|
||||
}
|
||||
|
||||
func (port *windowsPort) Break(d time.Duration) error {
|
||||
if err := setCommBreak(port.handle); err != nil {
|
||||
if err := windows.SetCommBreak(port.handle); err != nil {
|
||||
return &PortError{causedBy: err}
|
||||
}
|
||||
|
||||
time.Sleep(d)
|
||||
|
||||
if err := clearCommBreak(port.handle); err != nil {
|
||||
if err := windows.ClearCommBreak(port.handle); err != nil {
|
||||
return &PortError{causedBy: err}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createOverlappedEvent() (*syscall.Overlapped, error) {
|
||||
h, err := createEvent(nil, true, false, nil)
|
||||
return &syscall.Overlapped{HEvent: h}, err
|
||||
func createOverlappedEvent() (*windows.Overlapped, error) {
|
||||
h, err := windows.CreateEvent(nil, 1, 0, nil)
|
||||
return &windows.Overlapped{HEvent: h}, err
|
||||
}
|
||||
|
||||
func nativeOpen(portName string, mode *Mode) (*windowsPort, error) {
|
||||
portName = "\\\\.\\" + portName
|
||||
path, err := syscall.UTF16PtrFromString(portName)
|
||||
path, err := windows.UTF16PtrFromString(portName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
handle, err := syscall.CreateFile(
|
||||
handle, err := windows.CreateFile(
|
||||
path,
|
||||
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
|
||||
windows.GENERIC_READ|windows.GENERIC_WRITE,
|
||||
0, nil,
|
||||
syscall.OPEN_EXISTING,
|
||||
syscall.FILE_FLAG_OVERLAPPED,
|
||||
windows.OPEN_EXISTING,
|
||||
windows.FILE_FLAG_OVERLAPPED,
|
||||
0)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case syscall.ERROR_ACCESS_DENIED:
|
||||
case windows.ERROR_ACCESS_DENIED:
|
||||
return nil, &PortError{code: PortBusy}
|
||||
case syscall.ERROR_FILE_NOT_FOUND:
|
||||
case windows.ERROR_FILE_NOT_FOUND:
|
||||
return nil, &PortError{code: PortNotFound}
|
||||
}
|
||||
return nil, err
|
||||
@@ -436,8 +337,8 @@ func nativeOpen(portName string, mode *Mode) (*windowsPort, error) {
|
||||
}
|
||||
|
||||
// Set port parameters
|
||||
params := &dcb{}
|
||||
if getCommState(port.handle, params) != nil {
|
||||
params := &windows.DCB{}
|
||||
if windows.GetCommState(port.handle, params) != nil {
|
||||
port.Close()
|
||||
return nil, &PortError{code: InvalidSerialPort}
|
||||
}
|
||||
@@ -445,14 +346,14 @@ func nativeOpen(portName string, mode *Mode) (*windowsPort, error) {
|
||||
params.Flags &= dcbDTRControlDisableMask
|
||||
params.Flags &= dcbRTSControlDisableMask
|
||||
if mode.InitialStatusBits == nil {
|
||||
params.Flags |= dcbDTRControlEnable
|
||||
params.Flags |= dcbRTSControlEnable
|
||||
params.Flags |= windows.DTR_CONTROL_ENABLE
|
||||
params.Flags |= windows.RTS_CONTROL_ENABLE
|
||||
} else {
|
||||
if mode.InitialStatusBits.DTR {
|
||||
params.Flags |= dcbDTRControlEnable
|
||||
params.Flags |= windows.DTR_CONTROL_ENABLE
|
||||
}
|
||||
if mode.InitialStatusBits.RTS {
|
||||
params.Flags |= dcbRTSControlEnable
|
||||
params.Flags |= windows.RTS_CONTROL_ENABLE
|
||||
}
|
||||
}
|
||||
params.Flags &^= dcbOutXCTSFlow
|
||||
@@ -468,7 +369,7 @@ func nativeOpen(portName string, mode *Mode) (*windowsPort, error) {
|
||||
params.XoffLim = 512
|
||||
params.XonChar = 17 // DC1
|
||||
params.XoffChar = 19 // C3
|
||||
if setCommState(port.handle, params) != nil {
|
||||
if windows.SetCommState(port.handle, params) != nil {
|
||||
port.Close()
|
||||
return nil, &PortError{code: InvalidSerialPort}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
//
|
||||
// Copyright 2014-2024 Cristian Maglie. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
//
|
||||
|
||||
package serial
|
||||
|
||||
//sys regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, value *uint16, valueLen *uint32) (regerrno error) = advapi32.RegEnumValueW
|
||||
|
||||
//sys getCommState(handle syscall.Handle, dcb *dcb) (err error) = GetCommState
|
||||
|
||||
//sys setCommState(handle syscall.Handle, dcb *dcb) (err error) = SetCommState
|
||||
|
||||
//sys setCommTimeouts(handle syscall.Handle, timeouts *commTimeouts) (err error) = SetCommTimeouts
|
||||
|
||||
//sys escapeCommFunction(handle syscall.Handle, function uint32) (res bool) = EscapeCommFunction
|
||||
|
||||
//sys getCommModemStatus(handle syscall.Handle, bits *uint32) (res bool) = GetCommModemStatus
|
||||
|
||||
//sys createEvent(eventAttributes *uint32, manualReset bool, initialState bool, name *uint16) (handle syscall.Handle, err error) = CreateEventW
|
||||
|
||||
//sys resetEvent(handle syscall.Handle) (err error) = ResetEvent
|
||||
|
||||
//sys getOverlappedResult(handle syscall.Handle, overlapEvent *syscall.Overlapped, n *uint32, wait bool) (err error) = GetOverlappedResult
|
||||
|
||||
//sys purgeComm(handle syscall.Handle, flags uint32) (err error) = PurgeComm
|
||||
|
||||
//sys setCommBreak(handle syscall.Handle) (err error) = SetCommBreak
|
||||
|
||||
//sys clearCommBreak(handle syscall.Handle) (err error) = ClearCommBreak
|
||||
@@ -1,161 +0,0 @@
|
||||
// Code generated by 'go generate'; DO NOT EDIT.
|
||||
|
||||
package serial
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var _ unsafe.Pointer
|
||||
|
||||
// Do the interface allocations only once for common
|
||||
// Errno values.
|
||||
const (
|
||||
errnoERROR_IO_PENDING = 997
|
||||
)
|
||||
|
||||
var (
|
||||
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||
errERROR_EINVAL error = syscall.EINVAL
|
||||
)
|
||||
|
||||
// errnoErr returns common boxed Errno values, to prevent
|
||||
// allocations at runtime.
|
||||
func errnoErr(e syscall.Errno) error {
|
||||
switch e {
|
||||
case 0:
|
||||
return errERROR_EINVAL
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
var (
|
||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
|
||||
procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW")
|
||||
procClearCommBreak = modkernel32.NewProc("ClearCommBreak")
|
||||
procCreateEventW = modkernel32.NewProc("CreateEventW")
|
||||
procEscapeCommFunction = modkernel32.NewProc("EscapeCommFunction")
|
||||
procGetCommModemStatus = modkernel32.NewProc("GetCommModemStatus")
|
||||
procGetCommState = modkernel32.NewProc("GetCommState")
|
||||
procGetOverlappedResult = modkernel32.NewProc("GetOverlappedResult")
|
||||
procPurgeComm = modkernel32.NewProc("PurgeComm")
|
||||
procResetEvent = modkernel32.NewProc("ResetEvent")
|
||||
procSetCommBreak = modkernel32.NewProc("SetCommBreak")
|
||||
procSetCommState = modkernel32.NewProc("SetCommState")
|
||||
procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts")
|
||||
)
|
||||
|
||||
func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, value *uint16, valueLen *uint32) (regerrno error) {
|
||||
r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(valueLen)), 0)
|
||||
if r0 != 0 {
|
||||
regerrno = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func clearCommBreak(handle syscall.Handle) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procClearCommBreak.Addr(), 1, uintptr(handle), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createEvent(eventAttributes *uint32, manualReset bool, initialState bool, name *uint16) (handle syscall.Handle, err error) {
|
||||
var _p0 uint32
|
||||
if manualReset {
|
||||
_p0 = 1
|
||||
}
|
||||
var _p1 uint32
|
||||
if initialState {
|
||||
_p1 = 1
|
||||
}
|
||||
r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttributes)), uintptr(_p0), uintptr(_p1), uintptr(unsafe.Pointer(name)), 0, 0)
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func escapeCommFunction(handle syscall.Handle, function uint32) (res bool) {
|
||||
r0, _, _ := syscall.Syscall(procEscapeCommFunction.Addr(), 2, uintptr(handle), uintptr(function), 0)
|
||||
res = r0 != 0
|
||||
return
|
||||
}
|
||||
|
||||
func getCommModemStatus(handle syscall.Handle, bits *uint32) (res bool) {
|
||||
r0, _, _ := syscall.Syscall(procGetCommModemStatus.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(bits)), 0)
|
||||
res = r0 != 0
|
||||
return
|
||||
}
|
||||
|
||||
func getCommState(handle syscall.Handle, dcb *dcb) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procGetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(dcb)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getOverlappedResult(handle syscall.Handle, overlapEvent *syscall.Overlapped, n *uint32, wait bool) (err error) {
|
||||
var _p0 uint32
|
||||
if wait {
|
||||
_p0 = 1
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall6(procGetOverlappedResult.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(overlapEvent)), uintptr(unsafe.Pointer(n)), uintptr(_p0), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func purgeComm(handle syscall.Handle, flags uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procPurgeComm.Addr(), 2, uintptr(handle), uintptr(flags), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func resetEvent(handle syscall.Handle) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procResetEvent.Addr(), 1, uintptr(handle), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setCommBreak(handle syscall.Handle) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetCommBreak.Addr(), 1, uintptr(handle), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setCommState(handle syscall.Handle, dcb *dcb) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetCommState.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(dcb)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setCommTimeouts(handle syscall.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
|
||||
}
|
||||
Reference in New Issue
Block a user