@@ -70,10 +70,19 @@ class UTMScriptingUSBDeviceImpl: NSObject, UTMScriptable {
7070 /// - usbManager: USB manager
7171 /// - Returns: USB device in same context as the manager
7272 private func same( usbDevice: CSUSBDevice , for usbManager: CSUSBManager ) -> CSUSBDevice ? {
73- for other in usbManager. usbDevices {
74- if other. isEqual ( to: usbDevice) {
75- return other
76- }
73+ let devices = usbManager. usbDevices
74+ if let device = devices. first ( where: { $0. isEqual ( to: usbDevice) } ) {
75+ return device
76+ }
77+ if let device = devices. first ( where: { $0. matchesLocation ( of: usbDevice) } ) {
78+ return device
79+ }
80+ if let device = devices. first ( where: { $0. matchesSerial ( of: usbDevice) } ) {
81+ return device
82+ }
83+ let matchingDevices = devices. filter ( { $0. matchesVidPid ( of: usbDevice) } )
84+ if matchingDevices. count == 1 {
85+ return matchingDevices [ 0 ]
7786 }
7887 return nil
7988 }
@@ -139,6 +148,23 @@ extension UTMScriptingUSBDeviceImpl {
139148 }
140149}
141150
151+ private extension CSUSBDevice {
152+ func matchesVidPid( of other: CSUSBDevice ) -> Bool {
153+ usbVendorId == other. usbVendorId && usbProductId == other. usbProductId
154+ }
155+
156+ func matchesLocation( of other: CSUSBDevice ) -> Bool {
157+ matchesVidPid ( of: other) && usbBusNumber == other. usbBusNumber && usbPortNumber == other. usbPortNumber
158+ }
159+
160+ func matchesSerial( of other: CSUSBDevice ) -> Bool {
161+ guard let serial = usbSerial, let otherSerial = other. usbSerial, !serial. isEmpty else {
162+ return false
163+ }
164+ return matchesVidPid ( of: other) && serial == otherSerial
165+ }
166+ }
167+
142168// MARK: - NSApplication extension
143169extension AppDelegate {
144170 @MainActor
0 commit comments