标题：竹林蹊径:深入浅出Windows驱动开发
图书基本信息
书名：竹林蹊径：深入浅出Windows驱动开发  作者：张佩 马勇 董鉴源 编著
ISBN 978-7-121-12555-3
出版社：电子工业出版社
出版日期：2011年2月 
定价：69.00元
内 容 简 介
本书是作者根据多年的工作学习经验，总结的第一手驱动开发资料。本书更多的是经验之谈，一些实践中的小发现小意外，颇为书中内容添彩。
本书的特色之一，是对WDF框架做了较多的切入。本书第一个主要内容是（第3～7章）围绕WDF而展开讨论，侧重点各有不同。第3章以框架为讨论的中心；第4、5两章以WDF框架开发USB和1394驱动；第6章讲述内核C++编程，也以WDF框架为蓝本；第7章讲述WDF驱动的测试和调试。
第二个主要内容是关于音视频驱动开发（第10～11章）。音视频驱动包括AVStream架构，本书做了较详细的阐述。第10章讲述使用AVStream小端口架构，第11章讲述ASIO音频驱动开发。
第三个主要内容是关于设备驱动安装（第12～14章）。第12章讲系统安装模块，从总体角度阐述系统和设备驱动如何配合完好地进行工作；第13章讲述INF安装文件的细节，包括各个域的作用，以及诸多安装指令的使用。第14章讲如何编写驱动安装软件。
剩余的一些章节，分别是关于驱动入门（第1、2章）、Windbg调试命令（第8章）、内核同步（第9章）等内容。
本书适合一般入门级内核程序员，对WDF有兴趣，准备开发USB或1394设备驱动者，本书尤其有用。本书对于入行较久，经验丰富的程序员，也具有一定的参考价值。
推 荐 序
我一直认为，编写程序是一件很奇妙的事情，它可以带来创造和控制的欲望。每当我阅读或者编写一段代码时，脑子里自然地就会想象这段代码怎样完成预定的逻辑。当面对一个不熟悉的开发环境，或者一个新的基础平台时，首先要清楚这个环境或者平台是如何工作的，以及提供了哪些功能。代码本身可能非常复杂，甚至奥妙无穷，但通常情况下，真正优美的高质量代码往往是简单的、易于理解的。对于代码编写者或者维护者来说，真正见功夫的地方不在于代码本身，而在于对下层开发平台的理解和驾驭能力，可能这就是俗称的“内功”。
这个观点既适用于应用软件程序员，也适用于系统软件程序员。对于应用软件程序员，低层的应用开发平台是支撑应用开发的基础，譬如，基于Windows SDK来开发Windows应用程序。那么，程序员有必要理解Windows SDK中的基本要素，诸如消息分发机制、各种图形功能等。在这种情况下，阅读一些典型的例子程序代码往往能起到快速引领入门的效果。同样地，C/C++程序员如果局限于C/C++语言本身，很难编写出高质量的实用程序。他们不仅要掌握C/C++运行库中函数和类型的用法，甚至还要理解这些函数和类型的实现机理。即使源代码层面上的库，例如STL（C++的标准模板库），也需要理解其代码实现才能灵活自如地用好这些库（比如STL中的各种容器数据结构、迭代器或算法）。
那么，对于系统软件程序员，“内功”是什么呢？系统软件是指操作系统本身或者依附于操作系统上为应用软件提供服务的软件。系统软件可能有机会跟硬件直接打交道，这赋予了程序员更强的控制能力，他们有机会介入操作系统的行为逻辑，甚至改变操作系统的行为特性。但随之而来的是对系统软件代码的更高要求。现代操作系统为应用软件提供了很强的容错能力，应用程序的失败通常不会波及到操作系统自身的稳定性，但操作系统对系统软件的容错能力却比较有限，毕竟系统软件运行起来之后可能被融入到操作系统的执行逻辑中成为操作系统的一部分。因此，理解和掌握操作系统的运行机制成为系统程序员编写出正确、高效的系统软件的基本前提。所谓“内功”，便着落在此。
在Windows平台上开发软件，编写Windows内核驱动程序是最为考验程序员“内功”的。内核驱动程序的代码量通常不大，但驱动程序框架中的任何一个函数，甚至这些函数中任何一行代码背后都可能蕴含着复杂的逻辑，或者隐式的要求和假设。即使驱动程序编写者在纯粹自行定义的函数中，也必须谨慎地关注一些与环境有关的因素，譬如代码是否可被中断、是否可重入，或者所引用的内存是否被交换到外存。另一方面，应用软件开发中的很多概念，比如地址空间、内存管理、异常处理和多线程并发等，在驱动程序开发中可能需要有不同的理解方法。此外，常用的C运行库函数基本上不再适合于驱动程序了，驱动程序编写者必须面对一个全新的底层环境和支持平台。因此，要编写可正确运行的驱动程序，程序员不仅要清楚地理解驱动程序所针对的目标设备或功能（可能包括硬件设备的各种特性），还要掌握Windows内核是如何与驱动程序打交道的，以及内核中诸多管理和运行机制，尤其是内存管理、线程调度和并发控制。
当Windows内核驱动程序被加载到内核中并且启动以后，它们变成了Windows内核的一部分，驱动程序中的接口函数在恰当的时刻被内核调用，这是Windows驱动程序的基本工作方式。Microsoft定义了WDM（Windows驱动程序模型）来规定驱动程序的结构，以及Windows内核如何与WDM驱动程序打交道。WDM不仅包括I/O管理器定义的驱动程序框架，还定义了在驱动程序中如何支持PnP（Plug and Play，即插即用）、电源管理和WMI（Windows Management Instrumentation，Windows管理规范）。因此，若要编写一个完全支持WDM的驱动程序，也需要理解WDM中所涉及的各个内核组件。
Windows内核驱动程序与内核的紧密关联性使得驱动程序的调试极为不方便，从某种意义上讲，驱动程序的调试等同于Windows内核的调试。而且，对于某些特定的逻辑错误，内核调试器甚至是无能为力的。正因为这个原因，内核驱动程序的代码尽可能精简，从软件设计角度而言，应最大程度地把功能代码放到应用程序中，在驱动程序中只留下最必要的功能逻辑。这样的设计也可以使Windows内核被不正确驱动程序代码牵连而导致稳定性问题的几率相对减小。
为了便于Windows驱动程序的开发，Microsoft定义了一个驱动程序框架，称为WDF（Windows Driver Foundation），其中针对内核驱动程序的部分称为KMDF（Kernel-Mode Driver Framework）。KMDF实际上是一个库，它封装了WDM中一些基本的代码逻辑，从而使程序员可以更加方便地编写出WDM驱动程序。KMDF可以部分地简化Windows内核驱动程序的开发任务，但是本质上它并没有降低内核驱动程序的复杂性，甚至需要程序员付出额外的学习努力。
总而言之，作为一名系统程序员，你需要洞悉目标操作系统中与你的软件打交道的各个部件，也要非常清楚地知道你所依赖的开发工具是如何帮助你做到这一点的。系统程序员往往面临着比应用程序员更长的学习曲线，但是，系统程序员从编写程序中获得的乐趣也是在应用层上难以体会得到的。我相信，当你发现自己编写的软件模块已经与操作系统内核融为一体时，那一刻你的感觉一定是手心里攥着一个操作系统——操作系统尽在你的掌控中了。
这本书《竹林蹊径——深入浅出Windows驱动开发》是三位作者张佩、马勇和董鉴源的最新力作，他们将自己在实践中积累起来的经验整理成册，以期望后学者能少走弯路，缩短Windows驱动程序开发的学习之路。这本书重点介绍了KMDF、USB/1394和音频驱动程序的开发，以及设备驱动程序的发行和安装。建议有一定Windows驱动程序开发基础的读者看一看这本书，尤其是，如果你正打算使用KMDF，或者正在从事与USB/1394或音频驱动程序相关的编程工作，那么，这本书便是一份宝贵的实践指导了。
潘爱民
2010年12月5日于北京西二旗
推 荐 序
我认识一个共享软件的作者，近十年来都在开发他的虚拟光驱的软件，不时给这个软件添加一点新的东西。我对此觉得很奇怪，对他说，我觉得虚拟光驱是一个很简单的东西。用一个映象文件容纳光盘上的数据，并开发一套驱动接口让系统以为这是一个光驱。下载网上开源的代码，应该不超过5000行。为什么他要为此耗费这么多年的精力呢？
他举了个例子说：国外知名的虚拟光驱Daemon，它的强项在于兼容性。几乎任何软件都能正常使用它的虚拟光驱，并当做真正的光驱来访问。而普通的开源的虚拟光驱，就有很多不支持了。
他曾经发现一种游戏，要求用户插入光盘。用他自己编写的虚拟光驱来模拟，总是不行。同样的映象文件，换了Daemon就一切OK。这让他大为诧异。碰到这样的情况，他根本就不可能到网上去搜索“为何我的虚拟光驱不支持某某游戏”这样的傻问题，也不可能在某处找来一段代码拷贝一番就解决。他必须找到问题的实质，才能找到对策。
花去漫长的时间，最终分析的结果是，原来因为该游戏希望每个用户都购买正版光盘，它就用了一种特殊的策略来分析用户所用的是不是真实的光驱。大家都知道硬盘的读取速度一般都比较快，而且事实上也更加稳定。光驱读盘的速度比硬盘相对慢一些，而且读取数据的速度有一定的不稳定性。比如说，数据读取的速率可能会以某种数学模型所定义的曲线为轨迹发生波动。而这个软件就根据这种不稳定性的匹配程度来进行检查。如果虚拟光驱提供的数据是不匹配这种特征的，则它很简单地禁止游戏继续运行。
而Daemon则在内部插入了这样的模拟函数，有意对数据的读出进行各种延时的处理，使之看上去非常像真实的光驱读出的数据。
总而言之，他开发的是一个逼近世界顶尖品质的好东西。当然代价是汗水与时间。
我能想象到在没有任何公开的代码，或者是前人的经验指引，自己去钻研发现并解决这些问题的困难。能在网上找到解决方案的问题必定不会是软件技术里的关键问题。相反是这样一个一个的无头悬案，才构成了程序员们所谓的“核心技术”。
我和一些人的见解不同。我并不认为越底层的技术就越“核心”。总有人认为系统比软件底层，所以程序更“核心”。而芯片比程序更底层，则芯片又更“核心”。其实硅片比芯片更底层，沙子又比硅片更底层，那是不是沙子才是最核心的技术呢？
我认为，在任何一个领域里，能够进行持之以恒的钻研，当大部分人选择放弃，而你依旧锲而不舍地学习、研究、解决一个又一个实际问题，你就能掌握核心技术。简言之，善于把握自己能够掌握的知识，并不断深化拓展知识领域，这才是真正的学习之道，也是成就个人和团队核心技术的途径。
我见到一些工作过多年的人，很有特点。有一种号称对技术没兴趣，更喜欢做管理，但其实并没有那么多做管理的机会，或者真的有机会，而做得也并不理想；有一种全凭在新手面前吹牛皮支撑老资格，实际编程依旧一塌糊涂。我从来不对别人妄加评论，但从技术学习上讲，他们都算是没到家。
《竹林蹊径——深入浅出Windows驱动开发》终于出版了。据我了解，张佩因写作这本书，在家伏案了半年。他是凭着极大的热情和信念去写作的，否则即便薪资上的损失都很值得惋惜。就本书而言，先不去考量书中内容的深浅，技术的精粗，仅就作者的诚心和写作精神，便值得称赞。
牛不是一天吃大的，小牛雏要不断地吃进养料，才能变成大牛。牛人要有牛技术，牛的技术，就是核心技术。我希望这本书的每一位读者，不管你现在或是将来，做的是应用开发还是内核编程，不管用的是C++还是Java或.NET，在工作、学习过程中都具有锲而不舍、精益求精的精神，哪怕最菜鸟的新手，在若干年的积累和沉淀后，都能够逐渐形成自己的核心技术。只有掌握了自己的核心技术，才能进入程序员的自由天地。
此文送给《竹林蹊径——深入浅出Windows驱动开发》的读者，是为序。
谭文
2010年12月10日
前 言
国内内核开发方面的书籍特别少，一个原因是很多技术牛人，没有时间或机会把自己掌握的知识编辑成书。真的很遗憾。希望我砸出这块砖头后，后面会在书店里看到无数的翡翠之作。
相比较国外的程序员，国内程序员在学习内核驱动开发的时候，学习曲线特别长，主要原因是没有趁手可用的资料。有一些初学者联系我，倒出的苦水大多是：资料太少，技术太难，不知从何下手。我给出的建议多是希望他们努力学习WDK中的现成文档，并推荐一些经典的英文电子档。但大多数初级学习者，并不满足我这个答案——他们希望有中文资料。这时候，我会向他们推荐《深入解析Windows操作系统》或者《软件调试》，有时候，我还会谨慎地向他们推荐《驱网核心技术丛书》。
很高兴有机会，写成这样一本书。本书的另外两位作者是马勇和董鉴源，他们分别写了第1章和第2章。写《竹林蹊径——深入浅出Windows驱动开发》花了我整整八个月的时间，有半年左右，我把所有的时间都花在上面，不上班，不娱乐。这本书是我的劳苦之作。
我利用写作的机会，纵深渗透学习了不少知识。与其说它是在展示个人才华，不如说是做了一次自我进修和测试。我做不到文采飞扬，能保证的是负责任的态度。此书在写作过程中，增删若干遍，完稿之后，请多位前辈老师审稿。我现在唯一期望的是书中的内容，确实能够对读者起到帮助、参考的作用。
本书特色
《竹林蹊径——深入浅出Windows驱动开发》这本书的一个最大特点是插图和示例多，对涉及到的大部分知识，能做到一定深度的挖掘。谭文跟我说，无法把自己的技术经验完全写出来。我当然同意他这句话的正确性；但写作的过程中，我仍然尽最大的可能，把技术和经验文字化、图形化，尽量做到由浅入深，脉络分明——这是我个人的最高目标。
平时给别人讲某个知识点的时候，哪怕是最简单的，我喜欢讲得360度面面俱到。说了一层，爱说下面还有一层。讲了烧水之釜，还要介绍釜底之薪。有人不喜欢这样，但我喜欢。如果以后还写书，我仍会保持这一点。
本书主要内容
本书主要包含这几个方面的内容：WDF框架、驱动测试、音视频编程、驱动安装。这其中，最费精神的是WDF框架相关章节。
WDF是目前和将来驱动开发的大势所趋。如果初学者因为资料的关系，而紧握着WDM架构的双手的话，他一定要留神，不要冷落了旁边正如日中天的WDF。搞技术，特别是在Windows平台上，不建议大伙具有怀旧情绪，跟着形势走是必然的。
书中有四章内容介绍WDF。笔者如农夫翻地一般，把WDF奇异表面下的具体实现做了一定的揭露。笔者饶有兴趣地为大家分析WDF的对象模型，而从Wdf01000符号文件中揭露的内部结构体定义，能令很多人吃惊不小。
用WDF框架编写驱动，要比WDM方便、简单一半以上。本书中介绍了使用WDF框架进行USB和1394编程的内容。由于USB的运用之广，使USB驱动成为Windows内核驱动中的显学。驱动开发网专门辟有“USB驱动”版块，并几乎是最聚人气的地方。为配合USB一章的写作与学习，笔者专门请朋友精心设计了一款USB驱动学习开发板。读者在本书中的多处地方，都能看到它的玲珑身影。
驱动测试方面包括两章内容，一章以WDF驱动测试为中心进行介绍，另一章介绍了Windbg调试命令。曾经的王者SoftIce湮没不闻后，Windbg成了唯一的内核调试利器，不可不掌握。
音视频驱动向来都比较小众，做相关开发的公司和个人都很少，资料也就更加少。本书有两章内容介绍音视频开发，一章介绍AVStream小端口架构，一章介绍酷酷的ASIO音频驱动，并以虚拟ASIO声卡的创新技术，为有兴趣的读者带去福音。
本书最后三章，介绍驱动安装有关的知识。一章介绍驱动安装的原理及系统模块，一章介绍INF安装文件的技术细节，一章以示例介绍如何编写驱动安装软件。看过这些内容后，试着为你的驱动写一个安装软件，会很酷。
本书读者对象
本书适合一般程序员
对WDF感兴趣，准备开发VSB或1394设备驱动者
下面要说一些和技术无关的东西。
在本书写作过程中，有许多书外的记忆。比如，夏天我工作的时候，我女儿常常站在床头，猛地一下用手扑打我的笔记本，电脑屏幕就倾了下去，一阵惊叫。
一次两章隔夜刚新鲜写好的内容，保存在移动硬盘中，第二日在另一台电脑上开机，却怎么都找不到了。翻遍整个系统，用了N种数据、磁盘恢复工具，都无济于事，踪影全无。那种无助得想哭的感觉，一直记在心间（这个问题我后来把它再现了，可以认定是Windows 7操作系统的BitLocker功能在休眠唤醒处理上的一个Bug）。
致谢
感谢我的好朋友，谭文。是他推荐我主笔这本书的写作。这套系列中的《天书夜读——从汇编语言到Windows内核编程》和《寒江独钓——Windows内核安全编程》出版后，大家都很忙。谭文很信任我，推荐我写《竹林蹊径——深入浅出Windows驱动开发》。谭文是我以前的同事，湖南人，故在网上号楚狂人，赫赫有名，散文随笔一级好，技术文章有散文风。他为本书写了一篇小序，特此感谢。谢谢李冰编辑和文字编辑葛娜女士，她们的信任和支持，使我有可能完成这本书。
感谢本书两另外两位作者，他们贡献了第1章和第2章。
感谢潘爱民老师，他为本书写了序，令我有蓬荜生辉之感。
感谢张银奎老师，张帆兄，他们也对本书给予了鼓励，并写了推荐语。 
我要感谢所有照顾过我的亲人们：谢谢我大阿姨，她现在只在天上看着我们。她以力排众议的气势，关心照顾过我。谢谢红兵表哥，他正好大我一轮，学习成绩冠于全镇。当初我老爱从他那里偷书，那些书正是我童年和少年时代仅有的课外书。谢谢小姨父，父执辈中他是唯一给我严肃、客观教育的人。感谢我舅舅，他给我很多帮助。以前，我总是把去上海说成“去我舅舅那”。
谢谢我所有的亲人们。
感谢双方父母，感谢他们所有的辛勤付出。
最后，感谢我的妻子，近两年以来，她离职在家做专职母亲，好像把十几年的事情放在一两年里做了，岁月催人老，我把她累坏了。
最后是一首五言八句，会意书名曰：《竹林蹊径》
荫荫翠竹百亩林，
结庐恒爱此中景。
寻常偶遇方外客，
殷勤指点通幽径。
张佩
目 录
向内核世界说一声：hello，我来了。如果你是一个初学者，并对这个世界充满好奇心，请从这一章开始，我们一起打招呼～
第1章 Hello World驱动 1
1.1 从Hello World开始 2
1.1.1 HelloDRIVER 4
1.1.2 代码解释 8
1.1.3 驱动程序的编译和安装 11
1.1.4 查看我们的驱动 14
1.2 虚拟环境 15
1.2.1 使用虚拟环境进行驱动开发 15
1.2.2 使用VMware虚拟机 15
1.2.3 目标机设置 16
1.2.4 Virtual PC虚拟机 18
1.3 小结 19
如何在规范的商业环境中，开发成功而有效的驱动软件？驱网站长马勇（ZnSoft）将向你娓娓道来。你会学到这些内容：建立一个简单而有效的开发、调试环境；64位环境下的内核编程技巧；如何发布你的驱动软件。
第2章 商业驱动开发技术 20
2.1 建立开发调试环境 21
2.1.1 SVN环境 21
2.1.2 创建工程，导入SVN 23
2.1.3 建立符号服务器 25
2.1.4 用符号调试 27
2.2 64位驱动开发技术 34
2.2.1 64位驱动编写技术 35
2.2.2 32位应用程序与64位驱动混合模式 36
2.3 驱动程序的发布与测试 42
2.3.1 驱动程序签名 42
2.3.2 驱动程序测试 46
2.3.3 WHQL 49
2.4 小结 50
WDF是目前最新的驱动编程框架。当很多内核程序员还紧抱WDM的巨大佛脚时，千万要记住，WDF已是大势所趋。本章介绍了WDF最重要的几个概念，并进行了一定程度的深度挖掘。对于WDF框架的三大核心模型：对象模型、事件模型、PNP/Power模型，本章作了重点讲述。
第3章 WDF概述 51
3.1 主要特点 52
3.2 框架视图 53
3.3 兼容性 55
3.4 对象模型 56
3.4.1 对象和句柄 59
3.4.2 引用计数 60
3.4.3 上下文空间 61
3.4.4 PME接口 67
3.4.5 DDI接口 69
3.4.6 父子关系 76
3.4.7 对象同步 77
3.5 驱动对象和设备对象 78
3.5.1 驱动对象 78
3.5.2 驱动入口DriverEntry 81
3.5.3 设备对象 84
3.5.4 创建设备对象 85
3.5.5 设备栈 86
3.6 IO模型 88
3.6.1 IO目标对象 88
3.6.2 IO目标对象的细节 90
3.6.3 安全的缓冲区 93
3.6.4 内存对象（一） 96
3.6.5 内存对象（二） 98
3.6.6 框架和IO请求 102
3.6.7 更详细的处理流程 103
3.6.8 IO请求参数 105
3.6.9 队列 107
3.6.10 创建IO请求 110
3.7 PNP和电源模型 112
3.8 小结 115
使用WDF框架开发USB驱动，方便且简单。本章首先总体上从硬件和软件两个方面介绍USB相关知识点，包括设备的电气特性、总线结构、USB驱动类型以及类驱动。编程方面，从USB设备初始化、数据操作以及设备控制等几个方面来讲解，透彻并且翔实。
第4章 WDF USB设备驱动开发 116
4.1 USB设备硬件结构 117
4.1.1 主从结构 117
4.1.2 硬件拓扑 118
4.1.3 USB中断 119
4.2 USB软件结构 120
4.2.1 总线驱动 120
4.2.2 系统类驱动 121
4.2.3 功能驱动 122
4.2.4 父驱动与混合设备 122
4.2.5 过滤驱动 125
4.2.6 USB驱动栈、设备栈 125
4.3 内核开发 127
4.3.1 设备驱动 127
4.3.2 入口函数 128
4.3.3 USB描述符 129
4.3.4 描述符介绍 130
4.3.5 汇总举例 133
4.3.6 读取描述符 135
4.3.7 初始化 137
4.3.8 设备初始化函数 138
4.3.9 创建设备对象 141
4.3.10 设备命名、符号链接 143
4.3.11 启动设备 147
4.3.12 创建队列 156
4.3.13 停止设备/反初始化 158
4.4 数据I/O操作 160
4.4.1 USB控制命令 160
4.4.2 构造并发送控制命令 162
4.4.3 读USB中断端口 163
4.4.4 连续读操作 165
4.4.5 数据处理函数 166
4.4.6 中断端口的效率 167
4.4.7 读/写批量端口 168
4.5 设备控制 171
4.5.1 关于I/O Target对象 171
4.5.2 获取USB版本 172
4.5.3 管道重置 174
4.5.4 设备重置 176
4.5.5 管道中止与终止 177
4.6 用户程序 179
4.6.1 内核读/写 179
4.6.2 控制命令 179
4.7 小结 180
1394俗称火线。大伙平时最多接触它的地方大概是内核调试时，借助1394卡进行双机互联。本章首先从硬件方面介绍了1394的知识，它的总线结构很特别，极具可扩性，能非常方便地在各种类型的1394设备之间建立数据链路。内核编程方面，本章重点讲解了数据通信相关知识，分为异步通信和同步通信两种方式，颇为复杂，相对难于掌握，但套路是现成的，变化的东西不多，可以熟能生巧。本章最后介绍了1394双机互联的原理，有兴趣的读者可参考之。
第5章 WDF 1394驱动开发 181
5.1 1394一席谈 182
5.1.1 版本情况 183
5.1.2 电源特性 183
5.1.3 1394卡 183
5.1.4 总线拓扑 184
5.2 发送请求 186
5.2.1 同步方式 187
5.2.2 异步方式 189
5.2.3 对WDM的回忆 191
5.3 总线重置与计数 193
5.3.1 总线重置 193
5.3.2 设置重置回调 193
5.3.3 计数更新 194
5.4 PNP操作 195
5.5 异步通信 196
5.5.1 地址范围 197
5.5.2 异步读 200
5.5.3 异步写 201
5.5.4 异步锁请求 202
5.5.5 数据流 203
5.6 等时通信 204
5.6.1 申请带宽 205
5.6.2 释放带宽 206
5.6.3 等时通道 206
5.6.4 资源句柄 207
5.6.5 缓冲区挂载 210
5.6.6 缓冲区解挂 211
5.6.7 开始传输 211
5.6.8 停止传输 212
5.6.9 其他等时操作 213
5.7 其他操作 213
5.7.1 设备配置 213
5.7.2 获取控制器信息 214
5.7.3 速度信息 215
5.7.4 厂商自定义命令 216
5.8 安装与测试 216
5.8.1 1394虚拟设备 216
5.8.2 创建虚拟设备 218
5.8.3 示例代码 219
5.8.4 安装与测试 221
5.9 小结 222
内核天生适合于C语言编程，但越来越多的内核项目，规模达到10数万的规模。在这种情况下，人们不由地会将目光投向优雅的C++语言。总体上说，C和C++是至亲好友，内核中使用C++本不应有什么大问题，但有几个暗礁潜伏已久，不小心的程序员，你可千万不要触礁。
第6章 内核驱动C++编程 223
6.1 驱动中的类 224
6.1.1 一个简单的例子 224
6.1.2 new/delete 225
6.1.3 extern "C" 227
6.1.4 全局/静态变量 228
6.1.5 栈的忧虑 230
6.2 类封装的驱动程序 233
6.2.1 寻找合适的存储所 233
6.2.2 类方法与事件函数 235
6.2.3 KMDF驱动实现 236
6.2.4 WDM驱动实现 237
6.3 多态 238
6.3.1 基类、子类 238
6.3.2 实现多态 239
6.3.3 测试 241
6.4 小结 241
使用WDF框架编写的驱动程序，在测试和调试的时候，有特殊的工具。本章介绍了目前所知的三个，它们分别是：Windbg扩展调试命令、WDFTester测试工具、WDFVerifier测试工具。本章将以示例方式，介绍这些工具的使用。
第7章 WDF驱动测试 242
7.1 WDF错误 243
7.1.1 实例分析 245
7.1.2 USB错误 246
7.2 WDF扩展调试命令 247
7.3 WDFTester 254
7.3.1 WDFFiTester 254
7.3.2 使用 256
7.3.3 WDFCallTracer 260
7.4 WDFVerifier 263
7.4.1 识别KMDF驱动 263
7.4.2 使用与介绍 265
7.5 小结 266
SoftIce渐行渐远之后，Windbg成为内核调试的第一利器。使用Windbg的最大难点是命令繁多，参数复杂。本章以总结归纳的形式，介绍了作者在工作中经常用到的几大类调试命令，并以实例形式一一介绍。作者根据个人经验所作的分类，未能全备，但能够保证的是，所有实例翔实而可靠，可以作为可信的参考。
第8章 调试命令详解 267
8.1 概述 268
8.1.1 寻求帮助 269
8.1.2 DML语言 270
8.1.3 基本信息 271
8.1.4 基本设置 272
8.1.5 格式化显示 273
8.1.6 开始调试 273
8.2 符号与源码 276
8.2.1 模块列表 277
8.2.2 模块信息 279
8.2.3 符号路径 280
8.2.4 符号加载 283
8.2.5 符号搜索 285
8.2.6 源码命令 287
8.3 进程与线程 289
8.3.1 进程命令 289
8.3.2 线程命令 292
8.3.3 异常与事件 296
8.3.4 局部变量 300
8.3.5 显示类型 301
8.4 断点 301
8.4.1 软件断点 301
8.4.2 硬件断点 303
8.4.3 其他操作 303
8.5 内存命令 304
8.5.1 查看内存 304
8.5.2 内存信息 307
8.5.3 其他命令 311
8.6 小结 312
相信大多数人在学习内核开发的时候，都问过这样一个问题：内核驱动怎么向用户程序发送消息，或者如何调用Win32函数。用户程序和内核同步，是一个基本而重要的知识，本章介绍了三种主要的实现方式。至于内核是否可以调用Win32函数，读一读本章开篇的话，你就有答案了。
第9章 内核同步 313
9.1 关于内核同步 314
9.2 内核事件同步 316
9.2.1 原理 316
9.2.2 用户程序 318
9.2.3 内核实现 319
9.3 IRP同步 320
9.3.1 用户程序 321
9.3.2 内核实现 323
9.4 WMI同步 325
9.5 数据缓冲区同步 326
9.6 反向调用 328
9.7 小结 330
微软最新的音视频编程框架即AVStream框架，不管从什么方面来说，音视频编程都是一个很小众的领域。AVStream框架极其复杂，个人看法是掌握的难度超过了WDF。本章介绍了AVStream框架的各种基本知识点，并以实例讲解一个内核音频过滤器在系统中是如何工作的。
第10章 音频驱动开发 331
10.1 简介 332
10.1.1 音频模块架构 332
10.1.2 系统中的音频设备 334
10.2 AVStream对象 338
10.2.1 设备对象 339
10.2.2 Filter工厂和Filter对象 340
10.2.3 Pin工厂和Pin对象 342
10.2.4 Node对象与Connection结构体 343
10.3 AVStream描述符 346
10.3.1 描述符简介 346
10.3.2 描述符示例 347
10.3.3 分发函数表 349
10.3.4 自控表 349
10.3.5 自控表示例 351
10.4 代码讲解 355
10.4.1 入口函数 355
10.4.2 设备分发函数 357
10.4.3 Filter与Pin分发函数 358
10.4.4 创建和删除 359
10.4.5 数据处理 360
10.4.6 数据格式 362
10.5 自控表函数 364
10.5.1 事件函数 364
10.5.2 属性函数 366
10.5.3 方法函数 367
10.5.4 用户接口 367
10.6 硬件操作 370
10.6.1 数据DMA 370
10.6.2 AVStream中的DMA实现 371
10.6.3 谈谈ISR 374
10.7 安装与测试 376
10.7.1 安装 376
10.7.2 测试工具 376
10.8 小结 379
ASIO音频驱动具有两个非常亮眼的优点：低延迟、多通道。低延迟能够达到几毫秒，使得最灵敏的耳朵也难也察觉；多通道则让通常的双声道、6.1声道等一齐歇菜，而可以很轻松地让多达十几、几十个声道同时工作，在进行高级音频编辑时，这非常重要。
第11章 ASIO虚拟声卡 380
11.1 引言 381
11.2 关于ASIO 383
11.3 ASIO用户驱动 384
11.3.1 COM接口 384
11.3.2 安装与卸载 386
11.3.3 IASIO接口 387
11.3.4 技术核心 390
11.3.5 计算延迟 392
11.4 内核驱动实现 393
11.4.1 同步 393
11.4.2 原理 393
11.4.3 实现 396
11.5 ASIO音频软件 396
11.6 小结 397
从本章开始的三章内容，讲的都是“驱动安装”这个话题。在本章中，介绍了系统中和驱动安装有关的各种系统模块。读者通过阅读本章后，至少能够掌握这两个基本知识：系统如何识别一个旧设备，并为它加载合适的驱动文件；系统如何发现一个新设备，并完成驱动安装。
第12章 设备驱动安装入门 399
12.1 基础知识预介 400
12.1.1 设备类型 400
12.1.2 设备实例ID 401
12.1.3 驱动加载和安装 403
12.2 安装模块 404
12.2.1 内核PNP管理器 405
12.2.2 用户PNP管理器 406
12.2.3 安装接口函数（Setup API） 408
12.2.4 配置管理器接口（CfgMgr API） 410
12.2.5 类安装器（Class Installers） 410
12.2.6 类协安装器（Class Co-Installers） 410
12.2.7 设备协安装器（Device Co-Installers） 411
12.2.8 驱动包（Driver Package） 412
12.2.9 驱动仓库（Driver Store） 413
12.2.10 设备管理器（Device Manager） 414
12.2.11 安装程序 415
12.2.12 新设备向导 416
12.2.13 添加硬件向导 416
12.2.14 驱动安装器（Driver Installer） 416
12.3 重要问题 417
12.3.1 寻找和选择 417
12.3.2 32位与64位系统兼容 418
12.3.3 系统重启 419
12.4 安装模式 420
12.4.1 示例1：客户端模式 421
12.4.2 示例2：服务器模式 423
12.5 安装器编程 424
12.5.1 DIF码 424
12.5.2 处理流程 427
12.5.3 工程示例 429
12.5.4 注册 430
12.6 小结 431
INF文件即驱动程序的“安装文件”，它包含了各种与驱动安装有关的指令信息。通过INF文件，系统知道如何处理驱动包中的各个文件，并在系统注册表中做出准确记录。本章主要从指令和域，这两个方面进行讲解。
第13章 深入解析INF文件 432
13.1 概述 433
13.1.1 域 433
13.1.2 指令 434
13.1.3 多系统 435
13.2 注册表指令 436
13.2.1 缩写根键 436
13.2.2 软件键 437
13.2.3 硬件键 437
13.2.4 AddReg 438
13.2.5 DelReg 440
13.2.6 BitReg 441
13.3 文件操作指令 441
13.3.1 CopyFiles 441
13.3.2 DelFiles 443
13.3.3 RenFiles 443
13.4 服务指令 444
13.4.1 AddService 444
13.4.2 DelService 445
13.5 基本域 446
13.5.1 版本域 446
13.5.2 文件域 447
13.5.3 默认安装域 451
13.5.4 控制域 454
13.5.5 字符串域 457
13.6 设备类安装域 458
13.6.1 主域 459
13.6.2 服务子域 461
13.7 接口类安装域 461
13.8 厂商/产品域 462
13.8.1 厂商域 463
13.8.2 产品域 464
13.9 设备安装域 464
13.9.1 硬件子域 466
13.9.2 协安装器子域 467
13.9.3 接口子域 468
13.9.4 厂商默认配置子域 469
13.9.5 逻辑优先配置子域 470
13.10 ChkInf介绍 471
13.11 小结 472
驱动安装程序让你的驱动软件显得更加专业，所以，放弃手动安装驱动的做法吧，你的驱动将显得更靓。本章的示例软件MyDrvInst，可以作为读者设计更漂亮的安装软件的开始。
第14章 设计驱动安装程序 473
14.1 驱动包 474
14.1.1 安装方式 474
14.1.2 安装驱动包 475
14.1.3 卸载驱动包 476
14.2 驱动更新 477
14.2.1 设备已连接 477
14.2.2 设备未连接 478
14.2.3 枚举系统设备 481
14.3 分析INF文件 484
14.3.1 函数介绍 484
14.3.2 打印设备ID 486
14.4 MyDrvInst介绍 487
14.5 制作软件安装包 490
14.5.1 视图介绍 490
14.5.2 我们的工程 492
14.5.3 编译执行 493
14.6 小结 494
附录A CY001 USB开发板 495
附录B VisualKD + VMWare实现单机内核调试 501