一个简单的串口过滤驱动及一点体会
来源:互联网 发布:如何将程序导入单片机 编辑:程序博客网 时间:2024/05/02 04:15
最近写一个简单的串口过滤驱动,代码如下:
driver.h
#ifdef __cplusplus
extern "C"
{
#endif
#include <ntddk.h>
#ifdef __cplusplus
}
#endif
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")
#define arraysize(x) (sizeof(x) / sizeof(x[0]))
typedef struct
{
PDEVICE_OBJECT LowerLevelDeviceObject;
UNICODE_STRING SymbolicLink;
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
NTSTATUS DispatchPassthrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS Read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS CreateDevice(IN PDRIVER_OBJECT DriverObject);
NTSTATUS OnRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
driver.cpp
#include "Driver.h"
#pragma INITCODE
#ifdef __cplusplus
extern "C"
{
#endif
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
KdPrint(("Enter DriverEntry!/n"));
for(int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
DriverObject->MajorFunction[i] = DispatchPassthrough;
DriverObject->MajorFunction[IRP_MJ_READ] = Read;
DriverObject->DriverUnload = DriverUnload;
KdPrint(("Leave DriverEntry!/n"));
return CreateDevice(DriverObject);
}
#ifdef __cplusplus
}
#endif
#pragma PAGEDCODE
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
KdPrint(("Enter DriverUnload!/n"));
PDEVICE_OBJECT Dev = DriverObject->DeviceObject;
while(NULL != Dev)
{
PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)Dev->DeviceExtension;
//删除符号链接
IoDeleteSymbolicLink(&DevExt->SymbolicLink);
IoDetachDevice(DevExt->LowerLevelDeviceObject);
//删除设备对象
IoDeleteDevice(Dev);
Dev = Dev->NextDevice;
}
KdPrint(("Leave DriverUnload!/n"));
}
#pragma PAGEDCODE
NTSTATUS DispatchPassthrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
KdPrint(("Enter DispatchPassthrough!/n"));
NTSTATUS status = STATUS_SUCCESS;
static char* irpname[] =
{
"IRP_MJ_CREATE",
"IRP_MJ_CREATE_NAMED_PIPE",
"IRP_MJ_CLOSE",
"IRP_MJ_READ",
"IRP_MJ_WRITE",
"IRP_MJ_QUERY_INFORMATION",
"IRP_MJ_SET_INFORMATION",
"IRP_MJ_QUERY_EA",
"IRP_MJ_SET_EA",
"IRP_MJ_FLUSH_BUFFERS",
"IRP_MJ_QUERY_VOLUME_INFORMATION",
"IRP_MJ_SET_VOLUME_INFORMATION",
"IRP_MJ_DIRECTORY_CONTROL",
"IRP_MJ_FILE_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CONTROL",
"IRP_MJ_INTERNAL_DEVICE_CONTROL",
"IRP_MJ_SHUTDOWN",
"IRP_MJ_LOCK_CONTROL",
"IRP_MJ_CLEANUP",
"IRP_MJ_CREATE_MAILSLOT",
"IRP_MJ_QUERY_SECURITY",
"IRP_MJ_SET_SECURITY",
"IRP_MJ_POWER",
"IRP_MJ_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CHANGE",
"IRP_MJ_QUERY_QUOTA",
"IRP_MJ_SET_QUOTA",
"IRP_MJ_PNP",
};
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
UCHAR type = stack->MajorFunction;
if(type >= arraysize(irpname))
KdPrint(("Unkown IRP, major type %X/n", type));
else
KdPrint(("/t%s/n", irpname[type]));
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(DevExt->LowerLevelDeviceObject, Irp);
KdPrint(("Leave DispatchPassthrough!/n"));
return status;
}
#pragma PAGEDCODE
NTSTATUS CreateDevice(IN PDRIVER_OBJECT DriverObject)
{
NTSTATUS status = STATUS_SUCCESS;
KdPrint(("Enter CreateDevice!/n"));
UNICODE_STRING DevName;
RtlInitUnicodeString(&DevName, L"//Device//MyDevice");
PDEVICE_OBJECT fdo = NULL;
status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo);
if(!NT_SUCCESS(status))
return status;
PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)fdo->DeviceExtension;
RtlZeroMemory(DevExt, sizeof(DEVICE_EXTENSION));
UNICODE_STRING SymbolicLinkName;
RtlInitUnicodeString(&SymbolicLinkName, L"//??//COMMFILT");
status = IoCreateSymbolicLink(&SymbolicLinkName, &DevName);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(fdo);
return status;
}
DevExt->SymbolicLink = SymbolicLinkName;
UNICODE_STRING TargetDeviceName;
RtlInitUnicodeString(&TargetDeviceName, L"//Device//Winachsf0");
status = IoAttachDevice(fdo, &TargetDeviceName, &DevExt->LowerLevelDeviceObject);
if(!NT_SUCCESS(status))
{
IoDeleteSymbolicLink(&SymbolicLinkName);
IoDeleteDevice(fdo);
return status;
}
fdo->DeviceType = DevExt->LowerLevelDeviceObject->DeviceType;
fdo->Characteristics = DevExt->LowerLevelDeviceObject->Characteristics;
fdo->Flags |= (DevExt->LowerLevelDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO));
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
KdPrint(("Leave CreateDevice!/n"));
return status;
}
#pragma PAGEDCODE
NTSTATUS Read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
KdPrint(("Enter Read!/n"));
PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, OnRead, NULL, TRUE, TRUE, TRUE);
KdPrint(("Leave Read!/n"));
return IoCallDriver(DevExt->LowerLevelDeviceObject, Irp);
}
#pragma LOCKEDCODE
NTSTATUS OnRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
KdPrint(("Enter OnRead!/n"));
if(Irp->PendingReturned)
IoMarkIrpPending(Irp);
else if(NT_SUCCESS(Irp->IoStatus.Status))
{
if(Irp->IoStatus.Information > 0 && NULL != Irp->AssociatedIrp.SystemBuffer)
{
for(unsigned int i = 0; i < Irp->IoStatus.Information; i++)
KdPrint(("0x%2x", ((char*)Irp->AssociatedIrp.SystemBuffer)[i]));
KdPrint(("/n"));
}
}
KdPrint(("Leave OnRead!/n"));
return Irp->IoStatus.Status;
}
在这个过程中我有以下四点体会:
1、在将新建的设备挂接到串口之后,需要将串口的DeviceType和Characteristic赋值给新建的设备的相应成员中
2、对于过滤驱动,由于不知道下层设备的IO方式到底是哪种,所以需要将Flags |= lowerDev->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO)
3、只有在完成例程返回STATUS_MORE_PROCESSING_REQUIRED时才需要由上层驱动结束IRP(IoCompleteRequest)
4、过滤驱动派遣函数的默认处理中应该将IRP转发至下层驱动,否则下层驱动会有很多IRP接收不到,这样会出问题
- 一个简单的串口过滤驱动及一点体会
- 一个简单的串口过滤驱动
- 驱动的一点体会
- 一个可以过滤串口输入的过滤驱动
- 一个串口输入过滤驱动
- 串口过滤驱动(过滤所有的串口)
- 一个简单的文件系统过滤驱动框架
- 一个简单的文件系统过滤驱动框架
- 串口接收缓冲区的一点体会
- 串口的过滤驱动例子
- windows驱动开发的一点体会
- 关于简单模式的一点体会
- 串口过滤驱动源码
- 串口过滤驱动练习
- 一个基于简单USB过滤驱动。。
- <寒江独钓>Windows内核安全编程__一个简单的Windows串口过滤驱动程序的开发
- 一个简单的文字过滤
- 在工作中的一点体会
- IBM技术社区2009 Java 专区最受欢迎内容
- U-boot-13.0-rc3 cpu/pxa/start.S 分析
- Java 复习笔记_第3天
- Google is leaving...
- spring集成quartz,出现2次重复调用的问题
- 一个简单的串口过滤驱动及一点体会
- .net程序中资源文件的保护办法探讨
- SQL Server里的 ISNULL 与 Oracle 中的 NULLIF
- SSH 端口转发
- 菜鸟提问:啊D注入工具 猜解出来的密码貌似不正确
- Delphi 之运算符重载
- Spring AOP声明式事务异常回滚
- Java 复习笔记_第4天
- 再见,谷歌