📄 pnp.c
字号:
NT status code.
--*/
{
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
KIRQL oldIrql;
//
// 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->DevicePnPState) {
status = ForwardAndWait( DeviceObject, Irp );
if(NT_SUCCESS( status )) {
RESTORE_PREVIOUS_PNP_STATE( deviceExtension );
}
// Re-start workthread. omit now.
//
}
else {
//
// spurious cancel-remove
//
status = STATUS_SUCCESS;
}
return status;
}
NTSTATUS PnpRemoveDevice( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
/*++
Routine Description:
Pnp handler to IRP_MN_REMOVE_DEVICE.
Arguments:
deviceExtension - pointer to a device object extension.
Irp - the pointer to PnP IRP_MN_START_DEVICE Irp.
Return Value:
NT status code.
--*/
{
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
KIRQL oldIrql;
ULONG requestCount;
DebugPrint(("+Enter RemoveDevice routine\n" ));
deviceExtension = DeviceObject->DeviceExtension;
// TODO: handle our remove work at first
if ( SurpriseRemoved != deviceExtension->DevicePnPState )
{
//
// If the device is not surprise removed, we should call set interface to FALSE.
// If surprise removed, This step has been called in SurprisedRemoved handle.
//
status = IoSetDeviceInterfaceState( &deviceExtension->InterfaceName, FALSE );
if( !NT_SUCCESS( status ) ){
DebugPrint(( "RemoveDevice: IoSetDeviceInterfaceState failed (%x)\n", status ));
}
}
// set new PNP state
SET_NEW_PNP_STATE(deviceExtension, Removed );
requestCount = SampleIoDecrement( deviceExtension );
ASSERT(requestCount > 0);
requestCount = SampleIoDecrement( deviceExtension );
KeWaitForSingleObject(&deviceExtension->RemoveEvent,
Executive,
KernelMode,
FALSE,
NULL);
Disconnection( deviceExtension );
// Unregister serial DosName and delete register
SerialUndoExternalNaming( deviceExtension );
// delete buffer pool used for device name , dos name and others.
SerialRemoveDevObj( DeviceObject );
RtlFreeUnicodeString( &deviceExtension->InterfaceName );
Disconnection( deviceExtension );
if ( deviceExtension->RxBuffer )
ExFreePool ( deviceExtension->RxBuffer );
if ( deviceExtension->recvContext.RemainderBuffer )
ExFreePool ( deviceExtension->recvContext.RemainderBuffer );
// Pass down the IRP
status = DefaultPnpHandler( DeviceObject, Irp );
IoDetachDevice( deviceExtension->NextLowerDriver );
//
// Free up interface memory
//
IoDeleteDevice( DeviceObject );
DebugPrint(("-Exit RemoveDevice routine\n"));
return status;
}
NTSTATUS
PnpSurpriseRemoval(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Pnp handler to IRP_MN_SURPRISE_REMOVAL.
Arguments:
deviceExtension - pointer to a device object extension.
Irp - the pointer to PnP IRP_MN_START_DEVICE Irp.
Return Value:
NT status code.
--*/
{
KIRQL oldIrql;
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
// set new PNP state
SET_NEW_PNP_STATE(deviceExtension, SurpriseRemoved );
status = IoSetDeviceInterfaceState( &deviceExtension->InterfaceName, FALSE );
if( !NT_SUCCESS( status ) ){
DebugPrint(( "RemoveDevice: IoSetDeviceInterfaceState failed (%x)\n", status ));
}
status = DefaultPnpHandler( DeviceObject, Irp );
return status;
}
NTSTATUS PnpQueryCapabilities( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
/*++
Routine Description:
Pnp handler to IRP_MN_QUERY_CAPABILITIES.
Arguments:
deviceExtension - pointer to a device object extension.
Irp - the pointer to PnP IRP_MN_START_DEVICE Irp.
Return Value:
NT status code.
--*/
{
NTSTATUS status;
PIO_STACK_LOCATION stack;
PDEVICE_CAPABILITIES deviceCapabilities;
PAGED_CODE ();
status = ForwardAndWait( DeviceObject, Irp );
stack = IoGetCurrentIrpStackLocation (Irp);
//
// add our device's capabilities.
//
deviceCapabilities = stack->Parameters.DeviceCapabilities.Capabilities;
//
// thess mean the device is Removeable and NOT surprise removed.
// If user force to surprise remove the device, "Unsafe remove device" dialog will appear.
//
deviceCapabilities->SurpriseRemovalOK = FALSE;
//deviceCapabilities->Removable = TRUE;
status = CompleteRequest( Irp, status, Irp->IoStatus.Information );
SampleIoDecrement( DeviceObject->DeviceExtension );
return status;
}
NTSTATUS DefaultPnpHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PDEVICE_EXTENSION deviceExtension;
deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoSkipCurrentIrpStackLocation( Irp );
return IoCallDriver( deviceExtension->NextLowerDriver, Irp);
}
NTSTATUS ForwardAndWait(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
/*++
Routine Description:
pass down Irp to lower driver and wait for its completion.
Arguments:
deviceExtension - pointer to a device object extension.
Irp - the pointer to PnP IRP_MN_START_DEVICE Irp.
Return Value:
NT status code.
--*/
{
KEVENT event;
NTSTATUS status;
PDEVICE_EXTENSION deviceExtension;
deviceExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
OnRequestComplete, (PVOID) &event, TRUE, TRUE, TRUE);
status = IoCallDriver( deviceExtension->NextLowerDriver, Irp);
if (status == STATUS_PENDING)
{ // wait for completion
KeWaitForSingleObject(
&event,
Executive, // Waiting for reasion of a driver
KernelMode, // Waiting in kernel mode
FALSE, // No alert
NULL); // No timeout
status = Irp->IoStatus.Status;
} // wait for completion
return status;
}
NTSTATUS OnRequestComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,
IN PKEVENT event)
{
KeSetEvent( event, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
#if DBG
PCHAR
PnPMinorFunctionString (
UCHAR MinorFunction
)
/*++
Routine Description:
Print PnP Irp's minor function informaion.
Arguments:
deviceExtension - pointer to a device object extension.
Irp - the pointer to PnP IRP_MN_START_DEVICE Irp.
Return Value:
NT status code.
--*/
{
switch (MinorFunction)
{
case IRP_MN_START_DEVICE:
return "IRP_MN_START_DEVICE";
case IRP_MN_QUERY_REMOVE_DEVICE:
return "IRP_MN_QUERY_REMOVE_DEVICE";
case IRP_MN_REMOVE_DEVICE:
return "IRP_MN_REMOVE_DEVICE";
case IRP_MN_CANCEL_REMOVE_DEVICE:
return "IRP_MN_CANCEL_REMOVE_DEVICE";
case IRP_MN_STOP_DEVICE:
return "IRP_MN_STOP_DEVICE";
case IRP_MN_QUERY_STOP_DEVICE:
return "IRP_MN_QUERY_STOP_DEVICE";
case IRP_MN_CANCEL_STOP_DEVICE:
return "IRP_MN_CANCEL_STOP_DEVICE";
case IRP_MN_QUERY_DEVICE_RELATIONS:
return "IRP_MN_QUERY_DEVICE_RELATIONS";
case IRP_MN_QUERY_INTERFACE:
return "IRP_MN_QUERY_INTERFACE";
case IRP_MN_QUERY_CAPABILITIES:
return "IRP_MN_QUERY_CAPABILITIES";
case IRP_MN_QUERY_RESOURCES:
return "IRP_MN_QUERY_RESOURCES";
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS";
case IRP_MN_QUERY_DEVICE_TEXT:
return "IRP_MN_QUERY_DEVICE_TEXT";
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS";
case IRP_MN_READ_CONFIG:
return "IRP_MN_READ_CONFIG";
case IRP_MN_WRITE_CONFIG:
return "IRP_MN_WRITE_CONFIG";
case IRP_MN_EJECT:
return "IRP_MN_EJECT";
case IRP_MN_SET_LOCK:
return "IRP_MN_SET_LOCK";
case IRP_MN_QUERY_ID:
return "IRP_MN_QUERY_ID";
case IRP_MN_QUERY_PNP_DEVICE_STATE:
return "IRP_MN_QUERY_PNP_DEVICE_STATE";
case IRP_MN_QUERY_BUS_INFORMATION:
return "IRP_MN_QUERY_BUS_INFORMATION";
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
return "IRP_MN_DEVICE_USAGE_NOTIFICATION";
case IRP_MN_SURPRISE_REMOVAL:
return "IRP_MN_SURPRISE_REMOVAL";
default:
return "IRP_MN_?????";
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -