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

📄 pnp.c

📁 好东东
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -