驱动其实很早以前就写了 只不过功能没有达到 加上一直很忙 所以就放下了 今天闲着无聊 就接着写吧...
写完了 发上来 留着 主要的问题就是效率很低下 不知道为什么有大量的IRP_MJ_DEVICE_CONTROL
这个IRP CPU全部占满
程序很简单 暴力枚举 主要是锻炼一下内核编程 以及WinDbg的调试
头文件
1 /*******************************************************************************
2 *文件名称: MyDDK.h
3 *作 者: 李佳
4 *完成日期: 09.7.29
5 *******************************************************************************/
6 #pragma once
7
8 #ifdef __cplusplus
9 extern "C"
10 {
11 #endif
12 #include <ntddk.h>
13 //使用RtlStringCchPrintfW
14 #include <ntstrsafe.h>
15 #pragma comment(lib , "ntstrsafe.lib")
16 #ifdef __cplusplus
17 }
18 #endif
19
20 #define PAGEDCODE code_seg("PAGE")
21 #define LOCKEDCODE code_seg()
22 #define INITCODE code_seg("INIT")
23
24 #define PAGEDDATA date_seg("PAGE")
25 #define LOCKEDDATA date_seg()
26 #define INITDATA date_seg("INIT")
27
28 #define arraysize(p) (sizeof(p) / sizeof((p)[0]))
29
30 typedef struct _DEVICE_EXTENSION
31 {
32 PDEVICE_OBJECT pDevice;
33 UNICODE_STRING ustrDeviceName; //设备名称
34 UNICODE_STRING ustrSysLinkName; //链接名称
35 }DEVICE_EXTENSION , *PDEVICE_EXTENSION;
36
37 //函数声明
38 //创建设备
39 NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject);
40 //卸载例程
41 VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject);
42 //默认IRP处理例程
43 NTSTATUS HelloDDKDispatchRoutine( IN PDEVICE_OBJECT pDeviceObject ,
44 IN PIRP Irp);
45 //绑定所有COM端口
46 VOID AttachAllComs(PDRIVER_OBJECT Driver);
47 //打开COM端口
48 PDEVICE_OBJECT OpenCom(ULONG id , NTSTATUS * status);
49 //绑定COM口
50 NTSTATUS AttachDevice( PDRIVER_OBJECT pDriver ,
51 PDEVICE_OBJECT pOldDeviceObj ,
52 PDEVICE_OBJECT * pNewDeviceObj ,
53 PDEVICE_OBJECT* pNext);
实现文件
1 /*****************************************************************************
2 *文件名称: MyDDK.cpp
3 *作 者: 李佳
4 *完成日期: 09.7.29
5 ****************************************************************************/
6 #include "MyDDK.h"
7
8 #define MAX_COM_NUM 32 //最大COM数
9 static PDEVICE_OBJECT fltDevObj[MAX_COM_NUM] = {0}; //过滤设备的指针
10 static PDEVICE_OBJECT realDevObj[MAX_COM_NUM] = {0}; //真实设备的指针
11 /***************************************************************************
12 *函数名称: DriverEntry
13 *功能描述: 驱动程序的入口函数
14 *参数列表: pDriverObject : I/O管理器中传递进来的驱动对象
15 * pRegistryPath : 驱动程序在注册表中的存储路径
16 *返 回 值: 返回初始化驱动的执行状态
17 **************************************************************************/
18 #pragma INITCODE
19 extern "C" DriverEntry(IN PDRIVER_OBJECT pDriverObject ,
20 IN PUNICODE_STRING pRegistryPath)
21 {
22 NTSTATUS status;
23 KdPrint(("Enter DriverEntry!\n"));
24 size_t i = 0;
25 for (i = 0 ; i < IRP_MJ_MAXIMUM_FUNCTION ; i++)
26 {
27 pDriverObject->MajorFunction[i] = HelloDDKDispatchRoutine;
28 }
29 pDriverObject->DriverUnload = HelloDDKUnload; //卸载例程入口
30 /*pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;
31 pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;
32 pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
33 pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;
34
35 status = CreateDevice(pDriverObject);*/
36 AttachAllComs(pDriverObject); //绑定COM
37 KdPrint(("Leave DriverEntry!\n"));
38 return STATUS_SUCCESS;
39 }
40
41 /***************************************************************************
42 *函数名称: HelloDDKUnload
43 *功能描述: 负责卸载驱动
44 *参数列表: pDriverObject : I/O管理器中传递进来的驱动对象
45 *返 回 值: 返回函数执行结果
46 **************************************************************************/
47 #pragma PAGEDCODE
48 VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject)
49 {
50 ULONG i = 0 ;
51 LARGE_INTEGER intervel;
52
53 //解除设备锁定
54 for (i = 0 ; i < MAX_COM_NUM ; i++)
55 {
56 if (realDevObj[i] != NULL)
57 IoDetachDevice(realDevObj[i]);
58 }
59
60 //等待所有IRP完成
61 #define DELAY_ONE_MICROSECOND (-10)
62 #define DELAY_ONE_MILLSECOND (DELAY_ONE_MICROSECOND*1000)
63 #define DELAY_ONE_SECOND (DELAY_ONE_MILLSECOND * 1000)
64 intervel.QuadPart = (5 * 1000 * DELAY_ONE_MILLSECOND);
65 KeDelayExecutionThread(KernelMode , FALSE , &intervel);
66
67 //删除设备
68 for (i = 0 ; i < MAX_COM_NUM ; i ++)
69 {
70 if(fltDevObj[i] != NULL)
71 IoDetachDevice(fltDevObj[i]);
72 }
73 }
74
75
76 /***************************************************************************
77 *函数名称: HelloDDKDispatchRoutine
78 *功能描述: 默认IRP处理例程
79 *参数列表: pDeviceObject : I/O管理器传递进来的设备对象
80 * Irp : I/O请求包
81 *返 回 值: 返回IRP的处理结果
82 **************************************************************************/
83 #pragma PAGEDCODE
84 NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDeviceObject , IN PIRP Irp)
85 {
86 //KdPrint(("Enter HelloDDKDispatchRoutine!\n"));
87 NTSTATUS status = STATUS_SUCCESS;
88 PIO_STACK_LOCATION Irpsp = IoGetCurrentIrpStackLocation(Irp);
89 ULONG i = 0 , j = 0;
90 for (i = 0 ; i < MAX_COM_NUM ; i++)
91 {
92 if (fltDevObj[i] == pDeviceObject)
93 {
94 //电源操作 直接放过
95 if (Irpsp->MajorFunction == IRP_MJ_POWER)
96 {
97 PoStartNextPowerIrp(Irp);
98 IoSkipCurrentIrpStackLocation(Irp);
99 return PoCallDriver(realDevObj[i] , Irp); //调用真实设备
100 }
101 //过滤写请求
102 if (Irpsp->MajorFunction == IRP_MJ_WRITE)
103 {
104 ULONG uLen = Irpsp->Parameters.Write.Length; //获取写入的长度
105 PUCHAR pBuf = NULL;
106 if (Irp->MdlAddress != NULL)
107 pBuf = (PUCHAR)MmGetSystemAddressForMdlSafe (Irp->MdlAddress , NormalPagePriority);
108 else
109 pBuf = (PUCHAR)Irp->UserBuffer;
110 if(pBuf == NULL)
111 pBuf = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
112
113 for (j = 0 ; j < uLen ; j++)
114 KdPrint(("comcap : SendData : %2x\r\n" , pBuf[j]));
115 }
116
117 }
118 }
119 //找不到这个设备
120 Irp->IoStatus.Status = status;
121 Irp->IoStatus.Information = 0;
122 IoCompleteRequest(Irp , IO_NO_INCREMENT);
123 return STATUS_SUCCESS;
124 }
125
126 /***************************************************************************
127 *函数名称: AttachAllComs
128 *功能描述: 绑定所有串口设备
129 *参数列表: pDriverObject : I/O管理器中传递进来的驱动对象
130 *返 回 值: 无
131 **************************************************************************/
132 #pragma PAGEDCODE
133 VOID AttachAllComs(PDRIVER_OBJECT Driver)
134 {
135 ULONG i;
136 PDEVICE_OBJECT pComDev;
137 NTSTATUS status;
138 for (i = 0 ; i < MAX_COM_NUM ; i++)
139 {
140 pComDev = OpenCom(i , &status);
141 if (pComDev == NULL)
142 continue;
143 AttachDevice(Driver , pComDev , &fltDevObj[i] , &realDevObj[i]);
144 }
145 }
146
147 /***************************************************************************
148 *函数名称: OpenCom
149 *功能描述: 绑定所有串口设备
150 *参数列表: id : 需要绑定的COM号
151 * status : 返回函数的执行状态
152 *返 回 值: 返回打开的COM口的设备对象
153 **************************************************************************/
154 #pragma PAGEDCODE
155 PDEVICE_OBJECT OpenCom(ULONG id , NTSTATUS * status)
156 {
157 UNICODE_STRING ustrDevName ;
158 WCHAR wName[32];
159 PFILE_OBJECT pFileObj;
160 PDEVICE_OBJECT pDevObj;
161 memset(wName , 0 , sizeof(WCHAR)*32);
162 RtlStringCchPrintfW(wName , 32 , L"\\Device\\Serial%d" , id);
163 RtlInitUnicodeString(&ustrDevName , wName);
164
165 //打开设备
166 *status = IoGetDeviceObjectPointer(&ustrDevName , FILE_ALL_ACCESS ,&pFileObj , &pDevObj);
167 if (*status == STATUS_SUCCESS)
168 ObDereferenceObject(pFileObj); //解除文件对象
169
170 return pDevObj;
171 }
172
173 /***************************************************************************
174 *函数名称: AttachDevice
175 *功能描述: 生成虚拟设备绑定COM口
176 *参数列表: pDriver : I/O管理器中传递进来的驱动对象
177 * pOldDeviceObj : 真实设备的设备对象
178 * pNewDeviceObj : 创建的虚拟设备的设备对象
179 * pNext : 指向下一个设备
180 *返 回 值: 返回创建设备对象的执行结果
181 **************************************************************************/
182 #pragma PAGEDCODE
183 NTSTATUS AttachDevice( PDRIVER_OBJECT pDriver ,
184 PDEVICE_OBJECT pOldDeviceObj ,
185 PDEVICE_OBJECT * pNewDeviceObj ,
186 PDEVICE_OBJECT * pNext)
187 {
188 NTSTATUS status;
189 PDEVICE_OBJECT pTopDev = NULL;
190
191 //生成设备
192 status = IoCreateDevice( pDriver ,
193 0 ,
194 NULL ,
195 pOldDeviceObj->DeviceType ,
196 0 ,
197 FALSE ,
198 pNewDeviceObj );
199 if (status != STATUS_SUCCESS)
200 return status;
201
202 //拷贝重要标志
203 if(pOldDeviceObj->Flags & DO_BUFFERED_IO)
204 (*pNewDeviceObj)->Flags |= DO_BUFFERED_IO;
205 if(pOldDeviceObj->Flags & DO_DIRECT_IO)
206 (*pNewDeviceObj)->Flags |= DO_DIRECT_IO;
207 if(pOldDeviceObj->Characteristics & FILE_DEVICE_SECURE_OPEN)
208 (*pNewDeviceObj)->Characteristics |= FILE_DEVICE_SECURE_OPEN;
209 (*pNewDeviceObj)->Flags |= DO_POWER_PAGABLE;
210
211 pTopDev = IoAttachDeviceToDeviceStack(*pNewDeviceObj , pOldDeviceObj);
212 if (pTopDev == NULL)
213 {
214 //绑定失败
215 IoDeleteDevice(*pNewDeviceObj);
216 *pNewDeviceObj = NULL;
217 return STATUS_UNSUCCESSFUL;
218 }
219 *pNext = pTopDev;
220 //启动设备
221 (*pNewDeviceObj)->Flags = (*pNewDeviceObj)->Flags & ~DO_DEVICE_INITIALIZING;
222 return STATUS_SUCCESS;
223 }
224
225 /***************************************************************************
226 *函数名称: CreateDevice
227 *功能描述: 创建设备对象
228 *参数列表: pDriverObject : I/O管理器中传递进来的驱动对象
229 *返 回 值: 返回创建设备对象的执行结果
230 **************************************************************************/
231 #pragma INITCODE
232 NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject)
233 {
234 NTSTATUS status;
235 PDEVICE_OBJECT pDeviceObject;
236 PDEVICE_EXTENSION pDeviceExtension;
237
238 //设备名称
239 UNICODE_STRING ustrDeviceName;
240 RtlInitUnicodeString(&ustrDeviceName , L"\\Device\\MyDDKDevice");
241
242 //创建设备
243 status = IoCreateDevice(pDriverObject ,
244 sizeof(DEVICE_EXTENSION),
245 &ustrDeviceName ,
246 FILE_DEVICE_UNKNOWN ,
247 0,
248 TRUE,
249 &pDeviceObject/*注意此处为OUT PDEVICE_OBJECT *DeviceObject*/);
250 if (!NT_SUCCESS(status))
251 return status;
252
253 pDeviceObject->Flags |= DO_BUFFERED_IO;
254 pDeviceExtension = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension; //填充DeviceObject的DeviceExtension字段的内容 便于以后使用
255 pDeviceExtension->pDevice = pDeviceObject;
256 pDeviceExtension->ustrDeviceName = ustrDeviceName;
257
258 //创建符号链接
259 UNICODE_STRING ustrSysLinkName;
260 RtlInitUnicodeString(&ustrSysLinkName , L"\\??\\MyDDK");
261 pDeviceExtension->ustrSysLinkName = ustrSysLinkName;
262 status = IoCreateSymbolicLink(&ustrSysLinkName,&ustrDeviceName);
263 if (!NT_SUCCESS(status))
264 {
265 IoDeleteDevice(pDeviceObject);
266 return status;
267 }
268 return STATUS_SUCCESS;
269 }
270
效率方面 接下来再考虑如何提高
还是那句话 Make it right before you make it faster!
posted on 2009-08-28 16:20
李佳 阅读(1482)
评论(0) 编辑 收藏 引用 所属分类:
驱动开发