串口过滤驱动

串口过滤驱动
驱动其实很早以前就写了  只不过功能没有达到  加上一直很忙 所以就放下了 今天闲着无聊  就接着写吧...
写完了 发上来 留着 主要的问题就是效率很低下   不知道为什么有大量的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!

你可能感兴趣的:(串口过滤驱动)