Get rid of Bugcheck DRIVER_VERIFIER_DETECTED_VIOLATION (IrqlPsPassive) on ? RRS feed

  • Question

  • Hello,

    I'm currently working on our PC card driver (that worked fine for years). Initially I fixed a problem where the system crashed in Windows 10 due to unexpected sequence of IRP_MJ_DEVICE_CONTROL packets. Now (again Windows 10) the system crashes with DRIVER_VERIFIER_DETECTED_VIOLATION (bug check 0xC4) with arg1=0x002001c ('IrqlPsPassive'). Debugging has shown that this happens when PsCreateSystemThread() is called.

    "Easily" said: Driver verifiier expects that PsCreateSystemThread() is call when running at PASSIVE_LEVEL....

    Unfortunately, I'm not very familiar with programming drivers, and the code I have is very old. I'm able to understand what the code does in general, but at several places I need to trust in the author 's (which isn't available any more, of course) work.

    General workflow of the driver

    In general, IRP_MJ_READ and IRP_MJ_WRITE IRPs are queued to a thread since PC card is avery time consuming task. If this thread does not exit, it will created. If there are no more IRPs occour for some time, the thread will terminate automatically. This process is create using PsCreateSystemThread() function.

    Now the question

    What can/need I to do that this procedure will run at the PASSIVE_LEVEL as expected by the DriverVerifier?

    I hope you can help me. Have much thanks in before.
    Willi K.

    P.S.: Here is some relevant code that may help to understand what happens:

    // Code (simplified view)
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDrvObj, ...)
        pDrvObj->MajorFunction[IRP_MJ_READ] = MyDrv_ReadWrite;
        pDrvObj->MajorFunction[IRP_MJ_WRITE] = MyDrv_ReadWrite;
        PIO_STACK_LOCATION  pIrpStack;
        pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
        switch (pIrpStack->MajorFunction) 
            case IRP_MJ_READ:
            case IRP_MJ_WRITE:
                Status = MyDrv_QueueIrpToThread(pIrp, ...);
    NTSTATUS MyDrv_QueueIrpToThread(PIRP pIrp, PVOID pData)
        OBJECT_ATTRIBUTES ObjAttributes;
        InitializeObjectAttributes(&ObjAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
        Status = PsCreateSystemThread(&hThread, (ACCESS_MASK) 0L, &ObjAttributes, (HANDLE) 0L, NULL, MyDrv_Thread, pData);
    VOID MyDrv_Thread(PVOID pData)

    • Edited by Willi K Tuesday, May 29, 2018 3:25 PM Improve code cample
    Tuesday, May 29, 2018 3:25 PM


  • First, just because it worked up until now, does not mean that it is bug-free.

    In your case, your MyDrv_ReadWrite dispatch routine may be called at IRQL 2 (DISPATCH_LEVEL), and calling PsCreateSystemThread from that IRQL is not allowed. It appears that the overall design of your driver needs work. Usually, DriverEntry routine would create the thread and the dispatch routine will add requests to a queue that is then worked off by the system thread, thereby avoiding the problem that you're now seeing. In a nutshell, your driver's architecture will need to be reworked.


    Azius Developer Training Windows device driver, internals, security, & forensics training and consulting. Blog at

    Tuesday, May 29, 2018 6:24 PM