迭代 IOService 对象时,迭代器是否进入子节点?

When iterating IOService objects, does the iterator go into children nodes?

比如我要查找所有的IOPCIDevice,我使用

CFMutableDictionaryRef dict = IOServiceMatching("IOPCIDevice");
IOServiceGetMatchingServices(kIOMasterPortDefault,matchDict,
                                     &iterator) == kIOReturnSuccess

在此之后,迭代器指向一个节点,即 IOPCIDevice。

      iterator
         |
Parent (IOPCIDevice) <--- child of ---- Child(IOPCIDevice)
         |
         |
Another parent (IOPCIDevice)
         |
         ---------------- ...

我的问题是,这个迭代器会进入子节点吗?它如何遍历所有匹配的节点?[​​=12=]

My question is that, would this iterator goes into the children nodes?

是,如果任何子节点也满足匹配条件。

How does it iterates all the matched nodes?

我认为没有任何关于对象返回顺序的保证,如果这是你的要求的话。

使用以下代码演示该行为非常容易:

#include <IOKit/IOKitLib.h>
#include <stdio.h>

int main(int argc, const char* argv[])
{
    CFMutableDictionaryRef matching_dict = IOServiceMatching("IOPCIDevice");
    io_iterator_t match_iter = IO_OBJECT_NULL;
    IOReturn result = IOServiceGetMatchingServices(
        kIOMasterPortDefault, matching_dict, &match_iter);
    if (result == kIOReturnSuccess)
    {
        io_service_t matched_service;
        while ((matched_service = IOIteratorNext(match_iter)))
        {
            io_name_t service_class = "";
            io_string_t service_path = "";
            IORegistryEntryGetPath(matched_service, kIOServicePlane, service_path);
            IOObjectGetClass(matched_service, service_class);
            printf("%s [%s]\n", service_path, service_class);
            IOObjectRelease(matched_service);
        }
        IOObjectRelease(match_iter);
    }

    return 0;
}

在我的系统上,一个 Mac Mini (2018) 和一些通过 Thunderbolt 连接的设备,我得到以下输出:

IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/MCHC@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG0@1 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG2@1,2 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/pci8086,a379@12 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG0@1/IOPP/XGBE@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/pci8086,a36f@14,2 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IMEI@16 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG2@1,2/IOPP/UPSB@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/RP17@1B [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB0@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB1@1 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/RP17@1B/IOPP/ANS2@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB1@1/IOPP/UPS0@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB2@2 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB4@4 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/RP17@1B/IOPP/IOBC@0,1 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG2@1,2/IOPP/UPSB@0/IOPP/DSB0@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB1@1/IOPP/UPS0@0/IOPP/pci-bridge@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG2@1,2/IOPP/UPSB@0/IOPP/DSB1@1 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/RP17@1B/IOPP/SEPM@0,2 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB4@4/IOPP/UPS0@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB1@1/IOPP/UPS0@0/IOPP/pci-bridge@0/IOPP/pci11c1,5901@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/RP17@1B/IOPP/ADIO@0,3 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG2@1,2/IOPP/UPSB@0/IOPP/DSB2@2 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG2@1,2/IOPP/UPSB@0/IOPP/DSB4@4 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB2@2/IOPP/XHC2@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB4@4/IOPP/UPS0@0/IOPP/pci-bridge@1 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB0@0/IOPP/NHI0@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB4@4/IOPP/UPS0@0/IOPP/pci-bridge@1/IOPP/display@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG1@1,1/IOPP/UPSB@0/IOPP/DSB4@4/IOPP/UPS0@0/IOPP/pci-bridge@1/IOPP/pci1002,aaf0@0,1 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG2@1,2/IOPP/UPSB@0/IOPP/DSB2@2/IOPP/XHC3@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG2@1,2/IOPP/UPSB@0/IOPP/DSB0@0/IOPP/NHI0@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/RP01@1C [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/RP02@1C,1 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/URT0@1E [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/LPCB@1F [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/HDEF@1F,3 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/RP01@1C/IOPP/ARPT@0 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/SBUS@1F,4 [IOPCIDevice]
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XSPI@1F,5 [IOPCIDevice]

你可以看到

IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG0@1

的父节点
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/PEG0@1/IOPP/XGBE@0