1、
IoCopyCurrentIrpStackLocationToNext是拷贝本层的IO_STACK_LOCATION 到下一层。在楚狂人的驱动教程中说:
如果对irp完成之后的事情有兴趣,并打算在完成函数中处理,应该首先拷贝当前 IO_STACK_LOCATION(IoCopyCurrentIrpStackLocationToNext),然后指定完成函数,并返回 IoCallDriver()所返回的status.完成函数中,不需要调用IoCompleteRequest!直接返回Irp的当前状态即可.但是IoCopyCurrentIrpStackLocationToNext是这样的:
#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; }
也就是说他并没有拷贝当前的完成例程给下层,而是通过IoSetCompletionRoutine来设置的 这样一来的话,拷不拷贝本层的IO_STACK_LOCATION 到下层不都是没有关系的了?因为下层的IO_STACK_LOCATION 有他自己的结构内容,何必要用本层的拷贝过去呢?
2、
#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;} }\
这样一来IoSetCompletionRoutine不是设置的下层的完成例程么?为什么是设置下层的完成例程?为什么不是本层的?
3、
PIO_STACK_LOCATION IrpSp;
PIO_STACK_LOCATION NextIrpSp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
NextIrpSp = IoGetNextIrpStackLocation(Irp);
*NextIrpSp = *IrpSp;
return IoCallDriver(NextDeviceObject, Irp);
这种方法OSR中说IO_STACK_LOCATION中有两个成员CompletionRoutine、Context,即完成例程和完成例程的上下文参数。也就是说方法二会让Lb层拥有这两个原本不一定会属于它的成员。如果这两个成员都是NULL,那还好。
一旦这两个成员有有效的内容,那么就会导致"an eventual blue screen"。但是在filemon源码的FilemonHookRoutine例程靠后中有
*nextIrpStack = *currentIrpStack;
但是随后
#if defined(_IA64_)
IoSetCompletionRoutine( Irp, FilemonHookDone, (PVOID) (ULONG_PTR) seqNum, TRUE, TRUE, TRUE );
#else
IoSetCompletionRoutine( Irp, FilemonHookDone, (PVOID) seqNum, TRUE, TRUE, TRUE );
#endif
而并没有出现什么蓝屏。而且我不明白为什么会出现蓝屏原本不属于他的成员CompletionRoutine、Context在IoSetCompletionRoutine不就是设置NextIrpSp 自己的成员么?(IoSetCompletionRoutine的定义 )
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课