代码:

///
///
/// Copyright (c) 2014 - <company name here>
///
/// Original filename: HelloWdm.cpp
/// Project          : HelloWdm
/// Date of creation : 2014-07-02
/// Author(s)        : <author name(s)>
///
/// Purpose          : <description>
///
/// Revisions:
///  0000 [2014-07-02] Initial revision.
///
///// $Id$#ifdef __cplusplus
extern "C" {
#endif
#include <ntddk.h>
#include <string.h>
#ifdef __cplusplus
}; // extern "C"
#endif#include "HelloWdm.h"static const GUID WdmHello1 = { 0xf8f8064c, 0xee05, 0x41ea, { 0x99, 0xd5, 0x55, 0x36, 0x5a, 0xb8, 0x17, 0x18 } };
// {F8F8064C-EE05-41ea-99D5-55365AB81718}/*
#ifdef __cplusplus
namespace { // anonymous namespace to limit the scope of this global variable!
#endif
PDRIVER_OBJECT pdoGlobalDrvObj = 0;
#ifdef __cplusplus
}; // anonymous namespace
#endif*/typedef struct _DEVICE_EXTENSION
{PDEVICE_OBJECT pFdo;PDEVICE_OBJECT pNextStackDev;UNICODE_STRING interfaceName;}DEVICE_EXTENSION,*PDEVICE_EXTENSION;NTSTATUS HELLOWDM_DispatchCreateClose(IN PDEVICE_OBJECT     DeviceObject,IN PIRP                    Irp)
{NTSTATUS status = STATUS_SUCCESS;Irp->IoStatus.Status = status;Irp->IoStatus.Information = 0;IoCompleteRequest(Irp, IO_NO_INCREMENT);return status;
}NTSTATUS HELLOWDM_DispatchDeviceControl(IN PDEVICE_OBJECT      DeviceObject,IN PIRP                    Irp)
{NTSTATUS status = STATUS_SUCCESS;PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);switch(irpSp->Parameters.DeviceIoControl.IoControlCode){case IOCTL_HELLOWDM_OPERATION:// status = SomeHandlerFunction(irpSp);break;default:Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;Irp->IoStatus.Information = 0;break;}status = Irp->IoStatus.Status;IoCompleteRequest(Irp, IO_NO_INCREMENT);return status;
}VOID HELLOWDM_DriverUnload(IN PDRIVER_OBJECT       DriverObject)
{KdPrint(("HELLOWDM_DriverUnload...."));
}NTSTATUS HelloWdmAddDevice(PDRIVER_OBJECT pDriverObj,PDEVICE_OBJECT pPhysicalDeviceObj)
{NTSTATUS status = STATUS_UNSUCCESSFUL;PDEVICE_OBJECT pFdo;status = IoCreateDevice(pDriverObj,sizeof(DEVICE_EXTENSION),NULL,FILE_DEVICE_UNKNOWN,0,FALSE,&pFdo);if (!NT_SUCCESS(status)){KdPrint(("IoCreateDevice Error:0x%x",status));return status;}PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pFdo->DeviceExtension;pDevExt->pFdo =   pFdo;pDevExt->pNextStackDev = IoAttachDeviceToDeviceStack(pFdo,pPhysicalDeviceObj);if (pDevExt->pNextStackDev == NULL){KdPrint(("IoAttachDeviceToDeviceStack Error:0x%x",status));IoDeleteDevice(pFdo);return status;}status = IoRegisterDeviceInterface(pPhysicalDeviceObj,&WdmHello1,NULL,&pDevExt->interfaceName);if (!NT_SUCCESS(status)){KdPrint(("IoRegisterDeviceInterface Error:0x%x",status));IoDeleteDevice(pFdo);return status;}KdPrint(("%wZ\n",&pDevExt->interfaceName));status = IoSetDeviceInterfaceState(&pDevExt->interfaceName,TRUE);if (!NT_SUCCESS(status)){KdPrint(("IoSetDeviceInterfaceState Error:0x%x",status));IoDeleteDevice(pFdo);return status;}//设置缓冲区方式pFdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;pFdo->Flags &= ~DO_DEVICE_INITIALIZING;return status;}#pragma  code_seg("PAGE")
NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx,PIRP irp)
{IoSkipCurrentIrpStackLocation(irp);return IoCallDriver(pdx->pNextStackDev,irp);
}#pragma  code_seg("PAGE")
NTSTATUS HandleStartDevice(PDEVICE_EXTENSION pdx,PIRP irp)
{NTSTATUS status = STATUS_UNSUCCESSFUL;KdPrint(("HandleStartDevice enter"));DefaultPnpHandler(pdx,irp);KdPrint(("HandleStartDevice leave"));return status;}#pragma  code_seg("PAGE")
NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx,PIRP irp)
{KdPrint(("HandleRemoveDevice enter"));NTSTATUS status = STATUS_UNSUCCESSFUL;irp->IoStatus.Status = STATUS_SUCCESS;status = DefaultPnpHandler(pdx,irp);IoSetDeviceInterfaceState(&pdx->interfaceName,FALSE);RtlFreeUnicodeString(&pdx->interfaceName);//把FDO从设备栈脱开if (pdx->pNextStackDev){IoDetachDevice(pdx->pNextStackDev);}//删除FDOIoDeleteDevice(pdx->pFdo);KdPrint(("HandleRemoveDevice leave"));return status;}#define  arraySize(p)  (sizeof(p)/sizeof(p[0]))NTSTATUS HelloWdmPnp(PDEVICE_OBJECT pDeviceObj,PIRP pIrp)
{NTSTATUS status = STATUS_UNSUCCESSFUL;PAGED_CODE();//Checked模式下有效,确保运行在irql足够低,允许分页的级别KdPrint(("HelloWdmPnp Enter..."));//获得设备扩展PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDeviceObj->DeviceExtension;//获得当前IO栈PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);static NTSTATUS (*FunTab[])(PDEVICE_EXTENSION ,PIRP ) = {HandleStartDevice,      // IRP_MN_START_DEVICEDefaultPnpHandler,        // IRP_MN_QUERY_REMOVE_DEVICEHandleRemoveDevice,        // IRP_MN_REMOVE_DEVICEDefaultPnpHandler,       // IRP_MN_CANCEL_REMOVE_DEVICEDefaultPnpHandler,        // IRP_MN_STOP_DEVICEDefaultPnpHandler,     // IRP_MN_QUERY_STOP_DEVICEDefaultPnpHandler,       // IRP_MN_CANCEL_STOP_DEVICEDefaultPnpHandler,      // IRP_MN_QUERY_DEVICE_RELATIONSDefaultPnpHandler,      // IRP_MN_QUERY_INTERFACEDefaultPnpHandler,     // IRP_MN_QUERY_CAPABILITIESDefaultPnpHandler,      // IRP_MN_QUERY_RESOURCESDefaultPnpHandler,     // IRP_MN_QUERY_RESOURCE_REQUIREMENTSDefaultPnpHandler,     // IRP_MN_QUERY_DEVICE_TEXTDefaultPnpHandler,       // IRP_MN_FILTER_RESOURCE_REQUIREMENTSDefaultPnpHandler,        // DefaultPnpHandler,       // IRP_MN_READ_CONFIGDefaultPnpHandler,     // IRP_MN_WRITE_CONFIGDefaultPnpHandler,        // IRP_MN_EJECTDefaultPnpHandler,       // IRP_MN_SET_LOCKDefaultPnpHandler,        // IRP_MN_QUERY_IDDefaultPnpHandler,        // IRP_MN_QUERY_PNP_DEVICE_STATEDefaultPnpHandler,      // IRP_MN_QUERY_BUS_INFORMATIONDefaultPnpHandler,       // IRP_MN_DEVICE_USAGE_NOTIFICATIONDefaultPnpHandler,       // IRP_MN_SURPRISE_REMOVAL};ULONG uFunc = pStack->MinorFunction;if (uFunc >= arraySize(FunTab)){status = DefaultPnpHandler(pDevExt,pIrp);return status;}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 uFunc:%d (%s)\n",uFunc, fcnname[uFunc]));status = (*FunTab[uFunc])(pDevExt,pIrp);KdPrint(("HelloWdmPnp leave..."));return status;}#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(IN OUT PDRIVER_OBJECT   DriverObject,IN PUNICODE_STRING      RegistryPath)
{KdPrint(("DriverEntry enter...."));DriverObject->DriverExtension->AddDevice = HelloWdmAddDevice;DriverObject->MajorFunction[IRP_MJ_PNP] = HelloWdmPnp;DriverObject->MajorFunction[IRP_MJ_CREATE] =DriverObject->MajorFunction[IRP_MJ_CLOSE] = HELLOWDM_DispatchCreateClose;DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HELLOWDM_DispatchDeviceControl;DriverObject->DriverUnload = HELLOWDM_DriverUnload;KdPrint(("DriverEntry leave...."));return STATUS_SUCCESS;
}
#ifdef __cplusplus
}; // extern "C"
#endif

INF文件:

;--------- Version Section ---------------------------------------------------[Version]
Signature="$CHICAGO$";
Provider=WorldWang_Device
DriverVer=11/1/2007,3.0.0.3; If device fits one of the standard classes, use the name and GUID here,
; otherwise create your own device class and GUID as this example shows.Class=WorldWangDevice
ClassGUID={F8F8064C-EE05-41ea-99D5-55365AB81718};--------- SourceDiskNames and SourceDiskFiles Section -----------------------; These sections identify source disks and files for installation. They are
; shown here as an example, but commented out.[SourceDisksNames]
1 = "HelloWdm",Disk1,,[SourceDisksFiles]
HelloWdm.sys = 1, ,;--------- ClassInstall/ClassInstall32 Section -------------------------------; Not necessary if using a standard class; 9X Style
[ClassInstall]
Addreg=Class_AddReg; NT Style
[ClassInstall32]
Addreg=Class_AddReg[Class_AddReg]
HKR,,,,%DeviceClassName%
HKR,,Icon,,"-5";--------- DestinationDirs Section -------------------------------------------[DestinationDirs]
YouMark_Files_Driver = 10,System32\Drivers;--------- Manufacturer and Models Sections ----------------------------------[Manufacturer]
%MfgName%=Mfg0[Mfg0]; PCI hardware Ids use the form
; PCI\VEN_aaaa&DEV_bbbb&SUBSYS_cccccccc&REV_dd
;改成你自己的ID
%DeviceDesc%=YouMark_DDI, PCI\VEN_9999&DEV_9999;---------- DDInstall Sections -----------------------------------------------
; --------- Windows 9X -----------------; Experimentation has shown that DDInstall root names greater than 19 characters
; cause problems in Windows 98[YouMark_DDI]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_9X_AddReg[YouMark_9X_AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,HelloWdm.sys
HKR, "Parameters", "BreakOnEntry", 0x00010001, 0; --------- Windows NT -----------------[YouMark_DDI.NT]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_NT_AddReg[YouMark_DDI.NT.Services]
Addservice = HelloWdm, 0x00000002, YouMark_AddService[YouMark_AddService]
DisplayName = %SvcDesc%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %10%\System32\Drivers\HelloWdm.sys[YouMark_NT_AddReg]
HKLM, "System\CurrentControlSet\Services\HelloWdm\Parameters",\
"BreakOnEntry", 0x00010001, 0; --------- Files (common) -------------[YouMark_Files_Driver]
HelloWdm.sys;--------- Strings Section ---------------------------------------------------[Strings]
ProviderName="WorldWang."
MfgName="WorldWang Soft"
DeviceDesc="Hello World WDM!"
DeviceClassName="WorldWang_Device"
SvcDesc="WorldWang"

不知道是什么问题,使用EzDriverInstaller.exe工具加载以后,在IRP_MJ_PNP派遣函数内,都调用次类型为IRP_MN_REMOVE_DEVICE的派遣函数将设备又直接卸载了,真搞不懂什么原因导致的? 希望有人能解答,或者我搞明白后,会编辑文档。

找到问题所在了,在HandleStartDevice函数内,调用DefaultPnpHandler后没有把函数返回状态赋值给status,导致HandleStartDevice始终返回STATUS_UNSUCCESSFUL,因此驱动认为启动设备失败了,然后直接进行卸载操作了。

修改后的HandleStartDevice函数如下:

#pragma  code_seg("PAGE")
NTSTATUS HandleStartDevice(PDEVICE_EXTENSION pdx,PIRP irp)
{NTSTATUS status = STATUS_UNSUCCESSFUL;KdPrint(("HandleStartDevice enter"));status = DefaultPnpHandler(pdx,irp);KdPrint(("HandleStartDevice leave"));return status;}

WDM模式驱动简单例子相关推荐

  1. C#操作MySQL数据库的简单例子

    其实很简单,但是我在网上找的时候却找不到有用的信息,奇怪. 到这里下载驱动 http://www.mysql.com/products/connector/ 下载的包里面有使用的例子. 需要具备的知识 ...

  2. 设计模式—工厂模式之简单工厂模式

    1. 简单工厂模式简介 简单工厂模式(Simple Factory),又被称为"静态工厂方法模式".它属于"创建模式"(创建对象的模式),并且是"工厂 ...

  3. 策略模式与简单工厂模式区别(转)

    最近一直在抽时间研究设计模式,之前对设计模式也有一定的了解,但是都没有平心静气的去研究过,只是了解了一些皮毛,最近打算再深入研究一下,重新打开了设计模式的数据,对之前的疑问一个个的刨根问底,今天看了简 ...

  4. Java设计模式之(工厂模式)--简单工厂模式--工厂方法模式--抽象工厂模式

    工厂模式: 工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂方法模式(Factory Method) 3)抽象工厂模式(Abstract Factory) 简单工厂模 ...

  5. 工厂模式(简单工厂、工厂方法、抽象工厂)

    简单工厂模式 从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决 ...

  6. 你以为工厂模式很简单,可能是因为你懂的只是冰山的一角

    很多人认为工厂模式很简单,只是有一个建造工厂,帮我们进行对象构造而已.那么请尝试回答下以下问题: 1.工厂模式分为几类? 2.GOF 23种设计模式中,工厂方法模式和抽象工厂模式有什么区别? 3.不在 ...

  7. 一个简单例子:贫血模型or领域模型

    转:一个简单例子:贫血模型or领域模型 贫血模型 我们首先用贫血模型来实现.所谓贫血模型就是模型对象之间存在完整的关联(可能存在多余的关联),但是对象除了get和set方外外几乎就没有其它的方法,整个 ...

  8. 设计模式系列——三个工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)...

    转自:http://www.cnblogs.com/stonehat/archive/2012/04/16/2451891.html 设计模式系列--三个工厂模式(简单工厂模式,工厂方法模式,抽象工厂 ...

  9. GOLANG工厂模式、简单工厂模式、抽象工厂模式、创建者模式

    设计模式可以大大提高代码复用性,使得程序的修改更加灵活.另外将各个功能模块抽象解耦出来,在某个模块需要更改时不至于会对整体代码进行修改,解耦的好的话只简单修改几个地方即可以切换某个模块在实现上的切换, ...

最新文章

  1. 网站如何才能吸引用户,增加网站点击率?
  2. 计算机安全的最后一道防线,汪文勇:灾备,数据安全的最后一道防线
  3. java中如何做模糊查询_到底Java里的模糊查询语句该怎么写
  4. 项目太大 传不到服务器,上传大文件的解决方案
  5. java导出mysql数据表的结构生成word文档
  6. 无法复制文件到U盘解决办法
  7. 找到弹窗广告所在的程序文件位置
  8. QQ空间添加背景音乐
  9. 展览 | 2018届中国国际信息通信展览的所见所闻
  10. 机器学习基础-统计学习-SLT
  11. MATLAB学习笔记 MATLAB仿PhotoShop油画/毛玻璃/漩涡/锥形等特效
  12. python can总线_MicroPython教程之TPYBoard v102 CAN总线通信
  13. android chrome 夜间,【科技知识】(暗黑模式)Android安卓版的Chrome谷歌浏览器这样设置暗黑模式(夜间模式)...
  14. SAP License:SAP常见问题与解决办法(汇总帖)
  15. P5638 【CSGRound2】光骓者的荣耀
  16. Android-PickerView系列之介绍与使用篇(一)
  17. MVC详解:mvc是什么?为什么要用MVC?MVC工作原理以及MVC优缺点
  18. [Swift]LeetCode871. 最低加油次数 | Minimum Number of Refueling Stops
  19. mysql数据库环境的搭建
  20. skycc营销软件为我赚取的第一个30万

热门文章

  1. 销售和程序员哪个好_2020阿里云双11程序员种草清单
  2. QT应用程序开发到Android
  3. 请各位博友对Hyper-V的运用终了指摘
  4. FT2000+下LPC中断绑核使用说明
  5. 基于Android电视机的ZigBee智能家居系统设计
  6. boke | 前后端分离中使用JWT保持前端数据的持久化,并自动登录
  7. 使用matlab解压不同层次文件夹中.gz压缩包并另存
  8. 计算平面与平面的交线(附c++实现)
  9. snort + barnyard2如何正确读取snort.unified2格式的数据集并且入库MySQL(图文详解)...
  10. 最新EyouCMS响应式少儿舞蹈培训网站模板源码