Странная ошибка с кодом ATTEMPTED_SWITCH_FROM_DPC
От: Аноним  
Дата: 07.12.07 15:25
Оценка:
Драйвер валится с данным кодом при попытке ожидания на событии.
Код выглядит так:


    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 при этом не вызывается.
Что это может быть?
Re: Странная ошибка с кодом ATTEMPTED_SWITCH_FROM_DPC
От: Аноним  
Дата: 07.12.07 15:30
Оценка:
А>

А>    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'
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.