越来越,感到呆着这里,没有意思了,过去的成就,只是代表着过去,对于现在的自己,只是0而已,公司不会记住你的过去,只是在乎你的现在,有没有为它创造价值,这本无可厚非,因为开公司,本来就是为了赚钱的。天下的乌鸦一般黑,这样的公司,只会成就公司,而不会成就个人,这样的公司,肯定是不能长久的,所以,我们应该在有限的时间里,提高自己,飞向更好的明天。
Canceling I/O Requests
正在被设备处理的IO请求,可以被应用程序,系统,或者驱动取消。如果设备的IO操作被取消,IO管理器尝试取消所有的和IO操作所关联的没有被处理的IO请求。设备驱动可以一个例程得到通知但IO管理器尝试取消IO请求的时候,然后驱动可以通过设置IO请求的完成状态值为ERROR_OPERATION_ABORTED取消请求。
作为基于框架的驱动,框架会处理大多数的请求取消工作。如果设备的IO操作被取消了,框架以HRESULT_FROM_WIN32(ERROR_OPERATION_ABORTED)的完成状态来结束请求。下面是一些和取消操作所关联的IO请求。
框架已经放入在驱动默认的IO队列中的请求,但是这个请求还未分发。
驱动因为调用IWDFIoQueue::ConfigureRequestDispatching,框架将请求转发到另一个队列,但是请求还未分发。
因为框架要取消这些请求,框架不会将这些请求分发到驱动。
如果,框架已经将IO请求分发到驱动,驱动拥有请求,所以框架不能取消请求。在这种情况下,驱动可以取消IO请求,但是框架必须通知驱动这个请求必须取消。驱动可以在其提供的IRequestCallbackCancel::OnCancel回调函数中得到这个通知。
通常驱动从IO队列中接收请求,但是,有时候驱动并不处理这个请求,而是将请求重新入到同样一个队列或另一个队列延后处理。举例来说,框架可能将请求发送给驱动任一个请求处理例程,驱动可能在其例程中调用IWDFIoRequest::ForwardToIoQueue将请求发送到不同的队列,或者调用IWDFIoRequest2::Requeue 将请求重排在这个队列中。
在一些情况下,框架可以取消已经在IO队列中的IO请求。当请求正在被取消,如果驱动已经为请求已经在的IO队列注册了一个回调函数,框架会调用回调函数,而不是取消请求。如果框架调用驱动的回调函数,驱动必须取消请求。
通常,当请求被取消,框架也会取消和IO请求所关联的所有还没有分发到驱动的请求。如果驱动接收到一个请求并将其重新排队,框架会取消请求除非驱动为IO队列已经提供了回调函数。
Calling MarkCancelable
驱动可以调用IWDFIoRequest::MarkCancelable注册一个 IRequestCallbackCancel::OnCancel 的回调函数。如果驱动已经调用MarkCancelable,但是和IO操作相关联的请求已经被取消了,框架调用驱动的OnCancel回调函数,让驱动取消IO请求。
驱动应该调用MarkCancelable,如果驱动会拥有请求比较长的时间。举例来说,驱动可能不得不等待设备响应,或者当驱动接收到一个请求,但是其创建一组请求,并发送到下层驱动,并等待下层驱动进行处理。
Calling IsCanceled
如果驱动没有调用MarkCancelable,或者在调用后,又调用了IWDFIoRequest::UnmarkCancelable。驱动将不知道取消操作因此它将预前定义的处理请求。
Calling IsCanceled
如果驱动没有调用MarkCancelable去注册一个OnCancel回调函数,但是它可以调用IWDFIoRequest2::IsCanceled 去发现是否IO管理器已经试图取消IO请求。如果IsCanceled返回TRUE,驱动应该取消请求。
举例来说,驱动接收到一个很大的读写请求,并将其分段成很多小的请求,如果驱动没有调用MarkCancelable去注册取消通知,当驱动的IO目标对象完成每一个小的请求的时候,驱动可以调用IsCanceled是否请求被取消。
Canceling the Request
取消请求可能涉及到如下操作。
停止正在处理的IO操作。
停止分发请求到IO目标对象。
调用IWDFIoRequest::CancelSentRequest