Cœur的答案非常接近。
plugInInterface.QueryInterface()
的最后一个参数期望是一个
双重间接指针的地址。
UnsafeMutablePointer<UnsafeMutablePointer<IOUSBDeviceInterface>?>?
但它被“伪装”成指向
LPVOID?
,也就是
UnsafeMutableRawPointer
的指针。
因此,必须对获取的指针进行两次解引用。
可以使用
withMemoryRebound()
进行指针转换。
我对代码进行了一些更改:
- 使用
defer
继续下一个USB设备的操作,即使由于错误而“中止”当前迭代。
- 删除不必要的类型注释。
- 使用
MemoryLayout<io_name_t>.size
代替128
。
- 在使用后释放
usbDevice
和接口指针,以避免内存泄漏。
- 将一些变量声明从顶部移到需要它们的位置。
把它们整合起来:
import Foundation
import IOKit
import IOKit.usb
import IOKit.usb.IOUSBLib
print("Scanning USB Bus.....\n\n\n")
let kIOUSBDeviceUserClientTypeID = CFUUIDGetConstantUUIDWithBytes(kCFAllocatorDefault,
0x9d, 0xc7, 0xb7, 0x80, 0x9e, 0xc0, 0x11, 0xD4,
0xa5, 0x4f, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61)
let kIOCFPlugInInterfaceID = CFUUIDGetConstantUUIDWithBytes(kCFAllocatorDefault,
0xC2, 0x44, 0xE8, 0x58, 0x10, 0x9C, 0x11, 0xD4,
0x91, 0xD4, 0x00, 0x50, 0xE4, 0xC6, 0x42, 0x6F)
let kIOUSBDeviceInterfaceID = CFUUIDGetConstantUUIDWithBytes(kCFAllocatorDefault,
0x5c, 0x81, 0x87, 0xd0, 0x9e, 0xf3, 0x11, 0xD4,
0x8b, 0x45, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61)
let matchingDictionary: NSMutableDictionary = IOServiceMatching(kIOUSBDeviceClassName)
var usbIterator = io_iterator_t()
let matchingServicesResult = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &usbIterator)
if matchingServicesResult != kIOReturnSuccess {
print("Error getting deviceList!")
exit(EXIT_FAILURE)
}
var usbDevice = IOIteratorNext(usbIterator)
while usbDevice != 0 {
defer {
usbDevice = IOIteratorNext(usbIterator)
}
var deviceNameCString = [CChar](repeating: 0, count: MemoryLayout<io_name_t>.size)
let deviceNameResult = IORegistryEntryGetName(usbDevice, &deviceNameCString)
if deviceNameResult != kIOReturnSuccess {
print("Error getting device name")
continue
}
let deviceName = String(cString: &deviceNameCString)
print("USB device name: \(deviceName)")
var plugInInterfacePtrPtr: UnsafeMutablePointer<UnsafeMutablePointer<IOCFPlugInInterface>?>?
var score: Int32 = 0
let plugInInterfaceResult = IOCreatePlugInInterfaceForService(
usbDevice,
kIOUSBDeviceUserClientTypeID,
kIOCFPlugInInterfaceID,
&plugInInterfacePtrPtr,
&score)
IOObjectRelease(usbDevice)
guard plugInInterfaceResult == kIOReturnSuccess,
let plugInInterface = plugInInterfacePtrPtr?.pointee?.pointee else {
print("Unable to get Plug-In Interface")
continue
}
var deviceInterfacePtrPtr: UnsafeMutablePointer<UnsafeMutablePointer<IOUSBDeviceInterface>?>?
let deviceInterfaceResult = withUnsafeMutablePointer(to: &deviceInterfacePtrPtr) {
$0.withMemoryRebound(to: Optional<LPVOID>.self, capacity: 1) {
plugInInterface.QueryInterface(
plugInInterfacePtrPtr,
CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID),
$0)
}
}
_ = plugInInterface.Release(plugInInterfacePtrPtr)
guard deviceInterfaceResult == kIOReturnSuccess,
let deviceInterface = deviceInterfacePtrPtr?.pointee?.pointee else {
print("Unable to get Device Interface")
continue
}
var usbVendorID: UInt16 = 0
let vendorResult = deviceInterface.GetDeviceVendor(deviceInterfacePtrPtr, &usbVendorID)
_ = deviceInterface.Release(deviceInterfacePtrPtr)
if vendorResult != kIOReturnSuccess {
print("Unable to get device Vendor ID")
continue
}
print("USB Vendor ID: \(usbVendorID)")
}
exit(EXIT_SUCCESS)
}()``` 没有起作用。
- Arti