Pull to refresh

Comments 7

Вызывать AddDevice одного драйвера из обработчика AddDevice другого, да еще когда оба хотят работать с одними и теми же устройствами - так себе идея. Чтоб так делать, нужно знать все тонкости процесса обработки, используемые ресурсы, зависимости и прочее. Попытка сделать такое в лоб закономерно приводит к нестабильности и глюкам.

По-хорошему, при обработке AddDevice в драйвере-перехватчике, Вам нужно дожидаться ее успешного завершения, подтверждающего, что устройство успешно создано, затем где-то запомнить его реквизиты, и вызвать callback основного драйвера независимо (например, через Work Item), чтобы исключить любые гонки.

Ну и вызывать в качестве callback'а AddDevice основного драйвера имеет смысл лишь в том случае, когда такой вызов неотличим от "честного" вызова из Device Manager, иначе стоило бы предусмотреть для этого собственную функцию.

Вообще, WDF предназначен для "чайников" драйверостроения, чтобы программисты, предметно не изучавшие ядро, могли наскоро сляпать типовой драйвер по одной из стандартных моделей. Делать на нем что-то нестандартное.

Вы похоже не совсем меня поняли: AddDevice драйвера-клиента - это просто функция коллбэк, не регистрируемая через DRIVER_OBJECT и c PnP не связанная. Драйвер-клиент с PnP вообще не связна, для него эту задачу выполняет фильтр-драйвер. Тут вышла небольшая путаница наверное - настоящий AddDevice регистрируется только в фильтре, он же отслеживает список подключенных устройств. В конце своей работы "настоящий" AddDevice вызывает AddDevice драйвера-клиента, который и сохраняет те самые "реквизиты" и создаёт связанный с ними control device (это происходит внутри work item-а). Название у них общее только исходя из-за назначения, но регистрация и прототип совсем разные. Если бы они обе были зарегистрированы через DRIVER_OBJECT - это был бы лютый треш, тут Вы несомненно правы - но я не настолько не в себе чтобы такое делать :-) Вообще статья несколько упрощает схему работы - так как она тут больше для общего понимания (манипуляции с фильтр устройствами задействуют ещё и обработку IRP_MN_START_DEVICE). Насчёт KMDF - вопрос спорный, идея применения дерева родителей из коробки мне показалась интересной (для GUI фреймворков это норма), да и упрощение часто используемых вещей вроде автоматической очередизации - тоже полезно, сокращение возможностей отстрелить себе много он тоже сокращает - да и ничто не мешает комбинировать техники, что я и сделал. Ещё забавный момент, который меня удивил в KMDF - это то, что он написан на C++ (ограниченном - оно понятно). Wil даёт RAII классы для хендлов - идёт явное смещение в эту сторону. Хорошо ли всё это - вопрос спорный, но если одно не отменяет другого - я за. Рад увидеть первый коммент, я уж счёл что данной темой тут никто не интересуется Ъ

P.S. добавил статью этот момент, чтобы не сбивать с толку :-)

AddDevice драйвера-клиента - это просто функция коллбэк, не регистрируемая через DRIVER_OBJECT

Именно поэтому ее и стоило бы назвать по-другому, даже для себя. Привычка к подобным коллизиям в какой-то момент может сработать против Вас.

упрощение часто используемых вещей вроде автоматической очередизации - тоже полезно

До тех пор, пока Вы в точности понимаете, как это реализовано, чтобы быть уверенным, что нигде не возникнет побочных эффектов. В таких задачах неожиданные эффекты нередко возникают даже при работе на самом низком уровне API, а лишние прослойки лишь увеличивают риски.

Это как делать на каком-нибудь WTL или MFC приложение, цель которого - перехват и нестандартная обработка оконных сообщений, организация нестандартных связей между окнами и т.п. Сделать-то можно, но риск отстрелить себе что-нибудь в процессе будет приличный.

А вот изготовление типовых драйверов, со стандартизованным стилем взаимодействия между собой и системой, WDF действительно облегчает.

момент, который меня удивил в KMDF - это то, что он написан на C++

Что здесь удивительного? Драйверы писались на C++ задолго до его появления - еще с конца 90-х.

Удивительное то, что у как минимум в моём окружении матёрые разработчики драйверов морщат нос при использовании С++ в дровах - только С. А тут такой удар под дых от MS :-) Да и на форумах жёсткие холивары на эту тему припоминаются.

Морщат нос две категории разработчиков: ненавистники C++ (как правило, они не могут толком объяснить свои убеждения, и постоянно путаются в показаниях), и те, кто плохо понимает, какой код порождается компилятором для тех или иных языковых конструкций (они твердо убеждены, будто код для C безусловно эффективнее).

Те, кто не имеет предубеждения, и понимает, как порождается код, спокойно пишут на C++ любой код, не уступающий по эффективности коду на C.

Полностью согласен (там ещё куча оправданий связанных с неявными вызовами и полиморфизмом), но в целом там скорее нежелание разобраться.

Сам таким был в 90-е, во времена тупых и тормозных 16-разрядных компиляторов с C++. :) Когда во второй половине декады пошли нормальные 32-разрядные VC++ 4.x, все ядерное стал писать только на C++.

Sign up to leave a comment.

Articles