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

📄 pnp.c

📁 如题:POLAR LPC23XX-EK_DEMO software_Keil
💻 C
📖 第 1 页 / 共 4 页
字号:

                // Reset this flag so new IOCTL and IO Irp processing will be re-enabled
        deviceExtension->StopDeviceRequested = FALSE;
        Irp->IoStatus.Status = STATUS_SUCCESS;
        break; // end, case IRP_MN_CANCEL_STOP_DEVICE

	case IRP_MN_QUERY_CAPABILITIES: {

		PDEVICE_CAPABILITIES pdc;
		KEVENT event;
        //
        // Send this down to the PDO first
        //

        KeInitializeEvent (&event, NotificationEvent, FALSE);
        IoCopyCurrentIrpStackLocationToNext (Irp);

        IoSetCompletionRoutine (Irp,
                                UsbCom_IrpCompletionRoutine,
                                &event,
                                TRUE,
                                TRUE,
                                TRUE);

        ntStatus = IoCallDriver (stackDeviceObject, Irp);

        if (STATUS_PENDING == ntStatus) {
            // wait for it...

            ntStatus = KeWaitForSingleObject (&event,
                                            Executive,
                                            KernelMode,
                                            FALSE, // Not allertable
                                            NULL); // No timeout structure

            ASSERT (STATUS_SUCCESS == ntStatus);

            ntStatus = Irp->IoStatus.Status;
        }
        if (NT_SUCCESS(ntStatus)) {

            //irpStack = IoGetCurrentIrpStackLocation(Irp);
			pdc = irpStack->Parameters.DeviceCapabilities.Capabilities;

			// Allow surprise removals...
			DbgPrint("[ss] Allow surprise removals -- \n");
			pdc->SurpriseRemovalOK = TRUE;

        }

        UsbCom_DecrementIoCount(DeviceObject);

		DbgPrint("Allow surprise removals\n");	

        return ntStatus;    
	}

    case IRP_MN_STOP_DEVICE:

        // The PnP Manager sends this IRP to stop a device so it can reconfigure
        // its hardware resources. The PnP Manager only sends this IRP if a prior
        // IRP_MN_QUERY_STOP_DEVICE completed successfully.


        // Cancel any pending io requests.  (there shouldn't be any)
        //UsbCom_CancelPendingIo( DeviceObject );
        
		//
		// If any pipes are still open, call USBD with URB_FUNCTION_ABORT_PIPE
        // This call will also close the pipes; if any user close calls get through,
        // they will be noops
        UsbCom_AbortPipes( DeviceObject );
		
		
		//
        // Send the select configuration urb with a NULL pointer for the configuration
        // handle, this closes the configuration and puts the device in the 'unconfigured'
        // state.
        //
        ntStatus = UsbCom_StopDevice(DeviceObject);
        Irp->IoStatus.Status = ntStatus;

		break; // end, case IRP_MN_STOP_DEVICE

    case IRP_MN_QUERY_REMOVE_DEVICE:

        //  In response to this IRP, drivers indicate whether the device can be
        //  removed without disrupting the system.
        //  If a driver determines it is safe to remove the device,
        //  the driver completes any outstanding I/O requests, arranges to hold any subsequent
        //  read/write requests, and sets Irp->IoStatus.Status to STATUS_SUCCESS. Function
        //  and filter drivers then pass the IRP to the next-lower driver in the device stack.
        //  The underlying bus driver calls IoCompleteRequest.

        //  If a driver sets STATUS_SUCCESS for this IRP, the driver must not start any
        //  operations on the device that would prevent that driver from successfully completing
        //  an IRP_MN_REMOVE_DEVICE for the device. If a driver in the device stack determines
        //  that the device cannot be removed, the driver is not required to pass the
        //  query-remove IRP down the device stack. If a query-remove IRP fails, the PnP Manager
        //  sends an IRP_MN_CANCEL_REMOVE_DEVICE to the device stack, notifying the drivers for
        //  the device that the query has been cancelled and that the device will not be removed.

        // It is possible to receive this irp when the device has not been started
        if (!deviceExtension->DeviceStarted) { // if get when never started, just pass on
            DbgPrint("UsbCom_ProcessPnPIrp() IRP_MN_QUERY_STOP_DEVICE when device not started\n");
            IoSkipCurrentIrpStackLocation (Irp);
            ntStatus = IoCallDriver (deviceExtension->TopOfStackDeviceObject, Irp);
            UsbCom_DecrementIoCount(DeviceObject);

            return ntStatus;
        }

                // Once RemoveDeviceRequested is set no new IOCTL or read/write irps will be passed
                // down the stack to lower drivers; all will be quickly failed
       deviceExtension->RemoveDeviceRequested = TRUE;

        // Wait for any io request pending in our driver to
        // complete before returning success.
                // This  event is set when deviceExtension->PendingIoCount goes to 1
        waitStatus = KeWaitForSingleObject(
                    &deviceExtension->NoPendingIoEvent,
                    Suspended,
                    KernelMode,
                    FALSE,
                    NULL);


        Irp->IoStatus.Status = STATUS_SUCCESS;
        break; // end, case IRP_MN_QUERY_REMOVE_DEVICE

    case IRP_MN_CANCEL_REMOVE_DEVICE:

                // The PnP Manager uses this IRP to inform the drivers
                // for a device that the device will not be removed.
                // It is sent only after a successful IRP_MN_QUERY_REMOVE_DEVICE.

        if (!deviceExtension->DeviceStarted) { // if get when never started, just pass on
            DbgPrint("UsbCom_ProcessPnPIrp() IRP_MN_CANCEL_REMOVE_DEVICE when device not started\n");
            IoSkipCurrentIrpStackLocation (Irp);
            ntStatus = IoCallDriver (deviceExtension->TopOfStackDeviceObject, Irp);
            UsbCom_DecrementIoCount(DeviceObject);
            return ntStatus;
        }

                // Reset this flag so new IOCTL and IO Irp processing will be re-enabled
        deviceExtension->RemoveDeviceRequested = FALSE;
        Irp->IoStatus.Status = STATUS_SUCCESS;

        break; // end, case IRP_MN_CANCEL_REMOVE_DEVICE
#if 1
    case IRP_MN_SURPRISE_REMOVAL: {
	
        DbgPrint("UsbCom_ProcessPnPIrp() IRP_MN_SURPRISE_REMOVAL FDO=%08x\n", DeviceObject );
		
	
		IoSetDeviceInterfaceState ( &deviceExtension->DeviceNameLink, FALSE);

        // For a surprise-style device removal ( i.e. sudden cord yank ),
        // the physical device has already been removed so the PnP Manager sends
        // the remove IRP without a prior query-remove. A device can be in any state
        // when it receives a remove IRP as a result of a surprise-style removal.

        // match the inc at the begining of the dispatch routine
        UsbCom_DecrementIoCount(DeviceObject);

        //
        // Once DeviceRemoved is set no new IOCTL or read/write irps will be passed
        // down the stack to lower drivers; all will be quickly failed
        //
        deviceExtension->DeviceRemoved = TRUE;

        // Cancel any pending io requests; we may not have gotten a query first!
        //UsbCom_CancelPendingIo( DeviceObject );

        // If any pipes are still open, call USBD with URB_FUNCTION_ABORT_PIPE
        // This call will also close the pipes; if any user close calls get through,
        // they will be noops
        //UsbCom_AbortPipes( DeviceObject );

        //
        // Mark this handled
        //
        Irp->IoStatus.Status = STATUS_SUCCESS;

        // We don't explicitly wait for the below driver to complete, but just make
        // the call and go on, finishing cleanup
        IoCopyCurrentIrpStackLocationToNext(Irp);

        ntStatus = IoCallDriver(stackDeviceObject,
                                Irp);
        return ntStatus;
	}
	break;
#else

    case IRP_MN_SURPRISE_REMOVAL:
        DbgPrint("UsbCom_ProcessPnPIrp() IRP_MN_SURPRISE_REMOVAL\n");

		GlobalPdaCount = 0;
		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = 0;

		IoSkipCurrentIrpStackLocation(Irp);
		Status = IoCallDriver(stackDeviceObject, Irp);
		break;
#endif
		
    case IRP_MN_REMOVE_DEVICE:
        DbgPrint("UsbCom_ProcessPnPIrp() IRP_MN_REMOVE_DEVICE FDO=%08x\n", DeviceObject );

        // The PnP Manager uses this IRP to direct drivers to remove a device.
        // For a "polite" device removal, the PnP Manager sends an
        // IRP_MN_QUERY_REMOVE_DEVICE prior to the remove IRP. In this case,
        // the device is in the remove-pending state when the remove IRP arrives.
        // For a surprise-style device removal ( i.e. sudden cord yank ),
        // the physical device has already been removed and the PnP Manager may not
        //  have sent IRP_MN_SURPRISE_REMOVAL. A device can be in any state
        // when it receives a remove IRP as a result of a surprise-style removal.

        // match the inc at the begining of the dispatch routine
        UsbCom_DecrementIoCount(DeviceObject);

        //
        // Once DeviceRemoved is set no new IOCTL or read/write irps will be passed
        // down the stack to lower drivers; all will be quickly failed
        //
        deviceExtension->DeviceRemoved = TRUE;

        // Cancel any pending io requests; we may not have gotten a query first!
        UsbCom_CancelPendingIo( DeviceObject );

        // If any pipes are still open, call USBD with URB_FUNCTION_ABORT_PIPE
        // This call will also close the pipes; if any user close calls get through,
        // they will be noops
        UsbCom_AbortPipes( DeviceObject );
		
        // We don't explicitly wait for the below driver to complete, but just make
        // the call and go on, finishing cleanup
        IoCopyCurrentIrpStackLocationToNext(Irp);

        ntStatus = IoCallDriver(stackDeviceObject,
                                Irp);
        //
        // The final decrement to device extension PendingIoCount == 0
                // will set deviceExtension->RemoveEvent, enabling device removal.
                // If there is no pending IO at this point, the below decrement will be it.
        //
        UsbCom_DecrementIoCount(DeviceObject);

        // wait for any io request pending in our driver to
        // complete for finishing the remove

        KeWaitForSingleObject(
                    &deviceExtension->RemoveEvent,
                    Suspended,
                    KernelMode,
                    FALSE,
                    NULL);

        //
        // Delete the link and FDO we created
        //
        UsbCom_RemoveDevice(DeviceObject);


        DbgPrint("UsbCom_ProcessPnPIrp() Detaching from %08X\n",
                         deviceExtension->TopOfStackDeviceObject);

		//
		// We're cleaning up here.  One reason we're cleaning up
		// is that we couldn't allocate space for the directory
		// name or the symbolic link.
		//
		if (deviceExtension->SymbolicLinkName.Buffer &&
			deviceExtension->CreatedSymbolicLink) {
        
			IoDeleteSymbolicLink (&deviceExtension->SymbolicLinkName);

		}

		//
		// We're cleaning up here.  One reason we're cleaning up
		// is that we couldn't allocate space for the NtNameOfPort.
		//

		if ((deviceExtension->DeviceName.Buffer != NULL)
				&& deviceExtension->CreatedSerialCommEntry) {

			ntStatus = RtlDeleteRegistryValue(RTL_REGISTRY_DEVICEMAP, SERIAL_DEVICE_MAP,
										 deviceExtension->DeviceName.Buffer);

			if (!NT_SUCCESS(ntStatus)) {
				DbgPrint("Couldn't delete value entry \n");
			}
		}

        IoDetachDevice(deviceExtension->TopOfStackDeviceObject);

        DbgPrint("UsbCom_ProcessPnPIrp() Deleting %08X\n",
                         DeviceObject);

		if (deviceExtension->DeviceName.Buffer != NULL) {
			ExFreePool(deviceExtension->DeviceName.Buffer);
		}

		if (deviceExtension->SymbolicLinkName.Buffer != NULL) {
			ExFreePool(deviceExtension->SymbolicLinkName.Buffer);
		}
        
		IoDeleteDevice (DeviceObject);

        return ntStatus; // end, case IRP_MN_REMOVE_DEVICE


    default:

        //
        // In this case we must not touch the status. As ntstatus is
        // STATUS_SUCCESS, we will skip the failure case and pass down the IRP
        // untouched.
        //
        DbgPrint("UsbCom_ProcessPnPIrp() Minor PnP IOCTL not handled\n");
    } /* case MinorFunction  */


    if (!NT_SUCCESS(ntStatus)) {

        // if anything went wrong, return failure  without passing Irp down
        Irp->IoStatus.Status = ntStatus;
        IoCompleteRequest (Irp,
                                           IO_NO_INCREMENT
                                           );

        UsbCom_DecrementIoCount(DeviceObject);

        DbgPrint("UsbCom_ProcessPnPIrp() Exit UsbCom_ProcessPnPIrp FAILURE %x\n", ntStatus);
        return ntStatus;
    }

    IoCopyCurrentIrpStackLocationToNext(Irp);

    //
    // All PNP_POWER messages get passed to the TopOfStackDeviceObject
    // we were given in PnPAddDevice
    //

    DbgPrint("UsbCom_ProcessPnPIrp() Passing PnP Irp down, status = %x\n", ntStatus);

    ntStatus = IoCallDriver(stackDeviceObject,
                            Irp);

    UsbCom_DecrementIoCount(DeviceObject);

    DbgPrint("UsbCom_ProcessPnPIrp() Exit UsbCom_ProcessPnPIrp %x\n", ntStatus);

    return ntStatus;
}

⌨️ 快捷键说明

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