Я пытаюсь взаимодействовать с dext из приложения. Я могу найти службу, используя IOServiceOpen
, и я получаю вызов NewUserClient
моего dext (я вижу, что переданный параметр type
выводится в журнале). После этого я немного растерялся. Читая здесь о NewUserClient Я вижу, что следует использовать Create
для создания нового объекта Service.
В разделе обсуждения здесь говорит Ключи в словаре propertiesKey
описывают новую услугу.
Должен ли этот словарь быть помещен в файл plist для расширения системы как запись верхнего уровня, или должен быть помещен словарь с ключом в IOKitPersonalities
?
Можно ли оставить ключ IOServiceDEXTEntitlements
с пустым значением, чтобы не накладывать никаких ограничений на права для приложения, подключающегося к расширению системы?
Мой plist выглядит следующим образом (с ключом MyUserClientProperties
/ dict в двух местах).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>MyUserClientProperties</key>
<dict>
<key>IOClass</key>
<string>MyUserClient</string>
<key>IOUserClass</key>
<string>MyUserUSBInterfaceDriver</string>
<key>IOServiceDEXTEntitlements</key>
<string></string>
</dict>
<key>IOKitPersonalities</key>
<dict>
<key>example_device</key>
<dict>
<key>MyUserClientProperties</key>
<dict>
<key>IOClass</key>
<string>MyUserClient</string>
<key>IOUserClass</key>
<string>MyUserUSBInterfaceDriver</string>
<key>IOServiceDEXTEntitlements</key>
<string></string>
</dict>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>IOClass</key>
<string>IOUserService</string>
<key>IOProviderClass</key>
<string>IOUSBHostInterface</string>
<key>IOUserClass</key>
<string>MyUserUSBInterfaceDriver</string>
<key>IOUserServerName</key>
<string>sc.example.MyUserUSBInterfaceDriver</string>
<key>bConfigurationValue</key>
<integer>0x1</integer>
<key>bInterfaceNumber</key>
<integer>0x0</integer>
<key>idVendor</key>
<integer>0x123</integer>
<key>idProduct</key>
<integer>0x08</integer>
</dict>
</dict>
<key>OSBundleUsageDescription</key>
<string>Example user space USB driver</string>
</dict>
</plist>
Нужно ли передавать SUPERDISPATCH
в качестве последнего аргумента Create
?
Из главы «Программирование ядра OSX и iOS», страница 5:
Изобретательность конструкции I / O Kit заключается в том, что пользовательские клиентские объекты сами являются объектом драйвера: класс IOUserClient наследуется от IOService и, как и любой другой В другом экземпляре IOService каждый пользовательский клиент имеет класс провайдера, который для пользовательского клиента является экземпляром драйвера, которым управляет приложение.
Хотя приведенное выше может быть правильным только для kext (? ) Я бы предположил, что для dext все работает одинаково:
С Создание документации: Используйте ключ kIOUserClassKey для указания имени пользовательского подкласса IOService, который вы хотите система для создания экземпляров.
Почему требуется создание другого класса IOService
? Какова цель этого класса? Это провайдер для моего класса, который наследуется от IOUserClient
? Если так, как я могу сделать экземпляр моего драйвера (тот, который реализует NewUserClient
) поставщиком?
С Создать документацию: Используйте kIOClassKey
, чтобы указать имя пользовательского подкласса IOUserClient
для возврата клиентам вашей службы.
Является ли тип класса, который будет создан и назначен третьему аргументу Create
? Если да, то это тот, которому я должен назначить указатель IOUserClient*
, который передается в NewUserClient
?
kern_return_t IMPL(MyUserUSBInterfaceDriver, NewUserClient) {
os_log(OS_LOG_DEFAULT, "%{public}d:", type);
IOPropertyName propertiesKey = "MyUserClientProperties";
IOService* client;
auto ret = Create(this, propertiesKey, &client, SUPERDISPATCH);
// Need to do more things here...
return ret;
}
Независимо от того, что я пытаюсь, я всегда получаю утверждение, но я не вижу, что вызывая это.
3 com.apple.DriverKit 0x0000000102f2b24b __assert_rtn + 102
4 com.apple.DriverKit 0x0000000102f2c20a IOService::Create_Impl(IOService*, char const*, IOService**) (.cold.2) + 35
5 com.apple.DriverKit 0x0000000102f1766b IOService::Create_Impl(IOService*, char const*, IOService**) + 91
6 com.apple.DriverKit 0x0000000102f2668f IOService::Create_Invoke(IORPC, OSMetaClassBase*, int (*)(OSMetaClassBase*, IOService*, char const*, IOService**)) + 135
7 com.apple.DriverKit 0x0000000102f276d7 IOService::Create(IOService*, char const*, IOService**, int (*)(OSMetaClassBase*, IORPC)) + 267
8 sc.example.MyUserUSBInterfaceDriver 0x0000000102ee0c89 MyUserUSBInterfaceDriver::NewUserClient_Impl(unsigned int, IOUserClient**) + 313 (MyUserUSBInterfaceDriver.cpp:155)