diff --git a/enumerator/usb_darwin.go b/enumerator/usb_darwin.go index 1b1cbd1..2e653ec 100644 --- a/enumerator/usb_darwin.go +++ b/enumerator/usb_darwin.go @@ -28,7 +28,7 @@ func nativeGetDetailedPortsList() ([]*PortDetails, error) { for _, service := range services { defer service.Release() - port, err := extractPortInfo(C.io_registry_entry_t(service)) + port, err := extractPortInfo(io_registry_entry_t(service)) if err != nil { return nil, &PortEnumerationError{causedBy: err} } @@ -37,7 +37,7 @@ func nativeGetDetailedPortsList() ([]*PortDetails, error) { return ports, nil } -func extractPortInfo(service C.io_registry_entry_t) (*PortDetails, error) { +func extractPortInfo(service io_registry_entry_t) (*PortDetails, error) { port := &PortDetails{} // If called too early the port may still not be ready or fully enumerated // so we retry 5 times before returning error. @@ -82,14 +82,14 @@ func extractPortInfo(service C.io_registry_entry_t) (*PortDetails, error) { return port, nil } -func getAllServices(serviceType string) ([]C.io_object_t, error) { +func getAllServices(serviceType string) ([]io_object_t, error) { i, err := getMatchingServices(serviceMatching(serviceType)) if err != nil { return nil, err } defer i.Release() - var services []C.io_object_t + var services []io_object_t tries := 0 for tries < 5 { // Extract all elements from iterator @@ -105,7 +105,7 @@ func getAllServices(serviceType string) ([]C.io_object_t, error) { for _, s := range services { s.Release() } - services = []C.io_object_t{} + services = []io_object_t{} i.Reset() tries++ } @@ -121,58 +121,64 @@ func serviceMatching(serviceType string) C.CFMutableDictionaryRef { } // getMatchingServices look up registered IOService objects that match a matching dictionary. -func getMatchingServices(matcher C.CFMutableDictionaryRef) (C.io_iterator_t, error) { +func getMatchingServices(matcher C.CFMutableDictionaryRef) (io_iterator_t, error) { var i C.io_iterator_t err := C.IOServiceGetMatchingServices(C.kIOMasterPortDefault, C.CFDictionaryRef(matcher), &i) if err != C.KERN_SUCCESS { return 0, fmt.Errorf("IOServiceGetMatchingServices failed (code %d)", err) } - return i, nil + return io_iterator_t(i), nil } // CFStringRef -func cfStringCreateWithString(s string) C.CFStringRef { +type cfStringRef C.CFStringRef + +func cfStringCreateWithString(s string) cfStringRef { c := C.CString(s) defer C.free(unsafe.Pointer(c)) - return C.CFStringCreateWithCString( - C.kCFAllocatorDefault, c, C.kCFStringEncodingMacRoman) + return cfStringRef(C.CFStringCreateWithCString( + C.kCFAllocatorDefault, c, C.kCFStringEncodingMacRoman)) } -func (ref C.CFStringRef) Release() { +func (ref cfStringRef) Release() { C.CFRelease(C.CFTypeRef(ref)) } // CFTypeRef -func (ref C.CFTypeRef) Release() { - C.CFRelease(ref) +type cfTypeRef C.CFTypeRef + +func (ref cfTypeRef) Release() { + C.CFRelease(C.CFTypeRef(ref)) } // io_registry_entry_t -func (me *C.io_registry_entry_t) GetParent(plane string) (C.io_registry_entry_t, error) { +type io_registry_entry_t C.io_registry_entry_t + +func (me *io_registry_entry_t) GetParent(plane string) (io_registry_entry_t, error) { cPlane := C.CString(plane) defer C.free(unsafe.Pointer(cPlane)) var parent C.io_registry_entry_t - err := C.IORegistryEntryGetParentEntry(*me, cPlane, &parent) + err := C.IORegistryEntryGetParentEntry(C.io_registry_entry_t(*me), cPlane, &parent) if err != 0 { return 0, errors.New("No parent device available") } - return parent, nil + return io_registry_entry_t(parent), nil } -func (me *C.io_registry_entry_t) CreateCFProperty(key string) (C.CFTypeRef, error) { +func (me *io_registry_entry_t) CreateCFProperty(key string) (cfTypeRef, error) { k := cfStringCreateWithString(key) defer k.Release() - property := C.IORegistryEntryCreateCFProperty(*me, k, C.kCFAllocatorDefault, 0) + property := C.IORegistryEntryCreateCFProperty(C.io_registry_entry_t(*me), C.CFStringRef(k), C.kCFAllocatorDefault, 0) if property == 0 { return 0, errors.New("Property not found: " + key) } - return property, nil + return cfTypeRef(property), nil } -func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { +func (me *io_registry_entry_t) GetStringProperty(key string) (string, error) { property, err := me.CreateCFProperty(key) if err != nil { return "", err @@ -191,7 +197,7 @@ func (me *C.io_registry_entry_t) GetStringProperty(key string) (string, error) { return C.GoString(&buff[0]), nil } -func (me *C.io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberType) (int, error) { +func (me *io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberType) (int, error) { property, err := me.CreateCFProperty(key) if err != nil { return 0, err @@ -204,34 +210,52 @@ func (me *C.io_registry_entry_t) GetIntProperty(key string, intType C.CFNumberTy return res, nil } +func (me *io_registry_entry_t) Release() { + C.IOObjectRelease(C.io_object_t(*me)) +} + +func (me *io_registry_entry_t) GetClass() string { + class := make([]C.char, 1024) + C.IOObjectGetClass(C.io_object_t(*me), &class[0]) + return C.GoString(&class[0]) +} + // io_iterator_t +type io_iterator_t C.io_iterator_t + // IsValid checks if an iterator is still valid. // Some iterators will be made invalid if changes are made to the // structure they are iterating over. This function checks the iterator // is still valid and should be called when Next returns zero. // An invalid iterator can be Reset and the iteration restarted. -func (me *C.io_iterator_t) IsValid() bool { - return C.IOIteratorIsValid(*me) == C.true +func (me *io_iterator_t) IsValid() bool { + return C.IOIteratorIsValid(C.io_iterator_t(*me)) == C.true } -func (me *C.io_iterator_t) Reset() { - C.IOIteratorReset(*me) +func (me *io_iterator_t) Reset() { + C.IOIteratorReset(C.io_iterator_t(*me)) } -func (me *C.io_iterator_t) Next() (C.io_object_t, bool) { - res := C.IOIteratorNext(*me) - return res, res != 0 +func (me *io_iterator_t) Next() (io_object_t, bool) { + res := C.IOIteratorNext(C.io_iterator_t(*me)) + return io_object_t(res), res != 0 +} + +func (me *io_iterator_t) Release() { + C.IOObjectRelease(C.io_object_t(*me)) } // io_object_t -func (me *C.io_object_t) Release() { - C.IOObjectRelease(*me) +type io_object_t C.io_object_t + +func (me *io_object_t) Release() { + C.IOObjectRelease(C.io_object_t(*me)) } -func (me *C.io_object_t) GetClass() string { +func (me *io_object_t) GetClass() string { class := make([]C.char, 1024) - C.IOObjectGetClass(*me, &class[0]) + C.IOObjectGetClass(C.io_object_t(*me), &class[0]) return C.GoString(&class[0]) }