После этого ОС отправит IRP_MN_QUERY_DEVICE_RELATIONS
запрос с BusRelations
. В этом обработчике запроса мы исключим устройство из массива и выполним другую необходимую работу, чтобы «отключить» его от шины, а также установим флаг RemovePending
в его расширении устройства.
здесь нужно только исключить устройство из массива и установить флаг RemovePending
в его расширении устройства. но выполните другую необходимую работу, чтобы "отключить" его от шины - нужно делать только тогда, когда вы обрабатываете IRP_MN_REMOVE_DEVICE
(после того, как устройство не было включено в последний ответ драйвера шины на запрос IRP_MN_QUERY_DEVICE_RELATIONS
для BusRelations
- или другими словами - когда флаг RemovePending
в его расширение устройства)
как обрабатывать входящие запросы ввода-вывода к устройству после того, как оно становится «удалить ожидающим» и до того, как ОС отправит IRP_MN_REMOVE_DEVICE
запрос. Должны ли мы проверить флаг RemovePending
и вернуть STATUS_DEVICE_DOES_NOT_EXIST
или действовать как обычно?
я думаю, что возможно оба поведения - вы можете обработать его как обычно и также можете вернуть STATUS_DEVICE_DOES_NOT_EXIST
. и предположим следующую ситуацию - вы получаете запрос ввода-вывода одновременно с процессом удаления устройства. когда вы проверяете флаг RemovePending
- он еще не установлен. и вы начинаете обрабатывать запрос "как обычно". но сразу после того, как вы проверите флаг RemovePending
внутри запроса ввода-вывода, вы можете установить его при обработке запроса IRP_MN_QUERY_DEVICE_RELATIONS
с помощью BusRelations
. и эта ситуация напрямую связана со смыслом использования Remove Locks или Защита от перегрузки.
мы действительно можем использовать Run-Down Protection вместо Remove Locks почти таким же образом и точно в тех же местах и по той же причине, что и Remove Locks. и я думаю, что API-интерфейс защиты от износа (более новый сравните удаление блокировок) - лучший дизайн и лучше для использования (однако разница минимальна)
Я не понимаю, зачем нам снимать блокировку внутри обработчика запросов PnP?
прежде всего обратите внимание, что о снятии блокировки сказано только в Удаление устройства в функциональном драйвере. у вас, как я понимаю, есть не функция, а драйвер шины, поэтому Удаление устройства в драйвере шины больше подходит для вас. и в документации для Удаление устройства в функциональном драйвере существует серьезная ошибка — рекомендуется сначала позвонить IoReleaseRemoveLockAndWait
в точке 4 - до точки 8< /strong> — передать запрос IRP_MN_REMOVE_DEVICE
следующему драйверу. но правильно должно быть
Драйвер должен вызвать IoReleaseRemoveLockAndWait
после передачи запроса IRP_MN_REMOVE_DEVICE
следующему нижестоящему драйверу и до того, как он освободит память, вызовет IoDetachDevice
или IoDeleteDevice
.
это правильно и указано в Использование снятия блокировок и IoReleaseRemoveLockAndWait а>. забавно, что в старых версиях msdn было
вызовите IoReleaseRemoveLockAndWait
прежде чем он пройдет..
но теперь это исправлено. почему после? потому что следующий более низкий драйвер может ожидать некоторых IRP (на которых мы вызываем IoAcquireRemoveLock
или ExAcquireRundownProtection
) и завершать их только тогда, когда получен IRP_MN_REMOVE_DEVICE
, а наш драйвер вызывает IoReleaseRemoveLock
или ExReleaseRundownProtection
только тогда, когда этот IRP будет завершен. в результате, если вызов IoReleaseRemoveLockAndWait
или ExWaitForRundownProtectionRelease
до передает удаление IRP следующему нижестоящему драйверу - мы можем ждать здесь вечно - следующий нижестоящий драйвер не может завершить какой-то IRP (пока не получит запрос на удаление) и мы не освобождать снять блокировку или защиту от износа.
так для чего нам нужно снять блокировку или защиту от износа? потому что мы можем получить IRP_MN_REMOVE_DEVICE
одновременно с другими запросами ввода-вывода. и эти запросы ввода-вывода могут использовать некоторые ресурсы на устройстве. другого размера, когда мы обрабатываем IRP_MN_REMOVE_DEVICE
, мы уничтожаем эти ресурсы. что будет, если мы будем использовать какой-то ресурс в запросе ввода-вывода после того, как он будет уничтожен в IRP_MN_REMOVE_DEVICE
? думаю не нужен ответ. для предотвращения этого и существуют блокировки удаления или защита от износа. перед использованием любого ресурса (который будет уничтожен при удалении) необходимо вызвать IoAcquireRemoveLock
или ExAcquireRundownProtection
и использовать его, только если возвращается статус ok. после того, как мы закончим использовать вызов ресурса IoReleaseRemoveLock
или ExReleaseRundownProtection
. а в IRP_MN_REMOVE_DEVICE
мы называем IoReleaseRemoveLockAndWait
или ExWaitForRundownProtectionRelease
. после того, как этот вызов возвращается - мы можем быть уверены, что никто не использует наши ресурсы и никогда не будет использоваться больше (вызовы IoAcquireRemoveLock
или ExAcquireRundownProtection
возвращают статус ошибки (false)). в этот момент мы можем безопасно начать уничтожать ресурсы: освобождать память (и т. д.), вызывать IoDetachDevice
, IoDeleteDevice
.
указатель на следующее ниже устройство - это тоже ресурс, который мы используем в процессе IO request и уничтожаем в IRP_MN_REMOVE_DEVICE
(вызовом IoDetachDevice
). действительно ли правильный вызов IofCallDriver(_nextDeviceObject, Irp);
(во время обработки некоторого запроса ввода-вывода) после вызова IoDetachDevice(_nextDeviceObject);
(внутри IRP_MN_REMOVE_DEVICE
)? потому что это удаление блокировок (или я использую здесь защиту от рандауна) всегда используется в функциях и драйверах фильтров. для драйвера шины, где у нас обычно нет указателя на следующее более низкое устройство (PDO не подключен к другому устройству, когда FDO подключен к PDO и фильтр всегда к чему-то прикреплен) - может быть и не нужны замки (или защита от износа вообще). это зависит - существуют ли другие ресурсы - используются и уничтожаются (при удалении).
а для устройств шины - обычная ситуация, когда мы получили IRP_MN_REMOVE_DEVICE
2 раза - сначала перед устройством, помеченным как RemovePending
- поэтому переходим к пункту 4. и после устройства, помеченного как RemovePending
(поэтому устройство не было включено в последний ответ драйвера шины на IRP_MN_QUERY_DEVICE_RELATIONS запрос на BusRelations) окончательно уничтожаем ресурсы и вызываем IoDeleteDevice
person
RbMm
schedule
01.08.2017