ReactOS-Freeldr注册表HIVE文件格式2
发布时间:2020-12-15 03:32:35 所属栏目:百科 来源:网络整理
导读:上一节读了HIVE文件读入内存时的初始化操作。现在来看看实际对内存中的HIVE文件的操作。 首先是从空闲CELL中分配一个指定大小的CELL。HvAllocateCell就是做这件事情的。 这个函数有四个参数: 1. RegistryHive HHIVE结构指针 2. Size 需要分配的CELL大小(不
上一节读了HIVE文件读入内存时的初始化操作。现在来看看实际对内存中的HIVE文件的操作。
首先是从空闲CELL中分配一个指定大小的CELL。HvAllocateCell就是做这件事情的。
这个函数有四个参数:
1. RegistryHive HHIVE结构指针
2. Size 需要分配的CELL大小(不包括HCELL结构的大小)
3. Storage 分配的CELL是Stable还是Volatile。
4. Vicinity 这个参数在Freeldr中没有使用
lib/cmlib/hivecell.c
这个函数从FreeDisplay中搜索大小符合的CELL,如果不存在需要生成一个BIN。最后把CELL的索引返回给调用者。
因为调用者传入的Size不包含HCELL的大小,8行先调整大小并且向上按8字节对其。
10行调用HvpFindFree从FreeDisplay中搜索符合Size大小的CELL,如果找到FreeCellOffset为CELL的索引。
如果没找则在末尾增加一个BIN,从这个BIN中分配符合大小的CELL,FreeCellOffset为CELL的索引(12-19)。
因为返回的CELL可能比请求的大,所以21行调用HvpGetCellHeader根据索引获得HCELL指针,如果返回的CELL比请求的大小大16字节以上的话则把CELL分配成两个,剩余的空间重新加入空闲列表FreeDisplay(23-31)。
最后如果Storage为Stable时,说明这些信息最终要写入硬盘的HIVE文件,所以要把CELL所在Block的DirtyVetor置位,这样注册表刷新文件时会把这个改变回写到硬盘的HIVE文件中。(33-34)
因为我们分配的CELL项是空闲的,所以要把大小变为负数,代表此CELL已经被使用。最后把CELL内容清0,把CELL索引返回给调用者。
从FreeDisplay中寻找空闲块是HvpFindFree的工作。
这个函数接受大小Size和存储类型Storage,返回找到的CELL的索引,如果没找到返回HCELL_NIL。
HvAllocateCell ->HvpFindFree
lib/cmlib/hivecell.c
HvpFindFree会从小到大搜索FreeDisplay链表,如果找到了大于等于Size的CELL,便把CELL从链表里面摘除,并把CELL的索引返回给用户。如果没有合适的空闲CELL将会返回HCELL_NIL。很直观。
这里有个有个HvGetCell函数,它的作用是根据CELL索引找到CELL指针(这个指针指向紧随着HCELL结构的内存地址)。我们来看看这个函数是如何实现的。
HvAllocateCell ->HvpFindFree ->HvpFindFree
lib/cmlib/hivecell.c
调用HvpGetCellHeader根据CELL索引获得HCELL结构,返回给用户。我们继续看HvpGetCellHeader。
HvAllocateCell ->HvpFindFree ->HvpFindFree -> HvpGetCellHeader
lib/cmlib/hivecell.c
正常情况下Flat为FALSE,所以HvpGetCellHeader将把CellIndex分解为存储类型CellType、CELL所在块编号CellBlock、CELL在块内偏移CellOffset(6-11行)。
之后查询对应的BlockList表得到CELL的实际地址,返回给用户(13-14)。这个过程类似X86的页表,不过它只有一层 :)
这里有个特殊情况,就是HIVE可以以Flat模式初始化。这个模式下HIVE只读,并且没有初始化Storage数组,同事HHIVE.BaseBlock指针直接指向HIVE文件内容,20行处理了这种情况。
到这里我们了解了HvpFindFree、HvGetCell、HvpGetCellHeader三个函数的作用。
我们回到HvAllocateCell的第10行,这里调用HvpFindFree从FreeDisplay中找到一个合适的空闲CELL,希望你还记得 :)
下面的代码你应该大部分经可以看明白了。还剩最后一点,如果HvpFindFree失败(没有合适的空闲区块),那么函数将会调用HvpAddBin在HIVE末尾新生成一个BIN,这个BIN将有足够的空间容纳请求的CELL。
这个函数逻辑很简单但代码比较多,大致是将请求的Size根据4kb向上对其,生成一个BIN,并且更新BlockList和DirtyVector,新生成的BIN占用的Block在尾部,具体代码这里就不列出了。有兴趣可以读读lib/cmlib/hivebin.c文件。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |