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

📄 pnp.c

📁 好东东
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 2005  Changzhi Zhou All Rights Reserved

Module Name:

    pnp.c

Abstract:

    This module works for the handles Plug&Play dispatch.

Environment:

    Kernel mode

Revision History:
	Changzhi Zhou Dec 20  2004

--*/
#include <ntddk.h>
#include <initguid.h>
#include "main.h"
#include "tdiclient.h"
#include "..\inc\wdmioctl.h"

NTSTATUS
SamplePnpDispatch (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++

Routine Description:

    The plug and play dispatch routines.

    Most of these the driver will completely ignore.
    In all cases it must pass on the IRP to the lower driver.

Arguments:

   DeviceObject - pointer to a device object.

   Irp - pointer to an I/O Request Packet.

Return Value:

      NT status code

--*/
{
    PDEVICE_EXTENSION   deviceExtension;
    PIO_STACK_LOCATION  irpStack;
    NTSTATUS            status;
    KEVENT              event;
	KIRQL				oldIrql;

    PAGED_CODE();

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
	irpStack = IoGetCurrentIrpStackLocation(Irp);
    DebugPrint(("Sample %s IRP:0x%x \n", PnPMinorFunctionString(irpStack->MinorFunction), Irp));

	if ( Removed == deviceExtension->DevicePnPState) {
        status = STATUS_DELETE_PENDING;
		return CompleteRequest(Irp, status, 0 );
    }
	status = STATUS_SUCCESS;
	SampleIoIncrement( deviceExtension );
    
    switch (irpStack->MinorFunction) {
    case IRP_MN_START_DEVICE:
		status = PnpStartDevice( DeviceObject, Irp);
		break;
    case IRP_MN_QUERY_STOP_DEVICE:
		status = PnpQueryStopDevice( DeviceObject, Irp );
		return status;
    case IRP_MN_CANCEL_STOP_DEVICE:
		status = PnpCancelStopDevice( DeviceObject, Irp );
		break;
    case IRP_MN_STOP_DEVICE:
        SET_NEW_PNP_STATE(deviceExtension, Stopped);
		SampleIoDecrement( deviceExtension );
 		status = DefaultPnpHandler( DeviceObject, Irp );
		return status;
    case IRP_MN_QUERY_REMOVE_DEVICE:
		status = PnpQueryRemoveDevice( DeviceObject, Irp );
		return status;
    case IRP_MN_CANCEL_REMOVE_DEVICE:
		status = PnpCancelRemoveDevice( DeviceObject, Irp );
		break;
    case IRP_MN_REMOVE_DEVICE:
		status = PnpRemoveDevice( DeviceObject, Irp );        
        return status;
    case IRP_MN_SURPRISE_REMOVAL:
		status = PnpSurpriseRemoval( DeviceObject, Irp );
		SampleIoDecrement( deviceExtension );
        return status;
	case IRP_MN_QUERY_CAPABILITIES:
		return PnpQueryCapabilities( DeviceObject, Irp );
    default:
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(deviceExtension->NextLowerDriver, Irp);
		SampleIoDecrement(deviceExtension);
		return status;
    }
	CompleteRequest( Irp, status, 0 );
    SampleIoDecrement(deviceExtension);
	return status;
}

NTSTATUS PnpStartDevice(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
/*++

Routine Description:

	Pnp handler to IRP_MN_START_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;
    PIO_STACK_LOCATION	irpStack;
	KIRQL				oldIrql;

	deviceExtension = DeviceObject->DeviceExtension;
	status = ForwardAndWait( DeviceObject, Irp);
    if ( !NT_SUCCESS( status ) )
        return CompleteRequest(Irp, status, Irp->IoStatus.Information);

	irpStack = IoGetCurrentIrpStackLocation( Irp );
	//status = CreateWorkThread( deviceExtension );
	//	Open transport address, set clienteventhandler and initialize recvContext.
	status = InitializeConnection( deviceExtension );
	if( NT_SUCCESS( status ) && NT_SUCCESS( Irp->IoStatus.Status ) ){

		status = IoSetDeviceInterfaceState( &deviceExtension->InterfaceName, TRUE );
		if( !NT_SUCCESS( status )){
			DebugPrint(( "StartDevice:  IoSetDeviceInterfaceState failed (%x)\n", status ));
		}
		SET_NEW_PNP_STATE( deviceExtension, Working );
	}
    return status;
}
NTSTATUS
PnpQueryStopDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++

Routine Description:

	Pnp handler to IRP_MN_QUERY_STOP_DEVICE.

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;
    //
    // If we can stop the device, we need to set the QueueState to 
    // PendingStop so further requests will be queued.
    //
    SET_NEW_PNP_STATE(deviceExtension, PendingStop);
    SampleIoDecrement( deviceExtension );

    KeWaitForSingleObject(&deviceExtension->StopEvent,
                          Executive,
                          KernelMode,
                          FALSE,
                          NULL);
	status = DefaultPnpHandler( DeviceObject, Irp );
    return status;
}

NTSTATUS
PnpCancelStopDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++

Routine Description:

	Pnp handler to IRP_MN_CANCEL_STOP_DEVICE.

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;    
    KEVENT            event;
    NTSTATUS          status;
    PDEVICE_EXTENSION deviceExtension;

    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->DevicePnPState) {
		status = ForwardAndWait( DeviceObject, Irp );
        if(NT_SUCCESS( status )) {
            RESTORE_PREVIOUS_PNP_STATE(deviceExtension);
        }
    }
    else {
        status = STATUS_SUCCESS;
    }
    return status;
}

NTSTATUS
PnpQueryRemoveDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++

Routine Description:

	Pnp handler to IRP_MN_QUERY_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.

--*/

{
#define WDM_DELAY_VALUE            (ULONG)(-1 * 20000 * 1000)     // 2s
    KIRQL             oldIrql;
    NTSTATUS          status;
    PDEVICE_EXTENSION deviceExtension;
    LARGE_INTEGER deltaTime;


    deviceExtension		= (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    SampleIoDecrement( deviceExtension );

	deltaTime.LowPart	= WDM_DELAY_VALUE;
	deltaTime.HighPart	= -1;
    //
    // Wait deltaTime for all the requests to be completed.
    // If timeout, that means some Irps haven't be completed.
	// So we will simply return Device_Busy and not pass down to lower driver.
	//
    status = KeWaitForSingleObject(&deviceExtension->StopEvent, 
                          Executive,
                          KernelMode,
                          FALSE,
                          &deltaTime);
	if( STATUS_TIMEOUT == status )
		return CompleteRequest( Irp, STATUS_DEVICE_BUSY, 0 );
    //
    // 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. 
    //
    SET_NEW_PNP_STATE(deviceExtension, PendingRemove );

	status = DefaultPnpHandler( DeviceObject, Irp );
    return status;
}

NTSTATUS
PnpCancelRemoveDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++

Routine Description:

	Pnp handler to IRP_MN_CANEL_REMOVE_DEVICE.

Arguments:

    deviceExtension - pointer to a device object extension.
	Irp				- the pointer to PnP IRP_MN_START_DEVICE Irp.

Return Value:

⌨️ 快捷键说明

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