⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pnp.c

📁 基于DDK的驱动间同步调用测试示例程序,DriverA是目标驱动,DriverB是主驱动,test是MFC测试示例
💻 C
📖 第 1 页 / 共 2 页
字号:
        // remove request. It could happen that we did not if
        // someone above us failed a query remove and passed down the
        // subsequent cancel remove request.
        if (PnpStateRemovePending == deviceExtension->PnpState)
        {
            status = DriverB_SynSubmitIrpSync(deviceExtension->LowerDeviceObject, Irp);

            if (NT_SUCCESS(status))
            {
                // restore pnp state, since remove was canceled
                deviceExtension->PnpState = deviceExtension->PreviousPnpState;

                // restart the queues
                DriverB_SynRestartQueues(deviceExtension);
            }
            else
            {
                // Nobody can fail this IRP. This is a fatal error.
                ASSERTMSG("IRP_MN_CANCEL_REMOVE_DEVICE failed. Fatal error!", FALSE);

                DriverB_SynDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
            }
        }
        else
        {
            // Spurious cancel remove request so we just complete it
            status = STATUS_SUCCESS;
        }

        break;

   case IRP_MN_SURPRISE_REMOVAL:

        // The device has been unexpectedly removed from the machine
        // and is no longer available for I/O.
        // We must return device and memory resources,
        // disable interfaces. We will defer failing any outstanding
        // request to IRP_MN_REMOVE.

        // stall all the queues
        DriverB_SynStallQueues(deviceExtension);

        // flush pending io list
        DriverB_SynInvalidateIo(&deviceExtension->IoLock, STATUS_NO_SUCH_DEVICE);

        // update pnp state
        deviceExtension->PnpState = PnpStateSurpriseRemoved;

        // Return any resources acquired during device startup.
        DriverB_SynFreeResources(deviceExtension);

        // We must set Irp->IoStatus.Status to STATUS_SUCCESS before
        // passing it down.
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoSkipCurrentIrpStackLocation (Irp);
        
        status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);

        // Adjust the active I/O count
        DriverB_SynReleaseRemoveLock(deviceExtension);

        DriverB_SynDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

        return status;

   case IRP_MN_REMOVE_DEVICE:

        // The Plug & Play system has dictated the removal of this device.  We
        // have no choice but to detach and delete the device object.

        if (deviceExtension->PnpState != PnpStateSurpriseRemoved)
        {
            // flush pending io list
            DriverB_SynInvalidateIo(&deviceExtension->IoLock, STATUS_NO_SUCH_DEVICE);

            DriverB_SynFreeResources(deviceExtension);
        }

        // Update our PnP state
        deviceExtension->PnpState = PnpStateRemoved;

        DriverB_SynReleaseRemoveLock(deviceExtension);
        DriverB_SynWaitForSafeRemove(deviceExtension);

        // Send the remove IRP down the stack.
        Irp->IoStatus.Status = STATUS_SUCCESS;
        IoSkipCurrentIrpStackLocation (Irp);
        status = IoCallDriver (deviceExtension->LowerDeviceObject, Irp);

        // Detach our device object from the device stack
        IoDetachDevice(deviceExtension->LowerDeviceObject);
        
        RtlInitUnicodeString(&win32Name, L"\\??\\DriverBDevice");
        IoDeleteSymbolicLink(&win32Name);

        // free power work item
        IoFreeWorkItem(deviceExtension->PowerWorkItem);

        // attempt to delete our device object
        IoDeleteDevice(deviceExtension->DeviceObject);

        DriverB_SynDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

        return status;

    case IRP_MN_QUERY_CAPABILITIES:

        // Check the device capabilities struct
        deviceCapabilities = 
            irpStack->Parameters.DeviceCapabilities.Capabilities;

        if (deviceCapabilities->Version != 1 ||
            deviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES))
        {
            // We don't support this version. Fail the request
            break;
        }

        // Pass the IRP down
        status = DriverB_SynSubmitIrpSync(deviceExtension->LowerDeviceObject, Irp);

        // Lower drivers have finished their operation, so now
        // we can finish ours.
        if (NT_SUCCESS(status)) 
        {
            //*****************************************************************
            //*****************************************************************
            // TODO: Override the device capabilities 
            //       set by the underlying drivers here.
            //*****************************************************************
            //*****************************************************************
        }

        break;

    default:
        // Pass down any unknown requests.
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(deviceExtension->LowerDeviceObject, Irp);

        // Adjust our active I/O count
        DriverB_SynReleaseRemoveLock(deviceExtension);

        DriverB_SynDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

        return status;
    }

    Irp->IoStatus.Status = status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);

    // Adjust the active I/O count
    DriverB_SynReleaseRemoveLock(deviceExtension);

    DriverB_SynDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverB_SynGetDeviceCapabilities
//      Gets device capabilities structure from a bus driver
//
//  Arguments:
//      IN  DeviceExtension
//              our device extension
//
//  Return Value:
//      NT status code
//
NTSTATUS DriverB_SynGetDeviceCapabilities(
    IN  PDRIVERB_SYN_DEVICE_EXTENSION    DeviceExtension
    )
{
    NTSTATUS            status;
    PDEVICE_OBJECT      targetDeviceObject;
    PIRP                irp;
    KEVENT              event;
    IO_STATUS_BLOCK     ioStatus;
    PIO_STACK_LOCATION  irpStack;

    DriverB_SynDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"++");

    // initialize device capabilities structure
    RtlZeroMemory(&DeviceExtension->DeviceCaps, sizeof(DEVICE_CAPABILITIES));
    DeviceExtension->DeviceCaps.Size = sizeof(DEVICE_CAPABILITIES);
    DeviceExtension->DeviceCaps.Version = 1;
    DeviceExtension->DeviceCaps.UINumber = -1;
    DeviceExtension->DeviceCaps.Address = -1;

    targetDeviceObject = IoGetAttachedDeviceReference(DeviceExtension->DeviceObject);

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    irp = IoBuildSynchronousFsdRequest(
                IRP_MJ_PNP,
                targetDeviceObject,
                NULL,
                0,
                NULL,
                &event,
                &ioStatus
                );

    if (irp != NULL)
    {
        irpStack = IoGetNextIrpStackLocation(irp);

        irpStack->MajorFunction = IRP_MJ_PNP;
        irpStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
        irpStack->Parameters.DeviceCapabilities.Capabilities = &DeviceExtension->DeviceCaps;

        irp->IoStatus.Status = STATUS_NOT_SUPPORTED;

        status = IoCallDriver(targetDeviceObject, irp);
        if (status == STATUS_PENDING)
        {
            KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
            status = ioStatus.Status;
        }
    }
    else
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
    }

    ObDereferenceObject(targetDeviceObject);

    DriverB_SynDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. STATUS %x", status);

    return status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -