首页
社区
课程
招聘
[旧帖] [求助]《WINDOW驱动开发技术详解》这本书里关于介绍StartIO处的几个问题 0.00雪花
发表于: 2012-8-31 22:24 1067

[旧帖] [求助]《WINDOW驱动开发技术详解》这本书里关于介绍StartIO处的几个问题 0.00雪花

2012-8-31 22:24
1067
#pragma LOCKEDCODE
VOID
  HelloDDKStartIO(
    IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp 
    )
{
	KIRQL oldirql;
	KdPrint(("Enter HelloDDKStartIO\n"));

	//获取cancel自旋锁
        ///////oldirql  是提出的问题1 /////////////////////
	IoAcquireCancelSpinLock(&oldirql);
       ///////下面的/*Irp!=DeviceObject->CurrentIrp*/是  问题2/////
        /////////////////Irp->Cancel/////// 是问题3///////////
	if (Irp!=DeviceObject->CurrentIrp||Irp->Cancel)
	{
		//如果当前有正在处理的IRP,则简单的入队列,并直接返回
		//入队列的工作由系统完成,在StartIO中不用负责
		IoReleaseCancelSpinLock(oldirql);
		KdPrint(("Leave HelloDDKStartIO\n"));
		return;
	}else
	{
		//由于正在处理该IRP,所以不允许调用取消例程
		//因此将此IRP的取消例程设置为NULL
		IoSetCancelRoutine(Irp,NULL);
		IoReleaseCancelSpinLock(oldirql);
	}
////////////////////////////////////////////////////////////////////////////////////////

OnCancelIRP(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
	KdPrint(("Enter CancelReadIRP\n"));

	if (Irp==DeviceObject->CurrentIrp)
	{
		//表明当前正在改由StartIo处理
		//但StartIo并没有获取cancel自旋锁之前
		//这时候需要
               ///////关于oldirql = Irp->CancelIrql;关于这两个变量的代码是  问题4/////////
          
		KIRQL oldirql = Irp->CancelIrql;

		//释放Cancel自旋锁
		IoReleaseCancelSpinLock(Irp->CancelIrql);

		IoStartNextPacket(DeviceObject,TRUE);

		KeLowerIrql(oldirql);
	}else
	{
		//从设备队列中将该IRP抽取出来
		KeRemoveEntryDeviceQueue(&DeviceObject->DeviceQueue,&Irp->Tail.Overlay.DeviceQueueEntry);
		//释放Cancel自旋锁
		IoReleaseCancelSpinLock(Irp->CancelIrql);
	}



问题1:oldirql这个自旋锁,第一,是局部的变量,是不是起不到什么临界区的作用。
           第二,就算他起到了自旋的用,可是        IoAcquireCancelSpinLock(&oldirql);不管获没获得到自旋锁,是不是都应该是继续执行下面的代码?是不是不像临界区那样直接就卡在这里了?那么一直到释放这个自旋锁为止,所有的代码并没有起到什么锁的作用啊?

问题2:Irp!=DeviceObject,这个判断有可能为真吗?StartIO是由IOStartPacket,和IOStartNextPacket两个函数触发,在P266页,两个函数的伪代码明明写的其内部在调用DriverStartIO值前已经将DeviceObject->CurrentIrp=Irp;然后调用StartIO.
这个问题我或许多少能猜到点,不知道对不对。假设StartIO刚进入例程代码,什么事还没干,有一个新的IRP产生,并在某派遣函数中调用IOStartPacket,和IOStartNextPacket两个函数,而这两个函数将DeviceObject->CurrentIrp=Irp(Irp为新的值了),因此StartIO函数代码里Irp!=DeviceObject,所以StartIO不去处理这个Irp是吗?感觉如果是这样代码有点没有效率,不过或许还有其他的操作会改变DeviceObject->CurrentIrp,如果StartIO不管这两个变量是否相等而去继续处理,会引发什么异常吧。

问题3:Irp->Cance这个变量我才开始一直以为是自旋锁,后来看看又不像,因为已经有了Irp->CancelIrql这个自旋锁了,所以这个Irp->Cance是不是取消例程的一个标志,就是标志取消例程正在运行?如果是这样能解释下,这个标志是再什么时间被赋值的吗?

问题4:

	if (Irp==DeviceObject->CurrentIrp)
	{
		//表明当前正在改由StartIo处理
		//但StartIo并没有获取cancel自旋锁之前
		//这时候需要
    
		KIRQL oldirql = Irp->CancelIrql;

		//释放Cancel自旋锁
		IoReleaseCancelSpinLock(Irp->CancelIrql);

		IoStartNextPacket(DeviceObject,TRUE);

		KeLowerIrql(oldirql);
	}

第一,注释里说        /*//但StartIo并没有获取cancel自旋锁之前   */StartIo的代码里只有这个        IoAcquireCancelSpinLock(&oldirql);,难道自旋锁就一个吗?如果自旋锁就一个,我也没看出他起了什么锁的作用啊?而且假设我学错了,自旋锁就一个,那么参数oldirql也就没什么实际的用处了,直接就两个函数 一个获取(),一个释放(),不是更简单?加个参数有什么用?
第二,如果IRP的取消例程还没有运行,StartIO已经将这个IRP处理了,是不是最后的        IoCompleteRequest( Irp, IO_NO_INCREMENT );也会释放这个Irp->CancelIrql自旋锁?因为我在StartIO里再没看到这个IoReleaseCancelSpinLock(Irp->CancelIrql);的代码。
第三,KeLowerIrql(oldirql);这里是降低IRQL,这里又有点迷糊了,降低自旋锁等级是什么意思,求大侠解释下。

新手问题就是多,大侠别介意,有哪个大侠给解释下,我先碰头谢谢了,(磕头就不磕了,有点过,多碰几下吧)

谁能解答下,小弟真心真心的谢谢了

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
// // 统计代码