梦织未来Windows驱动编程 第03课 驱动的编程规范
最近根据梦织未来论坛的驱动教程学习了一下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课 驱动的编程规范相关推荐
- 梦织未来Windows驱动编程 第05课 小结(读取另一驱动,遍历所有驱动)
读取另一驱动 驱动通过"\\Driver\\XueTr"获取到了XueTr工具的驱动,并Hook了XueTr驱动的分发函数. 具体的驱动代码如下: 1 //FilterDriver ...
- 可编程计算机控制器课设,可编程计算机控制器课程设计(电气)
[可编程计算机控制器课程设计] [Programmable Computer Controller] 一.基本信息 课程代码:[099582] 课程学分:[1] 面向专业:[电气工程及其自动化] ...
- 扇贝编程python认知课_扇贝编程-人人能学会的python课 in de App Store
"扇贝编程将带领你在不经意之间从0到1掌握编程奥秘,写出人生第一行代码,带你打开编程世界的大门! 60天精通python语言,掌握爬虫技术.数据分析方法,入门人工智能,未来,就是现在! [适 ...
- 可编程计算机控制器课设,可编程控制器课程设计.doc
可编程控制器课程设计 中央空调的设计 一.前言 我国是一个人均能源相对贫乏的国家,人均能源占有量不足世界水平的一半,随着我国经济的快速发展,我国已成为世界第二耗能大国,但能源使用效率普通偏低, 造成电 ...
- python编程入门第一课教案_python编程从入门到实践 第一课:输入输出
#print()函数使用 messger="hello python world!" print(messger) hello python world! 1.使用"#& ...
- windows游戏编程_2020年适合程序员编程的笔记本电脑推荐
在购买编程笔记本电脑时,一套智能的基准规格包括至少 8GB 的内存.像样的 SSD.强大的集成 GPU 和一个 i5 或 i7 处理器.虽然这些基准配置很好,但它们不足以帮助您找到最好的笔记本电脑.在 ...
- PL2303HX在Windows 10下面不装安装驱动的解决办法(Code:10)
Prolific在很早之前推出了一款名为PL2303HX的芯片, 用于USB转RS232, 这款芯片使用的范围非常广, 并且年代久远. 但是这款芯片因为用的特别多, 所以中国就有很多厂家生产了仿造的P ...
- Linux下的C编程实战(开发平台搭建,文件系统编程,进程控制与进程通信编程,“线程”控制与“线程”通信编程,驱动程序设计,专家问答)
Linux下的C编程实战(一) ――开发平台搭建 1.引言 Linux操作系统在服务器领域的应用和普及已经有较长的历史,这源于它的开源特点以及其超越Windows的安全性和稳定性.而近年来,Linux ...
- “西湖论剑”四大观察:十年筑梦向未来,数字安全开新局
既有人工智能与安全何去何从的激烈讨论,又有数据安全与数据治理的深度解读,还有数字中国建设背景下安全产业升级的蓝图规划,更有数字安全人才培养的期许与行动--这就是2023 西湖论剑·数字安全大会所呈现出 ...
- 腾讯“云+未来”峰会:以云为基石,加速编程,走向人工智能的未来
7月5日,腾讯"云+未来"峰会(专题报道)在深圳开幕,腾讯公司董事长兼首席执行官马化腾亲自出席,与百余名国内外行家里手共同探讨云+各产业的未来.马化腾重申:未来是传统行业利用互联网 ...
最新文章
- git查看各个branch之间的关系图
- SIGGRAPH2018黑科技:开源语义软分割改进图像编辑
- iOS sql的简单封装
- Spring IOC 和 AOP 概览
- hsf 架构_HSF源码剖析 - 汪兴的个人空间 - OSCHINA - 中文开源技术交流社区
- mac下复制粘贴需要多次的问题
- Codeforces 1013 A. Piles With Stones
- 华人操作系统项目列表
- 8个深度学习/计算机视觉错误,应该如何避免它们
- 关于vue项目中移动端实现用户选择照片、照片裁剪、一次上传多张图片功能。
- 数据分析师三个等级_数据分析课|这三个等级的数据分析师报考条件,一定是你需要的...
- 小猪的Python学习之旅 —— 1.基础知识储备
- K8S==springboot项目生成image部署到K8S
- 有道云笔记,熊掌记和 Effie 哪个适合单口或脱口秀作者?
- MyIE2几个让我欣赏的地方
- 【C应用】红外遥控小车程序分析(下)——红外传输数据程序分析
- 【python】【惰性序列】【iterator】
- pywinauto爬取微信通讯录 2023年1月有效
- ffmpeg 实现转码一个普通视频文件为视频mpeg4,音频mp3的功能的程序(摘)
- git pull 时候报错Your configuration specifies to merge with the ref ‘refs/heads/master‘ from the remote,