驱动开发详解笔记的存档

Windows CrashDump

在自动化测试过程中,如果碰到应用程序崩溃,往往会弹出一个”error reporting”的对话框,如果不人工关闭这个对话框的话会导致程序无法继续进行下去。所以需要禁止弹出这个对话框并启用Windows CrashDump来收集错误日志。采用如下方法进行:

阅读全文… 

完成例程返回Status_Processing_Required

上一篇谈到了这个完成例程, 我们在完成例程中返回的是Status_Success, 这样Irp会继续向上回卷, 此时的完成例程仅仅是一个通知, 表明Irp已经完成. 但是如果此时我们不返回Status_success而是返回Status_Processing_Required则会停止回卷, 这时候的本层的Irp处理例程又重新获得Irp的控制. 并且该Irp又变成的未完成状态. 需要再次的调用IoCompleteRequest完成Irp.
 

阅读全文… 

完成例程

在将Irp发送给底层驱动程序, 或者其他驱动之前, 我们可以对Irp设置一个完成例程, 这样一旦在底层驱动程序将Irp完成以后, Irp完成例程将被触发, 通过设置完成例程可以方便的使程序员了解其他驱动对Irp进行的处理.

阅读全文… 

遍历设备栈

这一篇基本上就没有什么新东西了, 就是上几篇的应用. 遍历一个驱动的所有设备对象, 还有绑定在设备上面的所有的驱动对象, 设备对象.

阅读全文… 

分层驱动程序

分层驱动程序也不难嘛, 就是逻辑上有点乱了. 不过逻辑上分开以后写代码就清晰多了. 在结构上可以得到很多好处,恩, 这个分层驱动也不只是WDM式驱动才支持, NT式驱动也是可以的, 优点很多.

阅读全文… 

驱动程序调用驱动程序2

上一篇说到内核里面用户态这边差不多的函数, 比如ZwCreateFile, ZwReadFile什么之类的, 内核里面其实还有些更加暴力的东西存在的, 比如说用户态这边打开设备只有一个句柄, 但是内核里面是可以直接触摸到指针的, 用户态那边只可以调用几个固定的函数来发送Irp. 那么内核里面可以自定义Irp的发送, 非常的暴力, 好用!
 

阅读全文… 

驱动程序调用驱动程序1

 除了在Win32下面可以调用ReadFile, WriteFile之类的函数打开设备对象, 在内核中也是可以的, 而且方法比用户态这边更多. 首先这种方法就是Win32上面相同的方式了, 直接打开设备. 内核也有一套函数类似Win32下面的CreateFile, WriteFile, ReadFile.

阅读全文… 

Irp超时处理

很多时候Irp被送到底层驱动程序后, 由于硬件设备的问题, Irp不能够得到及时的处理, 甚至有可能永远都不会被处理.这时候需要对Irp超时情况作出处理, 一旦在规定时间内Irp没有被处理, 操作系统就会进入到Irp的超时处理函数中.

阅读全文… 

内核定时器

在Win32上面基本上定时做事情事情的话, 一般会使用WM_TIMER消息, 当然其他还有很多种选择, 同样的, 在内核中一样很多种的定时器对象可供使用, 使用起来也是那么的简单.

阅读全文… 

自定义StartIo

这个系统给的StartIo虽然好用, 但是很多时候我们还是需要使用自定义的StartIo例程的. 因为系统提供的只能使用一个队列.如果是我们自己建立的话, 可以建立多个队列. 灵活性高, 但是稍微复杂些. 其实要说复杂也不尽然, 用那个系统的时候感觉不是很好,因为封装的时候不给力, 还需要在我们自己的函数中帮系统做一些事情.我倒. 还是这个好, 想建立几个队列就几个队列. 而且代码也不是那么的复杂. 也就是几个函数的调用了!  

 

阅读全文… 

StartIo例程


凡是和多线程有关的东西, 一般就涉及非常恼火的线程同步问题, 而这个问题还不是那么直观, 不像其他一般的bug比较好调试, 有时候这个多线程的问题, 在一般情况下又不会有问题, 但是特殊请求下程序又会崩溃. 这种bug想要重现都有点问题.

 

前面说了内核下面几种同步的方法, 那些是对线程进行同步的, 但是很明显IRP有很多时候也是需要同步处理的, 这个有个专门的名词, 就是串行化.串行化能够保证各个并行的IRP能够按照顺序执行, 典型情况下, 对某个设备的操作的, 假如有很多个线程同时去操作这个设备, 那么必须将这些操作排队, 然后一一进行处理, 如果不做串行化操作就会变得混乱.
 

阅读全文… 

取消IRP

上一篇说的是挂起IRP, 并在挂起IRP的时候将挂起的IRP结束, 还有另外一个办法就是取消IRP, 逐个结束. 这就是传说中的取消IRP请求. 这个取消IRP还是比较有用的, 我们很多时候在打开一个文件的时候, 如果需要等待的时间太长, 发现这个文件本来有不是太有用, 一般就会去点取消按钮. 取消当然需要内核的支持.在内核中如果要支持取消IRP, 那么首先要调用IoSetCancelRoutine, 设置一个取消例程, 这个IoSetCancelRoutine函数也是有两个作用, 如果传递的非NULL值, 那么就是设置取消例程, 如果是NULL, 那么就是删除原来设置的(取消例程).

阅读全文… 

挂起当前IRP

如果需要将IRP异步完成, 一般不会在处理函数中调用IoCompleteRequest函数, 因为调用IoCompleteRequest函数就意味着,该IRP请求处理完成了, 事实上很多时候是需要多次处理, 或者有其他需求的, 这边先谈谈将当前IRP挂起.

阅读全文… 

Win32与内核同步

关于这个线程同步这块, 就比较恶心了, Windows驱动开发技术详解里面 这章的源码都没有. 难道是当时忘记了? 不应该啊!
我倒. 虽然说起来和Win32上面差不多, 但是也不能这样. 连个源码都看不到. 也许是觉得这章并没有什么实际的例子好讲,我看到了第九章的时候, 关于IRP的同步问题, 大部分都用了这个知识, 所以我觉得第8章的话, 先混个眼熟就可以. 回头下面几章的时候再倒腾.

阅读全文… 

和内核共享内存

Windows确实给我们提供了很多的内存共享方法,有同进程的, 有不同进程的, 各种方法都有, 我看kmdkit中介绍了一种和内核共享内存的方法, 确实很不错. 忍不住自己写了一下, 确实很好用. 看来以后用这种方法就可以做到和内核共享内存了, 利用注册表啊什么的共享还是有点欠缺实时性. 还是这个MDL共享内存好.

阅读全文…