OSX: كيفية الحصول على اسم وحدة التخزين (أو اسم BSD) من iousbdeviceinterface أو معرف الموقع

StackOverflow https://stackoverflow.com/questions/2459414

  •  20-09-2019
  •  | 
  •  

سؤال

أحاول كتابة تطبيق يربط واصفًا لسلسلة USB معينة (لجهاز تخزين جماعي USB) باسم وحدة التخزين أو BSD.

وبالتالي فإن الكود يمر عبر جميع أجهزة USB المتصلة ، ويحصل على واصفات السلسلة ويستخرج المعلومات من أحدها. أود الحصول على اسم وحدة التخزين لأجهزة USB هذه. لا يمكنني العثور على واجهة برمجة التطبيقات المناسبة للقيام بذلك. لقد حاولت القيام بذلك:

DASessionRef session = DASessionCreate(kCFAllocatorDefault);
DADiskRef disk_ref = DADiskCreateFromIOMedia(kCFAllocatorDefault, 
                                             session,
                                             usb_device_ref);
const char* name = DADiskGetBSDName(disk_ref);

لكن وظيفة dadiskcreatefromiomedia عادت إلى شيء ، أفترض أن USB_Device_ref التي مررت بها لم تكن متوافقة مع IO_Service_T التي تتوقعها الوظيفة.

فكيف يمكنني الحصول على اسم وحدة التخزين لجهاز USB؟

هل يمكنني استخدام معرف الموقع للقيام بذلك؟

شكرا للقراءة. -L

FOO_Result              result = FOO_SUCCESS;
mach_port_t             master_port;
kern_return_t           k_result;
io_iterator_t           iterator = 0;
io_service_t            usb_device_ref;
CFMutableDictionaryRef  matching_dictionary = NULL; 

// first create a master_port
if (FOO_FAILED(k_result = IOMasterPort(MACH_PORT_NULL, &master_port))) {
    fprintf(stderr, "could not create master port, err = %d\n", k_result);
    goto cleanup;
}
if ((matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName)) == NULL)
{
    fprintf(stderr, "could not create matching dictionary, err = %d\n", k_result);
    goto cleanup;
}
if (FOO_FAILED(k_result = IOServiceGetMatchingServices(master_port, matching_dictionary, &iterator))) {
    fprintf(stderr, "could not find any matching services, err = %d\n", k_result);
    goto cleanup;
}
while (usb_device_ref = IOIteratorNext(iterator))
{       
    IOReturn                        err;
    IOCFPlugInInterface             **iodev;        // requires <IOKit/IOCFPlugIn.h>
    IOUSBDeviceInterface            **dev;
    SInt32                          score;

    err = IOCreatePlugInInterfaceForService(usb_device_ref, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &iodev, &score);
    if (err || !iodev)
    {
        printf("dealWithDevice: unable to create plugin. ret = %08x, iodev = %p\n", err, iodev);
        return;
    }
    err = (*iodev)->QueryInterface(iodev, 
                                   CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), 
                                   (LPVOID*)&dev);
    (*iodev)->Release(iodev);               // done with this


    FOO_String string_value;
    UInt8 string_index = 0x1;
    FOO_Result result = FOO_SUCCESS;
    CFStringRef device_name_as_cf_string;
    do {
        if (FOO_SUCCEEDED(result = FOO_GetStringDescriptor(dev, string_index, 0, string_value))) {
            printf("String at index %i is %s\n", string_index, string_value.GetChars());
            // extract the command code if it is the FOO string
            if (string_value.CompareN("FOO:", 4) == 0) {
                FOO_Byte code = 0;
                FOO_HexToByte(string_value.GetChars() + 4, code);
                // Get other relevant information from the device
                io_name_t        device_name;
                UInt32           location_id = 0;

                // Get the USB device's name.
                err = IORegistryEntryGetName(usb_device_ref, device_name);
                device_name_as_cf_string = CFStringCreateWithCString(kCFAllocatorDefault, device_name, 
                                                                     kCFStringEncodingASCII); 

                err = (*dev)->GetLocationID(dev, &location_id);

                // TODO: get volume or BSD name 

                // add the device to the list

                break;
            }
        }
        string_index++;
    } while (FOO_SUCCEEDED(result));


    err = (*dev)->USBDeviceClose(dev);
    if (err)
    {
        printf("dealWithDevice: error closing device - %08x\n", err);
        (*dev)->Release(dev);
        return;
    }
    err = (*dev)->Release(dev);
    if (err)
    {
        printf("dealWithDevice: error releasing device - %08x\n", err);
        return;
    }

    IOObjectRelease(usb_device_ref);            // no longer need this reference
}
هل كانت مفيدة؟

المحلول

بمجرد حصولك على io_service_t ، يمكنك إعادة تدوين IOREGISTY للعثور على اسم BSD. لا تحتاج إلى إنشاء واجهة بالفعل.

#import <IOKit/IOBSD.h>

CFStringRef bsdName = ( CFStringRef ) IORegistryEntrySearchCFProperty ( usbDevice,
                                                                       kIOServicePlane,
                                                                       CFSTR ( kIOBSDNameKey ),
                                                                       kCFAllocatorDefault,
                                                                       kIORegistryIterateRecursively );

نصائح أخرى

أنظر أيضا:

USBDEVs - قائمة أجهزة USB مثبتة

https://gist.github.com/atr000/621561

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top