驱动学习笔记一:实现一个简单的HelloDriver

原创 2008年09月28日 09:01:00

枉被人叫了这么久的驱动大牛,实际上驱动差的要命,哈哈。现在来补习下驱动知识,写个笔记,反正在学校里也算是个学习的过程吧。以下代码均在VC2008 + WDK2008下编译通过。至于DDK和选择的工具什么的我也不知道怎么说,反正现在可供选择的东西还有详细配置的教程还是比较多的,所以我就不再赘述了。我就直接跳过那些配置文章,直接从代码开始说起吧。至于逆向或者分析bug,这些可能我在文章里就完全不会涉及了…毕竟这个算是我的本行出身,哈哈。另外文中代码使用了C++语言而不是常见的C语言,因为有时候会想用到C++特性而故意为之,当然,做个c版本也是可以的事情。好在两者改写起来并不算十分复杂。

头文件Driver.h:

  1. #pragma once
  2. #ifdef __cplusplus
  3. extern "C"
  4. {
  5. #endif
  6. #include <NTDDK.h>
  7. #ifdef __cplusplus
  8. }
  9. #endif 
  10. #define PAGEDCODE code_seg("PAGE")
  11. #define LOCKEDCODE code_seg()
  12. #define INITCODE code_seg("INIT")
  13. #define PAGEDDATA data_seg("PAGE")
  14. #define LOCKEDDATA data_seg()
  15. #define INITDATA data_seg("INIT")
  16. #define arraysize(p) (sizeof(p)/sizeof((p)[0]))
  17. typedef struct _DEVICE_EXTENSION {
  18.     PDEVICE_OBJECT pDevice;
  19.     UNICODE_STRING ustrDeviceName;  //设备名称
  20.     UNICODE_STRING ustrSymLinkName; //符号链接名
  21. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
  22. // 函数声明
  23. NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);
  24. VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
  25. NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
  26.                                  IN PIRP pIrp);

Driver.cpp:

  1. #include "Driver.h"
  2. /************************************************************************
  3. * 函数名称:DriverEntry
  4. * 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
  5. * 参数列表:
  6.       pDriverObject:从I/O管理器中传进来的驱动对象
  7.       pRegistryPath:驱动程序在注册表的中的路径
  8. * 返回 值:返回初始化驱动状态
  9. *************************************************************************/
  10. #pragma INITCODE
  11. extern "C" NTSTATUS DriverEntry (
  12.             IN PDRIVER_OBJECT pDriverObject,
  13.             IN PUNICODE_STRING pRegistryPath    ) 
  14. {
  15.     NTSTATUS status;
  16.     KdPrint(("Enter DriverEntry/n"));
  17.     //注册其他驱动调用函数入口
  18.     pDriverObject->DriverUnload = HelloDDKUnload;
  19.     pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;
  20.     pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;
  21.     pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
  22.     pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;
  23.     
  24.     //创建驱动设备对象
  25.     status = CreateDevice(pDriverObject);
  26.     KdPrint(("DriverEntry end/n"));
  27.     return status;
  28. }
  29. /************************************************************************
  30. * 函数名称:CreateDevice
  31. * 功能描述:初始化设备对象
  32. * 参数列表:
  33.       pDriverObject:从I/O管理器中传进来的驱动对象
  34. * 返回 值:返回初始化状态
  35. *************************************************************************/
  36. #pragma INITCODE
  37. NTSTATUS CreateDevice (
  38.         IN PDRIVER_OBJECT   pDriverObject) 
  39. {
  40.     NTSTATUS status;
  41.     PDEVICE_OBJECT pDevObj;
  42.     PDEVICE_EXTENSION pDevExt;
  43.     
  44.     //创建设备名称
  45.     UNICODE_STRING devName;
  46.     RtlInitUnicodeString(&devName,L"//Device//MyDDKDevice");
  47.     
  48.     //创建设备
  49.     status = IoCreateDevice( pDriverObject,
  50.                         sizeof(DEVICE_EXTENSION),
  51.                         &(UNICODE_STRING)devName,
  52.                         FILE_DEVICE_UNKNOWN,
  53.                         0, TRUE,
  54.                         &pDevObj );
  55.     if (!NT_SUCCESS(status))
  56.         return status;
  57.     pDevObj->Flags |= DO_BUFFERED_IO;
  58.     pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
  59.     pDevExt->pDevice = pDevObj;
  60.     pDevExt->ustrDeviceName = devName;
  61.     //创建符号链接
  62.     UNICODE_STRING symLinkName;
  63.     RtlInitUnicodeString(&symLinkName,L"//??//HelloDDK");
  64.     pDevExt->ustrSymLinkName = symLinkName;
  65.     status = IoCreateSymbolicLink( &symLinkName,&devName );
  66.     if (!NT_SUCCESS(status)) 
  67.     {
  68.         IoDeleteDevice( pDevObj );
  69.         return status;
  70.     }
  71.     return STATUS_SUCCESS;
  72. }
  73. /************************************************************************
  74. * 函数名称:HelloDDKUnload
  75. * 功能描述:负责驱动程序的卸载操作
  76. * 参数列表:
  77.       pDriverObject:驱动对象
  78. * 返回 值:返回状态
  79. *************************************************************************/
  80. #pragma PAGEDCODE
  81. VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject) 
  82. {
  83.     PDEVICE_OBJECT  pNextObj;
  84.     KdPrint(("Enter DriverUnload/n"));
  85.     pNextObj = pDriverObject->DeviceObject;
  86.     while (pNextObj != NULL) 
  87.     {
  88.         PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
  89.             pNextObj->DeviceExtension;
  90.         //删除符号链接
  91.         UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
  92.         IoDeleteSymbolicLink(&pLinkName);
  93.         pNextObj = pNextObj->NextDevice;
  94.         IoDeleteDevice( pDevExt->pDevice );
  95.     }
  96. }
  97. /************************************************************************
  98. * 函数名称:HelloDDKDispatchRoutine
  99. * 功能描述:对读IRP进行处理
  100. * 参数列表:
  101.       pDevObj:功能设备对象
  102.       pIrp:从IO请求包
  103. * 返回 值:返回状态
  104. *************************************************************************/
  105. #pragma PAGEDCODE
  106. NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
  107.                                  IN PIRP pIrp) 
  108. {
  109.     KdPrint(("Enter HelloDDKDispatchRoutine/n"));
  110.     NTSTATUS status = STATUS_SUCCESS;
  111.     // 完成IRP
  112.     pIrp->IoStatus.Status = status;
  113.     pIrp->IoStatus.Information = 0; // bytes xfered
  114.     IoCompleteRequest( pIrp, IO_NO_INCREMENT );
  115.     KdPrint(("Leave HelloDDKDispatchRoutine/n"));
  116.     return status;
  117. }

build之后的结果如下:

driver

Windows HelloWorld驱动应用

一个简单完整的驱动开发框架仍然很复杂,至少在我看来字很多来个HelloWorld,超简单#include #include #include #include #include extern ...
  • ONE_SIX_MIX
  • ONE_SIX_MIX
  • 2016年07月23日 21:07
  • 758

如何写一个简单的linux驱动

写设备驱动时,了解“用户空间”和“内核空间”之间的区别是非常重要的。         - 内核空间。Linux内核简单并高效地管理着机器的硬件,为用户提供简单并         规范的编程接口...
  • jeason29
  • jeason29
  • 2015年08月14日 15:46
  • 177

HDMI的简单介绍

最近使用IMX6做HDMI的输出显示,记录一下关于HDMI的理解: 高清晰度多媒体接口(High Definition Multimedia Interface,HDMI)是一种数字化视频/音频接口...
  • a421701136
  • a421701136
  • 2016年05月17日 19:36
  • 545

通过内存模拟硬盘实现一个简单的块设备驱动

本文的主要工作是通过硬盘来模拟内存,按照块设备驱动编程的框架实现一个简单的块设备驱动程序。 一、前期的准备工作 1、基本开发环境 Linux内核版本:Linux-3.4.10 开发板 ...
  • TECH_PRO
  • TECH_PRO
  • 2017年05月22日 12:54
  • 727

一个JBPM工作流管理示例(三)

(二)Decisionpackage kellerdu.jbpm.delegation;import org.jbpm.delegation.*;import kellerdu.jbpm.LogsFa...
  • kellerdu
  • kellerdu
  • 2004年11月08日 14:14
  • 5461

简单Linux字符型驱动

Linux驱动分为三种类型:字符型驱动、块设备驱动和杂项网络设备驱动。其结构图如下 首先学习一下最简单的字符型驱动的写法。 字符驱动是指只能一个字节一个字节读写的设备,不能随机读取设备内存中...
  • u010073981
  • u010073981
  • 2016年01月08日 23:29
  • 354

一个简单数据库连接池的实现

一、已实现功能   数据库连接缓存。将数据库连接与线程ID绑定并提供执行数据库操作时检测。数据库连接超时检测。初始化数据库环境,包括初始化数据库,数据库用户,数据库表。 二、代码列表: 1、MySql...
  • huxuemin
  • huxuemin
  • 2016年10月04日 13:09
  • 967

Windows驱动开发WDM (2)- 一个简单的WDM驱动程序

这个例子是从《windows驱动开发技术详解》的光盘上copy的,我只是自己稍微改了一下。   入口函数DriverEntry #pragma INITCODE extern "C" NTST...
  • zj510
  • zj510
  • 2012年11月21日 17:54
  • 6963

关于《竹林蹊径 深入浅出Windows驱动开发》第一个例子在Win7下蓝屏

在尝试运行《竹林蹊径 深入浅出Windows驱动开发》的第一个例子-HelloDRIVER时,在XP下没有问题,但在Win7下却发生蓝屏,蓝屏发生点在于卸载函数DriverUnload。 先看看卸载...
  • qq429205464
  • qq429205464
  • 2016年04月05日 15:16
  • 1418

自己实现一个简单版的HashMap

public class MyHashMap { //默认初始化大小 16 private static final int DEFAULT_INITIAL_CAPACI...
  • uhgagnu
  • uhgagnu
  • 2017年03月03日 18:41
  • 552
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:驱动学习笔记一:实现一个简单的HelloDriver
举报原因:
原因补充:

(最多只允许输入30个字)