首页 > 学院 > 开发设计 > 正文

串口过滤驱动练习

2019-11-08 00:41:39
字体:
来源:转载
供稿:网友

一个简单的串口过滤驱动框架

参考《寒江独钓》完成用来对串口读写进行的过滤驱动。 注意问题:

用来和应用层通信的buffer区域有三种方式。完成的读写分发函数的方式特殊还未搞懂?//以下为完整代码#include <ntddk.h>#include <string.h>static PDEVICE_OBJECT m_fltobj;static PDEVICE_OBJECT m_topobj;//定义一个读的完成处理函数NTSTATUS fengReadComplete(IN PDEVICE_OBJECT DeviectObject, IN PIRP Irp, IN PVOID Context){ PIO_STACK_LOCATION IrpSp; ULONG i; IrpSp = IoGetCurrentIrpStackLocation(Irp); if(NT_SUCCESS( Irp->IoStatus.Status)) { PUCHAR buf = (PUCHAR)Irp->AssociatedIrp.SystemBuffer; DbgPRint("Driver1 Read:"); for(i=0; i<Irp->IoStatus.Information; i++) { DbgPrint("%02X, ", buf[i]); } DbgPrint("/r/n"); } if( Irp->PendingReturned) IoMarkIrpPending( Irp); return Irp->IoStatus.Status;}NTSTATUS DRIVER1_DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp){ ULONG j; NTSTATUS status = STATUS_SUCCESS; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); DbgPrint(("收到IRP/r/n")); if(m_fltobj == DeviceObject) { if(irpSp->MajorFunction == IRP_MJ_POWER)//所有的电源操作,全部直接放过。 { //直接发送,然后返回说已经被处理了。 PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); return PoCallDriver(m_topobj, Irp); } else if(irpSp->MajorFunction == IRP_MJ_WRITE) { PUCHAR buf = NULL; if(Irp->MdlAddress != NULL) buf = (PUCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);//将数据放到MdkAddress中,映射关系。 else buf = (PUCHAR)Irp->UserBuffer; //直接读取用户控件内存。 if(buf == NULL) buf = (PUCHAR)Irp->AssociatedIrp.SystemBuffer; //将用户空间内存拷贝到内核空间。 DbgPrint("Driver1 Write:"); for(j =0; j< irpSp->Parameters.Write.Length; j++) { DbgPrint("%02X, ", buf[j]); } DbgPrint("/r/n"); } else if(irpSp->MajorFunction == IRP_MJ_READ) { IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, fengReadComplete, DeviceObject, TRUE, TRUE, TRUE); return IoCallDriver(m_topobj, Irp); } //所有的读写请求直接下发执行即可,我们并不禁止或改变它。 IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(m_topobj, Irp); } //直接返回参数错误 Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status;}VOID DRIVER1_DriverUnload(IN PDRIVER_OBJECT DriverObject){ LARGE_INTEGER ilval; if(m_topobj != NULL) IoDetachDevice(m_topobj); ilval.QuadPart = 5 * 1000 * 1000 * (-10); //5秒 KeDelayExecutionThread(KernelMode, FALSE, &ilval); if(m_fltobj != NULL) IoDeleteDevice(m_fltobj);}#pragma code_seg("INIT")NTSTATUS DriverEntry(IN OUT PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath){ size_t i; NTSTATUS status; UNICODE_STRING namestr; PFILE_OBJECT fileobj = NULL; PDEVICE_OBJECT devobj = NULL; DbgBreakPoint(); for(i = 0; i< IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = DRIVER1_DispatchDeviceControl; } DriverObject->DriverUnload = DRIVER1_DriverUnload; //打开一个端口设备 //根据id转换成串口的名字 RtlInitUnicodeString(&namestr, L"//Device//Serial0"); //打开设备 //从名字获取设备对象的指针。 status = IoGetDeviceObjectPointer( &namestr, FILE_ALL_access, //全部读写权限 &fileobj, //无用的文件对象指针 &devobj); //打开串口 //如果打开成功了,记得一定要把文件对象解除引用 if(status == STATUS_SUCCESS) ObDereferenceObject(fileobj); if(status == STATUS_SUCCESS) { NTSTATUS status; PDEVICE_OBJECT topdev = NULL; DbgPrint(("成功打开com1/r/n")); //生成设备然后绑定 status = IoCreateDevice(DriverObject, 0, NULL, devobj->DeviceType, 0, FALSE, &m_fltobj); if(status != STATUS_SUCCESS) return status; //拷贝重要标志位 没懂这个是干啥的? if(devobj->Flags & DO_BUFFERED_IO) m_fltobj->Flags |= DO_BUFFERED_IO; if(devobj->Flags & DO_DIRECT_IO) m_fltobj->Flags |= DO_DIRECT_IO; if(devobj->Characteristics & FILE_DEVICE_SECURE_OPEN) m_fltobj->Characteristics |= FILE_DEVICE_SECURE_OPEN; m_fltobj->Flags |= DO_POWER_PAGABLE; //将一个设备绑定到另一个设备 topdev = IoAttachDeviceToDeviceStack(m_fltobj, devobj); if(topdev == NULL) { //如果绑定失败了,销毁设备,返回错误 IoDeleteDevice(m_fltobj); m_fltobj = NULL; status = STATUS_UNSUCCESSFUL; return status; } DbgPrint(("driverentry 成功/r/n")); //设置这个设备已经启动 m_topobj= topdev; m_fltobj->Flags &= ~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; } return STATUS_SUCCESS;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表