博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第一个入门WDM驱动
阅读量:6525 次
发布时间:2019-06-24

本文共 9334 字,大约阅读时间需要 31 分钟。

HelloWDM.h

#pragma once#ifdef __cplusplusextern "C"{#endif#include 
#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 INITCODEextern "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 PAGEDCODENTSTATUS 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 PAGEDCODENTSTATUS 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 PAGEDCODENTSTATUS 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 PAGEDCODENTSTATUS 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 PAGEDCODENTSTATUS 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 PAGEDCODEvoid HelloWDMUnload(IN PDRIVER_OBJECT DriverObject){    PAGED_CODE();    KdPrint(("Enter HelloWDMUnload\n"));    KdPrint(("Leave HelloWDMUnload\n"));}

转载地址:http://qujbo.baihongyu.com/

你可能感兴趣的文章
WCF如何使用X509证书(安装和错误)(二)
查看>>
遍历聚合对象中的元素——迭代器模式(二)
查看>>
Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
查看>>
iOS中--NSArray调用方法详解 (李洪强)
查看>>
java异步操作实例
查看>>
Centos6.8防火墙配置
查看>>
php and web service with wsdl
查看>>
collection set
查看>>
JAVA多线程的问题以及处理【转】
查看>>
【Java面试题】10 abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?...
查看>>
简单记录一次ORA-00600 kcratr_nab_less_than_odr
查看>>
【视频教程】一步步将AppBox升级到Pro版
查看>>
[原]好玩的Linux,关于时间cal命令
查看>>
[ssh]SSH反向通道端口转发,在本地调试微信支付回调
查看>>
Linux学习之CentOS(十八)--与Linux文件和目录管理相关的一些重要命令②
查看>>
vim一些挺方便的功能
查看>>
开源Java时间工具类Joda-Time体验
查看>>
如何新建UML2项目?详细操作步骤介绍
查看>>
[精讲17] 组策略
查看>>
控制流
查看>>