首页> 中国专利> 一种IRP的处理方法及过滤驱动

一种IRP的处理方法及过滤驱动

摘要

本发明公开一种IRP的处理方法及过滤驱动,属于电子设备输入领域。该方法包括:过滤驱动获取并保存当前目标IRP,根据当前目标IRP创建新IRP,将当前目标IRP的特征信息复制到新IRP中;过滤驱动将新IRP发送到底层驱动,等待底层驱动完成新IRP;过滤驱动接收底层驱动完成的新IRP,从底层驱动完成的新IRP中取出底层驱动返回的数据,并将底层驱动返回的数据复制到当前目标IRP中;过滤驱动完成当前目标IRP。本发明提供的IRP处理方法,第三方驱动无法截断新IRP,可以保证过滤驱动的正常运行;过滤驱动在接收到底层驱动完成的新IRP之前不会向底层驱动继续发送目标IRP,保证系统能够稳定运行。

著录项

  • 公开/公告号CN105912482A

    专利类型发明专利

  • 公开/公告日2016-08-31

    原文格式PDF

  • 申请/专利权人 飞天诚信科技股份有限公司;

    申请/专利号CN201610473219.2

  • 发明设计人 陆舟;于华章;

    申请日2016-06-24

  • 分类号

  • 代理机构

  • 代理人

  • 地址 100085 北京市海淀区学清路9号汇智大厦B楼17层

  • 入库时间 2023-06-19 00:22:08

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2019-05-28

    授权

    授权

  • 2016-09-28

    实质审查的生效 IPC(主分类):G06F13/10 申请日:20160624

    实质审查的生效

  • 2016-08-31

    公开

    公开

说明书

技术领域

本发明涉及电子设备输入领域,尤其涉及一种IRP的处理方法及过滤驱动。

背景技术

操作系统中的应用程序使用一种I/O请求包(I/O请求包英文名称为:I/O request packet,记为IRP)进行和驱动程序(驱动程序包括过滤驱动)的通讯。当应用程序发出I/O请求时,系统I/O管理器根据I/O请求创建正确的IRP,发送给驱动程序。驱动程序将IRP完成后,I/O管理器从IRP中获取返回状态及数据,并将状态、数据返回给应用程序。

现有技术中,过滤驱动接收到来自系统的IRP,并向底层驱动下发IRP之后,会出现第三方驱动拦截IRP中的底层驱动数据。如果遇到恶意IRP,当底层驱动没有完成当前处理的IRP时,过滤驱动就继续向底层驱动发送IRP。

现有技术中,过滤驱动处理IRP的方法存在以下弊端:过滤驱动向底层驱动下发IRP之后,第三方驱动可以拦截IRP,并对IRP进行处理,处理后直接返回系统或上层驱动,使过滤驱动接收不到IRP中底层驱动返回的数据,从而导致过滤驱动处理异常;当遇到恶意IRP时,底层驱动没有完成当前处理的IRP就继续向底层驱动发送IRP,如此,容易导致过滤驱动崩溃,最终导致系统崩溃。

发明内容

本发明为解决上述现有技术中存在的技术问题提供一种IRP的处理方法及过滤驱动。

本发明提供了一种IRP的处理方法,包括以下步骤:

步骤S1:过滤驱动获取并保存当前目标IRP,根据当前目标IRP创建新IRP,将当前目标IRP的特征信息复制到新IRP中;

步骤S2:所述过滤驱动将新IRP发送到底层驱动,等待底层驱动完成新IRP;

步骤S3:所述过滤驱动接收底层驱动完成的新IRP,从底层驱动完成的新IRP中取出底层驱动返回的数据,并将底层驱动返回的数据复制到保存的当前目标IRP中;

步骤S4:所述过滤驱动完成当前目标IRP。

本发明还提供了一种过滤驱动,包括:

获取模块,用于获取当前目标IRP;

保存模块,用于保存所述获取模块获取的当前目标IRP;

创建模块,用于根据所述获取模块获取的当前目标IRP创建新IRP;

第一复制模块,用于将所述获取模块获取的当前目标IRP的特征信息复制到所述创建模块创建的新IRP中;

发送模块,用于将所述创建模块创建的新IRP发送到底层驱动,等待底层驱动完成新IRP;

第一接收模块,用于当底层驱动完成新IRP时,接收层驱动完成的新IRP;

取出模块,用于从所述第一接收模块接收的底层驱动完成的新IRP中取出底层驱动返回的数据,

第二复制模块,用于将所述取出模块取出的底层驱动返回的数据复制到所述保存模块保存的当前目标IRP中;

完成模块,用于当所述第二复制模块将底层驱动返回的数据复制到所述保存模块保存的当前目标IRP之后,完成所述保存模块保存的当前目标IRP。

本发明与现有技术相比的有益效果是:本发明中,过滤驱动获取当前目标IRP并根据当前目标IRP创建一个新IRP,将新IRP下发给底层驱动,第三方驱动无法截断新IRP,使过滤驱动能够接收到底层驱动完成的新IRP,从而能够接 收到底层驱动完成的新IRP中底层驱动返回的数据,保证过滤驱动的正常运行;过滤驱动将根据当前目标IRP创建的新IRP下发给底层驱动后,需要等待底层驱动完成新IRP,在接收到底层驱动完成的新IRP之前,不会向底层驱动发送目标IRP,如此可以保证过滤驱动不会因为下发IRP过多导致系统崩溃,从而保证系统能够稳定运行。

附图说明

图1所示为本发明实施例1中过滤驱动处理IRP的方法流程图;

图2所示为本发明实施例2中过滤驱动处理IRP的方法流程图;

图3所示为本发明实施例2中过滤驱动的线程处理目标IRP的方法流程图;

图4所示为本发明实施例3中过滤驱动处理IRP的方法流程图;

图5所示为本发明实施例4中过滤驱动的模块组成框图。

具体实施方式

为使本发明的目的、技术方案和优点更加清楚,下面将结合附图对本发明实施方式作进一步地详细描述。

实施例1

本实施例提供一种串行IRP处理的方法,如图1所示,包括:

步骤S1:过滤驱动获取当前目标IRP,根据当前目标IRP创建新IRP,将当前目标IRP的特征信息复制到新IRP中;

步骤S2:过滤驱动将新IRP发送到底层驱动,等待底层驱动完成新IRP;

步骤S3:过滤驱动接收底层驱动完成的新IRP,从底层驱动完成的新IRP中取出底层驱动返回的数据,并将底层驱动返回的数据复制到当前目标IRP中;

具体地,步骤S3具体为:过滤驱动接收底层驱动完成的新IRP,从底层驱动完成的新IRP中指定位置取出底层驱动返回的数据,并将底层驱动返回的数据复制到当前目标IRP中对应位置。更具体地,过滤驱动接收底层驱动完成的新IRP,具体为:过滤驱动接收底层驱动返回的数据。当底层驱动完成新IRP之后,过滤驱动中的新IRP的对应位置会接收到底层驱动返回的数据。

步骤S4:过滤驱动完成当前目标IRP;

具体地,步骤S4具体为:过滤驱动调用系统函数完成当前目标IRP。步骤S4中当前目标IRP中包括底层驱动返回的数据。

可选地,上述步骤S1中,过滤驱动根据当前目标IRP创建新IRP,具体为:过滤驱动获取当前目标IRP的数据长度,根据当前目标IRP的数据长度创建新IRP。

具体地,过滤驱动获取当前目标IRP的数据长度,具体为:过滤驱动获取当前目标IRP的数据结构指针,并根据数据结构指针访问当前目标IRP的数据结构,获取当前目标IRP的数据长度。

进一步具体地,上述步骤S1中,过滤驱动将当前目标IRP的特征信息复制到新IRP中,具体包括:

步骤A1:过滤驱动根据当前目标IRP的数据结构指针访问当前目标IRP的数据结构,获取当前目标IRP数据结构中的特征信息;

步骤A2:过滤驱动将特征信息复制到新IRP中。

具体地,上述过滤驱动根据当前目标IRP的数据长度创建新IRP,具体包括:

步骤a1:过滤驱动根据当前目标IRP的数据长度创建新IRP的内存空间;

步骤a2:过滤驱动根据内存空间创建新IRP。

在本实施例中,上述特征信息包括控制码和文件对象。

可选地,本实施例上述IRP的处理方法中,还包括:过滤驱动接收来自系统的目标IRP,并将目标IRP放入IRP队列中的数据末端,置位IRP通知事件;

相应地,上述步骤S1中过滤驱动获取当前目标IRP具体为:过滤驱动从IRP队列首端获取当前目标IRP;

具体地,上述步骤S1具体为:过滤驱动将IRP队列首端的目标IRP作为当前目标IRP,根据当前目标IRP创建新IRP,获取IRP队列中的当前目标IRP,将当前目标IRP的特征信息复制到新IRP中。

进一步具体地,上述过滤驱动根据当前目标IRP创建新IRP,获取IRP队列中的当前目标IRP,具体为:

过滤驱动首先获取IRP队列中当前目标IRP,然后根据当前目标IRP创建新IRP;

或者,过滤驱动首先根据当前目标IRP创建新IRP,然后获取IRP队列中的当前目标IRP。

进一步地,上述方法中,步骤S1之前还包括:

步骤M1:过滤驱动判断IRP队列中是否有目标IRP,是则执行步骤S1;否则执行步骤M2。

步骤M2:过滤驱动等待置位IRP通知事件,当置位IRP通知事件之后,复位IRP通知事件。

优选地,上述步骤M2之后、步骤S1之前,还包括:

步骤M3:过滤驱动判断IRP队列中是否有目标IRP,是则执行步骤S1;否则执行步骤M2。

进一步地,上述步骤S3中,当过滤驱动接收到来自底层驱动完成的新IRP之后,还包括:过滤驱动将当前目标IRP从IRP队列中移除。

进一步地,上述过滤驱动接收到来自系统的目标IRP之后,还包括:过滤驱动将目标IRP设为挂起状态,并将IRP挂起状态返回系统。

可选地,本实施例IRP的处理方法中,上述步骤S1中,还包括:过滤驱动将当前目标IRP和新IRP存储到自身的数据结构中;

相应地,上述步骤S3中,还包括:过滤驱动清除数据结构中的新IRP和当前目标IRP。

进一步地,上述步骤S4之后还包括:过滤驱动将状态码返回系统。

本发明与现有技术相比的有益效果是:本发明中,过滤驱动获取当前目标IRP并根据当前目标IRP创建一个新IRP,将新IRP下发给底层驱动,第三方驱动无法截断新IRP,使过滤驱动能够接收到底层驱动完成的新IRP,从而能够接收到底层驱动完成的新IRP中底层驱动返回的数据,保证过滤驱动的正常运行;过滤驱动将根据当前目标IRP创建的新IRP下发给底层驱动后,需要等待底层驱动完成新IRP,在接收到底层驱动完成的新IRP之前,不会向底层驱动发送目标IRP,如此可以保证过滤驱动不会因为下发IRP过多导致系统崩溃,从而保证系统能够稳定运行。

实施例2

本实施例提供一种IRP处理的方法,包括过滤驱动初始化流程、过滤驱动处理IRP流程以及过滤驱动中的线程处理目标IRP流程,具体地:

过滤驱动初始化流程具体包括:

步骤21:应用程序加载过滤驱动。

具体地,应用程序通过调用系统接口函数CreateFile加载过滤驱动,并根据系统接口函数CreateFile的返回值判断过滤驱动是否加载成功,以及在过滤驱动加载成功时根据系统接口函数CreateFile的返回值获取过滤驱动的句柄, 过滤驱动的句柄供应用程序和过滤驱动之间进行通信使用。

具体地,系统接口函数CreateFile的函数声明为:

其中,lpFileName用来指定过滤驱动的名称,例如,过滤驱动的名称为:"\\.\FT_KBD";若系统接口函数CreateFile的返回值为预设值,则过滤驱动加载失败;若系统接口函数CreateFile的返回值不为预设值,则过滤驱动加载成功,且系统接口函数CreateFile的返回值为过滤驱动的句柄;例如,预设值为-1。

步骤22:过滤驱动创建过滤设备对象。

例如,过滤驱动调用内核函数IoCreateDevice创建过滤设备对象。

步骤23:过滤驱动创建IRP通知事件,初始化IRP队列,为过滤设备对象创建线程,将过滤设备对象链接到系统键盘驱动设备链的顶层,并从系统中获取目标设备对象地址。

本实施例中,当过滤驱动将过滤设备对象链接到系统键盘驱动设备链的顶层,并从系统中获取目标设备对象地址之后,就建立了与底层驱动设备的连接。

具体地,过滤驱动初始化IRP队列,具体为将IRP队列中的数据清除。

本实施例中,IRP队列中的数据按照先进先出顺序进行存放,即过滤驱动将接收到的IRP放入IRP队列数据的末端,线程从IRP队列数据的首端取出目标IRP。

进一步地,在过滤驱动将过滤设备对象链接到系统键盘驱动设备链的顶层之前,还包括:过滤驱动通过调用系统函数获取系统键盘驱动设备链中一个设备对象地址;

相应地,过滤驱动将过滤设备对象链接到系统键盘驱动设备链的顶层,并从系统中获取目标设备对象的地址,具体为:过滤驱动根据获取的系统键盘驱动设备链的设备对象地址,将过滤设备对象链接到系统键盘驱动设备链的顶层,并获取系统函数返回的目标设备对象地址。

例如,过滤驱动通过调用系统函数

IoAttachDeviceToDeviceStack(DeviceObject,KBD_DeviceObject)将创建的过滤设备对象链接到系统键盘驱动设备链的顶层,并且接收到内核函数

IoAttachDeviceToDeviceStack返回的设备对象地址;其中参数DeviceObject为过滤设备对象,参数KBD_DeviceObject为过滤设备对象获取的系统键盘驱动设备链的设备对象地址(KBD_DeviceObject在应用程序加载过滤驱动或在过滤驱动创建过滤设备对象时从系统中获取),过滤驱动将过滤设备对象链接到系统键盘驱动设备链的顶层之后,通过系统函数IoAttachDeviceToDeviceStack返回目标设备对象地址,从而获取目标设备对象地址。

本实施例中,过滤驱动创建的IRP通知事件为自动复位处理事件,即每当线程接收到置位的IRP通知事件之后,自动复位IRP通知事件。

可选地,在步骤21之后、步骤22之前,还包括:过滤驱动判断是否已经 创建过滤设备对象,是则完成初始化,否则执行步骤22。

过滤驱动处理IRP流程,如图2所示,包括:

步骤201:过滤驱动通过过滤设备对象接收来自系统的IRP。

需要说明的是,当过滤驱动创建的过滤设备对象支持接收目标IRP时,过滤驱动接收来自系统的IRP类型为目标IRP;当过滤驱动创建的过滤设备对象支持接收PNP请求时,过滤驱动接收到来自系统的IRP类型为PNP请求。

当接收到的IRP类型为目标IRP时,执行步骤202,当接收到的IRP类型为PNP请求时,执行步骤203。

步骤202:过滤驱动将目标IRP设为挂起状态,将目标IRP放入IRP队列中的数据末端,获取目标IRP的数据长度,置位IRP通知事件,将IRP挂起状态返回系统。

具体地,过滤驱动将目标IRP设为挂起状态,具体为:过滤驱动调用内核函数IoMarkIrpPending将目标IRP设为挂起状态。例如,IoMarkIrpPending(Irp)。

具体地,过滤驱动将目标IRP放入IRP队列中的数据末端,具体为:过滤驱动使用内核函数InsertTailList将目标IRP加入IRP队列中的数据末端。例如,InsertTailList(&ReadQueue,&Irp->Tail.Overlay.ListEntry)。

具体地,过滤驱动置位IRP通知事件,具体为:过滤驱动使用内核函数KeSetEvent将IRP通知事件置位,例如:

KeSetEvent(&newIrpEvent,IO_NO_INCREMENT,FALSE)。

具体地,过滤驱动将IRP挂起状态返回系统,具体为:过滤驱动通过内核函数IoMarkIrpPending将Irp标记为挂起状态,并将挂起状态返回系统。例如,过滤驱动通过内核函数IoMarkIrpPending将Irp标记具体为IoMarkIrpPending (Irp);过滤驱动向系统返回的状态码具体为STATUS_PENDING。

步骤203:过滤驱动判断PNP请求是否为拔除请求,是则执行步骤204;否则执行步骤205。

步骤204:过滤驱动将目标设备的拔除标志设置为已拔除。

步骤205:过滤驱动通过目标设备对象向底层驱动发送PNP请求,等待底层驱动完成PNP请求。

具体地,过滤驱动根据目标设备对象地址将PNP请求发送到对应的目标设备对象,通过目标设备对象向底层驱动发送PNP请求。目标设备对象地址在过滤驱动创建过滤设备对象时从系统中获取,具体参考本实施例中步骤23。

步骤206:过滤驱动接收到底层驱动完成PNP请求返回的状态,判断目标设备的拔除标志是否为已拔除,是则执行步骤207;否则执行步骤208。

步骤207:过滤驱动将过滤设备对象与底层驱动设备断开连接。

步骤208:过滤驱动将接收到的底层驱动完成PNP请求返回的状态返回系统。

步骤202中,当过滤驱动置位IRP通知事件后,通知自身创建的线程处理IRP队列中的目标IRP。

过滤驱动中的线程处理目标IRP流程,如图3所示,包括:

步骤L1:线程判断IRP队列中是否有目标IRP,是则执行步骤L4,否则执行步骤L2。

具体地,线程通过系统函数IsListEmpty判断过滤驱动中IRP队列是否为空,是则没有目标IRP;否则有目标IRP;例如:

IsListEmpty(&ReadQueue),ReadQueue为空时,IsListEmpty返回TRUE,否则返回FALSE。

在本实施例中,当线程处理完IRP队列中所有目标IRP之后,IRP队列中没有 目标IRP时,执行步骤L2。

步骤L2:线程等待接收置位的IRP通知事件,当接收到置位的IRP通知事件之后,复位IRP通知事件。

具体地,线程通过调用系统函数等待接收置位的IRP通知事件。例如,线程通过调用系统函数等待接收置位的IRP通知事件如下:

KeWaitForSingleObject(&newIrpEvent,Executive,KernelMode,FALSE,NULL),其中,newIrpEvent为过滤驱动定义的IRP通知事件,其它参数为系统提供的值,当过滤驱动接收到系统函数KeWaitForSingleObject返回的状态时,线程接收到置位的IRP通知事件。

具体地,复位IRP通知事件,具体为:线程调用系统函数KeClearEvent(&newIrpEvent)复位IRP通知事件。

在本实施例中,线程判断IRP队列中没有目标IRP时,等待接收置位的IRP通知事件,当过滤驱动接收到来自系统的目标IRP并置位IRP通知事件,并且当线程接收到置位的IRP通知事件后,线程复位IRP通知事件。

步骤L3:线程判断IRP队列中是否有目标IRP,是则执行步骤L4,否则执行步骤L2。

具体地,线程通过系统函数IsListEmpty判断过滤驱动中IRP队列是否为空,是则没有目标IRP;否则有目标IRP;例如:

IsListEmpty(&ReadQueue),ReadQueue为空时,IsListEmpty返回TRUE,否则返回FALSE。

步骤L4:线程将IRP队列首端的目标IRP作为当前目标IRP,根据当前目标IRP创建新IRP,获取IRP队列中的当前目标IRP,将当前目标IRP的特征信息复制到新IRP中。

可选地,步骤L4中线程根据当前目标IRP创建新IRP,获取IRP队列中的当前目标IRP,具体为:线程首先获取IRP队列中当前目标IRP,然后根据当前目标IRP创建新IRP;

或者,线程首先根据IRP队列中的当前目标IRP创建新IRP,然后线程获取IRP队列中的当前目标IRP。

具体地,线程根据当前目标IRP创建新IRP,具体为:线程获取当前目标IRP的数据长度,根据当前目标IRP的数据长度创建新IRP。

进一步具体地,线程获取当前目标IRP的数据长度,具体为,线程获取当前目标IRP的数据结构指针,并根据数据结构指针访问当前目标IRP的数据结构,获取当前目标IRP的数据长度。更具体地,线程获取当前目标IRP的数据结构指针,具体为:线程调用内核函数获取当前目标IRP的数据结构指针。

例如,线程调用内核函数IoGetCurrentIrpStackLocation(Irp)获取当前目标IRP的PIO_STACK_LOCATION数据结构指针,并根据PIO_STACK_LOCATION数据结构指针访问当前目标IRP的PIO_STACK_LOCATION数据结构,获取当前目标IRP的数据长度。

具体地,上述线程将当前目标IRP中的特征信息复制到新IRP中,具体包括:

步骤A1:线程根据当前目标IRP的数据结构指针访问当前目标IRP的数据结构,获取所述当前目标IRP数据结构中的特征信息。

步骤A2:线程将特征信息复制到新IRP中。

具体地,上述特征信息包括控制码和文件对象。

例如,线程将当前目标IRP中的特征信息复制到新IRP中如下:

线程根据当前目标IRP的数据结构指针访问当前目标IRP的数据结构,获 取前目标IRP数据结构中的控制码MinorFunction和文件对象FileObject;

新IRP:newIrps=IoGetCurrentIrpStackLocation(newIrp);

当前目标IRP:Irps=IoGetCurrentIrpStackLocation(Irp);

线程将获取的控制码MinorFunction复制到新IRP中如下:

newIrps->MinorFunction=Irps->MinorFunction;//0

线程将文件对象FileObject复制到新IRP中如下:

newIrps->FileObject=Irps->FileObject;

其中,IoGetCurrentIrpStackLocation为内核函数。

具体地,上述线程根据当前目标IRP的数据长度创建新IRP,具体包括:

步骤a1:线程根据当前目标IRP的数据长度创建新IRP的内存空间;

步骤a2:线程根据内存空间创建新IRP。

本实施例中,线程还根据目标设备对象地址、当前目标IRP类型创建新IRP;

相应地,线程根据内存空间创建新IRP,具体为:线程根据内存空间、目标设备对象地址、目标IRP类型和当前目标IRP数据长度创建新IRP。目标设备对象在过滤驱动初始化时获取,具体参考步骤23;当前目标IRP类型从当前目标IRP的数据结构中获取。

例如,线程调用内核函数IoGetCurrentIrpStackLocation(Irp)获取当前目标IRP的PIO_STACK_LOCATION数据结构指针,并根据PIO_STACK_LOCATION数据结构指针获取当前目标IRP的数据长度,当前目标IRP的PIO_STACK_LOCATION数据结构如下:

上述PIO_STACK_LOCATION数据结构中着重体现当前目标IRP类型IRP_MJ_READ、文件对象FileObject、数据长度Length和控制码MinorFunction,…为省略部分。

线程获取的当前目标IRP为:Irp=CONTAINING_RECORD(ReadQueue.Flink,IRP,Tail.Overlay.ListEntry);

线程根据当前目标IRP的数据长度创建内存空间,记为user,调用内核函数根据内存空间、目标IRP的类型、目标设备对象地址创建的新IRP如下:

newIrp=IoBuildAsynchronousFsdRequest(IRP_MJ_READ,obj,user,userLen,&offset,Iostatus),其中,IRP_MJ_READ为IRP类型,obj为newIrp下发的目标设备对象地址,user为存放数据的内存空间,userLen为user长度,offset为偏移量(值为0),Iostatus为Irp返回时存储的返回信息,Iostatus中包括数据返回长度(user中实际存放多少数据)及处理状态。

步骤L5:线程将新IRP发送到底层驱动,等待底层驱动完成新IRP。

具体地,线程调用内核函数将新IRP发送到底层驱动,等待底层驱动完成新IRP。更具体地,线程等待底层驱动完成新IRP,具体包括:线程接收到内核函数的返回值,判断该返回值是否为需要等待置位事件,是则需要等待底层驱动返回的新IRP的置位事件,当接收到底层驱动返回的新IRP的置位事件之后执行步骤L6;否则执行步骤L6。例如,线程调用内核函数

KeWaitForSingleObject将新IRP发送到底层驱动,接收到内核函数的返回值,判断该返回值是否为STATUS_PENDING,是则需要等待底层驱动返回的新IRP的置位事件,当接收到底层驱动返回的新IRP的置位事件之后执行步骤L6;否则执行步骤L6。

在本实施例中,线程根据当前目标IRP创建新IRP时,还包括将新IRP通知事件与新IRP进行绑定,当底层驱动完成新IRP时置位新IRP通知事件。例如,线程将新IRP通知事件与新IRP进行绑定如下:newIrp->UserEvent=event。其中,新IRP的通知事件由线程在创建新IRP之前创建,或者在过滤驱动初始 化时创建,即上述步骤23中由过滤驱动创建(即与IRP通知事件同时创建)。

在本实施例中,线程将新IRP发生到底层驱动之后,需要等待底层驱动完成新IRP,在底层驱动完成新IRP之前,线程不会继续向底层驱动发送IRP,因此不会因为下发IRP过得导致系统崩溃,从而保证系统能够稳定运行。

步骤L6:线程接收底层驱动完成的新IRP,将当前目标IRP从IRP队列中移除;从底层驱动完成的新IRP中取出底层驱动返回的数据,并将底层驱动返回的数据复制到当前目标IRP中。

具体地,线程接收底层驱动完成的新IRP,具体为:线程接收底层驱动返回的数据。当底层驱动完成新IRP之后,线程中的新IRP的对应位置会接收到底层驱动返回的数据。

本实施例中,线程获取到当前目标IRP之后,保存当前目标IRP,在步骤L6中当线程将IRP队列中的当前目标IRP清除之后,线程中仍然保存有当前目标IRP。

在本实施例中,由于新IRP是过滤驱动中的线程创建,因此当新IRP下发到底层驱动后,底层驱动完成的新IRP必须将底层驱动数据返回到过滤驱动中线程的新IRP,如此可以保证过滤驱动中的线程能够接收到底层驱动完成的新IRP中底层驱动返回的数据。

步骤L6中,第三方驱动可以根据IRP队列中的当前目标IRP访问线程中保存的当前目标IRP,当线程将当前目标IRP从IRP队列中移除之后,第三方驱动无法访问线程中保存的当前目标IRP。当线程将底层驱动完成的新IRP中底层驱动返回的数据复制到当前目标IRP之后,因为IRP队列中的当前目标IRP已经被移除,所以第三方驱动无法获取底层驱动返回的数据。

具体地,线程从底层驱动完成的新IRP中取出底层驱动返回的数据,并将底 层驱动返回的数据复制到当前目标IRP中,具体为:线程从底层驱动完成的新IRP中指定位置取出底层驱动返回的数据,将底层驱动返回的数据复制到当前目标IRP中对应位置。

例如,当前目标IRP和新IRP的数据结构如下:

底层驱动将返回的数据写入到新IRP中SystemBuffer位置,过滤驱动从新 IRP中SystemBuffer位置取出底层驱动返回的数据,并将底层驱动返回的数据复制到当前IRP的SystemBuffer位置。

上述结构体着重体现SystemBuffer,…为省略部分。

步骤L7:线程完成当前目标IRP,执行步骤L1。

在步骤L7中的当前目标IRP中包括底层驱动返回的数据。

具体地,步骤L7具体为:线程调用系统函数完成当前目标IRP,完成当前目标IRP之后,执行步骤L1。

步骤L7中,线程调用系统函数完成当前目标IRP时,将当前目标IRP返回系统。

具体地,线程将当前目标IRP返回系统,具体为:线程将当前目标IRP中的数据返回系统。更具体地,线程将当前目标IRP中底层驱动的数据返回系统。

本实施例中,在步骤L1中,当线程判断IRP队列中有目标IRP时,步骤L4之前,还包括:

步骤H1:线程判断目标设备是否拔除或进入卸载状态,是则执行步骤H2;否则执行步骤L4。

具体地,线程判断目标设备是否拔除,具体为:线程判断目标设备的拔除标志是否为已拔除,如果是则目标设备已经拔除,否则目标设备未拔除;

例如,目标设备已拔出的标志为Flag1=1,即当Flag1=1时,目标设备为已拔出;当Flag1的值不为1时,目标设备没有拔出。

线程判断过滤驱动是否进入卸载状态,具体为:线程判断过滤驱动卸载标志是否为卸载状态,如果是,则驱动已经进入卸载状态,否则驱动没有进入卸载状态。

例如,过滤驱动进入卸载状态的标志为Flag2=1,即当Flag2=1时,过滤驱 动已经进入卸载状态;当Flag2的值不为1时,过滤驱动没有进入卸载状态。

步骤H2:线程依次从IRP队列中数据的首端获取并处理目标IRP,处理完IRP队列中所有的目标IRP之后,线程退出。

可选地,在步骤L2之后、步骤L3之前,还包括:

步骤H3:线程判断目标设备是否拔除或进入卸载状态,是则执行步骤H4;否则执行步骤L3。步骤L3具体参考步骤H1,在此不再赘述。

步骤H4:线程依次从IRP队列中数据的首端取出并处理目标IRP,处理完IRP队列中所有的目标IRP之后,线程退出。

可选地,在步骤L4之后、步骤L5之前,还包括:

步骤H5:线程判断目标设备是否拔除,是则释放新IRP,执行步骤H4。步骤H5中线程判断目标设备是否拔除具体参考上述步骤H1,在此不再赘述。

具体地,线程释放新IRP具体为:线程通过内核函数释放新Irp,例如:IoFreeIrp(newIrp);

本实施例中,线程将IRP队列中数据首端的IRP作为当前目标IRP,并根据当前目标IRP创建新IRP,将新IRP下发给底层驱动,底层第三方驱动无法截断新IRP,使过滤驱动能够接收到底层驱动返回的数据,从而保证过滤驱动的正常运行;过滤驱动接收到来自系统的目标IRP之后将目标IRP放入IRP队列的数据末端,线程从IRP队列的首端取出目标IRP,并且线程每次只能从IRP队列中取出一个目标IRP作为当前目标IRP,当线程将新IRP下发给底层驱动之后,需要等待底层驱动完成新IRP,在底层驱动完成新IRP之前不会继续向底层驱动发送IRP,如此可以保证过滤驱动有序处理IRP队列中的目标IRP,不会因为下发IRP过多导致系统崩溃,从而保证系统能够稳定运行。另外,本实施例中,当线程接收到置位的IRP通知事件之后,或处理完IRP队列中所有目标IRP之后,复位IRP通知事 件,避免IRP通知事件一直处于置位状态,可有效避免系统资源的浪费。

实施例3

本实施例提供一种IRP处理的方法,包括过滤驱动初始化流程、过滤驱动处理IRP流程,具体地:

过滤驱动初始化流程包括:

步骤31:应用程序加载过滤驱动。

具体地,应用程序通过调用系统接口函数CreateFile加载过滤驱动,并根据系统接口函数CreateFile的返回值判断过滤驱动是否加载成功,以及在过滤驱动加载成功时根据系统接口函数CreateFile的返回值获取过滤驱动的句柄,过滤驱动的句柄供应用程序和过滤驱动之间进行通信使用。

具体地,系统接口函数CreateFile的函数声明为:

其中,lpFileName用来指定过滤驱动的名称,例如,过滤驱动的名称为:"\\.\FT_KBD";若系统接口函数CreateFile的返回值为预设值,则过滤驱动加载失败;若系统接口函数CreateFile的返回值不为预设值,则过滤驱动加 载成功,且系统接口函数CreateFile的返回值为过滤驱动的句柄;例如,预设值为-1。

步骤32:过滤驱动创建过滤设备对象和数据结构。

例如,过滤驱动调用内核函数IoCreateDevice创建过滤设备对象。

步骤33:过滤驱动将过滤设备对象链接到系统键盘驱动设备链的顶层,并从系统中获取目标设备对象的地址。

本实施例中,当过滤驱动将过滤设备对象链接到系统键盘驱动设备链的顶层,并从系统中获取目标设备对象地址之后,就建立了与底层驱动设备的连接。

例如,过滤驱动调用内核函数IoAttachDeviceToDeviceStack将创建的过滤设备对象链接到系统键盘驱动设备链的顶层,并且接收到内核函数

IoAttachDeviceToDeviceStack返回的目标设备对象地址。

进一步地,在过滤驱动将过滤设备对象链接到系统键盘驱动设备链的顶层之前,还包括:过滤驱动通过调用系统函数获取系统键盘驱动设备链中一个设备对象地址;

相应地,过滤驱动将过滤设备对象链接到系统键盘驱动设备链的顶层,并从系统中获取目标设备对象的地址,具体为:过滤驱动根据获取的系统键盘驱动设备链的设备对象地址,将过滤设备对象链接到系统键盘驱动设备链的顶层,并获取系统函数返回的目标设备对象地址。

例如,过滤驱动通过调用系统函数

IoAttachDeviceToDeviceStack(DeviceObject,KBD_DeviceObject)将创建的过滤设备对象链接到系统键盘驱动设备链的顶层,并且接收到内核函数

IoAttachDeviceToDeviceStack返回的设备对象地址;其中参数DeviceObject为过滤设备对象,参数KBD_DeviceObject为过滤设备对象获取的系统键盘驱动设 备链的设备对象地址(KBD_DeviceObject在应用程序加载过滤驱动或在过滤驱动创建过滤设备对象时从系统中获取),过滤驱动将过滤设备对象链接到系统键盘驱动设备链的顶层之后,通过系统函数IoAttachDeviceToDeviceStack返回目标设备对象地址,从而获取目标设备对象地址。

可选地,在步骤31之后、步骤32之前,还包括:过滤驱动判断是否已经创建过滤设备对象,如果是则完成初始化,否则执行步骤32。

过滤驱动处理IRP流程,如图4所示,包括:

步骤301:过滤驱动通过过滤设备对象接收来自系统的IRP。

过滤设备对象在过滤驱动初始化时创建。

需要说明的是,当过滤驱动创建的过滤设备对象支持接收目标IRP时,过滤驱动接收来自系统的IRP类型为目标IRP;当过滤驱动创建的过滤设备对象支持接收PNP请求时,过滤驱动接收到来自系统的IRP类型为PNP请求。

在步骤301中,过滤驱动接收到的IRP类型为目标IRP时,即获取到当前目标IRP,执行步骤302;接收到的IRP类型为PNP请求时,对PNP请求进行处理,具体对PNP请求处理流程参考实施例2中步骤203-步骤208,在此不再赘述。

需要说明的是,过滤驱动接收到来自系统的目标IRP之后,将目标IRP保存到数据结构中,过滤驱动可以将多个目标IRP分别作为当前目标IRP同时处理(即将每个目标IRP作为一个当前目标IRP,同时处理多个当前目标IRP),也可以一次将一个目标IRP作为当前目标IRP进行处理。

步骤302:过滤驱动根据当前目标IRP创建新IRP,将当前目标IRP中的特征信息复制到新IRP中,并将新IRP和当前目标IRP存储到自身的数据结构中。

具体地,过滤驱动根据当前目标IRP创建新IRP,具体为:过滤驱动获取当前目标IRP的数据长度,根据当前目标IRP的数据长度创建新IRP。

进一步具体地,过滤驱动获取当前目标IRP的数据长度,具体为,过滤驱动获取当前目标IRP的数据结构指针,并根据数据结构指针访问当前目标IRP的数据结构,获取当前目标IRP的数据长度。更具体地,过滤驱动获取当前目标IRP的数据结构指针,具体为过滤驱动调用内核函数获取当前目标IRP的数据结构指针。

例如,过滤驱动调用内核函数IoGetCurrentIrpStackLocation(Irp)获取当前目标IRP的PIO_STACK_LOCATION数据结构指针,并根据PIO_STACK_LOCATION数据结构指针访问当前目标IRP的PIO_STACK_LOCATION数据结构,获取当前目标IRP的数据长度。

具体地,上述过滤驱动将当前目标IRP中的特征信息复制到新IRP中,具体包括:

步骤A1:过滤驱动根据当前目标IRP的数据结构指针访问当前目标IRP的数据结构,并获取所述当前目标IRP数据结构中的特征信息。

步骤A2:过滤驱动将特征信息复制到新IRP中。

具体地,上述特征信息包括控制码和文件对象。

例如,过滤驱动将当前目标IRP中的特征信息复制到新IRP中如下:

过滤驱动根据当前目标IRP的数据结构指针访问当前目标IRP的数据结构,获取前目标IRP数据结构中的控制码MinorFunction和文件对象FileObject;

新IRP:newIrps=IoGetCurrentIrpStackLocation(newIrp);

当前目标IRP:Irps=IoGetCurrentIrpStackLocation(Irp);

过滤驱动将获取的控制码MinorFunction复制到新IRP中如下:

newIrps->MinorFunction=Irps->MinorFunction;//0

过滤驱动将文件对象FileObject复制到新IRP中如下:

newIrps->FileObject=Irps->FileObject;

其中,IoGetCurrentIrpStackLocation为内核函数。

具体地,上述过滤驱动根据当前目标IRP的数据长度创建新IRP,具体包括:

步骤a1:过滤驱动根据当前目标IRP的数据长度创建新IRP的内存空间;

步骤a2:过滤驱动根据内存空间创建新IRP。

本实施例中,过滤驱动还根据目标设备对象地址、当前目标IRP类型创建新IRP;

相应地,过滤驱动根据内存空间创建新IRP,具体为:过滤驱动根据目标设备对象地址、目标IRP类型和当前目标IRP数据长度创建新IRP。目标设备对象地址在过滤驱动初始化时获取,具体参考步骤33;当前目标IRP类型从当前目标IRP数据结构中获取。

例如,过滤驱动调用内核函数IoGetCurrentIrpStackLocation(Irp)获取当前目标IRP的PIO_STACK_LOCATION数据结构指针,并根据PIO_STACK_LOCATION数据结构指针获取当前目标IRP的数据长度,当前目标IRP的

PIO_STACK_LOCATION数据结构如下:

上述PIO_STACK_LOCATION结构体中着重体现当前目标IRP类型IRP_MJ_READ、文件对象FileObject和控制码MinorFunction,…为省略部分。

过滤驱动获取的当前目标IRP为:Irp=CONTAINING_RECORD(ReadQueue.Flink,IRP,Tail.Overlay.ListEntry);

过滤驱动根据当前目标IRP的数据长度创建内存空间,记为user,调用内核函数根据内存空间、目标IRP的类型、目标设备对象地址创建的新IRP如下:

newIrp=IoBuildAsynchronousFsdRequest(IRP_MJ_READ,obj,user,userLen,&offset,Iostatus),其中,IRP_MJ_READ为IRP类型,obj为newIrp 下发的目标设备对象地址,user为存放数据的内存空间,userLen为user长度,offset为偏移量(值为0),Iostatus为Irp返回时存储的返回信息,Iostatus中包括数据返回长度(user中实际存放多少数据)及处理状态。

步骤303:过滤驱动将新IRP发送到底层驱动,等待底层驱动完成新IRP。

具体地,过滤驱动调用内核函数将新IRP发送到底层驱动,等待底层驱动完成新IRP。更具体地,过滤驱动等待底层驱动完成新IRP,具体包括:过滤驱动接收到内核函数的返回值,判断该返回值是否为需要等待置位事件,是则需要等待底层驱动返回的新IRP的置位事件,当接收到底层驱动返回的新IRP的置位事件之后执行步骤304;否则执行步骤304。例如,过滤驱动调用内核函数KeWaitForSingleObject将新IRP发送到底层驱动,接收到内核函数的返回值,判断该返回值是否为STATUS_PENDING,是则需要等待底层驱动返回的新IRP的置位事件,当接收到底层驱动返回的新IRP的置位事件之后执行步骤304;否则执行步骤304。

在本实施例中,过滤驱动根据当前目标IRP创建新IRP时,还包括将新IRP通知事件与新IRP进行绑定,当底层驱动完成新IRP时置位新IRP通知事件。例如,过滤驱动将新IRP通知事件与新IRP进行绑定如下:newIrp->UserEvent=event。其中,新IRP的通知事件由过滤驱动在创建新IRP之前创建,或者在过滤驱动初始化时创建,即可以在上述步骤32中由过滤驱动创建。

在本实施例中,过滤驱动将新IRP发生到底层驱动之后,需要等待底层驱动完成新IRP,在底层驱动完成新IRP之前,过滤驱动不会继续向底层驱动发送IRP,因此不会因为下发IRP过得导致系统崩溃,从而保证系统能够稳定运行。

步骤304:过滤驱动接收底层驱动完成的新IRP,清除自身数据结构中的新IRP和当前目标IRP,从底层驱动完成的新IRP中取出底层驱动返回的数据,并将 底层驱动返回的数据复制到当前目标IRP中。

具体地,过滤驱动接收底层驱动完成的新IRP,具体为:过滤驱动接收底层驱动返回的数据。当底层驱动完成新IRP之后,过滤驱动中的新IRP的对应位置会接收到底层驱动返回的数据。

本实施例中,过滤驱动接收到当前目标IRP之后,保存当前目标IRP,在步骤304中当过滤驱动将自身数据结构中的新IRP和当前目标IRP清除之后,过滤驱动中仍然保存有当前目标IRP。

在本实施例中,由于新IRP是过滤驱动中创建的,因此当新IRP下发到底层驱动后,底层驱动完成的新IRP必须返回过滤驱动,如此可以保证过滤驱动能够接收到底层驱动完成的新IRP中底层驱动返回的数据。

在本实施例中,第三方驱动只能根据过滤驱动自身数据结构访问过滤驱动中的当前目标IRP和新IRP,当过滤驱动清除自身数据结构中的新IRP和当前目标IRP之后,第三方驱动无法访问过滤驱动中当前目标IRP以及底层驱动完成的新IRP,从而使第三方驱动无法获取底层驱动完成的新IRP中底层驱动返回的数据。

具体地,步骤304中,过滤驱动从底层驱动完成的新IRP中取出底层驱动返回的数据,并将底层驱动返回的数据复制到当前目标IRP中,具体为:过滤驱动从底层驱动完成的新IRP中指定位置取出底层驱动返回的数据,将底层驱动返回的数据复制到当前目标IRP中对应位置。

例如,当前目标IRP和新IRP的数据结构如下:

底层驱动将返回的数据写入到新IRP中SystemBuffer位置,过滤驱动从新IRP中SystemBuffer位置取出底层驱动数据,并将底层驱动数据复制到当前IRP的SystemBuffer位置。

上述当前目标IRP和新IRP的数据结构中着重体现SystemBuffer,…为省略部分。

步骤305:过滤驱动完成当前目标IRP,并将状态码返回系统。

具体地,步骤305中过滤驱动完成当前目标IRP,具体为:过滤驱动调用系统函数完成当前目标IRP。例如,过滤驱动调用系统函数IoCompleteRequest(Irp, IO_NO_INCREMENT)完成当前目标IRP。在系统函数IoCompleteRequest完成当前目标IRP过程中,系统函数IoCompleteRequest将当前目标IRP返回系统。

在本实施例中,步骤302之后、步骤303之前,还包括:

步骤a:过滤驱动判断目标设备是否拔除,是则释放新IRP,并完成当前目标IRP,将完成结果返回系统;否则执行步骤303。

步骤a中完成当前目标IRP,具体为:过滤驱动调用系统函数完成当前目标IRP,在完成当前目标IRP的过程中,系统函数将当前目标IRP中的数据返回系统。

具体地,过滤驱动判断目标设备是否拔除,具体为:过滤驱动判断目标设备的拔除标志是否为已拔除,如果是则目标设备已经拔除,否则目标设备未拔除;

例如,目标设备已拔出的标志为Flag1=1,即当Flag1=1时,目标设备为已拔出;当Flag1的值不为1时,目标设备没有拔出。

具体地,当目标设备已经拔出时,过滤驱动释放并删除新IRP,具体为:过滤驱动通过调用系统内核函数释放并删除新IRP新Irp,例如:

IoFreeIrp(newIrp)。

本实施例中,过滤驱动获取当前目标IRP后,根据当前目标IRP创建新IRP,将新IRP下发给底层驱动,第三方驱动无法截断新IRP,使过滤驱动能够接收到底层驱动返回的数据,从而保证过滤驱动的正常运行;过滤驱动接收到来自系统的目标IRP之后,将目标IRP存储到自身数据结构中,当过滤驱动将新IRP发送到底层驱动之后,需要等待底层驱动完成新IRP,在底层驱动完成新IRP之前不会继续向底层驱动发送IRP,如此可以保证过滤驱动不会因为下发IRP过多导致系统崩溃,从而保证系统能够稳定运行。

实施例4

本实施例提供一种过滤驱动,如图5所示,包括:

获取模块10,用于获取当前目标IRP;

保存模块11,用于保存获取模块10获取的当前目标IRP;

创建模块12,用于根据获取模块10获取的当前目标IRP创建新IRP;

第一复制模块13,用于将获取模块10获取的当前目标IRP的特征信息复制到创建模块12创建的新IRP中;

发送模块14,用于将创建模块12创建的新IRP发送到底层驱动,等待底层驱动完成新IRP;

第一接收模块15,用于当底层驱动完成新IRP时,接收底层驱动完成的新IRP;

取出模块16,用于从第一接收模块15接收的底层驱动完成的新IRP中取出底层驱动返回的数据,

第二复制模块17,用于将取出模块16取出的底层驱动返回的数据复制到保存模块11保存的当前目标IRP中;

完成模块18,用于当第二复制模块17将底层驱动返回的数据复制到保存模块11保存的当前目标IRP之后,完成保存模块11保存的当前目标IRP。

进一步地,上述创建模块12,包括获取子模块和创建子模块;

获取子模块,用于获取上述获取模块10获取的当前目标IRP的数据长度;

创建子模块,用于根据获取子模块获取的当前目标IRP的数据长度创建新IRP。

具体地,获取子模块,具体用于:获取上述获取模块10获取的当前目标IRP的数据结构指针,并根据数据结构指针访问当前目标IRP的数据结构,获取当 前目标IRP的数据长度。

具体地,第一复制模块13,具体用于:根据获取子模块获取的当前目标IRP的数据结构指针访问当前目标IRP的数据结构,获取当前目标IRP数据结构中的特征信息,将特征信息复制到新IRP中。

具体地,上述创建子模块,具体用于:根据获取子模块获取的当前目标IRP的数据长度创建新IRP的内存空间,根据内存空间创建新IRP。

本实施例中,上述特征信息包括控制码和文件对象。

可选地,上述过滤驱动在包括获取模块10、保存模块11、创建模块12、第一复制模块13、发送模块14、第一接收模块15、取出模块16、第二复制模块17和完成模块18的基础上,还包括第二接收模块和置位模块;

第二接收模块,用于接收来自系统的目标IRP,并将目标IRP放入IRP队列中的数据末端;

置位模块,用于当第二接收模块接收到来自系统的目标IRP时,置位IRP通知事件;

相应地,上述获取模块,具体用于从所述IRP队列首端获取当前目标IRP。

进一步地,上述过滤驱动在包括第二接收模块和置位模块的基础上,还包括作为模块,

作为模块,用于将IRP队列首端的目标IRP作为当前目标IRP;

相应地,上述创建模块12,具体用于当作为模块将IRP队列首端的目标IRP作为当前目标IRP之后,根据当前目标IRP创建新IRP;

上述获取模块10,具体用于当作为模块将IRP队列首端的目标IRP作为当前目标IRP之后,获取IRP队列中的当前目标IRP。

具体地,上述创建模块12,具体用于,当获取模块10获取IRP队列中当前 目标IRP之后,根据获取模块10获取的当前目标IRP创建新IRP;

或者,上述获取模块10,具体用于,当创建模块12根据当前目标IRP创建新IRP之后,获取IRP队列中的当前目标IRP。

可选地,上述过滤驱动,在包括上述第二接收模块和置位模块的基础上,或在包括上述第二接收模块、置位模块和作为模块的基础上,还包括第一判断模块、等待模块和复位模块;

第一判断模块,用于在获取模块10获取当前目标IRP之前,判断IRP队列中是否有目标IRP;

等待模块,用于当第一判断模块判断IRP队列中没有目标IRP时,等待置位模块置位IRP通知事件;

复位模块,用于当置位模块置位IRP通知事件之后,复位IRP通知事件。

进一步地,上述过滤驱动在包括第一判断模块、等待模块和复位模块基础之上,还包括第二判断模块,

第二判断模块,用于当上述复位模块复位IRP通知事件之后,判断IRP队列中是否有目标IRP;

相应地,上述等待模块,还用于当第二判断模块判断IRP队列中没有目标IRP时,等待置位模块置位IRP通知事件;

上述获取模块,具体用于当第二判断模块判断IRP队列中有目标IRP时,从IRP队列中获取当前目标IRP。

在本实施例中,上述过滤驱动在包括第二接收模块和置位模块的基础上,还包括移除模块;

移除模块,用于当第一接收模块15接收到来自底层驱动完成的新IRP之后,将当前目标IRP从IRP队列中移除。

在本实施例中,上述过滤驱动在包括第二接收模块和置位模块的基础上,还包括挂起模块,

挂起模块,用于当第二接收模块接收来到自系统的目标IRP之后,将目标IRP设为挂起状态,并将IRP挂起状态返回系统。

在本实施例中,上述过滤驱动在包括获取模块10、保存模块11、创建模块12、第一复制模块13、发送模块14、第一接收模块15、取出模块16、第二复制模块17和完成模块18的基础上,还包括存储模块和清除模块;

存储模块,用于将获取模块10获取的当前目标IRP和创建模块12创建的新IRP存储到数据结构中;

清除模块,用于当第一接收模块15接收到底层驱动完成的新IRP之后,清除数据结构中的新IRP和当前目标IRP。

进一步地,上述过滤驱动在包括存储模块和清除模块的基础上,还包括返回模块,

返回模块,用于当完成模块18完成当前目标IRP、清除模块清除数据结构中的新IRP和当前目标IRP之后,将状态码返回系统。

本发实施例中,过滤驱动获取当前目标IRP并根据当前目标IRP创建一个新IRP,将新IRP下发给底层驱动,第三方驱动无法截断新IRP,使过滤驱动能够接收到底层驱动完成的新IRP,从而能够接收到底层驱动完成的新IRP中底层驱动返回的数据,保证过滤驱动的正常运行;过滤驱动将根据当前目标IRP创建的新IRP下发给底层驱动后,需要等待底层驱动完成新IRP,在接收到底层驱动完成的新IRP之前,不会向底层驱动发送目标IRP,如此可以保证过滤驱动不会因为下发IRP过多导致系统崩溃,从而保证系统能够稳定运行。

以上所述,仅为本发明的具体实施方式,但本发明的保护范围并不局限于 此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到变化或替换,都应涵盖在本发明的保护范围之内。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号