2

I am trying to unmount/eject usb device programmatically on macOS. Using IOkit I tried to register to IOServiceMatching(kIOUSBInterfaceClassName) and iterate over all devices and for each device i tried getting the BSD name and go from there:

IORegistryEntrySearchCFProperty(usbDevice,kIOServicePlane,CFSTR(kIOBSDNameKey),kCFAllocatorDefault,kIORegistryIterateRecursively); 

But i found that on Intel based devices that regestry search dosnt work.

I do have Vendor id, product id etc..

So my quistion:

  1. Is there diffrent alternative?
  2. Is there a syscall i can use?
  3. Maybe diffrent approch and not use IoKit?

Thanks

I tried to register using Iokit to: IOServiceMatching(kIOUSBHostDeviceClassName) and IOServiceMatching(kIOUSBInterfaceClassName); and IOServiceMatching(kIOUSBDeviceClassName);

pmdj
  • 22,018
  • 3
  • 52
  • 103
puris
  • 29
  • 1

1 Answers1

2

First of all, there's no concept of "ejecting" in USB itself. Mounting, unmounting, ejecting, etc. are all storage device/volume concepts, and USB mass storage devices are just one type of storage device on which you can perform these operations.

You therefore need to look at the Disk Arbitration framework, specifically the DADiskEject function for ejecting. There is a certain mapping between I/O Kit and Disk Arbitration objects, but not all DADisk objects will necessarily have corresponding I/O Kit objects, as they also exist for APFS snapshot volumes, network mounts, etc. If looking for the device via I/O Kit is natural (for example because you're interested in a specific vendor+product ID pair) then you can easily find an IOMedia object's corresponding DADisk using DADiskCreateFromIOMedia.

For searching the I/O Kit registry for USB devices, use one of the documented matching dictionary formats.

For example, something like:

            @{
                @kIOProviderClassKey: @kIOUSBHostDeviceClassName,
                @kUSBVendorID : @1234,
                @kUSBProductID: @5678,
            }
pmdj
  • 22,018
  • 3
  • 52
  • 103