использую обратную схему. событие создаю в приложении, и передаю драйверу.
в драйвере получаю указатель:
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);