Strange behavior of IOServiceNameMatching(..)

I'm trying to find extension by name with following code:

static const char* dextIdentifier = "someDextName";
CFMutableDictionaryRef cfd = IOServiceNameMatching(dextIdentifier);
int nMatch = (int)CFDictionaryGetCount(cfd);
printf("nMatch=%d\n",nMatch);

const void *keys[nMatch], *values[nMatch];
CFDictionaryGetKeysAndValues(cfd, keys, values);
for(int e=0; e < nMatch; e++) {
    char key[100] = "", value[100] = "";
    if(CFStringGetCString(reinterpret_cast<CFStringRef>(keys[e]), key, sizeof(key), kCFStringEncodingASCII)) {
		printf("Key: %s\n",key);
	}
    if(CFStringGetCString(reinterpret_cast<CFStringRef>(values[e]), value, sizeof(value), kCFStringEncodingASCII)) {
		printf("Value: %s\n",key);    
	}
}

Regardless of dextIdentifier value IOServiceNameMatching always returns single record (nMatch = 1), where key = "IONameMatch" and value = <passed to IOServiceNameMatching parameter> It doesn't matter whether the specified extension name exists or not

There is the single extension in the system, according to 'systemextensionsctl list' command

Accepted Reply

IOServiceNameMatching is a convenience function which creates a matching dictionary with the contents [ "IONameMatch": <name> ], so it is behaving exactly as it should. It does not return an IOService with name matching <name>. The "IOService" prefix serves as a poor man's namespace. You need to take the matching dictionary and pass it to IOServiceGetMatchingServices, which will return an iterator. You walk through that iterator to get the actual services (if found).

  • Thank you a lot! That was real misunderstanding. IOServiceGetMatchingServices(kIOMasterPortDefault, cfd, &iterator) returns nil iterator for existing extension name.The extension state is [activated enabled]. What can be a reason ?

Add a Comment

Replies

IOServiceNameMatching is a convenience function which creates a matching dictionary with the contents [ "IONameMatch": <name> ], so it is behaving exactly as it should. It does not return an IOService with name matching <name>. The "IOService" prefix serves as a poor man's namespace. You need to take the matching dictionary and pass it to IOServiceGetMatchingServices, which will return an iterator. You walk through that iterator to get the actual services (if found).

  • Thank you a lot! That was real misunderstanding. IOServiceGetMatchingServices(kIOMasterPortDefault, cfd, &iterator) returns nil iterator for existing extension name.The extension state is [activated enabled]. What can be a reason ?

Add a Comment