diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..b172482 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,92 @@ +name: test + +on: + push: + pull_request: + +jobs: + create-test-artifacts: + runs-on: ubuntu-20.04 + + steps: + - name: checkout + uses: actions/checkout@v1 + with: + fetch-depth: 0 + + - name: Install Taskfile + uses: arduino/actions/setup-taskfile@master + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Build + run: | + PACKAGE_NAME_PREFIX="${{ github.workflow }}" + if [ "${{ github.event_name }}" = "pull_request" ]; then + PACKAGE_NAME_PREFIX="$PACKAGE_NAME_PREFIX-${{ github.event.number }}" + fi + PACKAGE_NAME_PREFIX="$PACKAGE_NAME_PREFIX-${{ github.sha }}-" + export PACKAGE_NAME_PREFIX + task dist:all + + # Uploads all architectures as separate artifacts + - name: Upload Linux 32 bit artifact + uses: actions/upload-artifact@v2 + with: + name: Linux_32bit + path: dist/*Linux_32bit.tar.gz + + - name: Upload Linux 64 bit artifact + uses: actions/upload-artifact@v2 + with: + name: Linux_64bit + path: dist/*Linux_64bit.tar.gz + + - name: Upload Windows 32 bit artifact + uses: actions/upload-artifact@v2 + with: + name: Windows_32bit + path: dist/*Windows_32bit.zip + + - name: Upload Windows 64 bit artifact + uses: actions/upload-artifact@v2 + with: + name: Windows_64bit + path: dist/*Windows_64bit.zip + + - name: Upload Linux ARMv6 artifact + uses: actions/upload-artifact@v2 + with: + name: Linux_ARMv6 + path: dist/*Linux_ARMv6.tar.gz + + - name: Upload Linux ARMv7 artifact + uses: actions/upload-artifact@v2 + with: + name: Linux_ARMv7 + path: dist/*Linux_ARMv7.tar.gz + + - name: Upload Linux ARM64 artifact + uses: actions/upload-artifact@v2 + with: + name: Linux_ARM64 + path: dist/*Linux_ARM64.tar.gz + + - name: Upload Linux ARM64 bit artifact + uses: actions/upload-artifact@v2 + with: + name: Linux_ARM64 + path: dist/*Linux_ARM64.tar.gz + + - name: Upload MacOS 64 bit artifact + uses: actions/upload-artifact@v2 + with: + name: macOS_64bit + path: dist/*macOS_64bit.tar.gz + + - name: Upload checksums + uses: actions/upload-artifact@v2 + with: + name: checksums + path: dist/*checksums.txt diff --git a/DistTasks.yml b/DistTasks.yml new file mode 100644 index 0000000..3534328 --- /dev/null +++ b/DistTasks.yml @@ -0,0 +1,211 @@ +version: "3" + +# This taskfile is ideally meant to be project agnostic and could be dropped in +# on other Go projects with minimal or no changes. +# +# To use it simply add the following lines to your main taskfile: +# includes: +# dist: ./DistTasks.yml +# +# The following variables must be declared in the including taskfile for the +# build process to work correctly: +# * DIST_DIR: the folder that will contain the final binaries and packages +# * PROJECT_NAME: the name of the project, used in package name +# * VERSION: the version of the project, used in package name and checksum file +# * LD_FLAGS: flags used at build time +# +# The project MUST contain a LICENSE.txt file in the root folder or packaging will fail. + +tasks: + all: + desc: Build for distribution for all platforms + cmds: + - task: Windows_32bit + - task: Windows_64bit + - task: Linux_32bit + - task: Linux_64bit + - task: Linux_ARMv6 + - task: Linux_ARMv7 + - task: Linux_ARM64 + - task: macOS_64bit + + Windows_32bit: + desc: Builds Windows 32 bit binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + zip {{ .PACKAGE_NAME}} {{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }}.exe ../LICENSE.txt -j + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_windows_386" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }}.exe {{ .LDFLAGS }}" + BUILD_PLATFORM: "windows/386" + CONTAINER_TAG: "{{ .GO_VERSION }}-main" + PACKAGE_PLATFORM: "Windows_32bit" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.zip" + + Windows_64bit: + desc: Builds Windows 64 bit binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + zip {{ .PACKAGE_NAME}} {{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }}.exe ../LICENSE.txt -j + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_windows_amd64" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }}.exe {{ .LDFLAGS }}" + BUILD_PLATFORM: "windows/amd64" + CONTAINER_TAG: "{{ .GO_VERSION }}-main" + PACKAGE_PLATFORM: "Windows_64bit" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.zip" + + Linux_32bit: + desc: Builds Linux 32 bit binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_linux_386" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "linux/386" + CONTAINER_TAG: "{{ .GO_VERSION }}-main" + PACKAGE_PLATFORM: "Linux_32bit" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + + Linux_64bit: + desc: Builds Linux 64 bit binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_linux_amd64" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "linux/amd64" + CONTAINER_TAG: "{{ .GO_VERSION }}-main" + PACKAGE_PLATFORM: "Linux_64bit" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + + Linux_ARMv7: + desc: Builds Linux ARMv7 binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_linux_arm_7" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "linux/armv7" + CONTAINER_TAG: "{{ .GO_VERSION }}-arm" + PACKAGE_PLATFORM: "Linux_ARMv7" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + + Linux_ARMv6: + desc: Builds Linux ARMv6 binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_linux_arm_6" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "linux/armv6" + CONTAINER_TAG: "{{ .GO_VERSION }}-arm" + PACKAGE_PLATFORM: "Linux_ARMv6" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + + Linux_ARM64: + desc: Builds Linux ARM64 binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_linux_arm_6" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "linux/arm64" + CONTAINER_TAG: "{{ .GO_VERSION }}-arm" + PACKAGE_PLATFORM: "Linux_ARM64" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + + macOS_64bit: + desc: Builds Mac OS X 64 bit binaries + dir: "{{ .DIST_DIR }}" + cmds: + - | + docker run -v `pwd`/..:/home/build -w /home/build \ + -e CGO_ENABLED=1 \ + {{ .CONTAINER }}:{{ .CONTAINER_TAG }} \ + --build-cmd "{{ .BUILD_COMMAND }}" \ + -p "{{ .BUILD_PLATFORM }}" + + tar cz -C {{ .PLATFORM_DIR }} {{ .PROJECT_NAME }} -C ../.. LICENSE.txt -f {{ .PACKAGE_NAME }} + sha256sum {{ .PACKAGE_NAME }} >> {{ .CHECKSUM_FILE }} + + vars: + PLATFORM_DIR: "{{ .PROJECT_NAME }}_osx_darwin_amd64" + BUILD_COMMAND: "go build -o {{ .DIST_DIR }}/{{ .PLATFORM_DIR }}/{{ .PROJECT_NAME }} {{ .LDFLAGS }}" + BUILD_PLATFORM: "darwin/amd64" + CONTAINER_TAG: "{{ .GO_VERSION }}-darwin" + PACKAGE_PLATFORM: "macOS_64bit" + PACKAGE_NAME: "{{ .PROJECT_NAME }}_{{ .VERSION }}_{{ .PACKAGE_PLATFORM }}.tar.gz" + +vars: + CONTAINER: "docker.elastic.co/beats-dev/golang-crossbuild" + GO_VERSION: "1.15.8" + CHECKSUM_FILE: "{{ .VERSION }}-checksums.txt" diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100755 index 0000000..01f3d99 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,24 @@ +version: "3" + +includes: + dist: ./DistTasks.yml + +tasks: + build: + desc: Build the project + cmds: + - go build -v {{.LDFLAGS}} + +vars: + PROJECT_NAME: "serial-discovery" + DIST_DIR: "dist" + VERSION: + sh: echo "$(git describe --tags --dirty --broken)" + TIMESTAMP: + sh: echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" + LDFLAGS: > + -ldflags + ' + -X github.com/arduino/serial-discovery/version.Tag={{.VERSION}} + -X github.com/arduino/serial-discovery/version.Timestamp={{.TIMESTAMP}} + ' diff --git a/args.go b/args.go new file mode 100644 index 0000000..bac2f68 --- /dev/null +++ b/args.go @@ -0,0 +1,41 @@ +// +// This file is part of serial-discovery. +// +// Copyright 2021 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to modify or +// otherwise use the software for commercial activities involving the Arduino +// software without disclosing the source code of your own applications. To purchase +// a commercial license, send an email to license@arduino.cc. +// + +package main + +import ( + "fmt" + "os" +) + +var args struct { + showVersion bool +} + +func parseArgs() { + for _, arg := range os.Args[1:] { + if arg == "" { + continue + } + if arg == "-v" || arg == "--version" { + args.showVersion = true + continue + } + fmt.Fprintf(os.Stderr, "invalid argument: %s\n", arg) + os.Exit(1) + } +} diff --git a/main.go b/main.go index 3ddee54..69041a3 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,7 @@ // // This file is part of serial-discovery. // -// Copyright 2018 ARDUINO SA (http://www.arduino.cc/) +// Copyright 2021 ARDUINO SA (http://www.arduino.cc/) // // This software is released under the GNU General Public License version 3, // which covers the main part of arduino-cli. @@ -26,10 +26,17 @@ import ( "sync" "github.com/arduino/go-properties-orderedmap" + "github.com/arduino/serial-discovery/version" "go.bug.st/serial/enumerator" ) func main() { + parseArgs() + if args.showVersion { + fmt.Printf("serial-discovery %s (build timestamp: %s)\n", version.Tag, version.Timestamp) + return + } + syncStarted := false var syncCloseChan chan<- bool diff --git a/sync_windows.go b/sync_windows.go index 37a278b..2a60a73 100644 --- a/sync_windows.go +++ b/sync_windows.go @@ -27,7 +27,7 @@ import ( "go.bug.st/serial/enumerator" ) -//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go sync_windows.go +//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go sync_windows.go //sys getModuleHandle(moduleName *byte) (handle syscall.Handle, err error) = GetModuleHandleA //sys registerClass(wndClass *wndClass) (atom uint16, err error) = user32.RegisterClassA diff --git a/version/version.go b/version/version.go new file mode 100644 index 0000000..b7c9f31 --- /dev/null +++ b/version/version.go @@ -0,0 +1,24 @@ +// +// This file is part of serial-discovery. +// +// Copyright 2021 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to modify or +// otherwise use the software for commercial activities involving the Arduino +// software without disclosing the source code of your own applications. To purchase +// a commercial license, send an email to license@arduino.cc. +// + +package version + +// Tag is the current git tag +var Tag = "snapshot" + +// Timestamp is the current timestamp +var Timestamp = "unknown" diff --git a/zsyscall_windows.go b/zsyscall_windows.go index 5c671e1..4256568 100644 --- a/zsyscall_windows.go +++ b/zsyscall_windows.go @@ -19,6 +19,7 @@ const ( var ( errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) + errERROR_EINVAL error = syscall.EINVAL ) // errnoErr returns common boxed Errno values, to prevent @@ -26,7 +27,7 @@ var ( func errnoErr(e syscall.Errno) error { switch e { case 0: - return nil + return errERROR_EINVAL case errnoERROR_IO_PENDING: return errERROR_IO_PENDING } @@ -41,37 +42,29 @@ var ( moduser32 = windows.NewLazySystemDLL("user32.dll") procGetModuleHandleA = modkernel32.NewProc("GetModuleHandleA") - procRegisterClassA = moduser32.NewProc("RegisterClassA") - procDefWindowProcW = moduser32.NewProc("DefWindowProcW") procCreateWindowExA = moduser32.NewProc("CreateWindowExA") - procRegisterDeviceNotificationA = moduser32.NewProc("RegisterDeviceNotificationA") + procDefWindowProcW = moduser32.NewProc("DefWindowProcW") + procDispatchMessageA = moduser32.NewProc("DispatchMessageA") procGetMessageA = moduser32.NewProc("GetMessageA") + procRegisterClassA = moduser32.NewProc("RegisterClassA") + procRegisterDeviceNotificationA = moduser32.NewProc("RegisterDeviceNotificationA") procTranslateMessage = moduser32.NewProc("TranslateMessage") - procDispatchMessageA = moduser32.NewProc("DispatchMessageA") ) func getModuleHandle(moduleName *byte) (handle syscall.Handle, err error) { r0, _, e1 := syscall.Syscall(procGetModuleHandleA.Addr(), 1, uintptr(unsafe.Pointer(moduleName)), 0, 0) handle = syscall.Handle(r0) if handle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func registerClass(wndClass *wndClass) (atom uint16, err error) { - r0, _, e1 := syscall.Syscall(procRegisterClassA.Addr(), 1, uintptr(unsafe.Pointer(wndClass)), 0, 0) - atom = uint16(r0) - if atom == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func createWindowEx(exstyle uint32, className *byte, windowText *byte, style uint32, x int32, y int32, width int32, height int32, parent syscall.Handle, menu syscall.Handle, hInstance syscall.Handle, lpParam uintptr) (hwnd syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall12(procCreateWindowExA.Addr(), 12, uintptr(exstyle), uintptr(unsafe.Pointer(className)), uintptr(unsafe.Pointer(windowText)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(parent), uintptr(menu), uintptr(hInstance), uintptr(lpParam)) + hwnd = syscall.Handle(r0) + if hwnd == 0 { + err = errnoErr(e1) } return } @@ -82,28 +75,11 @@ func defWindowProc(hwnd syscall.Handle, msg uint32, wParam uintptr, lParam uintp return } -func createWindowEx(exstyle uint32, className *byte, windowText *byte, style uint32, x int32, y int32, width int32, height int32, parent syscall.Handle, menu syscall.Handle, hInstance syscall.Handle, lpParam uintptr) (hwnd syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall12(procCreateWindowExA.Addr(), 12, uintptr(exstyle), uintptr(unsafe.Pointer(className)), uintptr(unsafe.Pointer(windowText)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(parent), uintptr(menu), uintptr(hInstance), uintptr(lpParam)) - hwnd = syscall.Handle(r0) - if hwnd == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func registerDeviceNotification(recipient syscall.Handle, filter *devBroadcastDeviceInterface, flags uint32) (devHandle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall(procRegisterDeviceNotificationA.Addr(), 3, uintptr(recipient), uintptr(unsafe.Pointer(filter)), uintptr(flags)) - devHandle = syscall.Handle(r0) - if devHandle == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func dispatchMessage(msg *msg) (res int32, err error) { + r0, _, e1 := syscall.Syscall(procDispatchMessageA.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0) + res = int32(r0) + if res == 0 { + err = errnoErr(e1) } return } @@ -112,30 +88,31 @@ func getMessage(msg *msg, hwnd syscall.Handle, msgFilterMin uint32, msgFilterMax r0, _, e1 := syscall.Syscall6(procGetMessageA.Addr(), 4, uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(msgFilterMin), uintptr(msgFilterMax), 0, 0) res = int32(r0) if res == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } + err = errnoErr(e1) } return } -func translateMessage(msg *msg) (res bool) { - r0, _, _ := syscall.Syscall(procTranslateMessage.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0) - res = r0 != 0 +func registerClass(wndClass *wndClass) (atom uint16, err error) { + r0, _, e1 := syscall.Syscall(procRegisterClassA.Addr(), 1, uintptr(unsafe.Pointer(wndClass)), 0, 0) + atom = uint16(r0) + if atom == 0 { + err = errnoErr(e1) + } return } -func dispatchMessage(msg *msg) (res int32, err error) { - r0, _, e1 := syscall.Syscall(procDispatchMessageA.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0) - res = int32(r0) - if res == 0 { - if e1 != 0 { - err = errnoErr(e1) - } else { - err = syscall.EINVAL - } +func registerDeviceNotification(recipient syscall.Handle, filter *devBroadcastDeviceInterface, flags uint32) (devHandle syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall(procRegisterDeviceNotificationA.Addr(), 3, uintptr(recipient), uintptr(unsafe.Pointer(filter)), uintptr(flags)) + devHandle = syscall.Handle(r0) + if devHandle == 0 { + err = errnoErr(e1) } return } + +func translateMessage(msg *msg) (res bool) { + r0, _, _ := syscall.Syscall(procTranslateMessage.Addr(), 1, uintptr(unsafe.Pointer(msg)), 0, 0) + res = r0 != 0 + return +}