一个简单的串口过滤驱动

来源:互联网 发布:淘宝买家账号信誉查询 编辑:程序博客网 时间: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;}


原创粉丝点击