Драйвер валится с данным кодом при попытке ожидания на событии.
Код выглядит так:
NTSTATUS ntStatus = STATUS_SUCCESS;
PHOOK_EXTENSION pHookExt = (PHOOK_EXTENSION) pDevObj->DeviceExtension;
KIRQL irql;
PIO_STACK_LOCATION pNewIrpStackLocation = NULL;
PIRP pNewIrp = NULL;
KEVENT event;
COMPLETION_CONTEXT context;
DBGPRINT(("HandleAbnormalSituation - current IRQL: %d. \n", KeGetCurrentIrql()));
if(pIrp->Cancel)
{
ntStatus = STATUS_CANCELLED;
CompleteRequest(pIrp, ntStatus, 0);
return ntStatus;
}
RtlZeroMemory(&context, sizeof(context));
pNewIrp = IoAllocateIrp(pHookExt->pDevTarget->StackSize + 1, FALSE);
if(!pNewIrp)
{
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
CompleteRequest(pIrp, ntStatus, 0);
return ntStatus;
}
// Copy original Irp
pNewIrp->MdlAddress = pIrp->MdlAddress;
pNewIrp->Flags = pIrp->Flags;
pNewIrp->AssociatedIrp = pIrp->AssociatedIrp;
pNewIrp->RequestorMode = KernelMode;
pNewIrp->UserBuffer = pIrp->UserBuffer;
pNewIrp->Tail.Overlay.Thread = pIrp->Tail.Overlay.Thread;
pNewIrp->Tail.Overlay.AuxiliaryBuffer = pIrp->Tail.Overlay.AuxiliaryBuffer;
pNewIrp->Tail.Overlay.OriginalFileObject = pIrp->Tail.Overlay.OriginalFileObject;
PIO_STACK_LOCATION irpsOld = IoGetCurrentIrpStackLocation(pIrp);
PIO_STACK_LOCATION irpsNew = IoGetNextIrpStackLocation(pNewIrp);
*irpsNew = *irpsOld;
IoSetNextIrpStackLocation(pNewIrp);
IoCopyCurrentIrpStackLocationToNext(pNewIrp);
IoAcquireCancelSpinLock(&irql);
pIrp->Tail.Overlay.DriverContext[0] = (PVOID) pNewIrp;
IoSetCancelRoutine(pIrp, CancelRoutine);
IoReleaseCancelSpinLock(irql);
KeInitializeEvent(&event, NotificationEvent, FALSE);
context.pEvent = &event;
context.pOldIrp = pIrp;
IoSetCompletionRoutine(pNewIrp, Completion, &context, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(pHookExt->pDevTarget, pNewIrp);
if(ntStatus == STATUS_PENDING)
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); // вот здесь происходит ошибка
CompleteRequest(pIrp, ntStatus, 0);
Ожидание происходит, если IoCallDriver вернет STATUS_PENDING. При этом Completion выглядит так:
if(pIrp->PendingReturned)
{
IoMarkIrpPending(pIrp);
if(pCtx->pEvent)
KeSetEvent(pCtx->pEvent, 0 ,FALSE);
}
if(pCtx->pOldIrp)
pCtx->pOldIrp->IoStatus = pIrp->IoStatus;
IoFreeIrp(pIrp);
Но Completion при этом не вызывается.
Что это может быть?
А>
А> ntStatus = IoCallDriver(pHookExt->pDevTarget, pNewIrp);
А> if(ntStatus == STATUS_PENDING)
А> KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); // вот здесь происходит ошибка
А>
А>Что это может быть?
это плохо прочитанная документация и плохое понимание работы операционки, документацию процитирую, а над остальным предлагаю подумать самому.
Callers of KeWaitForSingleObject must be running at IRQL <= DISPATCH_LEVEL. Usually, the caller must be running at IRQL = PASSIVE_LEVEL and in a nonarbitrary thread context. A call while running at IRQL = DISPATCH_LEVEL is valid if and only if the caller specifies a Timeout of zero. That is, a driver must not wait for a nonzero interval at IRQL = DISPATCH_LEVEL.
на заметку — NULL это не 'Timeout of zero'