2017-01-06 12 views
1

Я пытаюсь написать очень простой пользовательский клиент, который - на данный момент - записывает в журнал ядра из пользовательского пространства. Если следующий код работал, он записывал бы «Hello World» в журнал.IOServiceOpen возвращает kIOReturnUnsupported, несмотря на то, что пользовательский клиентский клиентский экземпляр

Я проверил, что у меня есть правильный IOService - com_soggywizards_Foo - с вызовом IOObjectGetClass в коде ниже.

Всегда IOServiceOpen возвращает kIOReturnUnsupported. Однако, когда он вызывается, мой пользовательский клиент появляется в IORegistryExplorer. Я также вижу это в ioreg.

Похоже, что IOServiceOpen создает экземпляр пользовательского клиента, но возвращает его результат до того, как это завершение будет завершено.

Вызов IOServiceOpen в функции "doOpen":

int main(int argc, const char * argv[]) { 
CFMutableDictionaryRef dict = NULL; 

dict = IOServiceMatching("com_soggywizards_Foo"); 

kern_return_t result; 
io_iterator_t it = NULL; 

result = IOServiceGetMatchingServices(kIOMasterPortDefault, 
                (CFDictionaryRef)dict, 
                &it); 

if (result != KERN_SUCCESS){ 

    fprintf(stderr, "IOServiceGetMatchingServices failed 0x%x\n", result); 
    exit(1); 
} 

io_service_t service = IOIteratorNext(it); 
if (service == (io_service_t)NULL){ 
    fprintf(stderr, "IOIteratorNext cant find service\n "); 
    exit(1); 
} 

char name[ 256 ]; 

result = IOObjectGetClass(service, name); 

cout << "service: " << name << endl; // prints "service: com_soggywizards_Foo" 

io_connect_t connect; 

result = doOpen(service, &connect); 

if (result != KERN_SUCCESS) return 1; 

result = logMessage("Hello World\n", connect); 
if (result != KERN_SUCCESS) return 1; 

return 0; 

}

kern_return_t doOpen(io_service_t service, io_connect_t *connect) 
{ 
kern_return_t result = IOServiceOpen(service, mach_task_self(), 0, connect); // returns 0xe00002c7 

if (result != KERN_SUCCESS) fprintf(stderr, "IOServiceOpen failed: 0x%x\n", result); 
else{ 
    result = openUserClient(*connect); 
    if (result != KERN_SUCCESS) fprintf(stderr, "openUserClient failed: 0x%x\n", result); 
} 

return result; 

}

журнал ядра показывает мой клиент пользователя initWithTask вызывается, с супер: : initWithTask выполняется успешно. Также вызывается метод запуска моего клиента.

Непонятно, нужен ли пользовательскому клиенту registerService(). Однако, ioreg говорит, что его зарегистрировали, даже если я его не называю.

ответ

2

Действительно ли ваш класс водителя, или один из его суперклассов, кроме IOService, переопределяет метод newUserClient()? Если надкласс переопределяет его, и вы хотите добавить дополнительный пользовательский тип клиента, вам также придется переопределить его самостоятельно. Если вы уже переопределяете это, вам нужно показать нам свой код, так как это вероятно, где ваша проблема.

(Как правило, это выглядит как ваша проблема на стороне ядра, поэтому, если есть сомнения опубликовать этот код.)

Относительно registerService(): Вы должны назвать это, если вы хотите, чтобы ваш IOService объект, который будет соответствовать, и это готовые принять клиенты, найденные путем сопоставления, т.е. найдены по IOServiceGetMatchingServices() или аналогичным функциям в пространстве пользователя или ядра, включая личность IOKit для kext.