anatolich
Гость
|
|
« : 26-04-2007 07:27 » |
|
Я реализую следующую схему В приложении создаю событие и поток где его буду ждать В драйвере по имени получаю событие >HANDLE hEvent=NULL; >PKEVENT KSharEvent=NULL; >UNICODE_STRING EvName; >KSharEvent = IoCreateNotificationEvent(&EvName, &hEvent); Теперь по прерыванию в DPC хочу вызвать KeSetEvent Как правильно в DPC передать указатель? Через DEVICE_EXTENSION моего DeviceObject? Или заводить глобальные переменные? Или... ?
|
|
|
Записан
|
|
|
|
Vlaor
Гость
|
|
« Ответ #1 : 26-04-2007 08:14 » |
|
Я все это дело храню в DEVICE_EXTENSION. Может конечно зто и неправильно.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #2 : 27-04-2007 09:15 » |
|
использую обратную схему. событие создаю в приложении, и передаю драйверу. в драйвере получаю указатель: PKEVENT pkEvent; //Указатель на Event (поле status = ObReferenceObjectByHandle( (HANDLE)hEvent, //от приложения EVENT_MODIFY_STATE, *ExEventObjectType, KernelMode, (PVOID*)&pkEvent, NULL);
из драйвера выставляется на уровне не ниже DPC: KeSetEvent(pkEvent,IO_NO_INCREMENT,FALSE);//только FALSE, иначе я должен находится на IQRL==PASSIVE_LEVEL
плюсы такого подхода: при получении ссылки на открытый в ring3 объект - счетчик ссылок на него увеличивается и объект не удалится пока в драйвере не будет вызван ObDereferenceObject(pkEvent); и еще не обязательно событие именовать)) но в любом случае хранить вы KEVENT должны в любом NonPagedPool. DEVICE_EXTENSION для этого тоже подходит. PS а вообще... советую отвыкать от глобальных переменных) меньше ошибок будете делать) PPS как передавать чтото в DPC объявляете в devExt KDPC DpcForIsr; //структура DPC для обработчика ISR
инициализируете: KeInitializeDpc( &devExt->DpcForIsr,&DpcForIsr,devExt->DeviceObject);
используете: KeInsertQueueDpc( &devExt->DpcForIsr, devExt, <-ваш контекст NULL);
обрабатываете: VOID DpcForIsr( IN PKDPC Dpc, IN PDEVICE_OBJECT devObj, //==PVOID DeferredContext, IN PDEVICE_EXTENSION_MY devExt, IN PVOID SysArg2) { SOFT_ICE_DEBUG1; // по идее это все на Dispatch_IRQL выполняется.
//получаем указатель на device (пригодится так как //devExt = DeviceObject->devExt; /* if (devExt->pkEvent) { KeSetEvent(devExt->pkEvent,IO_NO_INCREMENT,FALSE);//только FALSE, иначе я должен находится на IQRL==PASSIVE_LEVEL };*/ KdPrint(("DPCForISR Exit>>>>>>>>>>>>>\n")); return; };
удаляете: KeRemoveQueueDpc(&devExt->DpcForIsr);
|
|
« Последнее редактирование: 30-09-2008 18:23 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
anatolich
Гость
|
|
« Ответ #3 : 27-04-2007 11:06 » |
|
Cnacuбо. Соmpuware мне так все и написала. Подправил только DevExt и как вы сказали, так и делаю. Думаю сейчас как лучше определить, что это моя железка выставила прерывание. Нужно смотреть регистр на PCI контроллере. Где это лучше делать - в Isr и в Dpc не лезть или в DpcForIsr.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #4 : 28-04-2007 07:50 » |
|
только в isr. по результатам проверки вы должны вернуть из isr либо true либо false. это необходимо для того чтобы диспечер прерываний винды не продолжал вызывать чужие isr зарегестрированные на том же прерывании. в ддк про обработчик isr все сказано. dpc нужен для того чтобы event выставлять. потому, что его НЕЛЬЗЯ выставлять на уровне выше DISPATCH_LEVEL , а isr вызывается на уровне DIRQL. раздел: Kernel-Mode Driver Architecture: Windows DDK -> Managing Hardware Priorities
|
|
« Последнее редактирование: 28-04-2007 07:57 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
anatolich
Гость
|
|
« Ответ #5 : 02-05-2007 06:48 » |
|
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #6 : 02-05-2007 09:28 » |
|
угу, все так)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
anatolich
Гость
|
|
« Ответ #7 : 03-05-2007 10:28 » |
|
Заработало в такой связке: в приложении SomeEvent = CreateEvent(NULL, true, false, "SomeEvent"); DeviceIoControl(DevHandle, IOCTL_XXX,&SomeEvent,sizeof(HANDLE),Null, 0, &L, NULL))
в драйвере hEvent = *((PHANDLE) inpBuff = Irp->AssociatedIrp.SystemBuffer); status = ObReferenceObjectByHandle(hEvent,GENERIC_ALL,NULL,KernelMode,&KSharEvent,NULL);
Ну и там уже на DPC KeSetEvent(deviceExtension->SharEvent, IO_NO_INCREMENT, FALSE); KeResetEvent(deviceExtension->SharEvent);
А вот где мне посмотреть, что по этому прерыванию именно моя карточка просигналила? Что, я должен смотреть регистры контроллера PCI своей железки, или где нибудь в свойствах deviceObject ?
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #8 : 03-05-2007 15:50 » |
|
я же говорю - в ISR смотрите регистры своей PCI и!!!! аппаратно сбрасываете прерывание если оно ваше (у вас на плате должны быть такая команда!). И!!!! возвращаете true или false в зависимости от того ваше оно или нет. и вообще была здесь уже такая тема. поиск - рулит) остальное - RTFM хоть раз! Reed The F****** Manual то бишь.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
anatolich
Гость
|
|
« Ответ #9 : 04-05-2007 08:44 » |
|
Ок. У меня контроллер s5920. У него есть регистр (INTCSR). Читая DATA BOOK я понял, что нужно установить Add-On Interrupt Pin в этом регистре, чтобы плата могла давать прерывания. Но она ничего не дает. Видеокарта, сидящая на этом же irq сигналит во всю. А как вы пишете смотреть в ISR, так я смотрю и вижу свой установленный бит и все, но к сожалению не от платы , а от видеокарты. Это я так просто от расстройства расписался. Понятно что нужно по железке информацию читать
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #10 : 04-05-2007 16:40 » |
|
ну тут уж не знаю, чесно говоря... но там вроде, помимо того что INTCSR установить, еще и само прерывание сгенерировать надо?... вроде бы) да еще сконфигурить кучку регистров... это я мельком описание глянул) не могу сейчас долго разбираться, к сожалению...
|
|
« Последнее редактирование: 04-05-2007 16:46 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
|
Ochkarik
|
|
« Ответ #12 : 30-09-2008 18:47 » |
|
эту ссылку уже давали)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
sergeyvass
Интересующийся
Offline
|
|
« Ответ #13 : 11-08-2016 13:17 » |
|
Здравствуйте! У меня похожая ситуация. Имею PCI устройство. Хочу из драйвера, при получении прерывания от устрйоства, активировать событие, которое примет пользовательское приложение. Решил использовать приведённую выше схему. В приложении создал событие, но при попытке передать его драйверу получаю ошибку (Incorrect function ) от DeviceIoControl. С чем этом может быть связано? При этом в драйвере я не сделал обработку запросов. Второй вопрос. Я пишу kmdf драйвер и нашёл несколько статей на эту тему, но для драйверов wdm. Подскажите, пожалуйста, где можно найти аналог для регистрации обработчика событий в kmdf драйвере? DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = EventSysDeviceControl;
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #14 : 12-08-2016 15:13 » |
|
В приложении создал событие, но при попытке передать его драйверу получаю ошибку (Incorrect function ) от DeviceIoControl. С чем этом может быть связано? При этом в драйвере я не сделал обработку запросов.
- не понял? куда передать? какую обработку? Второй вопрос. Я пишу kmdf драйвер и нашёл несколько статей на эту тему, но для драйверов wdm. Подскажите, пожалуйста, где можно найти аналог для регистрации обработчика событий в kmdf драйвере? DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = EventSysDeviceControl; - каких событий?
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
sergeyvass
Интересующийся
Offline
|
|
« Ответ #15 : 23-08-2016 06:27 » |
|
В приложении создал событие, но при попытке передать его драйверу получаю ошибку (Incorrect function ) от DeviceIoControl. С чем этом может быть связано? При этом в драйвере я не сделал обработку запросов.
- не понял? куда передать? какую обработку? Создаю в приложении новое событие: procLaunched.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); Передаю дескриптор на него в драйвер через запрос IOCTL_EVENT_READY: result = DeviceIoControl(hDevice, IOCTL_EVENT_READY, &procLaunched, sizeof(REGISTER_EVENT), NULL, 0, &L, NULL); Для чего я это делаю? Чтобы драйвер обработал запрос IOCTL_EVENT_READY и получил дескриптор на событие, которое будет ждать приложение. Потом драйвер сможет сделать активным это событие и приложение получит сигнал от драйвера (синхронизация работы драйвера и приложения). После вызова DeviceIoControl я получаю ошибку Incorrect function. О какой функции идёт речь и что в ней не корректного? Цитата: sergeyvass от 11-08-2016 13:17 Второй вопрос. Я пишу kmdf драйвер и нашёл несколько статей на эту тему, но для драйверов wdm. Подскажите, пожалуйста, где можно найти аналог для регистрации обработчика событий в kmdf драйвере? Код:
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = EventSysDeviceControl; - каких событий? Обработка драйвером вызовов из приложения функции DeviceIoControl.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #16 : 24-08-2016 10:29 » |
|
как определили IOCTL_EVENT_READY и как обрабатываете? "&L" - эт что такое? переменная L? вид странный)
Добавлено через 1 минуту и 20 секунд: то есть событие тут не причем. вы просто структуру не можете передать в драйвер. я правильно понял?
|
|
« Последнее редактирование: 24-08-2016 10:31 от Ochkarik »
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
sergeyvass
Интересующийся
Offline
|
|
« Ответ #17 : 24-08-2016 11:09 » |
|
как определили IOCTL_EVENT_READY В приложении определил так: #define IOCTL_EVENT_READY CTL_CODE(FILE_DEVICE_CONTROLLER, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS) и как обрабатываете? В драйвере никак не обрабатываю. В примерах которые нашёл рассматриваются wdm драйвера. В них в driverEntry регистрируется callback: DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = EventDispatchIoControl; и уже в нём вызываеется ObReferenceObjectByHandle(). Я же пишу kmdf драйвер и у меня есть структура WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; . Но не понятно какой callback задействовать для обработки DeviceIoControl(). Значит моя ошибка вызвана тем, что я в драйвере не обрабатываю вызов из приложения DeviceIoControl() ?. "&L" - эт что такое? переменная L? вид странный) Да это переменная которую я в дальнейшем не буду использовать. то есть событие тут не причем. вы просто структуру не можете передать в драйвер. я правильно понял? Всё верно.
|
|
|
Записан
|
|
|
|
|
sergeyvass
Интересующийся
Offline
|
|
« Ответ #19 : 19-09-2016 12:45 » |
|
Здравствуйте! Продолжаю писать драйвер для PCI платы. На данном этапе реализована вся требуемая функциональность, однако иногда получаю BSOD ( Ошибка 0хА IRQL_NOT_LESS_OR_EQUAL). Предполагаю, что это связано с неправильным использованием прерываний или обработкой пользовательских запросов. Вот алгоритм работы моего драйвера: 1) При старте пользовательской программы создаю два события CreateEvent() и передаю дескрипторы на них в драйвер. ( В драйвере делаю активными эти события после прерывания от устройства, а в пользовательской программе жду эти события). В обработчике прерываний вызываю WdfInterruptQueueDpcForIsr(devExt->Interrupt); если прерывание от моего устройства. В PLxEvtInterruptDpc() делаю активным то, или иное событие KeSetEvent(devExt->pkEvent, IO_NO_INCREMENT, FALSE); PLxEvtInterruptDpc() и PLxEvtInterruptIsr() вызываются на WdfExecutionLevelDispatch (на сколько я понимаю). Никаких пользовательских данных, кроме дескрипторов на события здесь не обрабатываю. 2) После получения пользователем события, начинаю вычитывать данные, обращаясь к драйверу. Пользовательские запросы на чтение обрабатываю в PLxEvtIoRead(), которое тоже работает на высоком уровне приоритета. Однако тут уже ведётся работа с пользовательскими буферами ввода-вывода. Правильно ли я понимаю, что работать с пользовательскими запросами нужно на PASSIVE_LEVEL, потому что иначе пользовательский буфер может быть выгружен из памяти в момент обработки запроса на чтение? Это и приводит к BSOD? Как понизить уровень приоритета обработчика запросов на чтение?
|
|
« Последнее редактирование: 19-09-2016 12:55 от sergeyvass »
|
Записан
|
|
|
|
sergeyvass
Интересующийся
Offline
|
|
« Ответ #20 : 22-09-2016 11:04 » |
|
Сейчас читаю статью о прерываниях и понимаю, что в предыдущем посте написал ерунду. Простите, пожалуйста.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #21 : 22-09-2016 11:44 » |
|
это ничего) ну тут я полной ерунды не заметил, просто все в одну кучку получилось) вопрос вроде короткий а цепь объяснений будет длинная и нюансов много)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
|