... case IRP_MN_STOP_DEVICE: status = PnpStopDeviceHandler(fdo,Irp); ... NTSTATUS PnpStopDeviceHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp) { ... StopDevice(dx); ... }
VOID StopDevice( IN PWDM2_DEVICE_EXTENSION dx) { if( !dx->GotResources) // 若需要获取资源,则退出 return; dx->GotResources = false; // 需要重新获取资源 KeSynchronizeExecution( dx->InterruptObject, (PKSYNCHRONIZE_ROUTINE)DisableDeviceInterrupts, (PVOID) dx); if( dx->GotInterrupt) IoDisconnectInterrupt( dx->InterruptObject); ... dx->InterruptObject=NULL; } 这所有的调用都发生在PASSIVE_LEVEL级的派遣例程中. 1. 由于PASSIVE_LEVEL级允许线程序切换. 2. 或在多核CPU上运行 假设: 1. 一个线程A调用StopDevice并测试dx->GotResources为True,并在执行 dx->GetResources之前; 2. 或被切换,或在另外一CPU上的执行线程B也调用StopDevice并测试 dx->GetResources也为True; 3. 则在随后的执行中,可能由于一个先执行的线程A/B设置 dx->InterruptObject=NULL,导致后调用的一个线程B/A使用 dx->InterruptObject为空的对象调用KeSynchronizeExecution 函数. 这应该是有问题的,请各位大佬指教 是否只有在调用WaitFor...阻塞线程后,线程切换才可以开始. |