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

📄 usbfx2lk_pnp.cpp

📁 基于vc++6.0环境的cypress USB 驱动源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                           OsrCsqCompleteCancelledIoIrp);
#else // W2K3
    status = IoCsqInitialize(&devExt->CancelSafeIoQueue,
                           OsrCsqInsertIoIrp,
                           OsrCsqRemoveIoIrp,
                           OsrCsqPeekNextIoIrp,
                           OsrCsqAcquireIoLock,
                           OsrCsqReleaseIoLock,
                           OsrCsqCompleteCancelledIoIrp);
#endif // W2K3


    if(!NT_SUCCESS(status)) {
        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO,
            ("UsbFx2LkAddDevice: IoCsqInitialize Error 0x%x (%s)\n",status,OsrNtStatusToString(status)));
        IoDeleteDevice(devExt->FunctionalDeviceObject);
        return status;
    }

    //
    // Register the Device Interface for the Device.   This will allow users to use the 
    // SetupDi interface API to connect to these devices.
    //
    status = IoRegisterDeviceInterface(PPhysicalDeviceObject,&GUID_OSR_USBFX2LK_INTERFACE,
                                       NULL,
                                       &devExt->InterfaceName);

    if(!NT_SUCCESS(status)) {
        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO,
            ("UsbFx2LkAddDevice: IoRegisterDeviceInterface Error 0x%x (%s)\n",status,OsrNtStatusToString(status)));
        IoDeleteDevice(pFunctionalDeviceObject);
        return status;
    }

    //
    // Attach the FDO to the PDO.   Remember to save the returned Device Object Address.  This
    // is the address of the Underlying PDO to which PnP and Power requests should be sent.
    //
    devExt->DeviceToSendIrpsTo = IoAttachDeviceToDeviceStack(devExt->FunctionalDeviceObject,
                                             devExt->PhysicalDeviceObject);

    if(!devExt->DeviceToSendIrpsTo) {
        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO,
            ("UsbFx2LkAddDevice: IoAttachDeviceToDeviceStack Error 0x%x (%s)\n",status,OsrNtStatusToString(status)));
        RtlFreeUnicodeString(&devExt->InterfaceName);
        IoDeleteDevice(devExt->FunctionalDeviceObject);
        return status;
    }

    //
    // Tell the I/O Manager to user Direct I/O for our reads/writes
    //
    devExt->FunctionalDeviceObject->Flags |= DO_DIRECT_IO;
    
    //
    // See if we can set the Power pageable flag.  We should because
    // we are not in the power pageable Path.
    //
    if(devExt->DeviceToSendIrpsTo->Flags & DO_POWER_PAGABLE) {
        devExt->FunctionalDeviceObject->Flags |= DO_POWER_PAGABLE;
    }

    //
	// Clear the Device Initializing bit. This indicates to the I/O
    //  manager that we are now ready to begin processing requests on
    //  this device
	//
	devExt->FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    //
    // Register with WMI after having cleared the DO_DEVICE_INITIALIZING
    //  flag. This is to ensure that our device is prepared to receive
    //  WMI IRPs as soon as the system wants to start sending them
    //
    status = UsbFx2LkWmiRegistration(devExt);

    if(!NT_SUCCESS(status)) {
        OsrTracePrint(TRACE_LEVEL_ERROR,OSRDBG_PNP_INFO,
            ("UsbFx2LkAddDevice: UsbFx2LkWmiRegistration Error 0x%x (%s)\n",status,OsrNtStatusToString(status)));
        RtlFreeUnicodeString(&devExt->InterfaceName);

        IoDetachDevice(devExt->DeviceToSendIrpsTo);
        IoDeleteDevice(pFunctionalDeviceObject);

        return status;
    }

    //
    // You need to include this function call only when WPP tracing
    //  is enabled on and we're built for Win2K. Do NOT call this until
    //  we have successfully registered with WMI, as this call will 
    //  begin sending WMI requests to the device, which isn't a 
    //  good thing if our WMI module isn't properly initialized
    //
#ifdef WPP_TRACING
#ifdef W2K
    W2KInitializeWPPTracing(pFunctionalDeviceObject,&GlobalRegistryPath);
#endif // W2K
#endif // WPP_TRACING

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("UsbFx2LkAddDevice: Exits\n"));

    return status;
}

///////////////////////////////////////////////////////////////////////////////
//
//  PnpRequestComplete
//
//      We are called at this entry point when an Irp forwarded to the driver
//      below us completes.
//
//
//  INPUTS:
//
//      DeviceObject         - Address of our DEVICE_OBJECT.
//
//      Irp                  - Address of the completing Irp
//
//      Context              -  Address of Event to set
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      STATUS_MORE_PROCESSING_REQUIRED
//
//  IRQL:
//
//      This routine is called at IRQL <= DISPATCH_LEVEL.
//
//  CONTEXT:
//
//      This routine is called in an arbitrary context
//
//  NOTES:
//
///////////////////////////////////////////////////////////////////////////////
#ifndef IoForwardIrpSynchronously
NTSTATUS PnpRequestComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
    PKEVENT pEvent = (PKEVENT) Context;

    UNREFERENCED_PARAMETER(DeviceObject);
    UNREFERENCED_PARAMETER(Irp);

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("PnpRequestComplete: Enter.\n"));

    KeSetEvent(pEvent, 0, FALSE);

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("PnpRequestComplete: Exit\n"));

    //
    // Take the IRP back so that we can continue using it during
    // the IRP_MN_START_DEVICE dispatch routine.
    // NB: we will have to call IoCompleteRequest
    //
    return STATUS_MORE_PROCESSING_REQUIRED;
}
#endif //IoForwardIrpSynchronously

///////////////////////////////////////////////////////////////////////////////
//
//  OsrForwardIrpSynchronous
//
//      We call this entry point when we want to forward an Irp to a 
//      device and we want to wait for the request to complete.  In
//      other words, we want SYNCHRONOUS behavior.
//
//
//  INPUTS:
//
//      TargetDevice         - Address of target device
//
//      Irp                  - Address of the Irp to deliver
//
//  OUTPUTS:
//
//      None.
//
//  RETURNS:
//
//      STATUS_UNSUCESSFUL if Irp could not be forwarded, otherwise
//      returns the status returned by the driver that the Irp was
//      forwarded to.
//
//  IRQL:
//
//      This routine is called at IRQL == PASSIVE_LEVEL.
//
//  CONTEXT:
//
//      This routine is called in an arbitrary context
//
//  NOTES:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS OsrForwardIrpSynchronous(PUSBFX2LK_EXT DevExt,PIRP Irp) 
{
    NTSTATUS    status;

    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("OsrForwardIrpSynchronous: Enter.\n"));

#ifdef IoForwardIrpSynchronously

    if(IoForwardIrpSynchronously(DevExt->DeviceToSendIrpsTo,Irp)) {
        status = Irp->IoStatus.Status;
    } else {
        status = STATUS_UNSUCCESSFUL;
    }

#else //IoForwardIrpSynchronously

    KEVENT      eventWaitLowerDrivers;

    KeInitializeEvent(&eventWaitLowerDrivers, NotificationEvent, FALSE);

    //
    // The BUS DRIVER handles this IRP before we do
    //
    IoCopyCurrentIrpStackLocationToNext(Irp);

    //
    // Call OsrPnpComplete() when this IRP is done...
    //
    IoSetCompletionRoutine(Irp,
                          PnpRequestComplete,
                          &eventWaitLowerDrivers,
                          TRUE,
                          TRUE,
                          TRUE);

    //
    // Send the IRP to the bus driver.  Let's see what HE
    // thinks.
    //
    status = IoCallDriver(DevExt->DeviceToSendIrpsTo, Irp);

    if (status == STATUS_PENDING) {

        OsrWaitForSingleObject(&eventWaitLowerDrivers);

        status = Irp->IoStatus.Status;
    }

#endif //IoForwardIrpSynchronously

    OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO,("OsrForwardIrpSynchronous: Exit.\n"));

    return status;

}

///////////////////////////////////////////////////////////////////////////////
//
// UsbFx2LkPnp
//
//  This routine is called by the IO Manager to process a IRP_MJ_PNP
//  Irp.
//
//
//  INPUTS:
//
//      DeviceObject  -  One of our Device Objects.
//      Irp  -  The Irp to process.
//
//  OUTPUTS:
//
//      None
//
//  RETURNS:
//
//      None
//
//  IRQL:
//
//      IRQL == PASSIVE_LEVEL
//
//  CONTEXT:
//
//      This routine is called either in an arbitrary thread context 
//      or in the context of the System thread, depending on the minor
//      function code. You can find out which by consulting the DDK
//      documentation for the particular minor function code.
//
//  NOTES:
//
//      There are several difficulties implementing Plug and Play.
//      Perhaps the greatest difficulty is deciding precisely how you
//      want your device to work, given the various requests the driver
//      can receive and the states the device can be in.  In our driver,
//      we've decided to implement the following policies:
//
//      1) When a removal of the device is requested, we will reject
//         any new IRPs we receive (completing them with an error
//         status in the dispatch routine).  We will wait until all IRPs
//         that are already present on the device's queue are complete
//         and then allow the remove.
//
//      2) When a stop of the device is requested, we'll queue any new
//         Irps then wait until any IRPs that are presently ACTIVE on the
//         device complete, and then allow the stop.
//
//      3) When a SUPRISE removal of the device is indicated, we
//         process any close, clean-up, power and PnP requests
//         but fail all others. This applies to in process, current 
//         queued and future irps
//
//      Of course, the second complexity in implementing plug and play
//      is getting the logic in your driver correct, so that it works
//      as you intend. According to our experience, this is easier said
//      than done.  We've changed the code in this function now, oh,
//      about ten million times.
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS UsbFx2LkPnp(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
    PIO_STACK_LOCATION ioStack = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS           status  = STATUS_SUCCESS;
    PUSBFX2LK_EXT      devExt  = (PUSBFX2LK_EXT)DeviceObject->DeviceExtension;
    POWER_STATE        powerState;
    BOOLEAN            enableInterface = FALSE;

    //
    // We're guaranteed to be called here at IRQL PASSIVE_LEVEL
    //
    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

    //
    // Increment the count of Outstanding IOs
    //
    OsrIncrementOutstandingIoCount(devExt,__FILE__,__LINE__);

    if (ioStack->MinorFunction <= IRP_MN_SURPRISE_REMOVAL) {

        OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO, 
                      ("OsrPnp: Entered at PnP State %s with Minor Function %s\n", 
                        OsrPrintState(devExt),
                        OsrMinorFunctionToString(ioStack->MajorFunction,
                                                 ioStack->MinorFunction)));

    } else {

        OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_PNP_INFO, 
                      ("OsrPnp: Entered at PnP State %s with unusual Minor Function 0x%x\n", 
                        OsrPrintState(devExt),
                        ioStack->MinorFunction));

    }

      

    //
    // Let's see what we have...
    //
    switch (devExt->DevicePnPState + ioStack->MinorFunction) {

        //
        // STATE:   STOPPED or NEVER_STARTED
        // IRP_MN:  _START_DEVICE
        //
        // We're here if we've received an AddDevice() call, but we
        // have not yet been told it's OK to talk to our device by
        // the PnP Manager.
        //
        // We're also here if we've been stopped for a resource 
        // rebalance 
        //

⌨️ 快捷键说明

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