最近根据梦织未来论坛的驱动教程学习了一下Windows下的驱动编程,做个笔记备忘。这是第03课《驱动的编程规范》。

驱动部分包括基本的驱动卸载函数、驱动打开关闭读取写入操作最简单的分发例程。代码如下:

  1 //CreateDevice.c
  2 //2016.07.14
  3
  4 #include "ntddk.h"
  5
  6 //驱动卸载函数Self
  7 VOID MyDriverUnload(PDRIVER_OBJECT pDriverObject)
  8 {
  9     UNICODE_STRING usSymName;
 10     RtlInitUnicodeString(&usSymName, L"\\??\\FirstDevice");
 11
 12     //先删除符号链接,后删除设备对象
 13     if (pDriverObject->DeviceObject != NULL)
 14     {
 15         IoDeleteSymbolicLink(&usSymName);                //删除符号链接
 16         IoDeleteDevice(pDriverObject->DeviceObject);    //删除设备对象
 17         KdPrint(("Delete Device Sucess."));
 18     }
 19 }
 20
 21 //创建设备函数Self
 22 NTSTATUS CreateDevice(PDRIVER_OBJECT pDriverObject)
 23 {
 24     NTSTATUS Status;
 25     UNICODE_STRING usDevName;
 26     UNICODE_STRING usSymName;
 27     PDEVICE_OBJECT pDevObj;        //设备对象,用于指向创建的设备
 28
 29     //DDK API    为UNICODE_STRING赋值的函数
 30     RtlInitUnicodeString(&usDevName, L"\\Device\\FirstDevice");
 31
 32     //创建设备函数API    创建设备"\\Device\\FirstDevice"
 33     //设备创建后,会返回给pDevObj,同时给pDriverObject->DeviceObject赋值
 34     //The IoCreateDevice routine creates a device object for use by a driver.
 35     /*
 36         NTSTATUS IoCreateDevice(
 37         _In_     PDRIVER_OBJECT  DriverObject,
 38         _In_     ULONG           DeviceExtensionSize,
 39         _In_opt_ PUNICODE_STRING DeviceName,
 40         _In_     DEVICE_TYPE     DeviceType,
 41         _In_     ULONG           DeviceCharacteristics,
 42         _In_     BOOLEAN         Exclusive,
 43         _Out_    PDEVICE_OBJECT  *DeviceObject
 44         );
 45     */
 46     Status = IoCreateDevice(pDriverObject,
 47                             0,
 48                             &usDevName,
 49                             FILE_DEVICE_UNKNOWN,
 50                             FILE_DEVICE_SECURE_OPEN,
 51                             TRUE,
 52                             &pDevObj);
 53     if (!NT_SUCCESS(Status))    //检查返回值
 54     {
 55         return Status;
 56     }
 57
 58     //DO_BUFFERED_IO or DO_DIRECT_IO
 59     //Specifies the type of buffering that is used by the I/O manager for I/O requests that are sent to the device stack.
 60     //Higher-level drivers OR this member with the same value as the next-lower driver in the stack, except possibly for highest-level drivers.
 61     pDevObj->Flags |= DO_BUFFERED_IO;
 62
 63     RtlInitUnicodeString(&usSymName, L"\\??\\FirstDevice");
 64
 65     //The IoCreateSymbolicLink routine sets up a symbolic link between a device object name and a user-visible name for the device.
 66     /*
 67         NTSTATUS IoCreateSymbolicLink(
 68         _In_ PUNICODE_STRING SymbolicLinkName,
 69         _In_ PUNICODE_STRING DeviceName
 70         );
 71     */
 72     Status = IoCreateSymbolicLink(&usSymName, &usDevName);    //DDK API    创建符号链接
 73     if (!NT_SUCCESS(Status))
 74     {
 75         IoDeleteDevice(pDevObj);    //删除设备对象
 76         return Status;
 77     }
 78
 79     return STATUS_SUCCESS;
 80 }
 81
 82 //打开设备的函数
 83 NTSTATUS CreateCompleteRoutine(PDRIVER_OBJECT pDriverObject, PIRP pIrp)
 84 {
 85     NTSTATUS Status;
 86
 87     Status = STATUS_SUCCESS;
 88
 89     KdPrint(("Create"));
 90
 91     //A driver sets an IRP's I/O status block to indicate the final status of an I/O request, before calling IoCompleteRequest for the IRP.
 92
 93     //This is the completion status, either STATUS_SUCCESS if the requested operation was completed successfully or an informational, warning, or error STATUS_ XXX value.
 94     //For more information, see Using NTSTATUS values.
 95     pIrp->IoStatus.Status = Status;
 96     //This is the completion status, either STATUS_SUCCESS if the requested operation was completed successfully or an informational, warning, or error STATUS_ XXX value.
 97     //For more information, see Using NTSTATUS values.
 98     pIrp->IoStatus.Information = 0;
 99
100     //The IoCompleteRequest routine indicates that the caller has completed all processing for a given I/O request and is returning the given IRP to the I/O manager.
101     //IO_NO_INCREMENT 不再往下层传递
102     IoCompleteRequest(pIrp, IO_NO_INCREMENT);
103     return Status;
104 }
105
106 //关闭设备的函数
107 NTSTATUS CloseCompleteRoutine(PDRIVER_OBJECT pDriverObject, PIRP pIrp)
108 {
109     NTSTATUS Status;
110
111     Status = STATUS_SUCCESS;
112
113     KdPrint(("Close"));
114
115     pIrp->IoStatus.Status = Status;
116     pIrp->IoStatus.Information = 0;
117
118     IoCompleteRequest(pIrp, IO_NO_INCREMENT);
119     return Status;
120 }
121
122 //读取设备的函数
123 NTSTATUS ReadCompleteRoutine(PDRIVER_OBJECT pDriverObject, PIRP pIrp)
124 {
125     NTSTATUS Status;
126
127     Status = STATUS_SUCCESS;
128
129     KdPrint(("Read"));
130
131     pIrp->IoStatus.Status = Status;
132     pIrp->IoStatus.Information = 0;
133
134     IoCompleteRequest(pIrp, IO_NO_INCREMENT);
135     return Status;
136 }
137
138 //写入设备的函数
139 NTSTATUS WriteCompleteRoutine(PDRIVER_OBJECT pDriverObject, PIRP pIrp)
140 {
141     NTSTATUS Status;
142
143     Status = STATUS_SUCCESS;
144
145     KdPrint(("Write"));
146
147     pIrp->IoStatus.Status = Status;
148     pIrp->IoStatus.Information = 0;
149
150     IoCompleteRequest(pIrp, IO_NO_INCREMENT);
151     return Status;
152 }
153
154 //驱动程序入口函数
155 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
156 {
157     //输出信息
158     //DbgPrint("1111");
159
160
161     NTSTATUS Status;
162     Status = CreateDevice(pDriverObject);    //创建设备对象和符号链接
163     if (!NT_SUCCESS(Status))
164     {
165         KdPrint(("Create Device Failed."));
166     } else {
167         KdPrint(("Create Device Sucess."));
168         KdPrint(("%wZ", pRegistryPath));
169     }
170
171     //打开关闭读取写入的分发例程赋值
172     pDriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)CreateCompleteRoutine;    //打开设备
173     pDriverObject->MajorFunction[IRP_MJ_CLOSE]    = (PDRIVER_DISPATCH)CloseCompleteRoutine;    //关闭设备
174     pDriverObject->MajorFunction[IRP_MJ_READ]    = (PDRIVER_DISPATCH)ReadCompleteRoutine;    //读取设备
175     pDriverObject->MajorFunction[IRP_MJ_WRITE]    = (PDRIVER_DISPATCH)WriteCompleteRoutine;    //写入设备
176
177     //驱动卸载函数赋值
178     pDriverObject->DriverUnload = MyDriverUnload;
179
180     return STATUS_SUCCESS;
181 }

CreateDevice.c

应用层采用了MFC创建了一个窗口,窗口有三个按钮:Create、Read、Write。界面如下:

其中Create按钮的处理函数如下:

 1 void CCheckMyDriverDlg::OnCreateButton()
 2 {
 3     // TODO: 在此添加控件通知处理程序代码
 4     HANDLE hFile = CreateFileW(L"\\\\.\\FirstDevice",
 5                 FILE_ALL_ACCESS,
 6                 0,
 7                 NULL,
 8                 OPEN_EXISTING,
 9                 FILE_ATTRIBUTE_NORMAL,
10                 NULL);
11     if (hFile == INVALID_HANDLE_VALUE)
12     {
13         AfxMessageBox (L"Open Device Failed.");
14         return;
15     }
16
17     CloseHandle (hFile);
18 }

Read按钮的处理函数如下:

 1 void CCheckMyDriverDlg::OnReadButton()
 2 {
 3     // TODO: 在此添加控件通知处理程序代码
 4     HANDLE hFile = CreateFileW(L"\\\\.\\FirstDevice",
 5         FILE_ALL_ACCESS,
 6         0,
 7         NULL,
 8         OPEN_EXISTING,
 9         FILE_ATTRIBUTE_NORMAL,
10         NULL);
11     if (hFile == INVALID_HANDLE_VALUE)
12     {
13         AfxMessageBox (L"Open Device Failed.");
14         return;
15     }
16
17     wchar_t Buffer[MAX_PATH] = {0};
18     DWORD len = 0;
19     if (!ReadFile (hFile, Buffer, MAX_PATH-1, &len, NULL))
20     {
21         AfxMessageBox (L"Read Device Failed.");
22         return;
23     }
24
25     CloseHandle (hFile);
26
27 }

Write按钮的处理函数如下:

 1 void CCheckMyDriverDlg::OnWriteButton()
 2 {
 3     // TODO: 在此添加控件通知处理程序代码
 4     HANDLE hFile = CreateFileW(L"\\\\.\\FirstDevice",
 5         FILE_ALL_ACCESS,
 6         0,
 7         NULL,
 8         OPEN_EXISTING,
 9         FILE_ATTRIBUTE_NORMAL,
10         NULL);
11     if (hFile == INVALID_HANDLE_VALUE)
12     {
13         AfxMessageBox (L"Open Device Failed.");
14         return;
15     }
16
17     wchar_t Buffer[MAX_PATH] = L"What The Fuck, Man ?";
18     DWORD len;
19     if (!WriteFile (hFile, Buffer, MAX_PATH, &len, NULL))
20     {
21         AfxMessageBox (L"Write Device Failed.");
22         return;
23     }
24
25     CloseHandle (hFile);
26
27 }

以下为操作部分:

将生成的FirstDevice.sys文件复制到XP虚拟机下,使用驱动加载工具InstDrv安装并启动驱动后,在Dbgview工具内有如下输出信息:

并能够找到相应注册表,使用WinObj工具查看设备对象\\Device\\FirstDevice:

然后查看符号链接\\??\\FirstDevice:

使用InstDrv停止此驱动时输出:

期间并未出现蓝屏问题

安装驱动程序后,使用上面写的MFC程序CheckMyDriver.exe,点击Create按钮后,输出

点击Read按钮后,输出:

点击Write按钮后,输出:

以上操作均为出现蓝屏。本课结束。

由于本人刚开始学习驱动程序,实力有限,可能对于某些地方的理解并不正确,希望大家能提出意见建议,共同学习,共同进步。

最后谢谢大家的支持。

2016-07-14 14:58:13

转载于:https://www.cnblogs.com/linuxxiaoyu/p/5668153.html

梦织未来Windows驱动编程 第03课 驱动的编程规范相关推荐

  1. 梦织未来Windows驱动编程 第05课 小结(读取另一驱动,遍历所有驱动)

    读取另一驱动 驱动通过"\\Driver\\XueTr"获取到了XueTr工具的驱动,并Hook了XueTr驱动的分发函数. 具体的驱动代码如下: 1 //FilterDriver ...

  2. 可编程计算机控制器课设,可编程计算机控制器课程设计(电气)

    [可编程计算机控制器课程设计] [Programmable  Computer  Controller] 一.基本信息 课程代码:[099582] 课程学分:[1] 面向专业:[电气工程及其自动化] ...

  3. 扇贝编程python认知课_‎扇贝编程-人人能学会的python课 in de App Store

    "扇贝编程将带领你在不经意之间从0到1掌握编程奥秘,写出人生第一行代码,带你打开编程世界的大门! 60天精通python语言,掌握爬虫技术.数据分析方法,入门人工智能,未来,就是现在! [适 ...

  4. 可编程计算机控制器课设,可编程控制器课程设计.doc

    可编程控制器课程设计 中央空调的设计 一.前言 我国是一个人均能源相对贫乏的国家,人均能源占有量不足世界水平的一半,随着我国经济的快速发展,我国已成为世界第二耗能大国,但能源使用效率普通偏低, 造成电 ...

  5. python编程入门第一课教案_python编程从入门到实践 第一课:输入输出

    #print()函数使用 messger="hello python world!" print(messger) hello python world! 1.使用"#& ...

  6. windows游戏编程_2020年适合程序员编程的笔记本电脑推荐

    在购买编程笔记本电脑时,一套智能的基准规格包括至少 8GB 的内存.像样的 SSD.强大的集成 GPU 和一个 i5 或 i7 处理器.虽然这些基准配置很好,但它们不足以帮助您找到最好的笔记本电脑.在 ...

  7. PL2303HX在Windows 10下面不装安装驱动的解决办法(Code:10)

    Prolific在很早之前推出了一款名为PL2303HX的芯片, 用于USB转RS232, 这款芯片使用的范围非常广, 并且年代久远. 但是这款芯片因为用的特别多, 所以中国就有很多厂家生产了仿造的P ...

  8. Linux下的C编程实战(开发平台搭建,文件系统编程,进程控制与进程通信编程,“线程”控制与“线程”通信编程,驱动程序设计,专家问答)

    Linux下的C编程实战(一) ――开发平台搭建 1.引言 Linux操作系统在服务器领域的应用和普及已经有较长的历史,这源于它的开源特点以及其超越Windows的安全性和稳定性.而近年来,Linux ...

  9. “西湖论剑”四大观察:十年筑梦向未来,数字安全开新局

    既有人工智能与安全何去何从的激烈讨论,又有数据安全与数据治理的深度解读,还有数字中国建设背景下安全产业升级的蓝图规划,更有数字安全人才培养的期许与行动--这就是2023 西湖论剑·数字安全大会所呈现出 ...

  10. 腾讯“云+未来”峰会:以云为基石,加速编程,走向人工智能的未来

    7月5日,腾讯"云+未来"峰会(专题报道)在深圳开幕,腾讯公司董事长兼首席执行官马化腾亲自出席,与百余名国内外行家里手共同探讨云+各产业的未来.马化腾重申:未来是传统行业利用互联网 ...

最新文章

  1. git查看各个branch之间的关系图
  2. SIGGRAPH2018黑科技:开源语义软分割改进图像编辑
  3. iOS sql的简单封装
  4. Spring IOC 和 AOP 概览
  5. hsf 架构_HSF源码剖析 - 汪兴的个人空间 - OSCHINA - 中文开源技术交流社区
  6. mac下复制粘贴需要多次的问题
  7. Codeforces 1013 A. Piles With Stones
  8. 华人操作系统项目列表
  9. 8个深度学习/计算机视觉错误,应该如何避免它们
  10. 关于vue项目中移动端实现用户选择照片、照片裁剪、一次上传多张图片功能。
  11. 数据分析师三个等级_数据分析课|这三个等级的数据分析师报考条件,一定是你需要的...
  12. 小猪的Python学习之旅 —— 1.基础知识储备
  13. K8S==springboot项目生成image部署到K8S
  14. 有道云笔记,熊掌记和 Effie 哪个适合单口或脱口秀作者?
  15. MyIE2几个让我欣赏的地方
  16. 【C应用】红外遥控小车程序分析(下)——红外传输数据程序分析
  17. 【python】【惰性序列】【iterator】
  18. pywinauto爬取微信通讯录 2023年1月有效
  19. ffmpeg 实现转码一个普通视频文件为视频mpeg4,音频mp3的功能的程序(摘)
  20. git pull 时候报错Your configuration specifies to merge with the ref ‘refs/heads/master‘ from the remote,

热门文章

  1. python 货币换算库,货币转换python代码你知道怎么写吗?
  2. 视频md5修改器苹果手机
  3. Android实现Telnet客户端
  4. wincc安装信息服务器,WinCC 7.4软件不会安装?怎么授权?一文教会你
  5. OpenCL简单入门
  6. PowerMockito框架入门及使用
  7. mysql增删改查sql语句_sql增删改查语句是什么?
  8. 五种主流的虚拟化技术
  9. 视频转换器如何将腾讯QLV格式转换成MP4视频文件
  10. VLfeat库---研习