第一个入门WDM驱动

HelloWDM.h

#pragma once



#ifdef __cplusplus

extern "C"

{

#endif

#include <ntddk.h>

#ifdef __cplusplus

};

#endif



#define PAGEDCODE code_seg("PAGE")

#define LOCKEDCODE code_seg()

#define INITCODE code_seg("INIT")



#define PAGEDDATA data_seg("PAGE")

#define LOCKEDDATA data_seg()

#define INITDATA data_seg("INIT")



#define arraysize(p) (sizeof(p)/sizeof((p)[0]))



typedef struct _DEVICE_EXTERNSION{

    PDEVICE_OBJECT fdo;

    PDEVICE_OBJECT NextStackDevice;

    UNICODE_STRING ustrDeviceName; //设备名称

    UNICODE_STRING ustrSymLinkName; //符号链接名

}DEVICE_EXTENSION, *PDEVICE_EXTENSION;



//函数声明

NTSTATUS HelloWDMAddDevice(

    IN PDRIVER_OBJECT pDriverObject,

    IN PDEVICE_OBJECT PhySicalDeviceObject);

NTSTATUS HelloWDMPnp(

    IN PDEVICE_OBJECT fdo,

    IN PIRP pIrp);

VOID HelloWDMUnload(IN PDRIVER_OBJECT pDriverObject);

NTSTATUS HelloWDMDispatchRoutine(

    IN PDEVICE_OBJECT fdo,

    IN PIRP pIrp);

extern "C" NTSTATUS DriverEntry(

    IN PDRIVER_OBJECT pDriverObject,

    IN PUNICODE_STRING pRegistryPath);

HelloWDM.cpp

#include "HelloWDM.h"



/************************************************************************

* 函数名称:DriverEntry

* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象

* 参数列表:

      pDriverObject:从I/O管理器中传进来的驱动对象

      pRegistryPath:驱动程序在注册表的中的路径

* 返回 值:返回初始化驱动状态

*************************************************************************/

#pragma INITCODE

extern "C" NTSTATUS DriverEntry(

    IN PDRIVER_OBJECT pDriverObject,

    IN PUNICODE_STRING pRegistryPath)

{

    KdPrint(("Enter DriverEntry\n"));



    pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;

    pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;

    pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = 

    pDriverObject->MajorFunction[IRP_MJ_CREATE] =

    pDriverObject->MajorFunction[IRP_MJ_READ] = 

    pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;

    pDriverObject->DriverUnload = HelloWDMUnload;



    KdPrint(("Leave DriverEntry\n"));

    return STATUS_SUCCESS;

}





/************************************************************************

* 函数名称:HelloWDMAddDevice

* 功能描述:添加新设备

* 参数列表:

      DriverObject:从I/O管理器中传进来的驱动对象

      PhysicalDeviceObject:从I/O管理器中传进来的物理设备对象

* 返回 值:返回添加新设备状态

*************************************************************************/

#pragma PAGEDCODE

NTSTATUS HelloWDMAddDevice(

    IN PDRIVER_OBJECT pDriverObject,

    IN PDEVICE_OBJECT PhySicalDeviceObject)

{

    PAGED_CODE();//只在Check版本中有效

    KdPrint(("Enter HelloWDMAddDevice\n"));



    NTSTATUS status;

    PDEVICE_OBJECT fdo;

    UNICODE_STRING devName;

    RtlInitUnicodeString(&devName, L"\\Device\\MyWDMDevice");

    

    status = IoCreateDevice(

        pDriverObject,

        sizeof(DEVICE_EXTENSION),

        &(UNICODE_STRING)devName,

        FILE_DEVICE_UNKNOWN,

        0, FALSE,

        &fdo);

    if(!NT_SUCCESS(status))

        return status;



    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;

    pdx->fdo = fdo;

    //将此fdo(功能设备对象)挂载在设备堆栈上,并将返回值(下层堆栈的位置),记录在设备扩展结构中

    pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhySicalDeviceObject);

    UNICODE_STRING symLinkName;

    RtlInitUnicodeString(&symLinkName, L"\\??\\HelloWDM");

    pdx->ustrDeviceName = devName;

    pdx->ustrSymLinkName = symLinkName;



    status = IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName, &(UNICODE_STRING)devName);

    if(!NT_SUCCESS(status))

    {

        IoDeleteSymbolicLink(&pdx->ustrSymLinkName);

        status = IoCreateSymbolicLink(&symLinkName, &devName);

        if(!NT_SUCCESS(status))

            return status;

    }



    fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;

    fdo->Flags &= ~DO_DEVICE_INITIALIZING;



    KdPrint(("Leave HelloWDMAddDevice\n"));

    return STATUS_SUCCESS;

}



/************************************************************************

* 函数名称:DefaultPnpHandler

* 功能描述:对PNP IRP进行缺省处理

* 参数列表:

      pdx:设备对象的扩展

      Irp:从IO请求包

* 返回 值:返回状态

*************************************************************************/ 

#pragma PAGEDCODE

NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)

{

    PAGED_CODE();

    KdPrint(("Enter DefaultPnpHandler\n"));

    //略过当前堆栈

    IoSkipCurrentIrpStackLocation(Irp);

    KdPrint(("Leave DefaultPnpHandler\n"));

    //用下层堆栈的驱动设备对象处理此IRP

    return IoCallDriver(pdx->NextStackDevice, Irp);

}



/************************************************************************

* 函数名称:HandleRemoveDevice

* 功能描述:对IRP_MN_REMOVE_DEVICE IRP进行处理

* 参数列表:

      pdx:设备对象的扩展

      Irp:从IO请求包

* 返回 值:返回状态

*************************************************************************/

#pragma PAGEDCODE

NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)

{

    PAGED_CODE();

    KdPrint(("Enter HandleRemoveDevice\n"));



    Irp->IoStatus.Status = STATUS_SUCCESS;

    NTSTATUS status = DefaultPnpHandler(pdx, Irp);

    //删除符号链接

    IoDeleteSymbolicLink(&(UNICODE_STRING)pdx->ustrSymLinkName);



    //从车陂堆栈中卸载此设备对象

    if (pdx->NextStackDevice)

        IoDetachDevice(pdx->NextStackDevice);

    

    //删除设备对象fdo:

    IoDeleteDevice(pdx->fdo);

    KdPrint(("Leave HandleRemoveDevice\n"));

    return status;

}



/************************************************************************

* 函数名称:HelloWDMPnp

* 功能描述:对即插即用IRP进行处理

* 参数列表:

      fdo:功能设备对象

      Irp:从IO请求包

* 返回 值:返回状态

*************************************************************************/

#pragma PAGEDCODE

NTSTATUS HelloWDMPnp(

    IN PDEVICE_OBJECT fdo,

    IN PIRP pIrp)

{

    PAGED_CODE();//确保该例程运行在低于APC_LEVEL的中断优先级的级别上



    KdPrint(("Enter HelloWDMPnp\n"));

    NTSTATUS status = STATUS_SUCCESS;

    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;

    //得到当前IRP的堆栈

    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);

    static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) = 

    {                    

        DefaultPnpHandler,        // IRP_MN_START_DEVICE

        DefaultPnpHandler,        // IRP_MN_QUERY_REMOVE_DEVICE

        HandleRemoveDevice,        // IRP_MN_REMOVE_DEVICE

        DefaultPnpHandler,        // IRP_MN_CANCEL_REMOVE_DEVICE

        DefaultPnpHandler,        // IRP_MN_STOP_DEVICE

        DefaultPnpHandler,        // IRP_MN_QUERY_STOP_DEVICE

        DefaultPnpHandler,        // IRP_MN_CANCEL_STOP_DEVICE

        DefaultPnpHandler,        // IRP_MN_QUERY_DEVICE_RELATIONS

        DefaultPnpHandler,        // IRP_MN_QUERY_INTERFACE

        DefaultPnpHandler,        // IRP_MN_QUERY_CAPABILITIES

        DefaultPnpHandler,        // IRP_MN_QUERY_RESOURCES

        DefaultPnpHandler,        // IRP_MN_QUERY_RESOURCE_REQUIREMENTS

        DefaultPnpHandler,        // IRP_MN_QUERY_DEVICE_TEXT

        DefaultPnpHandler,        // IRP_MN_FILTER_RESOURCE_REQUIREMENTS

        DefaultPnpHandler,        // 

        DefaultPnpHandler,        // IRP_MN_READ_CONFIG

        DefaultPnpHandler,        // IRP_MN_WRITE_CONFIG

        DefaultPnpHandler,        // IRP_MN_EJECT

        DefaultPnpHandler,        // IRP_MN_SET_LOCK

        DefaultPnpHandler,        // IRP_MN_QUERY_ID

        DefaultPnpHandler,        // IRP_MN_QUERY_PNP_DEVICE_STATE

        DefaultPnpHandler,        // IRP_MN_QUERY_BUS_INFORMATION

        DefaultPnpHandler,        // IRP_MN_DEVICE_USAGE_NOTIFICATION

        DefaultPnpHandler,        // IRP_MN_SURPRISE_REMOVAL

    };



    ULONG fcn = stack->MinorFunction;

    if (fcn >= arraysize(fcntab))

    {    // unknown function

        status = DefaultPnpHandler(pdx, pIrp); // some function we don't know about

        return status;

    }    // unknown function



#if DBG

    static char* fcnname[] = 

    {

        "IRP_MN_START_DEVICE",

        "IRP_MN_QUERY_REMOVE_DEVICE",

        "IRP_MN_REMOVE_DEVICE",

        "IRP_MN_CANCEL_REMOVE_DEVICE",

        "IRP_MN_STOP_DEVICE",

        "IRP_MN_QUERY_STOP_DEVICE",

        "IRP_MN_CANCEL_STOP_DEVICE",

        "IRP_MN_QUERY_DEVICE_RELATIONS",

        "IRP_MN_QUERY_INTERFACE",

        "IRP_MN_QUERY_CAPABILITIES",

        "IRP_MN_QUERY_RESOURCES",

        "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",

        "IRP_MN_QUERY_DEVICE_TEXT",

        "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",

        "",

        "IRP_MN_READ_CONFIG",

        "IRP_MN_WRITE_CONFIG",

        "IRP_MN_EJECT",

        "IRP_MN_SET_LOCK",

        "IRP_MN_QUERY_ID",

        "IRP_MN_QUERY_PNP_DEVICE_STATE",

        "IRP_MN_QUERY_BUS_INFORMATION",

        "IRP_MN_DEVICE_USAGE_NOTIFICATION",

        "IRP_MN_SURPRISE_REMOVAL",

    };



    KdPrint(("PNP Request (%s)\n", fcnname[fcn]));

#endif // DBG



    status = (*fcntab[fcn])(pdx, pIrp);

    KdPrint(("Leave HelloWDMPnp\n"));

    return status;

}



/************************************************************************

* 函数名称:HelloWDMDispatchRoutine

* 功能描述:对缺省IRP进行处理

* 参数列表:

      fdo:功能设备对象

      Irp:从IO请求包

* 返回 值:返回状态

*************************************************************************/

#pragma PAGEDCODE

NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo,

                                 IN PIRP Irp)

{

    PAGED_CODE();

    KdPrint(("Enter HelloWDMDispatchRoutine\n"));

    Irp->IoStatus.Status = STATUS_SUCCESS;

    Irp->IoStatus.Information = 0;    // no bytes xfered

    IoCompleteRequest( Irp, IO_NO_INCREMENT );

    KdPrint(("Leave HelloWDMDispatchRoutine\n"));

    return STATUS_SUCCESS;

}



/************************************************************************

* 函数名称:HelloWDMUnload

* 功能描述:负责驱动程序的卸载操作

* 参数列表:

      DriverObject:驱动对象

* 返回 值:返回状态

*************************************************************************/

#pragma PAGEDCODE

void HelloWDMUnload(IN PDRIVER_OBJECT DriverObject)

{

    PAGED_CODE();

    KdPrint(("Enter HelloWDMUnload\n"));

    KdPrint(("Leave HelloWDMUnload\n"));

}

你可能感兴趣的:(入门)