From c8b1c23a56e6a7683f2544848c03ef328007a80b Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sat, 7 Jan 2017 23:38:51 +0100 Subject: [PATCH] Moved USB enumerations subroutines in their own package --- doc.go | 19 ++- enumerator/enumerator.go | 41 +++++++ .../example_getdetailedportlist_test.go | 8 +- enumerator/syscall_windows.go | 113 ++++++++++++++++++ usb_darwin.go => enumerator/usb_darwin.go | 4 +- usb_freebsd.go => enumerator/usb_freebsd.go | 6 +- usb_linux.go => enumerator/usb_linux.go | 12 +- .../usb_ole_windows.go | 4 +- usb_windows.go => enumerator/usb_windows.go | 12 +- .../usb_windows_test.go | 4 +- serial.go | 20 ---- serial_windows.go | 2 +- syscall_windows.go | 109 +---------------- 13 files changed, 202 insertions(+), 152 deletions(-) create mode 100644 enumerator/enumerator.go rename example_getdetailedportlist_test.go => enumerator/example_getdetailedportlist_test.go (74%) create mode 100644 enumerator/syscall_windows.go rename usb_darwin.go => enumerator/usb_darwin.go (98%) rename usb_freebsd.go => enumerator/usb_freebsd.go (53%) rename usb_linux.go => enumerator/usb_linux.go (89%) rename usb_ole_windows.go => enumerator/usb_ole_windows.go (97%) rename usb_windows.go => enumerator/usb_windows.go (96%) rename usb_windows_test.go => enumerator/usb_windows_test.go (92%) diff --git a/doc.go b/doc.go index 5d9bc6f..c9b9901 100644 --- a/doc.go +++ b/doc.go @@ -79,12 +79,14 @@ serial port: fmt.Printf("%v", string(buff[:n])) } -If a port is a virutal USB-CDC serial port (an USB-to-RS232 cable or a -microcontroller development board are typical examples) is possible to -retrieve the USB metadata, like VID/PID or USB Serial Number, with the -GetDetailedPortsList function: +If a port is a virtual USB-CDC serial port (for example an USB-to-RS232 +cable or a microcontroller development board) is possible to retrieve +the USB metadata, like VID/PID or USB Serial Number, with the +GetDetailedPortsList function in the enumerator package: - ports, err := serial.GetDetailedPortsList() + import "go.bug.st/serial.v1/enumerator" + + ports, err := enumerator.GetDetailedPortsList() if err != nil { log.Fatal(err) } @@ -100,5 +102,12 @@ GetDetailedPortsList function: } } +for details on USB port enumeration see the documentation of the specific package. + +This library tries to avoid the use of the "C" package (and consequently the need +of cgo) to simplify cross compiling. +Unfortunately the USB enumeration package for darwin (MacOSX) requires cgo +to access the IOKit framework. This means that if you need USB enumeration +on darwin you're forced to use cgo. */ package serial // import "go.bug.st/serial.v1" diff --git a/enumerator/enumerator.go b/enumerator/enumerator.go new file mode 100644 index 0000000..b72a72f --- /dev/null +++ b/enumerator/enumerator.go @@ -0,0 +1,41 @@ +// +// Copyright 2014-2017 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 enumerator // import "go.bug.st/serial.v1/enumerator" + +// PortDetails contains detailed information about USB serial port. +// Use GetDetailedPortsList function to retrieve it. +type PortDetails struct { + Name string + IsUSB bool + VID string + PID string + SerialNumber string + + // Manufacturer string + // Product string +} + +// GetDetailedPortsList retrieve ports details like USB VID/PID. +// Please note that this function may not be available on all OS: +// in that case a FunctionNotImplemented error is returned. +func GetDetailedPortsList() ([]*PortDetails, error) { + return nativeGetDetailedPortsList() +} + +// PortEnumerationError is the error type for serial ports enumeration +type PortEnumerationError struct { + causedBy error +} + +// Error returns the complete error code with details on the cause of the error +func (e PortEnumerationError) Error() string { + reason := "Error while enumerating serial ports" + if e.causedBy != nil { + reason += ": " + e.causedBy.Error() + } + return reason +} diff --git a/example_getdetailedportlist_test.go b/enumerator/example_getdetailedportlist_test.go similarity index 74% rename from example_getdetailedportlist_test.go rename to enumerator/example_getdetailedportlist_test.go index 1c7a491..18c7738 100644 --- a/example_getdetailedportlist_test.go +++ b/enumerator/example_getdetailedportlist_test.go @@ -1,17 +1,17 @@ // -// Copyright 2014-2016 Cristian Maglie. All rights reserved. +// Copyright 2014-2017 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_test +package enumerator_test import "fmt" import "log" -import "go.bug.st/serial.v1" +import "go.bug.st/serial.v1/enumerator" func ExampleGetDetailedPortsList() { - ports, err := serial.GetDetailedPortsList() + ports, err := enumerator.GetDetailedPortsList() if err != nil { log.Fatal(err) } diff --git a/enumerator/syscall_windows.go b/enumerator/syscall_windows.go new file mode 100644 index 0000000..cd598c7 --- /dev/null +++ b/enumerator/syscall_windows.go @@ -0,0 +1,113 @@ +// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT + +package enumerator + +import ( + "syscall" + "unsafe" + + "golang.org/x/sys/windows" +) + +var _ unsafe.Pointer + +var ( + modsetupapi = windows.NewLazySystemDLL("setupapi.dll") + + procSetupDiClassGuidsFromNameW = modsetupapi.NewProc("SetupDiClassGuidsFromNameW") + procSetupDiGetClassDevsW = modsetupapi.NewProc("SetupDiGetClassDevsW") + procSetupDiDestroyDeviceInfoList = modsetupapi.NewProc("SetupDiDestroyDeviceInfoList") + procSetupDiEnumDeviceInfo = modsetupapi.NewProc("SetupDiEnumDeviceInfo") + procSetupDiGetDeviceInstanceIdW = modsetupapi.NewProc("SetupDiGetDeviceInstanceIdW") + procSetupDiOpenDevRegKey = modsetupapi.NewProc("SetupDiOpenDevRegKey") + procSetupDiGetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiGetDeviceRegistryPropertyW") +) + +func setupDiClassGuidsFromNameInternal(class string, guid *guid, guidSize uint32, requiredSize *uint32) (err error) { + var _p0 *uint16 + _p0, err = syscall.UTF16PtrFromString(class) + if err != nil { + return + } + return _setupDiClassGuidsFromNameInternal(_p0, guid, guidSize, requiredSize) +} + +func _setupDiClassGuidsFromNameInternal(class *uint16, guid *guid, guidSize uint32, requiredSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procSetupDiClassGuidsFromNameW.Addr(), 4, uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(guid)), uintptr(guidSize), uintptr(unsafe.Pointer(requiredSize)), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func setupDiGetClassDevs(guid *guid, enumerator *string, hwndParent uintptr, flags uint32) (set devicesSet, err error) { + r0, _, e1 := syscall.Syscall6(procSetupDiGetClassDevsW.Addr(), 4, uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(enumerator)), uintptr(hwndParent), uintptr(flags), 0, 0) + set = devicesSet(r0) + if set == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func setupDiDestroyDeviceInfoList(set devicesSet) (err error) { + r1, _, e1 := syscall.Syscall(procSetupDiDestroyDeviceInfoList.Addr(), 1, uintptr(set), 0, 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func setupDiEnumDeviceInfo(set devicesSet, index uint32, info *devInfoData) (err error) { + r1, _, e1 := syscall.Syscall(procSetupDiEnumDeviceInfo.Addr(), 3, uintptr(set), uintptr(index), uintptr(unsafe.Pointer(info))) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func setupDiGetDeviceInstanceId(set devicesSet, devInfo *devInfoData, devInstanceId unsafe.Pointer, devInstanceIdSize uint32, requiredSize *uint32) (err error) { + r1, _, e1 := syscall.Syscall6(procSetupDiGetDeviceInstanceIdW.Addr(), 5, uintptr(set), uintptr(unsafe.Pointer(devInfo)), uintptr(devInstanceId), uintptr(devInstanceIdSize), uintptr(unsafe.Pointer(requiredSize)), 0) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func setupDiOpenDevRegKey(set devicesSet, devInfo *devInfoData, scope dicsScope, hwProfile uint32, keyType uint32, samDesired regsam) (hkey syscall.Handle, err error) { + r0, _, e1 := syscall.Syscall6(procSetupDiOpenDevRegKey.Addr(), 6, uintptr(set), uintptr(unsafe.Pointer(devInfo)), uintptr(scope), uintptr(hwProfile), uintptr(keyType), uintptr(samDesired)) + hkey = syscall.Handle(r0) + if hkey == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} + +func setupDiGetDeviceRegistryProperty(set devicesSet, devInfo *devInfoData, property deviceProperty, propertyType *uint32, outValue *byte, outSize *uint32, reqSize *uint32) (res bool) { + r0, _, _ := syscall.Syscall9(procSetupDiGetDeviceRegistryPropertyW.Addr(), 7, uintptr(set), uintptr(unsafe.Pointer(devInfo)), uintptr(property), uintptr(unsafe.Pointer(propertyType)), uintptr(unsafe.Pointer(outValue)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(reqSize)), 0, 0) + res = r0 != 0 + return +} diff --git a/usb_darwin.go b/enumerator/usb_darwin.go similarity index 98% rename from usb_darwin.go rename to enumerator/usb_darwin.go index fa63667..a4b632a 100644 --- a/usb_darwin.go +++ b/enumerator/usb_darwin.go @@ -1,10 +1,10 @@ // -// Copyright 2014-2016 Cristian Maglie. All rights reserved. +// Copyright 2014-2017 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 // import "go.bug.st/serial.v1" +package enumerator // import "go.bug.st/serial.v1/enumerator" // #cgo LDFLAGS: -framework CoreFoundation -framework IOKit -fconstant-cfstrings // #include diff --git a/usb_freebsd.go b/enumerator/usb_freebsd.go similarity index 53% rename from usb_freebsd.go rename to enumerator/usb_freebsd.go index 8a60a19..d60d13f 100644 --- a/usb_freebsd.go +++ b/enumerator/usb_freebsd.go @@ -1,12 +1,12 @@ // -// Copyright 2014-2016 Cristian Maglie. All rights reserved. +// Copyright 2014-2017 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 // import "go.bug.st/serial.v1" +package enumerator // import "go.bug.st/serial.v1/enumerator" func nativeGetDetailedPortsList() ([]*PortDetails, error) { // TODO - return nil, &PortError{code: FunctionNotImplemented} + return nil, &PortEnumerationError{} } diff --git a/usb_linux.go b/enumerator/usb_linux.go similarity index 89% rename from usb_linux.go rename to enumerator/usb_linux.go index c671140..d2aca90 100644 --- a/usb_linux.go +++ b/enumerator/usb_linux.go @@ -1,30 +1,32 @@ // -// Copyright 2014-2016 Cristian Maglie. All rights reserved. +// Copyright 2014-2017 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 // import "go.bug.st/serial.v1" +package enumerator // import "go.bug.st/serial.v1/enumerator" import ( "bufio" "fmt" "os" "path/filepath" + + "go.bug.st/serial.v1" ) func nativeGetDetailedPortsList() ([]*PortDetails, error) { // Retrieve the port list - ports, err := nativeGetPortsList() + ports, err := serial.GetPortsList() if err != nil { - return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err} + return nil, &PortEnumerationError{causedBy: err} } var res []*PortDetails for _, port := range ports { details, err := nativeGetPortDetails(port) if err != nil { - return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err} + return nil, &PortEnumerationError{causedBy: err} } res = append(res, details) } diff --git a/usb_ole_windows.go b/enumerator/usb_ole_windows.go similarity index 97% rename from usb_ole_windows.go rename to enumerator/usb_ole_windows.go index 128aa86..bbc0435 100644 --- a/usb_ole_windows.go +++ b/enumerator/usb_ole_windows.go @@ -1,12 +1,12 @@ // -// Copyright 2014-2016 Lars Knudsen, Cristian Maglie. All rights reserved. +// Copyright 2014-2017 Lars Knudsen, 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. // // +build ignore -package serial +package enumerator import ( "log" diff --git a/usb_windows.go b/enumerator/usb_windows.go similarity index 96% rename from usb_windows.go rename to enumerator/usb_windows.go index 1e3a6c4..1431deb 100644 --- a/usb_windows.go +++ b/enumerator/usb_windows.go @@ -1,10 +1,10 @@ // -// Copyright 2014-2016 Cristian Maglie. All rights reserved. +// Copyright 2014-2017 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 // import "go.bug.st/serial.v1" +package enumerator // import "go.bug.st/serial.v1/enumerator" import ( "fmt" @@ -54,6 +54,8 @@ func parseDeviceID(deviceID string, details *PortDetails) { // setupapi based // -------------- +//go:generate go run ../extras/mksyscall_windows.go -output syscall_windows.go usb_windows.go + //sys setupDiClassGuidsFromNameInternal(class string, guid *guid, guidSize uint32, requiredSize *uint32) (err error) = setupapi.SetupDiClassGuidsFromNameW //sys setupDiGetClassDevs(guid *guid, enumerator *string, hwndParent uintptr, flags uint32) (set devicesSet, err error) = setupapi.SetupDiGetClassDevsW //sys setupDiDestroyDeviceInfoList(set devicesSet) (err error) = setupapi.SetupDiDestroyDeviceInfoList @@ -232,14 +234,14 @@ func (dev *deviceInfo) openDevRegKey(scope dicsScope, hwProfile uint32, keyType func nativeGetDetailedPortsList() ([]*PortDetails, error) { guids, err := classGuidsFromName("Ports") if err != nil { - return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err} + return nil, &PortEnumerationError{causedBy: err} } var res []*PortDetails for _, g := range guids { devsSet, err := g.getDevicesSet() if err != nil { - return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err} + return nil, &PortEnumerationError{causedBy: err} } defer devsSet.destroy() @@ -260,7 +262,7 @@ func nativeGetDetailedPortsList() ([]*PortDetails, error) { details.Name = portName if err := retrievePortDetailsFromDevInfo(device, details); err != nil { - return nil, &PortError{code: ErrorEnumeratingPorts, causedBy: err} + return nil, &PortEnumerationError{causedBy: err} } res = append(res, details) } diff --git a/usb_windows_test.go b/enumerator/usb_windows_test.go similarity index 92% rename from usb_windows_test.go rename to enumerator/usb_windows_test.go index ee58d47..853c1a2 100644 --- a/usb_windows_test.go +++ b/enumerator/usb_windows_test.go @@ -1,10 +1,10 @@ // -// Copyright 2014-2016 Cristian Maglie. All rights reserved. +// Copyright 2014-2017 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 // import "go.bug.st/serial.v1" +package enumerator // import "go.bug.st/serial.v1/enumerator" import ( "testing" diff --git a/serial.go b/serial.go index 54a1703..391911c 100644 --- a/serial.go +++ b/serial.go @@ -55,26 +55,6 @@ func GetPortsList() ([]string, error) { return nativeGetPortsList() } -// PortDetails contains detailed information about USB serial port. -// Use GetDetailedPortsList function to retrieve it. -type PortDetails struct { - Name string - IsUSB bool - VID string - PID string - SerialNumber string - - // Manufacturer string - // Product string -} - -// GetDetailedPortsList retrieve ports details like USB VID/PID. -// Please note that this function may not be available on all OS: -// in that case a FunctionNotImplemented error is returned. -func GetDetailedPortsList() ([]*PortDetails, error) { - return nativeGetDetailedPortsList() -} - // Mode describes a serial port configuration. type Mode struct { BaudRate int // The serial port bitrate (aka Baudrate) diff --git a/serial_windows.go b/serial_windows.go index 500e85a..ed04e6b 100644 --- a/serial_windows.go +++ b/serial_windows.go @@ -23,7 +23,7 @@ type windowsPort struct { handle syscall.Handle } -//go:generate go run extras/mksyscall_windows.go -output syscall_windows.go serial_windows.go usb_windows.go +//go:generate go run extras/mksyscall_windows.go -output syscall_windows.go serial_windows.go //sys regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, value *uint16, valueLen *uint32) (regerrno error) = advapi32.RegEnumValueW diff --git a/syscall_windows.go b/syscall_windows.go index add2cce..dfa3f84 100644 --- a/syscall_windows.go +++ b/syscall_windows.go @@ -14,21 +14,13 @@ var _ unsafe.Pointer var ( modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - modsetupapi = windows.NewLazySystemDLL("setupapi.dll") - procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW") - procGetCommState = modkernel32.NewProc("GetCommState") - procSetCommState = modkernel32.NewProc("SetCommState") - procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts") - procEscapeCommFunction = modkernel32.NewProc("EscapeCommFunction") - procGetCommModemStatus = modkernel32.NewProc("GetCommModemStatus") - procSetupDiClassGuidsFromNameW = modsetupapi.NewProc("SetupDiClassGuidsFromNameW") - procSetupDiGetClassDevsW = modsetupapi.NewProc("SetupDiGetClassDevsW") - procSetupDiDestroyDeviceInfoList = modsetupapi.NewProc("SetupDiDestroyDeviceInfoList") - procSetupDiEnumDeviceInfo = modsetupapi.NewProc("SetupDiEnumDeviceInfo") - procSetupDiGetDeviceInstanceIdW = modsetupapi.NewProc("SetupDiGetDeviceInstanceIdW") - procSetupDiOpenDevRegKey = modsetupapi.NewProc("SetupDiOpenDevRegKey") - procSetupDiGetDeviceRegistryPropertyW = modsetupapi.NewProc("SetupDiGetDeviceRegistryPropertyW") + procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW") + procGetCommState = modkernel32.NewProc("GetCommState") + procSetCommState = modkernel32.NewProc("SetCommState") + procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts") + procEscapeCommFunction = modkernel32.NewProc("EscapeCommFunction") + procGetCommModemStatus = modkernel32.NewProc("GetCommModemStatus") ) func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, value *uint16, valueLen *uint32) (regerrno error) { @@ -86,92 +78,3 @@ func getCommModemStatus(handle syscall.Handle, bits *uint32) (res bool) { res = r0 != 0 return } - -func setupDiClassGuidsFromNameInternal(class string, guid *guid, guidSize uint32, requiredSize *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(class) - if err != nil { - return - } - return _setupDiClassGuidsFromNameInternal(_p0, guid, guidSize, requiredSize) -} - -func _setupDiClassGuidsFromNameInternal(class *uint16, guid *guid, guidSize uint32, requiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiClassGuidsFromNameW.Addr(), 4, uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(guid)), uintptr(guidSize), uintptr(unsafe.Pointer(requiredSize)), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiGetClassDevs(guid *guid, enumerator *string, hwndParent uintptr, flags uint32) (set devicesSet, err error) { - r0, _, e1 := syscall.Syscall6(procSetupDiGetClassDevsW.Addr(), 4, uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(enumerator)), uintptr(hwndParent), uintptr(flags), 0, 0) - set = devicesSet(r0) - if set == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiDestroyDeviceInfoList(set devicesSet) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiDestroyDeviceInfoList.Addr(), 1, uintptr(set), 0, 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiEnumDeviceInfo(set devicesSet, index uint32, info *devInfoData) (err error) { - r1, _, e1 := syscall.Syscall(procSetupDiEnumDeviceInfo.Addr(), 3, uintptr(set), uintptr(index), uintptr(unsafe.Pointer(info))) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiGetDeviceInstanceId(set devicesSet, devInfo *devInfoData, devInstanceId unsafe.Pointer, devInstanceIdSize uint32, requiredSize *uint32) (err error) { - r1, _, e1 := syscall.Syscall6(procSetupDiGetDeviceInstanceIdW.Addr(), 5, uintptr(set), uintptr(unsafe.Pointer(devInfo)), uintptr(devInstanceId), uintptr(devInstanceIdSize), uintptr(unsafe.Pointer(requiredSize)), 0) - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiOpenDevRegKey(set devicesSet, devInfo *devInfoData, scope dicsScope, hwProfile uint32, keyType uint32, samDesired regsam) (hkey syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall6(procSetupDiOpenDevRegKey.Addr(), 6, uintptr(set), uintptr(unsafe.Pointer(devInfo)), uintptr(scope), uintptr(hwProfile), uintptr(keyType), uintptr(samDesired)) - hkey = syscall.Handle(r0) - if hkey == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func setupDiGetDeviceRegistryProperty(set devicesSet, devInfo *devInfoData, property deviceProperty, propertyType *uint32, outValue *byte, outSize *uint32, reqSize *uint32) (res bool) { - r0, _, _ := syscall.Syscall9(procSetupDiGetDeviceRegistryPropertyW.Addr(), 7, uintptr(set), uintptr(unsafe.Pointer(devInfo)), uintptr(property), uintptr(unsafe.Pointer(propertyType)), uintptr(unsafe.Pointer(outValue)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(reqSize)), 0, 0) - res = r0 != 0 - return -}