内核驱动开发---串口过滤驱动连载(part1)
张静茹2015/07/19软件综合 IP:天津
本程序来自<寒江独钓>Windows内核安全编程和<windows内核安全与驱动开发>中串口过滤一章
书中的程序绑定了串口设备0到31,而且只写了过滤发送而没有写过滤接收


程序被我修改为只过滤串口设备\Device\Serial2,而且过滤发送和接收
一般串口助手看到串口名称为COM*,但是在内核中串口设备的路径为"\Device\Serial*"




程序如下
<code class="lang-cpp">#include "DriverEntry.h"
#define DEBUG
    #ifdef DEBUG
    #define __asm_3 __asm int 3
    #define _asm_3 __asm int 3
    #else
    #define __asm_3  
    #define _asm_3  
    #endif
  
#endif
  
PDEVICE_OBJECT fltobj = NULL; //过滤设备
PDEVICE_OBJECT nextobj = NULL; //真实设备
//驱动程序是从DriverEntry开始执行的
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,//pDriverObject指向本驱动的驱动对象指针
    IN PUNICODE_STRING pRegistryPath)//本驱动所在的注册表路径
{
    _asm_3;//中断
    NTSTATUS status = 0;//初始化一个状态
    UNICODE_STRING Name;//驱动与设备名
      
    pDriverObject->DriverUnload = DriverUnload;//驱动卸载时候调用的派遣函数
    for (size_t i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    {
        pDriverObject->MajorFunction<i> = Device_General;//Device_General处理除了读,写,电源事件
    }
    pDriverObject->MajorFunction[IRP_MJ_READ] = Device_Read;//串口接收时会调用这个派遣函数
    pDriverObject->MajorFunction[IRP_MJ_WRITE] = Device_Write;//串口发送时会调用这个派遣函数
    pDriverObject->MajorFunction[IRP_MJ_POWER] = Device_Power;   
      
    PFILE_OBJECT fileobj = NULL;  //文件指针
    PDEVICE_OBJECT devobj = NULL; //串口设备
    RtlInitUnicodeString(&Name, L"\\Device\\Serial2");//串口设备路径
  
    status = IoGetDeviceObjectPointer(&Name, //打开串口设备\\Device\\Serial2
        FILE_ALL_ACCESS, //全部读写权限
        &fileobj,//无用的文件对象指针
        &devobj);//打开串口
  
    if (!NT_SUCCESS(status)) //如果返回的状态是错误的
    {
        _asm_3;     //中断
        return status;//返回驱动加载错误
    }
    ObDereferenceObject(fileobj);//返回状态为成功立即释放无用的文件对象指针
  
    ccpAttachDevice( //创建一个过滤设备并附加到串口设备\\Device\\Serial2上
        pDriverObject,//DriverEntry传进来的本驱动的驱动对象
        devobj,//串口设备\\Device\\Serial2
        &fltobj,//过滤设备
        &nextobj);//真实设备
      
    return STATUS_SUCCESS;
}
  
NTSTATUS
ccpAttachDevice(    //创建一个过滤设备并附加到串口设备上
PDRIVER_OBJECT Driver,  //DriverEntry传入
PDEVICE_OBJECT oldobj,  //源设备
PDEVICE_OBJECT *fltobj, //创建的过滤设备
PDEVICE_OBJECT *next)   //真事的设备
{
  
    NTSTATUS status = 0;
    PDRIVER_OBJECT topDev = NULL;
      
    status = IoCreateDevice( //创建一个过滤设备
        Driver,     //DriverEntry传入
        0,          //设备扩展
        NULL,       //过滤设备不需要名称
        oldobj->DeviceType,//设备类型
        0,          //设备特征
        FALSE,      //是否独占
        fltobj      //创建好的过滤设备
        );
    if (!NT_SUCCESS(status)) //如果错误
    {
        fltobj = NULL;
        DbgPrint("%s第%s行发生错误",__FILE__,__LINE__);
        return status;
    }
  
    //拷贝标记位 
    //内存传输策略
    if (oldobj->Flags & DO_BUFFERED_IO) (*fltobj)->Flags |= DO_BUFFERED_IO;
    if (oldobj->Flags & DO_DIRECT_IO) (*fltobj)->Flags |= DO_DIRECT_IO;
    if (oldobj->Flags & DO_BUFFERED_IO) (*fltobj)->Flags |= DO_BUFFERED_IO;
  
    if (oldobj->Characteristics & FILE_DEVICE_SECURE_OPEN)
        (*fltobj)->Characteristics |= FILE_DEVICE_SECURE_OPEN;
    (*fltobj)->Flags |= DO_POWER_PAGABLE;
  
    status = IoAttachDeviceToDeviceStackSafe(*fltobj, oldobj, &topDev); //把创建好的过滤设备附加到串口设备
    if ((!NT_SUCCESS(status)) || (topDev == NULL))//如果失败了
    {
        IoDeleteDevice(*fltobj);//删除创建的过滤设备
        *fltobj = NULL;
        return status;
    }
    //此时fltobj是创建好并且附加成功的过滤设备
    *next = topDev;//设备栈最下面的真实设备
  
    (*fltobj)->Flags = (*fltobj)->Flags & ~DO_DEVICE_INITIALIZING;
    return status;
}
  
NTSTATUS Device_Read(//读 //如果这个派遣函数被调用了说明单片机往计算机发送了数据
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp)
{
    _asm_3 
  
        PIO_STACK_LOCATION Irpsp = IoGetCurrentIrpStackLocation(Irp);
        NTSTATUS stayus = Device_General(DeviceObject, Irp);//从真实设备读取数据
        //此时单片机发往计算机的数据在Irp->AssociatedIrp->SystemBuffer中
        //数据的长度在Irp->IoStatusInformation中
        return stayus;
}
  
NTSTATUS Device_Write(//写 //如果这个派遣函数被调用了说明计算机往单片机发送了数据
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp)
{
    //此时计算机发出的数据在Irp->AssociatedIrp->SystemBuffer中
    PIO_STACK_LOCATION Irpsp = IoGetCurrentIrpStackLocation(Irp);
    //数据长度在Irps->Parameters.Write.Length中
    _asm_3
        return  Device_General(DeviceObject, Irp);
}
  
NTSTATUS Device_General(//通用处理
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp)
{
    //_asm_3;
    IoSkipCurrentIrpStackLocation(Irp);//跳过当前栈空间
    return IoCallDriver(nextobj, Irp);  //将请求发送给真实的设备
}
NTSTATUS Device_Power(//Power处理
    _In_ struct _DEVICE_OBJECT *DeviceObject,
    _Inout_ struct _IRP *Irp)
{
    //_asm_3;
    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);//跳过当前栈空间
    return PoCallDriver(nextobj, Irp);  //将请求发送给真实的设备
}
  
  
  
  
VOID DriverUnload(PDRIVER_OBJECT driver)
{
    //_asm_3;
    if (nextobj != NULL)
        IoDetachDevice(nextobj); //解除引用
  
    if (fltobj != NULL)
        IoDeleteDevice(fltobj); //删除过滤设备
    DbgPrint("%s%d卸载完毕", __FILE__, __LINE__);
}
  
NTSTATUS Device_Conteol(//设备控制
_In_ struct _DEVICE_OBJECT *DeviceObject,
_Inout_ struct _IRP *Irp)
{
    //_asm_3
      
    return 0;
}</i></code>
修改前.png 修改后.png
来自:计算机科学 / 软件综合
7
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
张静茹 作者
9年5个月前 IP:天津
779965
2.png
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
张静茹作者
9年5个月前 IP:天津
781916
引用 starpeng:
看来这里编程的人比较少,多好的东西,都没人支持呀!
写驱动的人少,资料也少
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
张静茹作者
9年5个月前 IP:天津
781943
引用 仓生木品:
这句感觉不太对。
支持!正在学51,还只会跑流水灯
<windows内核安全与驱动开发>是<天书夜读 从汇编到windows内核>和寒江独钓 windows内核安全编程的整合版,
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
张静茹作者
8年9个月前 修改于 8年9个月前 IP:江苏
814757
DeviceTree,Usb Tree View 与WinObj 下载
attachment icon devicetree_v230.zip 1.93MB ZIP 46次下载

attachment icon WinObj.zip 447.65KB ZIP 34次下载

attachment icon usbtreeview.zip 266.68KB ZIP 32次下载
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
张静茹
进士 学者 机友 笔友
文章
139
回复
1869
学术分
1
2010/12/30注册,1个月23天前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}