一个简单的串口过滤驱动
来源:互联网 发布:淘宝买家账号信誉查询 编辑:程序博客网 时间:2024/04/30 09:48
学习驱动开发一段时间了,在尝试着从最简单的驱动开发着手学习,我再尝试着编写一个最简单的串口过滤驱动,可是多次尝试都没有成功,总是一加载就蓝屏。看了网上的例子他们都是采用的IoAttachDeviceToDeviceStack,而我采用的是IoAttachDevice,现在把网上的代码整理成最简单的形式给大家分享一下,希望初学者能从中受益。我会再后面的博客里详细介绍。
#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);elsebuf = (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_OBJECTDriverObject){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;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;}把IRP请求处理再次简化就变成了下面的形式,我为什么要这样简化就是想告诉大家驱动过滤的简单框架。
#include <ntddk.h>#include <string.h>static PDEVICE_OBJECT m_fltobj;static PDEVICE_OBJECT m_topobj;NTSTATUS DRIVER1_DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp){NTSTATUS status = STATUS_SUCCESS;PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);DbgPrint(("收到IRP\r\n"));IoSkipCurrentIrpStackLocation(Irp);return IoCallDriver(m_topobj, Irp);}VOID DRIVER1_DriverUnload(IN PDRIVER_OBJECTDriverObject){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;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;}
- 一个简单的串口过滤驱动
- 一个简单的串口过滤驱动及一点体会
- 一个可以过滤串口输入的过滤驱动
- 一个串口输入过滤驱动
- 串口过滤驱动(过滤所有的串口)
- 一个简单的文件系统过滤驱动框架
- 一个简单的文件系统过滤驱动框架
- 串口的过滤驱动例子
- 串口过滤驱动源码
- 串口过滤驱动练习
- 一个基于简单USB过滤驱动。。
- <寒江独钓>Windows内核安全编程__一个简单的Windows串口过滤驱动程序的开发
- 一个简单的文字过滤
- 一个 SPI 转串口驱动的优化
- 为串口过滤驱动加上显示串口收发内容的应用程序
- 简单串口驱动
- 一个很简单的过滤下拉框
- 一个简单的协同过滤推荐算法
- repeater时间绑定
- POJ 1501 Word-Search Wonder
- 启动Apache
- POJ 1702 Eva's Balance
- 关于android安装sdk时找不到jdk的解决办法
- 一个简单的串口过滤驱动
- POJ 2021 Relative Relatives
- POJ 2418 Hardwood Species
- 关闭Aphache和重启Apache
- 嵌入式C笔试总结(长期更新)
- 优化资源
- POJ 1018 Communication System
- POJ 1220 NUMBER BASE CONVERSION
- POJ1287 Networking