📄 bulkpnp.c
字号:
KIRQL oldIrql;
NTSTATUS ntStatus;
PDEVICE_EXTENSION deviceExtension;
BulkUsb_DbgPrint(3, ("HandleQueryStopDevice - begins\n"));
//
// initialize variables
//
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
//
// If we can stop the device, we need to set the QueueState to
// HoldRequests so further requests will be queued.
//
KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
SET_NEW_PNP_STATE(deviceExtension, PendingStop);
deviceExtension->QueueState = HoldRequests;
KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
//
// wait for the existing ones to be finished.
// first, decrement this operation
//
BulkUsb_DbgPrint(3, ("HandleQueryStopDevice::"));
BulkUsb_IoDecrement(deviceExtension);
KeWaitForSingleObject(&deviceExtension->StopEvent,
Executive,
KernelMode,
FALSE,
NULL);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoSkipCurrentIrpStackLocation(Irp);
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
BulkUsb_DbgPrint(3, ("HandleQueryStopDevice - ends\n"));
return ntStatus;
}
NTSTATUS
HandleCancelStopDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine services Irp of minor type IRP_MN_CANCEL_STOP_DEVICE
Arguments:
DeviceObject - pointer to device object
Irp - I/O request packet sent by the pnp manager.
Return Value:
NT value
--*/
{
KIRQL oldIrql;
KEVENT event;
NTSTATUS ntStatus;
PDEVICE_EXTENSION deviceExtension;
BulkUsb_DbgPrint(3, ("HandleCancelStopDevice - begins\n"));
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
//
// Send this IRP down and wait for it to come back.
// Set the QueueState flag to AllowRequests,
// and process all the previously queued up IRPs.
//
// First check to see whether you have received cancel-stop
// without first receiving a query-stop. This could happen if someone
// above us fails a query-stop and passes down the subsequent
// cancel-stop.
//
if(PendingStop == deviceExtension->DeviceState) {
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE)IrpCompletionRoutine,
(PVOID)&event,
TRUE,
TRUE,
TRUE);
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
if(ntStatus == STATUS_PENDING) {
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
ntStatus = Irp->IoStatus.Status;
}
if(NT_SUCCESS(ntStatus)) {
KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
RESTORE_PREVIOUS_PNP_STATE(deviceExtension);
deviceExtension->QueueState = AllowRequests;
ASSERT(deviceExtension->DeviceState == Working);
KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
ProcessQueuedRequests(deviceExtension);
}
}
else {
// spurious Irp
//
// If the device is already in an active state when the driver
// receives this IRP, a function driver simply sets status to
// success and passes the IRP to the next driver. For such a
// cancel-stop IRP, a function driver need not set a completion
// routine.
//
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoSkipCurrentIrpStackLocation(Irp);
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
}
BulkUsb_DbgPrint(3, ("HandleCancelStopDevice - ends\n"));
return ntStatus;
}
NTSTATUS
HandleStopDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine services Irp of minor type IRP_MN_STOP_DEVICE
Arguments:
DeviceObject - pointer to device object
Irp - I/O request packet sent by the pnp manager.
Return Value:
NT status value
--*/
{
KIRQL oldIrql;
NTSTATUS ntStatus;
PDEVICE_EXTENSION deviceExtension;
BulkUsb_DbgPrint(3, ("HandleStopDevice - begins\n"));
//
// initialize variables
//
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
if(WinXpOrBetter == deviceExtension->WdmVersion) {
if(deviceExtension->SSEnable) {
//
// Cancel the timer so that the DPCs are no longer fired.
// Thus, we are making judicious usage of our resources.
// we do not need DPCs because the device is stopping.
// The timers are re-initialized while handling the start
// device irp.
//
KeCancelTimer(&deviceExtension->Timer);
//
// after the device is stopped, it can be surprise removed.
// we set this to 0, so that we do not attempt to cancel
// the timer while handling surprise remove or remove irps.
// when we get the start device request, this flag will be
// reinitialized.
//
deviceExtension->SSEnable = 0;
//
// make sure that if a DPC was fired before we called cancel timer,
// then the DPC and work-time have run to their completion
//
KeWaitForSingleObject(&deviceExtension->NoDpcWorkItemPendingEvent,
Executive,
KernelMode,
FALSE,
NULL);
//
// make sure that the selective suspend request has been completed.
//
KeWaitForSingleObject(&deviceExtension->NoIdleReqPendEvent,
Executive,
KernelMode,
FALSE,
NULL);
}
}
//
// after the stop Irp is sent to the lower driver object,
// the driver must not send any more Irps down that touch
// the device until another Start has occurred.
//
if(deviceExtension->WaitWakeEnable) {
CancelWaitWake(deviceExtension);
}
KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
SET_NEW_PNP_STATE(deviceExtension, Stopped);
KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
//
// This is the right place to actually give up all the resources used
// This might include calls to IoDisconnectInterrupt, MmUnmapIoSpace,
// etc.
//
ReleaseMemory(DeviceObject);
ntStatus = DeconfigureDevice(DeviceObject);
Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = 0;
IoSkipCurrentIrpStackLocation(Irp);
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
BulkUsb_DbgPrint(3, ("HandleStopDevice - ends\n"));
return ntStatus;
}
NTSTATUS
HandleQueryRemoveDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine services Irp of minor type IRP_MN_QUERY_REMOVE_DEVICE
Arguments:
DeviceObject - pointer to device object
Irp - I/O request packet sent by the pnp manager.
Return Value:
NT status value
--*/
{
KIRQL oldIrql;
NTSTATUS ntStatus;
PDEVICE_EXTENSION deviceExtension;
BulkUsb_DbgPrint(3, ("HandleQueryRemoveDevice - begins\n"));
//
// initialize variables
//
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
//
// If we can allow removal of the device, we should set the QueueState
// to HoldRequests so further requests will be queued. This is required
// so that we can process queued up requests in cancel-remove just in
// case somebody else in the stack fails the query-remove.
//
ntStatus = CanRemoveDevice(DeviceObject, Irp);
KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
deviceExtension->QueueState = HoldRequests;
SET_NEW_PNP_STATE(deviceExtension, PendingRemove);
KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
BulkUsb_DbgPrint(3, ("HandleQueryRemoveDevice::"));
BulkUsb_IoDecrement(deviceExtension);
//
// wait for all the requests to be completed
//
KeWaitForSingleObject(&deviceExtension->StopEvent,
Executive,
KernelMode,
FALSE,
NULL);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoSkipCurrentIrpStackLocation(Irp);
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
BulkUsb_DbgPrint(3, ("HandleQueryRemoveDevice - ends\n"));
return ntStatus;
}
NTSTATUS
HandleCancelRemoveDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine services Irp of minor type IRP_MN_CANCEL_REMOVE_DEVICE
Arguments:
DeviceObject - pointer to device object
Irp - I/O request packet sent by the pnp manager.
Return Value:
NT status value
--*/
{
KIRQL oldIrql;
KEVENT event;
NTSTATUS ntStatus;
PDEVICE_EXTENSION deviceExtension;
BulkUsb_DbgPrint(3, ("HandleCancelRemoveDevice - begins\n"));
//
// initialize variables
//
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
//
// We need to reset the QueueState flag to ProcessRequest,
// since the device resume its normal activities.
//
//
// First check to see whether you have received cancel-remove
// without first receiving a query-remove. This could happen if
// someone above us fails a query-remove and passes down the
// subsequent cancel-remove.
//
if(PendingRemove == deviceExtension->DeviceState) {
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE)IrpCompletionRoutine,
(PVOID)&event,
TRUE,
TRUE,
TRUE);
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
if(ntStatus == STATUS_PENDING) {
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
ntStatus = Irp->IoStatus.Status;
}
if(NT_SUCCESS(ntStatus)) {
KeAcquireSpinLock(&deviceExtension->DevStateLock, &oldIrql);
deviceExtension->QueueState = AllowRequests;
RESTORE_PREVIOUS_PNP_STATE(deviceExtension);
KeReleaseSpinLock(&deviceExtension->DevStateLock, oldIrql);
//
// process the queued requests that arrive between
// QUERY_REMOVE and CANCEL_REMOVE
//
ProcessQueuedRequests(deviceExtension);
}
}
else {
//
// spurious cancel-remove
//
// If the device is already started when the driver receives
// this IRP, the driver simply sets status to success and passes
// the IRP to the next driver. For such a cancel-remove IRP, a
// function driver need not set a completion routine. The device
// may not be in the remove-pending state, because, for example,
// the driver failed the previous IRP_MN_QUERY_REMOVE_DEVICE.
//
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoSkipCurrentIrpStackLocation(Irp);
ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp);
}
BulkUsb_DbgPrint(3, ("HandleCancelRemoveDevice - ends\n"));
return ntStatus;
}
NTSTATUS
HandleSurpriseRemoval(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine services Irp of minor type IRP_MN_SURPRISE_REMOVAL
Arguments:
DeviceObject - pointer to device object
Irp - I/O request packet sent by the pnp manager.
Return Value:
NT status value
--*/
{
KIRQL oldIrql;
NTSTATUS ntStatus;
PDEVICE_EXTENSION deviceExtension;
BulkUsb_DbgPrint(3, ("HandleSurpriseRemoval - begins\n"));
//
// initialize variables
//
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -