能力值:
( LV10,RANK:170 )
|
-
-
2 楼
肯定不行撒 ,举个最简单的例子 每个device设置一个完成例程 你怎么搞 必须多个啊
|
能力值:
( LV13,RANK:260 )
|
-
-
3 楼
如果单纯驱动就一个设备 ,这并不能保证 你底下没有其他设备 直到hal 层
一层设备基本就占用一个 irp—stack ...还不说其他的 灵活用法
|
能力值:
( LV5,RANK:70 )
|
-
-
4 楼
每个要处理这个irp的驱动程序都要IO_STACK_LOCATION,这个东西就是这个驱动程序的“IRP 栈”
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
既然每个设备都需要 那么我使用IoCopyCurrentIrptoNextlocation 不会把其他设备的IO_STACK_LOCATIOn 覆盖吊么?
|
能力值:
( LV5,RANK:70 )
|
-
-
6 楼
IoCopyCurrentIrptoNextlocation 会有两个动作,第一,再增长一个irp栈,第二、拷贝,所以不会存在覆盖的问题。
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
PIO_STACK_LOCATION __irpSp; \
PIO_STACK_LOCATION __nextIrpSp; \
__irpSp = IoGetCurrentIrpStackLocation( (Irp) ); \
__nextIrpSp = IoGetNextIrpStackLocation( (Irp) ); \
RtlCopyMemory( __nextIrpSp, __irpSp, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); \
__nextIrpSp->Control = 0; }
请教哪里可以看出 增长一个irp栈?
另外
可以不可以这么理解
如果我这几个设备 进行IRP操作的时候,就单单的简单的由上往下处理,没有完成例程,那么是不是只用到一个IO_STACK_LOCAION,也就是IO_STACK_LOCATION所有的栈空间的并不是每个IRP处理都会用到的。。
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
从这个就可以看出来 __nextIrpSp = IoGetNextIrpStackLocation( (Irp) ); \ IRP栈增长了一个
|
能力值:
( LV12,RANK:760 )
|
-
-
9 楼
所以有时候可以对IRPStack遍历找Device~然后你懂得~
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
这个只是得到下一个栈吧?不是将栈的总大小加1吧?
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
如果是问问题 请不要写原创
我兴冲冲的跑进来。。。
经过一个设备就要处理一个栈的相关数据
从发送到底层在从底层上来 怎么也不能只有一个栈的
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
嘿嘿, 不写原创就不能把你们忽悠进来了,罪过罪过。。。
一个设备对应一个IO_STACK_LOCATION,
还是那个老问题了 那当我们使用IoCopyCurrentIrpStacktoNextlocation时,将当前IO_STACK_LOCATION拷贝到下一个IO_STACK_LOCATION时候,覆盖掉了下面那个栈数据,不会出错么?
|
能力值:
( LV5,RANK:70 )
|
-
-
13 楼
copytonext 有先决条件的,建议楼主好好去看一下张帆的书,里面有专门讲。而且。覆盖不覆盖,为什么不去调试一下看呢?
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
这是我当时学习笔记 ,楼主可以参考下:
I/O管理其创建IRP时准确知道链中注册的驱动程序数目 ,为每个驱动程序添加额外的空间即 IO_STACK_LOCATION (顶端驱动程序堆栈位置在IRP 结构下面)
整个IRP 驻留在内存中,大小随着链中驱动程序数目而变化
IRP 头部存储当前IO堆栈数组的索引(最顶端驱动程序),也存储当前IO堆栈的指针,索引从底端驱动开始
WRK相关函数参考
IoCallDriver(IofCallDriver)->IopfCallDriver
Irp->CurrentLocation--; // 递减当前堆栈位置索引
if (Irp->CurrentLocation <= 0) //当前堆栈位置为0时 机器会崩溃
{
KiBugCheck3( NO_MORE_IRP_STACK_LOCATIONS, (ULONG_PTR) Irp, 0, 0 );
}
irpSp = IoGetNextIrpStackLocation( Irp ); //上一个堆栈指针
Irp->Tail.Overlay.CurrentStackLocation = irpSp; //调整当前堆栈指针
#define IoGetNextIrpStackLocation( Irp ) (\
(Irp)->Tail.Overlay.CurrentStackLocation - 1 )
#define IoSkipCurrentIrpStackLocation( Irp ) { \
(Irp)->CurrentLocation++; \
(Irp)->Tail.Overlay.CurrentStackLocation++; }
#define IoCopyCurrentIrpStackLocationToNext( Irp ) { \
PIO_STACK_LOCATION __irpSp; \
PIO_STACK_LOCATION __nextIrpSp; \
__irpSp = IoGetCurrentIrpStackLocation( (Irp) ); \
__nextIrpSp = IoGetNextIrpStackLocation( (Irp) ); \
RtlCopyMemory( __nextIrpSp, __irpSp, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); \
__nextIrpSp->Control = 0; }
#define IoSetCompletionRoutine( Irp, Routine, CompletionContext, Success, Error, Cancel ) { \
PIO_STACK_LOCATION __irpSp; \
ASSERT( ((Success) | (Error) | (Cancel)) ? (Routine) != NULL : TRUE ); \
__irpSp = IoGetNextIrpStackLocation( (Irp) ); \
__irpSp->CompletionRoutine = (Routine); \
__irpSp->Context = (CompletionContext); \
__irpSp->Control = 0; \
if ((Success)) { __irpSp->Control = SL_INVOKE_ON_SUCCESS; } \
if ((Error)) { __irpSp->Control |= SL_INVOKE_ON_ERROR; } \
if ((Cancel)) { __irpSp->Control |= SL_INVOKE_ON_CANCEL; } }
通过分析 我们知道IO_STACK_LOCATION多个,是为了支持分层过滤驱动的需要和IRP 处理的灵活性 。进一步分析 ,我们可以知道 正是通过IRP结构头部两个成员,当前IO堆栈数组的索和储当前IO堆栈的指针,配合IRP的内核函数,实现了IRP处理的直接处理结束;直接下发;下发,然后设置完成例程对下层返回结果处理,这正是过滤驱动存在的意义
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
函数是你自己用的
适合用的他的时候才用时正确的
乱用覆盖当然会出问题。
该READFILE的时候你WRITEFILE 一样会出问题
这个不是函数的问题 是你自己使用对错与否
|
|
|