上一篇文章学习了注册表的逻辑结构,接下来我这篇文章来学习注册表的存储结构。注册表实际存储是由一组储巢构成,每个储巢包含了一个由键和值构成的层次结构。下面表是windows的各个储巢的注册表路径和文件路径。一个系统的储巢列表存放在HKLM\SYSTEM\CurrentControlSet\Control\hivelist键下。当系统初始化时,HKLM\SYSTEM总是被先加载进来,然后配置管理器找到hivelist键,继续加载其他的储巢,并创建注册表的根键,将这些储巢连接起来,就建立起了完整的注册表结构。

储巢的内部结构类似于一个文件系统,储巢相当于一个磁盘分区,储巢的基本分配单元称为块(block),类似于文件系统定义的簇(cluster)。当储巢为了存储新的数据需要扩展时,它总是按照块的粒度来增长。在windows中,注册表的块的大小为4KB(4096B)。储巢的第一个块称为基本块,它包含了储巢文件标识、最新序列号、最后一次写操作时间戳、储巢格式的版本号、校验和,以及储巢的内部文件名。

储巢中的注册表数据是按照巢室(Cell)来组织的。巢室可大可小,具体取决于它的类型和数据,每个巢室可以存放一个键、值、安全描述符、子健列表或者值列表,对应的巢室分别称为键巢室、值巢室、安全描述符室、子健列表巢室和值列表巢室。巢室在储巢文件中的偏移称为该巢室的索引(cell index)。其他巢室可以利用此巢室索引来引用它,从而建立起巢室之间的关系。比如,父键的巢室包含一个指向子健列表巢室的巢室索引;子健列表巢室中又包含了一组巢室的索引,每个代表一个子健。因此,配置管理器利用巢室索引,可以从父键定位到子健。反过来,每个键还包含了父键巢室的巢室索引,因而配置管理器也可以从子健定位到父键。同样地,利用键的值列表巢室索引,配置管理器可以定位到值列表,再根据每一个值的巢室索引,可以定位到一个值。下图就展示了一个键及其子健和值之间的存储关系,其中每个长方块代表一个巢室,每个箭头则代表了通过巢室索引建立起来的一个引用关系。

基于巢室和巢室索引的关系,如果要从父键访问它的一个子健,那么,首先要找到父键的子健列表室,然后在该子健的表巢室指示的所有子健中,定位到符合搜索条件的那个子健巢室。注意,子健列表中的子健巢室索引是根据子健字符串名的顺序来排序的,因此查找子健时可以采用二分查找法,从而将搜索的复杂度降到O(log2n),然而,值列表中的巢室索引并非是排序的,所以,搜索值的复杂度为O(n)。

巢室的大小并不是都是相同的,配置管理器将根据需要从储巢中申请特定大小的存储空间作为一个巢室,然而,如果配置管理器必须要扩展已有的储巢文件才能分配一个新的巢室,那么,它并不是简单的申请此巢室大小的磁盘空间,而是会申请一个巢箱(bin)的存储单元。巢箱总是以块为边界,所以,当为一个巢室而扩展储巢文件时,实际申请的存储空间要扩展到下一块边界。巢箱中未使用的空间被当做空闲空间管理起来,从而可以再分配给其他巢室。而且,当巢室被删除时,它们的空间会被回收,如果有可能的话,相邻的空间被合并成更大的空闲空间。这样做也可以避免产生很多碎片的空闲空间。然而,储巢文件的本质时越长越大的,只有当尾部的巢箱空闲时,配置管理器才会缩短储巢文件。要想压缩整个储巢文件中的空闲巢箱,只有再原来储巢的基础上重构一个新的储巢文件(通过RegSaveKey函数),然后替换或恢复该储巢所在的键(通过RegReplaceKey或RegRestoreKey函数)。

配置管理器在巢室的基础上引入了巢箱的机制来管理储巢的空间使用,可以避免频繁的操作储巢文件,以及更加有效地管理内存中的巢室,毕竟巢箱的变化比巢室的变化要少的多。

为了方便地访问注册表的数据,最简单的方法是将储巢文件读入到内存中,因而巢室索引可以被解释成相对于该文件在内存中的起始地址的偏移,写操作也需要在适当的时候同步更新到储巢文件中。然而,这种做法需要消耗较大的虚拟地址空间,通常是换页内存池空间。在后期版本的windows中(2003以后版本)配置管理利用了缓存管理器来映射储巢文件中的数据,它可以有选择的映射所需要的那部分数据,并且也能够解除不再需要访问的或者长时间没有被访问的数据,以避免储巢文件占据太多的系统缓存空间。但是,同一个储巢的各个部分被独立地映射到系统缓存中,这样会导致巢室索引不能被直接转译为内存地址。

配置管理器使用了一种类似于Intel x86处理器的页表映射的做法来解释巢室地址转译。一个32位的巢室索引被划分为四个部分:存储类型、巢室目录索引、巢室索引和块内偏移。存储类型有两种可能:稳定的(stable,最高位用0表示)和易失的(volatile,最高位用1表示)。每个储巢在内存中有两个巢室的目录,分别对应于稳定和易失的配置数据;每个巢室目录有1024项,每一项指向一个巢室表;每个巢室表包含512个表项,每一项指向一个块。由于配置管理器用巢箱来管理分配内存,而巢箱总是以块为边界(4kb),所以,巢室索引的最后12位指定了一个巢室在块内的偏移。

基于这样的巢室索引结构,配置管理器将只为每个储巢映射那些需要用到的巢箱,而不是所有的巢箱,巢室目录和巢室表仍然占用换页内存池的空间,但通常情况下,相比于整个储巢文件,它们要小的多。配置管理器通过这种巢室映射的做法,可有效地降低注册表数据的内存使用量。

windows内核开发学习笔记四十四:注册表存储结构-储巢相关推荐

  1. windows内核开发学习笔记十五:IRP结构

    windows内核开发学习笔记十五:IRP结构   IRP(I/O Request Package)在windows内核中,有一种系统组件--IRP,即输入输出请求包.当上层应用程序需要访问底层输入输 ...

  2. Windows保护模式学习笔记(十四)—— 阶段测试

    Windows保护模式学习笔记(十四)-- 阶段测试 题目一 解题步骤 题目二 解题步骤 题目一 描述:给定一个线性地址,和长度,读取内容 int ReadMemory(OUT BYTE* buffe ...

  3. windows内核开发学习笔记十八:IRP 处理的标准模式

    windows内核开发学习笔记十八:IRP 处理的标准模式 在 Windows 内核中的请求基本上是通过 I/O Request Packet 完成的. I/O manager ---> Dis ...

  4. windows内核开发学习笔记十七:IRP 和 IO_STACK_LOCATION 的交互

    windows内核开发学习笔记十七:IRP 和 IO_STACK_LOCATION 的交互 前面两篇学习笔记分别介绍了IRP和IO_STACK_LOCATION,整个设备栈来处理这个IRP,但是每个设 ...

  5. Windows 8 Directx 开发学习笔记(十四)使用几何着色器实现三角形细分

    几何着色器是从DirectX 10才引入的着色器,是一个可选阶段,位于顶点着色器和像素着色器阶段之间.顶点着色器以顶点作为输入数据,而几何着色器以完整的图元作为输入数据,像点.直线.三角形等.之所以引 ...

  6. Windows驱动开发学习笔记(四)—— 3环与0环通信(常规方式)

    Windows驱动开发学习笔记(四)-- 3环与0环通信(常规方式) 设备对象 创建设备对象 设置数据交互方式 创建符号链接 IRP与派遣函数 IRP的类型 其它类型的IRP 派遣函数 派遣函数注册位 ...

  7. Windows驱动开发学习笔记(三)—— 内核空间内核模块

    Windows驱动开发学习笔记(三)-- 内核空间&内核模块 内核空间 实验 第一步:编译如下代码 第二步:将 .sys 文件拷贝到虚拟机中 第三步:部署 .sys 文件并运行 第四步:创建一 ...

  8. Windows驱动开发学习笔记(二)—— 驱动调试内核编程基础

    Windows驱动开发学习笔记(二)-- 驱动调试&内核编程基础 基础知识 驱动调试 PDB(Program Debug Database) WinDbg 加载 PDB 实验:调试 .sys ...

  9. 虚拟内存——Windows核心编程学习手札之十四

    虚拟内存 --Windows核心编程学习手札之十四 系统信息 有些操作系统的值是根据主机而定的,如页面大小.分配粒度大小等,这些值不用硬编码形式,进程初始化时应检索这些值以使用.函数GetSystem ...

最新文章

  1. ciclop读音,购机必备,15种 3D扫描 设备 优缺点汇总
  2. 断开式绑定数据在comboBox中 winform
  3. JS--------文件操作基本方法:上传/下载
  4. shell_study
  5. android实现双向绑定,Android使用DataBinding实现双向绑定(一)
  6. Beego 使用redigo连接redis
  7. vtk-m的安装与配置
  8. 浏览器事件 - 监听浏览器刷新问题及解决方案
  9. 百度地图-根据地址获取经纬度
  10. 纯CSS画基本图形(矩形、圆形、三角形、多边形、爱心)
  11. Git及Github之入门到进阶
  12. 豆瓣评分小程序Part-3
  13. IE高版本如何设置IE低版本进行测试
  14. 文本分类的14种算法(1)
  15. linux添加java环境变量
  16. 水井硬件集成与仪表仪器采集
  17. Linux 内存分配
  18. R语言——如何调用自己写的函数
  19. springboot项目:老年教育学习系统fte91(java+VUE+Mybatis+Maven+Mysql)
  20. FastAdmin自定义搜索,通用搜索失效

热门文章

  1. Vue 疑难杂症问题收录
  2. OpenNI2 和 OpenCV 结合的程序实例
  3. 快排亲兄弟:快速选择算法详解
  4. ue4 材质实现缩放UV后没有重复UV的贴图
  5. 大盘点 | 2020年两篇目标跟踪算法最佳综述
  6. 企业级用户画像:基于USG模型使用决策树开发用户购物性别
  7. Postgres分表
  8. 遂冀机器人_河北省实施“机器人+”行动计划 到2020年全省机器人产业产值将超70亿元...
  9. 双显示器扩展显示自定义鼠标移入方向
  10. 处理VS中scanf的安全警告