Windows核心编程(第5版)

Windows核心编程(第5版)
作 者: 杰瑞夫 克里斯托夫 葛子昂 周靖 廖敏
出版社: 清华大学出版社
丛编项:
版权说明: 本书为公共版权或经版权方授权,请支持正版图书
标 签: WINDOWS
ISBN 出版时间 包装 开本 页数 字数
未知 暂无 暂无 未知 0 暂无

作者简介

  JeffreyRichter是Wintellect公司的创始人之一,该公司从事培训,调试和咨询,致力于帮助其他公司以更快的速度开发出更优秀的软件。他著作颇丰,代表作有畅销书CLRviaC#。他还是MSDNMagazine的特约编辑和专栏作家。ChristopheNasarre是BusinessObjicts的软件架构师和开发部门领导,该公司致力于帮助其他企业更好地专注于其主营业务,通过商业智能方案来提升决策能力和业绩。他为Aiddison-Wesley,APress和MicrosoftPress出版的许多图书担任过技术审校,。此外,他还是MSDNMagazine的撰稿人。葛子昂,1998年毕业于南京理工大学计算机系,曾先后任职于上海育碧电脑软件有限公司和上海旭上电子有限公司,从事游戏软件的开发及图形处理器的设计。2005年加入微软中国研发集团/服务器与开发工具事业部至今,一直致力于WindowsCommunicationFoundation及相关领域的研发。代表译著有《NET设计规范》。周靖,1983年接触苹果机开始,“浸染”IT业数十年,涉猎广泛,具有深厚的技术功底和良好的文学素养。早期痴迷于硬件,曾担任《微型计算机》杂志特约作者多年。继而潜心钻研编程,并乐在其中,积累了丰富的经验。其翻译风格严谨、准确、朴实、流畅,深受读者欢迎。代表译著有《c++面向对象程序设计》(国内销量超过3万册)和《c#高级程序员指南》等。廖敏,毕业于上海交通大学软件学院并获硕士学位,目前在微软中国研发集团/服务器与开发工具事业部担任软件设计工程师。

内容简介

《Windows核心编程(第5版)》是为打算理解Windows的C和C++程序员精心设计的,作为Windows开发人员的必备参考。第5版全面覆盖WindowsXP,WindowsVista和WindowsServer2008中的170个新增函数和Windows特性。书中还讲解了Windows系统如何使用这些特性,我们开发的应用程序又如何充分使用这些特性,如何自行创建新的特性。《Windows核心编程(第5版)》重要主题:如何为32位和64位Windows系统构建和实现应用程序;如何新建和处理进程与作业;如何调度.管理、同步和销毁线程;如何通过I/O完成端口执行同步和异步设备I/O操作;如何使用虚拟内存、内存映射文件和堆之类的各种技术来分配内存;如何处理默认调拨的线程栈物理存储;如何为延迟加载、API拦截和进程注入构建DLL;如何使用结构化异常处理、Windows错误恢复和应用程序重启等机制。《微软技术丛书》包括以下几个子系列:从入门到精通:适合新手程序员的实用教程;侧重于基础技术和特征;提供范例文件。技术内幕:权威、必备的参考大全;包含丰富、实用的范例代码;帮助读者熟练掌握微软件技术。高级编程:侧重于高级特性、技术和解决问题;包含丰富、适用性强的范例代码;帮助读者精通微软技术。精通&宝典:着重剖析应用技巧,以帮助提高工作效率;主题包括办公应用和开发工具。认证考试教材:完全根据考试要求来阐述每一个知识点;提供可供搜索的Ebook(英文版)和训练题;提供实际场景、案例分析和故障诊断实验。

图书目录

第1章 错误处理 3

1.1 定义自己的错误代码 7

1.2 ErrorShow示例程序 7

第2章 字符和字符串处理 10

2.1 字符编码 11

2.2 ANSI字符和Unicode字符

与字符串数据类型 12

2.3 Windows中的Unicode函数

和ANSI函数 14

2.4 C运行库中的Unicode函数

和ANSI函数 16

2.5 C运行库中的安全字符串函数 17

2.5.1 初识新的安全字符串函数 18

2.5.2 在处理字符串时如何获得

更多控制 21

2.5.3 Windows字符串函数 23

2.6 为何要用Unicode 24

2.7 推荐的字符和字符串处理方式 25

2.8 Unicode与ANSI字符串转换 26

2.8.1 导出ANSI和Unicode DLL

函数 28

2.8.2 判断文本是ANSI还是

Unicode 29

第3章 内核对象 32

3.1 何为内核对象 32

3.1.1 使用计数 34

3.1.2 内核对象的安全性 34

3.2 进程内核对象句柄表 36

3.2.1 创建一个内核对象 37

3.2.2 关闭内核对象 38

3.3 跨进程边界共享内核对象 42

3.3.1 使用对象句柄继承 42

3.3.2 改变句柄的标志 45

3.3.3 为对象命名 46

3.3.4 终端服务命名空间 50

3.3.5 专有命名空间 51

3.3.5 复制对象句柄 58

第II部分 工作机制

第4章 进程 65

4.1 编写第一个Windows应用程序 66

4.1.1 进程实例句柄 71

4.1.2 进程前一个实例的句柄 72

4.1.3 进程的命令行 73

4.1.4 进程的环境变量 74

4.1.5 进程的关联性 79

4.1.6 进程的错误模式 79

4.1.7 进程当前所在的驱动器

和目录 80

4.1.8 进程的当前目录 81

4.1.9 系统版本 82

4.2 CreateProcess函数 85

4.2.1 pszApplicationName

和pszCommandLine参数 86

4.2.2 psaProcess,psaThread

和bInheritHandles参数 87

4.2.3 fdwCreate参数 89

4.2.4 pvEnvironment参数 91

4.2.5 pszCurDir参数 92

4.2.6 psiStartInfo参数 92

4.2.7 ppiProcInfo参数 98

4.3 终止进程 100

4.3.1 主线程的入口点函数返回 100

4.3.2 ExitProcess函数 101

4.3.3 TerminateProcess函数 102

4.3.4 当进程中的所有线程终止时 103

4.3.5 当进程终止运行时 103

4.4 子进程 104

4.5 管理员以标准用户权限运行时 106

4.5.1 自动提升进程的权限 109

4.5.2 手动提升进程的权限 111

4.5.3 何为当前权限上下文 112

4.5.4 枚举系统中正在运行的

进程 114

4.5.5 Process Information示例

程序 115

第5章 作业 121

5.1 对作业中的进程施加限制 124

5.2 将进程放入作业中 131

5.3 终止作业中的所有线程 132

查询作业统计信息 132

5.4 作业通知 135

5.6 Job Lab示例程序 138

第6章 线程基础 140

6.1 何时创建线程 141

6.2 何时不应该创建线程 143

6.3 编写第一个线程函数 144

6.4 CreateThread函数 144

6.4.1 psa参数 145

6.4.2 cbStackSize参数 145

6.4.3 pfnStartAddr和pvParam

参数 146

6.4.4 dwCreateFlags 147

6.4.5 pdwThreadID 147

6.5 终止运行线程 148

6.5.1 线程函数返回 148

6.5.2 ExitThread函数 148

6.5.3 TerminateThread函数 149

6.5.4 进程终止运行时 149

6.5.5 线程终止运行时 150

6.6 线程内幕 150

6.7 C/C++运行库注意事项 153

6.7.1 用_beginthreadex而不要用

CreateThread创建线程 161

6.7.2 绝对不应该调用的C/C++

运行库函数 161

6.8 了解自己的身份 162

6.8.1 将伪句柄转换为真正的

句柄 163

第7章 线程调度、优先级和关联性 165

7.1 线程的挂起和恢复 166

7.2 进程的挂起和恢复 167

7.3 睡眠 169

7.4 切换到另一个线程 169

7.5 在超线程CPU上切换到另一个

线程 170

7.6 线程的执行时间 170

7.7 在实际上下文中谈CONTEXT

结构 174

7.8 线程优先级 178

7.9 从抽象角度看优先级 179

7.10 优先级编程 182

7.10.1 动态提升线程优先级 185

7.10.2 为前台进程微调调度程序 186

7.10.3 调度I/O请求优先级 186

7.10.4 Scheduling Lab 示例程序 188

7.11 关联性 192

第8章 用户模式下的线程同步 197

8.1 原子访问:Interlocked系列函数 198

8.2 高速缓存行 203

8.3 高级线程同步 205

需要避免使用的一种方法 205

8.4 关键段 207

8.4.1 关键段:细节 209

8.4.2 关键段和旋转锁 212

8.4.3 关键段和错误处理 213

8.5 Slim读/写锁 214

8.6 条件变量 217

8.6.1 Queue示例程序 218

8.6.2 在停止线程时的死锁问题 225

8.6.3 一些有用的窍门和技巧 227

第9章 用内核对象进行线程同步 230

9.1 等待函数 232

9.2 等待成功所引起的副作用 235

9.3 事件内核对象 236

Handshake示例程序 241

9.4 可等待的计时器内核对象 245

9.4.1 让可等待的计时器添加APC

调用 248

9.4.2 计时器的剩余问题 250

9.5 信号量内核对象 251

9.6 互斥量内核对象 253

9.6.1 遗弃问题 255

9.6.2 互斥量与关键段的比较 256

9.6.3 Queue示例程序 256

9.7 线程同步对象速查表 264

9.8 其他的线程同步函数 265

9.8.1 异步设备I/O 265

9.8.2 WaitForInputIdle函数 265

9.8.3 MsgWaitForMultipleObjects(Ex)

函数 266

9.8.4 WaitForDebugEvent函数 267

9.8.5 SignalObjectAndWait函数 267

9.8.6 使用等待链遍历API来检测

死锁 268

第10章 同步设备I/O与异步设备I/O 275

10.1 打开和关闭设备 276

细看CreateFile函数 278

10.2 使用文件设备 285

10.2.1 取得文件的大小 285

10.2.2 设置文件指针的位置 286

10.2.3 设置文件尾 288

10.3 执行同步设备I/O 289

10.3.1 将数据刷新至设备 289

10.3.2 同步I/O的取消 290

10.4 异步设备I/O基础 291

10.4.1 OVERLAPPED结构 292

10.4.2 异步设备I/O的注意事项 294

10.4.3 取消队列中的设备I/O

请求 296

10.5 接收I/O请求完成通知 296

10.5.1 触发设备内核对象 297

10.5.2 触发事件内核对象 298

10.5.3 可提醒I/O 301

10.5.4 I/O完成端口 306

10.5.5 模拟已完成的I/O请求 316

第11章 Windows线程池 324

11.1 情形1:以异步方式调用函数 325

11.1.1 显式地控制工作项 325

11.1.2 Batch示例程序 327

11.2 情形2:每隔一段时间调用一个

函数 330

Timed Message Box示例程序 332

11.3 情形3:在内核对象触发时调用

一个函数 335

11.4 情形4:在异步I/O请求完成时

调用一个函数 337

11.5 回调函数的终止操作 339

11.5.1 对线程池进行定制 340

11.5.2 得体地销毁线程池:

清理组 342

第12章 纤程 345

使用纤程 345

Counter示例程序 349

第III部分 内存管理

第13章 Windows内存体系结构 355

13.1 进程的虚拟地址空间 355

13.2 虚拟地址空间的分区 356

13.2.1 空指针赋值分区 357

13.2.2 用户模式分区 357

13.3 地址空间中的区域 360

13.4 给区域调拨物理存储器 361

13.5 物理存储器和页交换文件 362

不在页交换文件中维护的物理

存储器 363

13.6 页面保护属性 365

13.6.1 写时复制 366

13.6.2 一些特殊的访问保护属性

标志 367

13.7 实例分析 367

区域内部 372

13.8 数据对齐的重要性 375

第14章 探索虚拟内存 379

14.1 系统信息 379

系统信息示例程序 382

14.2 虚拟内存状态 387

14.3 NUMA机器中的内存管理 388

示例程序:虚拟内存状态 389

14.4 确定地址空间的状态 391

14.4.1 VMQuery函数 392

14.4.2 示例程序:虚拟内存映射 397

第15章 在应用程序中使用虚拟内存 400

15.1 预订地址空间区域 400

15.2 给区域调拨物理存储器 402

15.3 同时预订和调拨物理存储器 403

15.4 何时调拨物理存储器 405

15.5 撤销调拨物理存储器及释放区域 407

15.5.1 何时撤销调拨物理存储器 407

15.5.2 虚拟内存分配示例程序 408

15.6 改变保护属性 414

15.7 重置物理存储器的内容 415

MemReset示例程序 417

15.8 地址窗口扩展 419

AWE示例程序 422

第16章 线程栈 429

16.1 C/C++运行库的栈检查函数 433

16.2 Summation示例程序 435

第17章 内存映射文件 440

17.1 映射到内存的可执行文件和DLL 441

17.1.1 同一个可执行文件或DLL的

多个实例不会共享静态

数据 442

17.1.2 在同一个可执行文件或DLL

的多个实例间共享静态

数据 444

17.1.3 Application Instances示例

程序 449

17.2 映射到内存的数据文件 451

17.2.1 方法1:一个文件,一块

缓存 451

17.2.2 方法2:两个文件,一块

缓存 452

17.2.3 方法3:一个文件,两块

缓存 452

17.2.4 方法4:一个文件,零个

缓存 453

17.3 使用内存映射文件 453

17.3.1 第1步:创建或打开文件

内核对象 454

17.3.2 第2步:创建文件映射

内核对象 455

17.3.3 第3步:将文件的数据映射

到进程的地址空间 458

17.3.4 第4步:从进程的地址空间

撤销对文件数据的映射 461

17.3.5 第5步和第6步:关闭文件

映射对象和文件对象 462

17.6 File Reverse示例程序 463

17.7 用内存映射文件来处理大文件 469

17.8 内存映射文件和一致性 470

17.9 给内存映射文件指定基地址 471

17.10 内存映射文件的实现细节 472

17.11 用内存映射文件在进程间共享

数据 473

17.12 以页交换文件为后备存储器的

内存映射文件 474

Memory-Mapped File Sharing示例

程序 475

17.13 稀疏调拨的内存映射文件 478

Sparse Memory-Mapped File示例

程序 480

第18章 堆 491

18.1 进程的默认堆 491

18.2 为什么要创建额外的堆 492

18.2.1 对组件进行保护 493

18.2.2 更有效的内存管理 493

18.2.3 使内存访问局部化 494

18.2.4 避免线程同步的开销 494

18.2.5 快速释放 495

18.3 如何创建额外的堆 495

18.3.1 从堆中分配内存块 497

18.3.2 调整内存块的大小 498

18.3.3 获得内存块的大小 499

18.3.4 释放内存块 500

18.3.5 销毁堆 500

18.3.6 在C++中使用堆 500

18.4 其他堆函数 503

第IV部分 动态链接库

第19章 DLL基础 509

19.1 DLL和进程的地址空间 510

19.2 纵观全局 512

19.2.1 构建DLL模块 514

19.2.2 构建可执行模块 519

19.2.3 运行可执行模块 522

第20章 DLL高级技术 524

20.1 DLL模块的显式载入和符号链接 524

20.1.1 显式地载入DLL模块 525

20.1.2 显式地卸载DLL模块 529

20.1.3 显式地链接到导出符号 532

20.2 DLL的入口点函数 533

20.2.1 DLL_PROCESS_ATTACH

通知 534

20.2.2 DLL_PROCESS_DETACH

通知 535

20.2.3 DLL_THREAD_ATTACH

通知 537

20.2.4 DLL_THREAD_DETACH

通知 538

20.2.5 DllMain的序列化调用 538

20.2.6 DllMain和C/C++运行库 541

20.3 延迟载入DLL 542

DelayLoadApp示例程序 547

20.4 函数转发器 553

20.5 已知的DLL 553

20.6 DLL重定向 555

20.7 模块的基地址重定位 556

20.8 模块的绑定 562

第21章 线程局部存储区 565

21.1 动态TLS 566

使用动态TLS 568

21.2 静态TLS 570

第22章 DLL注入和API拦截 572

22.1 DLL注入的一个例子 573

22.2 使用注册表来注入DLL 575

22.3 使用Windows挂钩来注入DLL 576

Desktop Item Position Saver(DIPS)

工具 578

22.4 使用远程线程来注入DLL 587

22.4.1 Inject Library示例程序 591

22.4.2 Image Walk DLL 596

22.5 使用木马DLL来注入DLL 598

22.6 把DLL作为调试器来注入 598

22.7 使用CreateProcess来注入

代码 599

22.8 API拦截的一个例子 599

22.8.1 通过覆盖代码来拦截API 600

22.8.2 通过修改模块的导入段来

拦截API 601

22.8.3 Last MessageBox Info示例

程序 604

第V部分 结构化异常处理

第23章 终止处理程序 621

通过实例理解终止处理程序 622

第24章 异常处理程序与软件异常 638

24.1 通过实例理解异常过滤程序

和异常处理程序 638

24.1.1 Funcmeister1函数 639

24.1.2 Funcmeister2函数 639

24.2 EXCEPTION_EXECUTE_

HANDLER 641

24.2.1 一些有用的例子 642

24.2.2 全局展开 645

24.2.3 停止全局展开 647

24.3 EXCEPTION_CONTINUE_

EXECUTION 648

谨慎使用EXCEPTION_CONTINUE_

EXECUTION 649

24.4 EXCEPTION_CONTINUE_

SEARCH 650

24.5 GetExceptionCode 652

24.6 GetExceptionInformation 656

24.7 软件异常 659

第25章 未处理异常、向量化异常处理

与C++异常 663

25.1 UnhandledExceptionFilter函数

详解 665

25.2 即时调试 671

25.3 电子表格示例程序 673

25.4 向量化异常和继续处理程序 681

25.5 C++异常与结构化异常的比较 683

25.6 异常与调试器 684

第26章 错误报告与应用程序恢复 688

26.1 Windows错误报告控制台 688

26.2 可编程的Windows错误报告 691

26.3 对进程中所有的问题报告进行

定制 693

26.4 问题报告的创建与定制 694

26.4.1 创建一个自定义的问题

报告 697

26.4.2 设置报告参数:

WerReportSetParameter 698

26.4.3 将小型转储文件放入报告:

WerReportAddDump 698

26.4.4 将任意文件放入报告:

WerReportAddFile 699

26.4.5 修改对话框文本:

WerReportSetUIOption 700

26.4.6 提交错误报告:

WerReportSubmit 700

26.4.7 关闭问题报告:

WerReportCloseHandle 702

26.4.8 Customized WER示例

程序 702

26.5 应用程序的自动重启与恢复 708

26.5.1 应用程序的自动重启 708

26.5.2 对应用程序恢复的支持 709

附录A 构建环境 713

A.1 CmnHdr.h头文件 713

A.1.1 Microsoft Windows Version

构建选项 713

A.1.2 Unicode构建选项 714

A.1.3 Windows Definitions与编译

警告级别4 714

A.1.4 pragma message辅助宏 715

A.1.5 chINRANGE宏 715

A.1.6 chBEGINTHREADEX宏 715

A.1.7 适用于x86平台的

对DebugBreak的改进 717

A.1.8 创建软件异常码 717

A.1.9 chMB宏 717

A.1.10 chASSERT宏

和chVERIFY宏 717

A.1.11 chHANDLE_DLGMSG宏 718

A.1.12 chSETDLGICONS宏 718

A.1.13 强制编译器寻找 (w)WinMain

入口点函数 718

A.1.14 通过pragma预处理指令来支持

XP风格的用户界面主题 718

附录B 消息处理宏、子控件宏和API宏 724

B.1 消息处理宏 725

B.2 子控件宏 727

B.3 API宏 727

索引 729