如果要保存的密钥是HKEY_LOCAL_MACHINE,为什么RegSaveKey()会失败,错误代码为5(访问被拒绝)?
这个问题与所使用的编程语言无关 在Windows7SP1和Windows10Version1803中测试 症状 RegSaveKey()如果要保存的密钥是如果要保存的密钥是HKEY_LOCAL_MACHINE,为什么RegSaveKey()会失败,错误代码为5(访问被拒绝)?,c,windows,winapi,C,Windows,Winapi,这个问题与所使用的编程语言无关 在Windows7SP1和Windows10Version1803中测试 症状 RegSaveKey()如果要保存的密钥是HKEY\U LOCAL\U MACHINE,则会失败,错误代码为5(访问被拒绝) 如果指定了子项,例如HKEY\U LOCAL\U MACHINE\SYSTEM,则不会发生此错误 如果键是HKEY\U CURRENT\U USER,则也不会发生此错误 第一个样本 在这里,我使用AutoIt快速编写复制错误的代码。我还将示例代码编译为.EXE,
HKEY\U LOCAL\U MACHINE
,则会失败,错误代码为5(访问被拒绝)
如果指定了子项,例如HKEY\U LOCAL\U MACHINE\SYSTEM
,则不会发生此错误
如果键是HKEY\U CURRENT\U USER
,则也不会发生此错误
第一个样本
在这里,我使用AutoIt快速编写复制错误的代码。我还将示例代码编译为.EXE,使人们能够轻松地查看问题
第二个样本
REG.EXE,这是一个使用Visual C++编写的内置Windows工具(这就是标记包含C的原因),具有与上述完全相同的问题。这并不奇怪,因为根据我的调查,REG.EXE SAVE
命令实际上使用了未记录的NtSaveKey()。顺便说一下,RegSaveKey()正在内部调用NtSaveKey()
REG.EXE SAVE "HKLM" "HKLM.hiv" /Y
上述命令失败,错误为“访问被拒绝”。请注意,我以管理员身份运行该命令
问题:
这个错误的原因是什么?有没有办法使RegSaveKey()适用于HKEY\U LOCAL\U机器
(不指定子键)
更新
我的进一步测试表明,regedit.exe与上面提到的问题相同
- 将
导出到HKEY\U LOCAL\U机器
文件失败;但是,将其导出到
文件会成功.REG
- 将
导出到HKEY\U LOCAL\U机器\
文件成功
- 将
导出到HKEY\U当前用户
文件成功.HIV
- 将
导出到HKEY\u当前用户\
文件成功
//
// Disallow attempts to "save" the master hive
//
Hive = KeyControlBlock->KeyHive;
if (Hive == &CmpMasterHive->Hive) {
return STATUS_ACCESS_DENIED;
}
HKEY\U LOCAL\U MACHINE
(即“\Registry\MACHINE”)位于主配置单元中,因此向调用者返回状态“访问被拒绝”(0xc0000022)。Windows子系统将此状态代码转换为ERROR\u ACCESS\u DENIED
(5)。我认为该错误隐藏了真正的问题:HKEY\u LOCAL\u计算机不是物理存在的密钥。NtSaveKey
内部调用。这个api从一开始就提供给您STATUS\u ACCESS\u DENIED
此时您有什么可能的原因想要保存整个HKEY\u LOCAL\u MACHINE配置单元?@CareyGregory,原因是regedit.exe
如果我们将整个HKLM密钥导出到.REG
文件中,则可以毫无问题地完成此操作。我的进一步测试表明,如果我们将整个HKLM密钥导出到.HIV
文件中,regedit.exe
也会失败。这是因为regedit不会尝试从.reg文件重新创建HKLM密钥本身。它只是通过.reg文件进行枚举,并分别恢复每个键/值。我认为@PaulStelian是正确的,HKLM不是一个可以直接操作的物理键。@eryksun我看我自己的调试器--我打开“\\registry\\machine”
键,看对象指针(CM\u key\u BODY
),从中得到指向KeyControlBlock->KeyHive
值的指针(0xFFFFB481BDE23000
在我的具体案例中)与&CmpMasterHive->Hive
@eryksun完全相同-好的,我的英语不是很好,但我只是检查不同的键-对于\registry\machine
键,我得到了KeyBody->KeyControlBlock->KeyHive==&CmpMasterHive->Hive
。而在另一个键上不是。即使在用户模式调试器中,我也能看到这一点。)@eryksun-在调试器中查找多个键。只有我想说的是,对于HKLM
我们在这项检查中被拒绝访问Hive==&CmpMasterHive->Hive
@eryksun-更准确地说,key更快CM\u key\u CONTROL\u BLOCK
不是HHIVE
,但它位于同一个HHIVE
handle->CM\u KEY\u BODY->CM\u KEY\u CONTROL\u BLOCK->HHIVE
FYI,对于不熟悉此模式的人,引用特定键的每个键对象的KeyControlBlock
字段将引用相同的键控制块(即CM\u KEY\u CONTROL\u BLOCK
记录)。文件系统的实现方式类似。文件系统中特定文件/流的文件对象具有引用公共文件/流控制块(FCB或SCB)的FsContext
字段。还请注意,密钥/文件对象可能由多个进程中的多个句柄引用。因此,每个对象可以有多个句柄,每个控制块可以有多个对象。