Windows 10系统编程 引言
# 引言
这应该是继《Windows核心编程》之后、最近十年最好且唯一的关于Windows编程的书吧,其涉及的内容涵盖Windows7到Window10程序的方方面面,非常详尽、通俗易懂。
很多人觉得利用Windows API进行Windows原生编程已经日薄西山了,Windows系统不常用了,这其实是程序员的幸存者偏差,无论是工作还是娱乐,对于普罗大众来说,Windows系统仍然是最最常使用的操作系统,就像现在一些人已经不愁吃不愁穿了,会忽视水稻的重要性了。
学习Windows编程的好处如下:
- 在如今的求职大环境下,Windows和Linux C/C++双修,更有竞争力;
- 很多著名的开源代码都有Windows版本,熟悉Windows编程让学习这些源码变得容易;
- 最后一点,也是最重要的一点,就是提高你的技术人生的职业容错性:如果有一天你不幸被裁员了或者因为生活压力不得不退居二三线城市,庞大的Windows软件需求市场,让你能够为其他人或者公司开发一些Windows实用工具或者软件。毕竟像Golang、Rust这样的编程技术,在非一线城市实乃屠龙之术,没啥市场,更不用说用这些技术来养家活口。
本专栏翻译自Pavel Yosifovich《Windows 10 System Programming》,首发于 cppguide.cn (opens new window)。
限于水平有限,如果您在阅读过程中有任何问题,可以联系小方(微信cppxiaofang),也欢迎加入小方的 技术交流群,群里面有很多技术高手,不定期发布招聘信息,加群请备注“加微信群”。
小方微信公众号【CppGuide】:
# 适合阅读本书的人群
本书面向以Windows平台为目标的软件开发人员,这些人员需要获得更高级别的框架和库无法实现的控制能力。本书使用C和C++作为代码示例,因为Windows API大多基于C语言。在合理的情况下,即当C++在维护性、清晰度、资源管理等方面或上述多方面结合体现出明显优势时,本书会使用C++。本书不会使用复杂的C++结构,如模板元编程。本书重点不在于C++,而在于Windows。
话虽如此,其他语言也可以通过其专门的互操作机制来调用Windows API。例如,.NET语言(C#、VB、F#等)可以使用平台调用(P/Invoke,Platform Invoke )来调用Windows API。其他语言,如Python、Rust、Java等,也都有各自等效的功能。
# 使用本书前应了解的内容
读者应熟练掌握C编程语言,尤其要熟悉指针、结构体及其标准库,因为这些在Windows API中频繁出现。强烈建议读者具备基本的C++知识,不过仅精通C语言也可以研读本书。
# 目录
- 引言
- 适合阅读本书的人群
- 使用本书前应了解的内容
- 示例代码
- 第1章:基础
- Windows架构概述
- 进程(Processes)
- 动态链接库(Dynamic Link Libraries)
- 虚拟内存(Virtual Memory)
- 线程(Threads)
- 通用系统架构
- Windows应用程序开发
- 你的第一个应用程序
- 处理字符串
- C/C++运行时中的字符串
- 字符串输出参数
- 安全字符串函数
- 32位与64位开发
- 编码规范
- C++用法
- 处理API错误
- 定义自定义错误代码
- Windows版本
- 获取Windows版本
- 练习
- 总结
- 第2章:对象和句柄(Handles)
- 内核对象(Kernel Objects)
- 运行单实例进程
- 句柄
- 伪句柄(Pseudo Handles)
- 句柄的资源获取即初始化(RAII,Resource Acquisition Is Initialization)
- 使用Windows 运行时库(WIL,Windows Implementation Library)
- 创建对象
- 对象名称
- 共享内核对象
- 按名称共享
- 通过句柄复制共享
- 私有对象命名空间
- 补充:用于私有命名空间的WIL包装器
- 其他对象和句柄
- 用户对象(User Objects)
- 图形设备接口对象(GDI Objects,Graphics Device Interface Objects)
- 总结
- 第3章:进程
- 进程基础
- 进程资源管理器中的进程
- 进程创建
- main函数
- 进程环境变量
- 创建进程
- 句柄继承
- 进程驱动器目录
- 进程(和线程)属性
- 受保护进程和并行编程库(PPL,Parallel Patterns Library)进程
- 通用Windows平台(UWP,Universal Windows Platform)进程
- 最小化进程和Pico进程
- 进程终止
- 枚举进程
- 使用EnumProcesses
- 使用Toolhelp函数
- 使用WTS函数
- 使用原生API
- 练习
- 总结
- 第4章:作业(Jobs)
- 作业简介
- 创建作业
- 嵌套作业
- 查询作业信息
- 作业记账信息
- 查询作业进程列表
- 设置作业限制
- CPU速率限制
- 用户界面限制
- 作业通知
- 隔离仓(Silos)
- 练习
- 总结
- 第5章:线程基础
- 引言
- 套接字(Sockets)、内核和逻辑处理器
- 创建和管理线程
- 质数计数器应用程序
- 运行质数计数器
- 终止线程
- 线程栈
- 线程名称
- C++标准库呢?
- 练习
- 总结
- 第6章:线程调度
- 优先级
- 调度基础
- 单CPU调度
- 时间片(The Quantum)
- 处理器组
- 多处理器调度
- 亲和力(Affinity)
- CPU集与硬亲和力
- 系统CPU集
- 修订后的调度算法
- 观察调度
- 通用调度
- 硬亲和力
- CPU集
- 后台模式
- 优先级提升
- 完成I/O操作
- 前台进程
- GUI线程唤醒
- 避免饥饿
- 调度的其他方面
- 暂停和恢复
- 暂停和恢复进程
- 睡眠和让步
- 总结
- 第7章:线程同步(进程内)
- 同步基础
- 原子操作(Atomic Operations)
- 简单递增应用程序
- Interlocked函数家族
- 临界区(Critical Sections)
- 锁和资源获取即初始化
- 死锁(Deadlocks)
- MD5计算器应用程序
- 计算MD5哈希值
- 哈希缓存
- 图像加载通知
- 事件解析
- 整合所有内容
- 读写锁(Reader Writer Locks)
- 资源获取即初始化包装器
- MD5计算器2
- 条件变量(Condition Variables)
- 队列演示应用程序
- 等待地址
- 同步屏障(Synchronization Barriers)
- C++标准库呢?
- 练习
- 总结
- 第8章:线程同步(进程间)
- 调度程序对象(Dispatcher Objects)
- 等待成功
- 互斥锁(Mutex)
- 互斥锁演示应用程序
- 废弃的互斥锁
- 信号量(Semaphore)
- 队列演示应用程序
- 事件(Event)
- 使用事件
- 可等待计时器(Waitable Timer)
- 其他等待函数
- 在可提醒状态下等待
- 在GUI线程上等待
- 等待空闲的GUI线程
- 原子性地发出信号和等待
- 练习
- 总结
- 第9章:线程池
- 为什么使用线程池?
- 线程池工作回调函数
- 简单工作应用程序
- 控制工作项
- MD5计算器应用程序
- 线程池等待回调函数
- 线程池定时器回调函数
- 简单定时器示例
- 线程池I/O回调函数
- 线程池实例操作
- 回调环境
- 私有线程池
- 清理组(Cleanup Groups)
- 练习
- 总结
- 第10章:高级线程处理
- 线程本地存储(Thread Local Storage)
- 动态线程本地存储(Dynamic TLS)
- 静态线程本地存储(Static TLS)
- 远程线程
- Breakin应用程序
- 线程枚举
- thlist应用程序
- 缓存和缓存行(Cache Lines)
- 等待链遍历(Wait Chain Traversal)
- 死锁检测器应用程序
- 异步等待链遍历(WCT,Wait Chain Traversal)会话
- 用户模式调度(User Mode Scheduling)
- Init Once初始化
- 调试多线程应用程序
- 断点(Breakpoints)
- 并行堆栈(Parallel Stacks)
- 并行监视(Parallel Watch)
- 线程名称
- 练习
- 总结
- 第11章:文件和设备I/O
- I/O系统
- CreateFile函数
- 使用符号链接(Symbolic Links)
- 路径长度
- 目录
- 文件
- 设置文件信息
- 同步I/O
- 异步I/O
- ReadFileEx和WriteFileEx
- 手动排队的异步过程调用(APC,Asynchronous Procedure Call)
- I/O完成端口(I/O Completion Ports)
- 批量复制应用程序
- 使用线程池进行I/O完成
- 批量复制2应用程序
- I/O取消
- 设备
- 管道(Pipes)和邮槽(Mailslots)
- 管道
- 事务性NTFS
- 文件搜索和枚举
- NTFS流
- 总结
- 第12章:内存管理基础
- 基本概念
- 进程地址空间
- 页面状态
- 地址空间布局
- 32位系统
- 64位系统
- 地址空间使用情况
- 内存计数器
- 进程内存计数器
- 进程内存映射
- 页面保护
- 枚举地址空间区域
- 简单的VMMap应用程序
- 更多地址空间信息
- 共享内存
- 页面文件
- 32位Windows应用程序在64位Windows上的运行环境(WOW64,Windows 32-bit on Windows 64-bit)
- WOW64重定向
- 虚拟地址转换
- 总结
- 第13章:内存操作
- 内存API
- VirtualAlloc系列函数
- 取消提交/释放内存
- 保留和提交内存
- 微型Excel应用程序
- 工作集(Working Sets)
- 工作集应用程序
- 堆(Heaps)
- 私有堆
- 堆类型
- 堆调试功能
- C/C++运行时
- 本地/全局API
- 其他堆函数
- 其他虚拟函数
- 内存保护
- 锁定内存
- 内存提示函数
- 读写其他进程的内存
- 大页面(Large Pages)
- 地址窗口化扩展(Address Windowing Extensions)
- 非统一内存访问(NUMA,Non-Uniform Memory Access)
- VirtualAlloc2函数
- 总结
- 第14章:内存映射文件
- 引言
- 映射文件
- filehist应用程序
- 共享内存
- 带文件后备的共享内存
- 微型Excel 2应用程序
- 其他内存映射函数
- 数据一致性
- 总结
- 第15章:动态链接库(Dynamic Link Libraries)
- 引言
- 构建DLL
- 隐式链接和显式链接
- 隐式链接
- 显式链接
- 调用约定(Calling Conventions)
- DLL搜索和重定向
- DllMain函数
- DLL注入
- 使用远程线程注入
- Windows钩子(Windows Hooks)
- 使用SetWindowsHookEx进行DLL注入和挂钩
- API挂钩
- 导入地址表(IAT,Import Address Table)挂钩
- “Detours”风格的挂钩
- DLL基地址
- 延迟加载DLL
- LoadLibraryEx函数
- 其他函数
- 总结
- 第16章:安全性
- 引言
- WinLogon
- LogonUI
- 本地安全授权子系统服务(LSASS,Local Security Authority Subsystem Service)
- LsaIso
- 安全引用监视器(Security Reference Monitor)
- 事件日志记录器(Event Logger)
- 安全标识符(SIDs,Security Identifiers)
- 令牌(Tokens)
- 二次登录服务(The Secondary Logon Service)
- 模拟(Impersonation)
- 客户端/服务器中的模拟
- 特权(Privileges)
- 超级特权
- 访问掩码(Access Masks)
- 安全描述符(Security Descriptors)
- 默认安全描述符
- 构建安全描述符
- 用户访问控制(User Access Control)
- 提升权限(Elevation)
- 要求以管理员身份运行
- 用户访问控制(UAC,User Access Control)虚拟化
- 完整性级别(Integrity Levels)
- 用户界面特权隔离(UIPI,User Interface Privilege Isolation)
- 专用安全机制
- 控制流防护(Control Flow Guard)
- 进程缓解措施(Process Mitigations)
- 总结
- 第17章:注册表(The Registry)
- 根键(The Hives)
- HKEY_LOCAL_MACHINE
- HKEY_USERS
- HKEY_CURRENT_USER(HKCU)
- HKEY_CLASSES_ROOT(HKCR)
- HKEY_CURRENT_CONFIG(HKCC)
- HKEY_PERFORMANCE_DATA
- 32位特定根键
- 操作键和值
- 读取值
- 写入值
- 删除键和值
- 创建注册表链接
- 枚举键和值
- 注册表通知
- 事务性注册表(Transactional Registry)
- 远程注册表(Remote Registry)
- 其他注册表函数
- 总结
- 根键(The Hives)