Я хочу чтобы мой драйвер был выгружаемым. Поэтому регистирирую UnloadRoutine.
Но в некоторые моменты работы я не могу выгружать драйвер. И, например, именно в этот момент пришел запрос на выгрузку драйвера, т.е. вызывается UnloadRoutine.
Как отменить выгрузку драйвера в UnloadRoutine? Или это делается не в UnloadRoutine?
VOID UnloadRoutine( IN PDRIVER_OBJECT DriverObject )
{
if (bDoNotUnload) {
//отменить выгрузку???
}
}
Здравствуйте, onyx2, Вы писали:
O>Я хочу чтобы мой драйвер был выгружаемым. Поэтому регистирирую UnloadRoutine.
O>Но в некоторые моменты работы я не могу выгружать драйвер. И, например, именно в этот момент пришел запрос на выгрузку драйвера, т.е. вызывается UnloadRoutine.
O>Как отменить выгрузку драйвера в UnloadRoutine? Или это делается не в UnloadRoutine?
O>
O>VOID UnloadRoutine( IN PDRIVER_OBJECT DriverObject )
O>{
O> if (bDoNotUnload) {
O> //отменить выгрузку???
O> }
O>}
O>
Эта функциональность не будет вызвана (согласно DDK) при опрелененных условиях. Одно из них это наличие ссылки на любой обьект устройства созданный драйвером.
Следовательно в местах критичный для выгрузки, увеличивайте ссылку на свой CDO например, а после этого снимайте ее.
Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
З>Эта функциональность не будет вызвана (согласно DDK) при опрелененных условиях. Одно из них это наличие ссылки на любой обьект устройства созданный драйвером. З>Следовательно в местах критичный для выгрузки, увеличивайте ссылку на свой CDO например, а после этого снимайте ее.
Хм, попробуем...
А я уже было хотел в местах критичных для выгрузки обнулять и востанавливать поле DriverObject->DriverUnload.
Даже не знаю, помогло ли бы это...
Здравствуйте, onyx2, Вы писали:
O>Здравствуйте, Злость, Вы писали:
З>>Эта функциональность не будет вызвана (согласно DDK) при опрелененных условиях. Одно из них это наличие ссылки на любой обьект устройства созданный драйвером. З>>Следовательно в местах критичный для выгрузки, увеличивайте ссылку на свой CDO например, а после этого снимайте ее.
O>Хм, попробуем...
O>А я уже было хотел в местах критичных для выгрузки обнулять и востанавливать поле DriverObject->DriverUnload. O>Даже не знаю, помогло ли бы это...
Очень кривой метод и не рабочий в принципе. Мог бы быть рабочим, если бы была возможность получить spinlock которым защищен доступ к базе driver object (поиск по коду это не вариант, устанешь подправлять для версий).
Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
Здравствуйте, onyx2,
O>Я хочу чтобы мой драйвер был выгружаемым. Поэтому регистирирую UnloadRoutine.
O>Но в некоторые моменты работы я не могу выгружать драйвер. И, например, именно в этот момент пришел запрос на выгрузку драйвера, т.е. вызывается UnloadRoutine.
O>Как отменить выгрузку драйвера в UnloadRoutine? Или это делается не в UnloadRoutine?
--
Лучше не "играться" с UnloadRoutine, а сообщать системе, что драйвер не может быть остановлен и/или выгружен.
Unload не может быть вызвана без посылки драйверу сообщений IRP_MN_QUERY_STOP_DEVICE и IRP_MN_QUERY_REMOVE_DEVICE. Обрабатывайте их корректно — и Ваш драйвер не будет остановлен или выгружен.
Если это не приемлимо и Вы знаете, что именно сейчас останавливать/выгружать драйвер нельзя, сообщите системе, что состояние Вашего драйвера изменилось, вызвав функцию IoInvalidateDeviceState, и далее, обрабатывая PNP_DEVICE_STATE, установите флаг PNP_DEVICE_NOT_DISABLEABLE.
Еще один способ добиться этого (если условие не выгрузки драйвера доступно в user's mode) — обрабатывать в driver co-installer сообщения DIF_PROPERTYCHANGE (для остановки драйвера) или DIF_REMOVE (для uninstall драйвера). Преимущество этого варианта — можно сообщить пользователю об этой ситуации.
[skip]
O>>Как отменить выгрузку драйвера в UnloadRoutine? Или это делается не в UnloadRoutine? ГМ>-- ГМ>Лучше не "играться" с UnloadRoutine, а сообщать системе, что драйвер не может быть остановлен и/или выгружен.
ГМ>Unload не может быть вызвана без посылки драйверу сообщений IRP_MN_QUERY_STOP_DEVICE и IRP_MN_QUERY_REMOVE_DEVICE. Обрабатывайте их корректно — и Ваш драйвер не будет остановлен или выгружен.
ГМ>Если это не приемлимо и Вы знаете, что именно сейчас останавливать/выгружать драйвер нельзя, сообщите системе, что состояние Вашего драйвера изменилось, вызвав функцию IoInvalidateDeviceState, и далее, обрабатывая PNP_DEVICE_STATE, установите флаг PNP_DEVICE_NOT_DISABLEABLE.
ГМ>Еще один способ добиться этого (если условие не выгрузки драйвера доступно в user's mode) — обрабатывать в driver co-installer сообщения DIF_PROPERTYCHANGE (для остановки драйвера) или DIF_REMOVE (для uninstall драйвера). Преимущество этого варианта — можно сообщить пользователю об этой ситуации.
[skip]
Все очень даже верно для PNP драйверов.
Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
Здравствуйте, Злость, Вы писали:
З>[skip]
O>>>Как отменить выгрузку драйвера в UnloadRoutine? Или это делается не в UnloadRoutine?
ГМ>>Unload не может быть вызвана без посылки драйверу сообщений IRP_MN_QUERY_STOP_DEVICE и IRP_MN_QUERY_REMOVE_DEVICE. Обрабатывайте их корректно — и Ваш драйвер не будет остановлен или выгружен.
З>[skip]
З>Все очень даже верно для PNP драйверов.
Не очень. IRP_MN_QUERY_STOP_DEVICE не обязан предшествовать IRP_MN_QUERY_REMOVE_DEVICE, мало того, девайс останавливается только для ребаланса ресурсов, а выключается он сразу, без перехода через состояние "stopped". Следует исключить IRP_MN_QUERY_STOP_DEVICE из вышепреведенного утверждения...
Здравствуйте, straightener, Вы писали:
S>Здравствуйте, Злость, Вы писали:
З>>[skip]
O>>>>Как отменить выгрузку драйвера в UnloadRoutine? Или это делается не в UnloadRoutine?
ГМ>>>Unload не может быть вызвана без посылки драйверу сообщений IRP_MN_QUERY_STOP_DEVICE и IRP_MN_QUERY_REMOVE_DEVICE. Обрабатывайте их корректно — и Ваш драйвер не будет остановлен или выгружен.
З>>[skip]
З>>Все очень даже верно для PNP драйверов. S>Не очень. IRP_MN_QUERY_STOP_DEVICE не обязан предшествовать IRP_MN_QUERY_REMOVE_DEVICE, мало того, девайс останавливается только для ребаланса ресурсов, а выключается он сразу, без перехода через состояние "stopped". Следует исключить IRP_MN_QUERY_STOP_DEVICE из вышепреведенного утверждения...
А там и нет четких фраз что они должны быть последовательными. Сказанно что обрабатывайте обе (правильно) и все будет хорошо.
Правда, Ложь — мне все одно — я имею свое мнение.
Если функция недокументированна — это не значит, что ее не используют все ваши конкуренты в своих продуктах.
Любой строй переходный и отрицать это значит быть закостенелым идиотом.
Здравствуйте, Злость, Вы писали:
З>>>Все очень даже верно для PNP драйверов. S>>Не очень. IRP_MN_QUERY_STOP_DEVICE не обязан предшествовать IRP_MN_QUERY_REMOVE_DEVICE, мало того, девайс останавливается только для ребаланса ресурсов, а выключается он сразу, без перехода через состояние "stopped". Следует исключить IRP_MN_QUERY_STOP_DEVICE из вышепреведенного утверждения...
З>А там и нет четких фраз что они должны быть последовательными. Сказанно что обрабатывайте обе (правильно) и все будет хорошо.
На "выгрузку" влияет только IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_QUERY_STOP_DEVICE, как я уже сказал, — это вопрос "можно ли остановить девайс для изменения его ресурсов", "отшибать" этот запрос следует только если остановка никак не возможна в настоящее время, на выгрузку драйвера остановка никак не влияет.
Здравствуйте, straightener,
O>>>>Как отменить выгрузку драйвера в UnloadRoutine? Или это делается не в UnloadRoutine?
ГМ>>>Unload не может быть вызвана без посылки драйверу сообщений IRP_MN_QUERY_STOP_DEVICE и IRP_MN_QUERY_REMOVE_DEVICE. Обрабатывайте их корректно — и Ваш драйвер не будет остановлен или выгружен.
З>>[skip]
З>>Все очень даже верно для PNP драйверов. S>Не очень. IRP_MN_QUERY_STOP_DEVICE не обязан предшествовать IRP_MN_QUERY_REMOVE_DEVICE, мало того, девайс останавливается только для ребаланса ресурсов, а выключается он сразу, без перехода через состояние "stopped". Следует исключить IRP_MN_QUERY_STOP_DEVICE из вышепреведенного утверждения...
--
Строго говоря, рассматривая только выгрузку драйвера, Вы, скорее всего, правы — для некоторых OS (но не для всех!) возможна ситуация, когда IRP_MN_QUERY_STOP_DEVICE не обязан предшествовать IRP_MN_QUERY_REMOVE_DEVICE.
(Но тогда Вам стоило указать так же и на DIF_PROPERTYCHANGE...) .
Я хотел подчеркнуть, что если драйвер по каким-то причинам нельзя выгружать, то и останавливать его так же, наверное, не стоит.
Здравствуйте, Геннадий Майко, Вы писали:
ГМ>Строго говоря, рассматривая только выгрузку драйвера, Вы, скорее всего, правы — для некоторых OS (но не для всех!) возможна ситуация, когда IRP_MN_QUERY_STOP_DEVICE не обязан предшествовать IRP_MN_QUERY_REMOVE_DEVICE.
Да, в 98/Me pnp менеджер работает по другому, IRP_MN_STOP_DEVICE используется для выключения устройства. Но и там IRP_MN_QUERY_STOP_DEVICE не обязан идти перед IRP_MN_QUERY_REMOVE_DEVICE. Не поручусь только за Висту, но на остальных нет связи между остановкой и выключением...
ГМ>(Но тогда Вам стоило указать так же и на DIF_PROPERTYCHANGE...) .
Да и вообще на идею с коинстолером. Девайс может оказаться в чьем-нибудь списке ремувал релейшенов. Про то, что он автоматически входит в такой список для родительского девайса я вообще молчу И не получит коинстолер в этом случае нифига...
ГМ>Я хотел подчеркнуть, что если драйвер по каким-то причинам нельзя выгружать, то и останавливать его так же, наверное, не стоит.
В принципе согласен. Но остановка — простая, обычно кратковременная, пауза зачастую совершенно не критична. Все зависит от конкретного девайса.