《Windows NT设备驱动程序设计指南》求取 ⇩

前言1

第1章 引言1

1.1 系统总体结构1

1.1.1 Windows NT的设计目标1

1.1.2 Windows NT中的硬件特权级1

1.1.3 操作系统的基础成分2

1.1.4 Executive的内容3

1.1.5 基操作系统的扩展5

1.1.6 Win32子系统6

1.2 内核模式I/O组件7

1.2.1 I/O子系统的设计目标7

1.2.2 Windows NT中的分层驱动程序7

1.2.3 SCSI驱动程序8

1.2.4 网络驱动程序9

1.3 专用驱动程序体系结构11

1.3.1 视频驱动程序11

1.3.2 打印机驱动程序12

1.3.3 多媒体驱动程序14

1.3.4 遗留16位应用的驱动程序15

1.4 小结16

第2章 硬件环境17

2.1 硬件基础知识17

2.1.1 设备寄存器17

2.1.2 访问设备寄存器18

2.1.3 设备中断19

2.1.4 数据传输机制20

2.1.5 直接内存存取(DMA)机制21

2.1.6 设备专用内存21

2.1.7 自动配置的要求22

2.1.6 自动配置的要求22

2.2 总线与Windows NT23

2.2.1 ISA——工业标准体系结构23

2.2.2 MCA——微通道体系结构25

2.2.3 EISA——扩展的工业标准总线27

2.2.4 PCI——外围部件互连30

2.3 处理硬件的提示32

2.3.1 了解硬件32

2.3.2 使用硬件智能33

2.3.3 测试硬件33

2.4 小结33

3.1.2 中断34

3.2.1 CPU优先级34

3.2 Windows NT的中断使用34

3.1.3 内核模式线程34

3.1.1 异常34

3.1 内核模式代码的执行34

第3章 内核模式I/O处理34

3.2.2 中断处理次序35

3.2.3 软件产生的中断35

3.3 推迟过程调用(DPC)36

3.3.1 DPC的操作36

3.3.2 DPC的行为36

3.4 访问用户缓冲区37

3.5 内核模式驱动程序的结构38

3.5.1 驱动程序初始化和清理例程38

3.5.2 I/O系统服务Dispatch例程39

3.5.3 数据传输例程39

3.5.4 资源同步回调40

3.5.5 其他驱动程序例程40

3.6.1 数据传输41

3.6.2 驱动程序的请求预处理41

3.6 I/O处理次序41

3.6.1 Windows NT的请求预处理41

3.6.4 驱动程序的后处理42

3.6.5 I/O管理器的后处理42

3.7 小结43

第4章 驱动程序和内核模式对象44

4.1 数据对象与Windows NT44

4.1.1 Windows NT和OOP44

4.1.2 NT对象和Win32对象44

4.2 I/O请求包(IRP)44

4.2.1 IRP结构45

4.2.2 操纵IRP46

4.3 驱动程序对象47

4.4 Device对象与Device Extension48

4.4.2 操纵Device对象49

4.4.1 Device对象的结构49

4.4.3 Device Extension50

4.5 Controller对象和Controller Extension50

4.5.1 Controller对象的结构51

4.5.2 操纵Controller对象51

4.5.3 Controller Extension52

4.6 Adapter对象52

4.6.1 Adapter对象的结构52

4.6.2 操纵Adapter对象52

4.7 Interrupt对象53

4.7.1 Interrupt对象的结构53

4.7.2 操纵Interrput对象53

4.8 小结54

5.1.2 使用渐进开发方法55

5.1.1 使用正规设计方法55

5.1 驱动程序设计策略55

第5章 一般的开发问题55

5.1.3 使用样板驱动程序56

5.2 编码约定和技术56

5.2.1 一般建议56

5.2.2 命名约定56

5.2.3 头文件57

5.2.4 状态返回值58

5.2.5 Windows NT驱动程序支持例程58

5.2.6 丢弃初始化例程59

5.2.7 控制驱动程序分页60

5.3 驱动程序内存分配60

5.3.1 对驱动程序可用的内存60

5.3.2 使用内核堆栈61

5.3.3 使用池区域61

5.3.4 内存再分配的系统支持62

5.4 Unicode字符串64

5.4.1 Unicode字符串数据类型64

5.4.2 处理Unicode64

5.5 中断同步65

5.5.1 问题65

5.5.2 中断阻塞65

5.5.3 阻塞中断的规则66

5.5.4 使用推迟过程调用的同步66

5.6 同步多个CPU66

5.6.1 自旋锁工作66

5.6.2 使用自旋锁66

5.6.3 使用自旋锁的规则67

5.7 链表68

5.7.1 单向链表68

5.7.2 双向链表69

5.7.3 删除链表块69

5.8 小结70

6.1 写DriverEntry例程71

6.1.1 执行上下文环境71

6.1.2 DriverEntry例程的工作71

第6章 初始化和清理例程71

6.1.3 初始化DriverEntry点72

6.1.4 创建Device对象72

6.1.5 选择缓冲策略73

6.1.6 NT和Win32设备名73

6.2 范例代码:驱动程序初始化74

6.3 写Reiruitiailze例程81

6.4 写Unload例程82

6.4.1 执行上下文82

6.4.2 Unload例程的作用82

6.3.2 Reinitiailze例程的作用82

6.3.1 执行上下文82

6.5 范例代码:驱动程序清理83

6.6 写Shutdown例程86

6.6.1 执行环境86

6.6.2 Shutdown例程的作用86

6.6.3 启用关闭通知86

6.7.2 WINOBJ实用程序87

6.7.1 测试过程87

6.7 驱动程序的测试87

6.8 小结88

第7章 硬件初始化89

7.1 查找自动检测的硬件89

7.1.1 自动检测如何工作89

7.1.2 自动检测硬件和Registry89

7.1.3 查询硬件数据库90

7.1.4 ConfigCallback例程的作用92

7.1.5 使用配置数据93

7.1.6 转换配置数据94

7.2 范例代码:查找自动检测硬件94

7.2.1 XXDRIVER.H95

7.2.2 AUTOCON.C96

7.3 查找未识别的硬件103

7.3.1 把驱动程序参数加到Registry103

7.3.2 从Registry中检索参数104

7.3.3 设备信息的其他来源105

7.4 范例代码:查询Registry106

7.5 分配和释放硬件115

7.5.1 如何进行资源分配115

7.5.2 如何声明拥有硬件资源116

7.5.3 如何释放硬件118

7.5.5 装入设备微代码119

7.5.4 映射设备内存119

7.6 范例代码:分配硬件120

7.7 小结124

第8章 驱动程序Dispatch例程125

8.1 启用驱动程序Dispatch例程125

8.1.1 I/O请求派发机制125

8.1.2 启用特定的功能代码126

8.1.3 决定支持哪些功能代码126

8.2 扩展派发接口126

8.2.1 定义私有的IOCTL值127

8.2.2 IOCTL参数传递方法127

8.2.3 编写IOCTL头文件128

8.3 写驱动程序Dispatch例程130

8.3.1 执行环境130

8.3.2 Dispatch例程的作用130

8.3.3 退出Dispatch例程131

8.4 处理特定种类的请求132

8.4.1 处理读写请求133

8.4.2 处理IOCTL请求133

8.4.3 管理IOCTL缓冲区135

8.5 测试驱动程序Dispatch例程136

8.5.1 测试过程136

8.5.2 测试程序范例137

8.6 小结137

第9章 编程I/O数据传输138

9.1 编程I/O的工作138

9.1.1 编程I/O过程中发生什么138

9.1.2 同步各种驱动程序例程139

9.2 驱动程序初始化和清理139

9.2.1 初始化StartI/O入口点139

9.2.3 连接到中断源140

9.2.2 初始化DpcForIsr例程140

9.2.4 从中断源断开141

9.3 写Start I/O例程142

9.3.1 执行上下文142

9.3.2 Start I/O例程的工作142

9.4 写中断服务例程(ISR)142

9.4.1 执行上下文142

9.4.2 中断服务例程的工作143

9.5 写Dpc Forlsr例程143

9.5.1 执行上下文143

9.5.2 DpcForlsr例程的工作144

9.5.3 优先级增量144

9.6 硬件:并行端口145

9.6.1 并行端口的工作145

9.6.2 设备寄存器145

9.6.4 并行端口的驱动程序146

9.6.3 中断行为146

9.7 范例代码:并行端口驱动程序147

9.7.1 XXDRIVER.H147

9.7.2 INIT.C147

9.7.3 TRANSFER.C149

9.8 测试数据传输例程155

9.9 小结155

第10章 定时器156

10.1 处理设备超时156

10.1.1 I/O定时器例程的工作156

10.1.2 如何截获设备超时条件156

10.2 范例代码:截获设备超时157

10.2.1 XXDRIVFR.H157

10.2.2 INIT.C158

10.2.3 TRANSFER.C158

10.2.4 TIMER.C161

10.3 管理没有中断的设备162

10.3.1 处理无中断设备163

10.3.2 CustomTimer Dpc例程的工作163

10.3.3 如何建立CustomTimerDpc例程164

10.3.4 如何指定到期时间164

10.3.5 CustomTimerDpc例程的其他使用165

10.4 范例代码.:基于定时器的驱动程序165

10.4.1 XXDRIVER.H165

10.4.2 INIT.C166

10.4.3 TRANSFER.C167

10.5 小结171

第11章 全双工驱动程序172

11.1 同时做两件事情172

11.1.1 处理并发的IRP172

11.1.4 实现辅路径173

11.1.3 全双工驱动程序的数据结构173

11.1.2 修改的驱动程序体系结构的工作173

11.2 使用Device Queue对象174

11.2.1 Device Queue对象的工作174

11.2.2 如何使用Device Queue对象175

11.3 写CustomDpc例程176

11.3.1 如何使用CustomDpc例程176

11.3.2 执行上下文177

11.4 取消I/O请求177

11.4.1 取消IRP的过程178

11.4.2 同步问题178

11.4.3 Cancel例程的工作179

11.4.4 Dispatch Cleanup例程的工作180

11.5.1 16550UART的工作182

11.5.2 设备寄存器182

11.5 硬件:16550 UART182

11.5.3 中断行为183

11.6 范例代码:全双工UART驱动程序185

11.6.1 目标185

11.6.2 XXDRIVER.H中的DEVICE EXTENSION185

11.6.3 DISPATCH.C186

11.6.4 DEVQUEUE.C188

11.6.5 INPUT.C191

11.6.6 ISR.C193

11.6.7 CANCEL.C197

11.7 小结201

第12章 DMA驱动程序202

12.1 Windows NT下的DMA如何工作202

12.1.1 使用Adapter对象隐藏DMA硬件的变化202

12.1.2 解决映射寄存器的分散/集中问题203

12.1.3 用内存描述符表管理I/O缓冲区204

12.1.4 维护Cache一致性205

12.1.5 DMA驱动程序分类206

12.1.6 NT DMA体系结构的限制207

12.2 使用Adapter对象207

12.2.1 找到正确的Adapter对象207

12.2.2 获取和释放Adapter对象209

12.2.3 设置DMA硬件210

12.2.4 清仓Adaper对象Cache211

12.3 写基于包的从属DMA驱动程序212

12.3.1 基于包的从属DMA的工作212

12.3.2 分割DMA传输213

12.4 范例代码:基于包的从属DMA驱动程序215

12.4.1 XXDRIVER.H215

12.4.2 REGOON.C216

12.4.3 TRANSFER.C217

12.5.1 设置总线主硬件224

12.5 写基于包总线的主DMA驱动程序224

12.5.2 带分散/集中支持的硬件226

12.5.3 用IoMapTransfer建立分散/集中列表228

12.6 写公共缓冲区从属DMA驱动程序229

12.6.1 分配公共缓冲区229

12.6.2 使用公共缓冲区从属DMA保持吞吐率229

12.7 写公共缓冲区总线主设备DMA驱动程序232

12.8 小结233

第13章 设备错误的日志记录234

13.1 Windows NT中的事件日志234

13.1.1 决定日志记录什么234

13.1.2 事件日志如何工作234

13.2 处理消息235

13.2.1 消息编码如何工作235

13.2.2 写消息定义文件236

13.2.3 一个小例子:XXMSG.MC238

13.2.4 编译消息定义文件240

13.2.5 给驱动程序增加消息资源241

13.2.6 登记驱动程序为事件源242

13.3 生成日志项242

13.3.1 准备驱动程序进行错误日志记录242

13.3.2 分配错误日志包242

13.3.4 日志记录错误244

13.4 范例:一个错误日志记录例程244

13.5 小结250

第14章 系统线程251

14.1 系统线程251

14.1.1 何时使用线程251

14.1.2 创建和终止系统线程251

14.1.4 系统工作者线程252

14.1.3 管理线程优先级252

14.2 线程同步253

14.2.1 时间同步253

14.2.2 一般同步253

14.3 使用派发器对象254

14.3.1 Event对象255

14.3.2 在驱动程序之间共享Event对象256

14.3.3 Mutex对象256

14.3.4 Semaphore对象257

14.3.5 Timer对象258

14.3.6 Thread对象259

14.3.7 Mutex的变种260

14.3.8 同步死锁261

14.4 范例代码:一个基于线程的驱动程序262

14.4.1 驱动程序的工作过程262

14.4.2 XXDRIVER-H中的DEVICE-EX-TENSION结构262

14.4.3 INIT.C中的XxCreateDevice函数263

14.4.4 DISPATCH.C中的XxDispatchRead-Write函数265

14.4.5 THREAD.C266

14.4.6 TRANSFER.C268

14.5 小结276

第15章 高层驱动程序277

15.1 中间驱动程序概述277

15.1.1 什么是中间驱动程序277

15.1.2 应使用分层结构吗277

15.2 编写分层驱动程序278

15.2.1 分层驱动程序如何工作278

15.2.2 分层驱动程序的初始化和清理279

15.2.3 代码段:连接到另一个驱动程序280

15.2.4 分层驱动程序的其他初始化考虑281

15.2.5 分层驱动程序中的I/O请求处理282

15.2.6 代码段:调用低层驱动程序283

15.3 写I/O Completion例程284

15.3.1 请求I/O Completion回调284

15.3.2 执行上下文285

15.3.3 I/O Completion例程的作用285

15.3.4 代码段:一个I/O Cornpletion例程286

15.4 分配另外的IRP287

15.4.1 IRP的I/O堆栈再讨论288

15.4.2 控制IRP堆栈的大小288

15.4.3 用IoBuildSynchronousFsdRequest创建IRP289

15.4.4 用IoBuildAsynchronousFsdRequest创建IRP291

15.4.5 用IoBuildDeviceIoControIRequest创建IRP292

15.4.6 从头建立IRP293

15.4.8 记录驱动程序分配的IRP296

15.5 写过滤器驱动程序297

15.5.2 过滤器驱动程序中的初始化和清理298

15.5.1 过滤器驱动程序如何工作298

15.5.3 实际发生的操作300

15.5.4 使挂接透明300

15.6 范例代码:过滤器驱动程序301

15.6.1 YYDRIVER.H-驱动程序数据结构301

15.6.2 INIT.C-初始化代码301

15.6.3 DISPATCH.C-过渡器Dispatch例程306

15.6.4 COMPLETE.C-I/O Completion例程309

15.7 写紧耦合驱动程序312

15.7.1 紧耦合驱动程序如何工作313

15.7.2 紧耦合驱动程序中的初始化和清理313

15.7.3 紧耦合驱动程序中的I/O请求处理314

15.8 小结315

第16章 构造和安装驱动程序316

16.1 构造驱动程序316

16.1.1 BUILD的用途316

16.1.2 如何构造驱动程序317

16.1.3 写SOURCES文件318

16.1.4 BUILD生成的日志文件319

16.1.5 递归的BUILD操作319

16.2.1 使用预编译头文件320

16.2.2 在驱动程序中包含版本信息320

16.2 其他BUILD时的活动320

16.2.3 在BUILD中包含非标准组件322

16.2.4 把驱动程序符号数据移入.DBG文件323

16.3.1 如何手工安装驱动程序324

16.3.2 驱动程序Registry项324

16.3 安装驱动程序324

16.3.3 标准驱动程序的最终用户安装326

16.4 控制驱动程序装入次序327

16.4.1 改变驱动程序的Start值327

16.3.4 非标准驱动程序的最终用户安装327

16.4.2 建立驱动程序之间明确的依赖关系328

16.4.3 建立全局组依赖关系328

16.4.4 控制组内的装入次序330

16.5 小结331

17.1 驱动程序测试指南332

17.1.1 尚未试驱动程序的一般方法332

第17章 测试和调试驱动程序332

17.1.2 使用Microsoft硬件兼容性测试(HCT)333

17.2 关于驱动程序错误的一些思考334

17.2.1 驱动程序错误分类334

17.2.2 重复产生驱动程序错误335

17.2.3 减少调试的编码策略335

17.3 阅读崩溃时显示的屏幕336

17.3.1 系统崩溃时发生什么336

17.2.4 跟踪驱动程序错误336

17.3.2 STOP消息的结构337

17.3.3 STOP消息解释339

17.4 WINDBG概述339

17.4.1 源代码调试的关键340

17.4.2 几个WINDBG命令340

17.5.2 开始分析342

17.5.1 分析的目标342

17.5.3 跟踪堆栈342

17.5 分析崩溃转储342

17.5.4 间接检查方法345

17.5.5 使用DUMPEXAM发现崩溃347

17.6.1 开始和结束调试会话348

17.6.2 设置断点348

17.6 交互式调试348

17.7 写WINDBG扩展349

17.6.4 使用打印语句349

17.7.1 WINDBG扩展如何工作349

17.6.3 设置硬断点349

17.7.2 初始化和版本检查函数350

17.7.3 写扩展命令351

17.7.4 WINDBG帮助函数351

17.8 范例代码:一个WINDBG扩展352

17.8.1 XXDBG.C352

17.7.5 构造和使用扩展DLL352

17.8.3 SOURCES文件357

17.8.4 样本输出357

17.8.2 XXDBG.DEF357

17.9.1 在驱动程序中留下调试代码358

17.9.2 截获不正确的假设358

17.9 其他调试技术358

17.9.3 使用错误检查回调函数359

17.9.4 截获内存遗漏359

17.9.5 使用计数器,二进制位和缓冲区360

17.10 小结362

18.1.2 了解硬件363

18.1.1 知道要达到的目标363

18.1.3 探讨创造性的驱动程序设计363

18.1 一般指南363

第18章 驱动程序性能363

18.2 Windows NT中的性能监视364

18.1.5 计量所做的每件事情364

18.2.1 一些术语364

18.1.4 创造性地优化代码364

18.2.2 性能监视系统如何工作365

18.3 把计数器名字加到Registry366

18.3.1 Registry中的计数器定义366

18.2.3 驱动程序如何输出性能数据366

18.3.2 写LODCTR命令文件367

18.3.3 使用LODCTR和UNLODCTR368

18.4 性能数据的格式369

18.4.1 性能数据的总体结构369

18.4.2 计数器的类型371

18.4.3 带多个实例的对象373

18.5 写数据收集DLL374

18.5.1 数据收集DLL的内容374

18.5.2 数据收集DLL中的错误处理375

18.5.3 安装DLL376

18.6 范例代码:数据收集DLL377

18.6.1 XXPERF-C377

18.6.2 构造和安装这个例子385

18.7 小结385

附录A 开发环境386

A.1 硬件和软件要求386

A.2 调试符号文件387

A.3 在目标系统上启用崩溃转储387

A.4 启用目标系统的调试客户程序388

附录B 常见错误检查代码390

B.1 驱动程序的常见问题390

B.2 同步问题391

B.3 破坏的驱动程序数据结构391

B.4 内存问题392

B.5 硬件故障393

B.6 配置管理器和Registry问题394

B.7 文件系统问题395

B.8 系统初始化故障395

15.4.7 为低层驱动程序建立缓冲区396

B.9 内部系统故障397

参考文献398

1997《Windows NT设备驱动程序设计指南》由于是年代较久的资料都绝版了,几乎不可能购买到实物。如果大家为了学习确实需要,可向博主求助其电子版PDF文件(由(美)(A.贝克)Art Baker著;科欣翻译组译 1997 机械工业出版社;西蒙与舒斯特国际出版公司 出版的版本) 。对合法合规的求助,我会当即受理并将下载地址发送给你。