«Я бы написал драйвер, который создает объект устройства WDF. Затем я открывал это устройство из пользовательского режима и отправлял настраиваемые запросы управления вводом-выводом» — типичный сценарий взаимодействия пользователя с ядром.

Сегодня, когда я делал это, я столкнулся с проблемой открытия устройства в пользовательском режиме. Я получил ERROR_ACCESS_DENIED. Приложение пользовательского режима работает с учетными данными администратора, тогда что пошло не так?

Я использовал WinObj, чтобы убедиться, что мои DosDevice и Device установлены правильно. Я также подтвердил, что в пользовательском режиме я использую путь как \\.\MyDevice (L»\\\\.\ \Мое устройство”).

Если вы еще не использовали WinObj, это отличный инструмент от Microsoft для изучения пространства имен диспетчера объектов Windows и списков управления доступом для этих объектов.

Пробовал все режимы доступа — GENERIC_READ, GENERIC_WRITE, ОБА (GENERIC_READ | GENERIC_WRITE) и NONE (0). Я также пробовал разные режимы обмена — FILE_SHARE_[READ | ЗАПИСАТЬ], НЕТ (0).

Должна признать, что это была скорее пробная попытка от разочарования. И это не помогло :-)

Затем я посмотрел на то, как я создал свое устройство.

WdfDeviceInitSetCharacteristics(pWDFDeviceInit, FILE_DEVICE_SECURE_OPEN, FALSE);

Это тоже хорошо. Характеристики устройства должны были быть Безопасное открытие, и, поскольку это была единственная характеристика, которую я устанавливал, третьим аргументом было Ложь.

Итак, я сделал еще один шаг назад…

pWDFDeviceInit = WdfControlDeviceInitAllocate(*pDriver, &SDDL_DEVOBJ_KERNEL_ONLY);

С SDDL_DEVOBJ_KERNEL_ONLY я настраиваю доступ к устройству только из ядра. Мне нужно установить для него значение SDDL_DEVOBJ_SYS_ALL, чтобы код ядра и пользовательского режима работал как система! Проблема найдена и исправлена!

WdfControlDeviceInitAllocate(*pDriver, &SDDL_DEVOBJ_SYS_ALL);


Ссылка SDDL для объектов устройств в MSDN.

Поскольку на различных форумах было много дискуссий по этому поводу, и никто не указал мне на это направление, я подумал, что было бы неплохо также задокументировать мое исправление. Надеюсь это поможет!