Winapi 什么';使用NtOpenKey时重定向注册表访问的正确方法是什么?

Winapi 什么';使用NtOpenKey时重定向注册表访问的正确方法是什么?,winapi,registry,64-bit,32-bit,wow64,Winapi,Registry,64 Bit,32 Bit,Wow64,我正在处理的代码包含32位和64位组件,它们需要在注册表中共享信息。因此,在使用NtOpenKey函数(相当于的用户模式)时,我试图控制注册表重定向-我需要从64位代码调用此函数,但要访问32位注册表。(以前的代码只有32位,现在升级到64位,所以我更喜欢使用尽可能多的现有代码-也就是说,我不想重写所有内容以使用RegOpenKeyEx) 当然,NtOpenKey无法识别KEY\u WOW64\u 32KEY访问标志,这与高级注册表函数不同,因此无法指定重定向 此时,我能想到的唯一解决方案是在访

我正在处理的代码包含32位和64位组件,它们需要在注册表中共享信息。因此,在使用
NtOpenKey
函数(相当于的用户模式)时,我试图控制注册表重定向-我需要从64位代码调用此函数,但要访问32位注册表。(以前的代码只有32位,现在升级到64位,所以我更喜欢使用尽可能多的现有代码-也就是说,我不想重写所有内容以使用
RegOpenKeyEx

当然,
NtOpenKey
无法识别
KEY\u WOW64\u 32KEY
访问标志,这与高级注册表函数不同,因此无法指定重定向

此时,我能想到的唯一解决方案是在访问注册表时在键名中显式地硬编码
Wow6432Node
;比如:

\Registry\Machine\Software\Wow6432Node\MyCompanyKey\MyKey

不幸的是,这更像是一种黑客行为,微软特别不鼓励这样做

这个问题有正确的解决办法吗?阅读文档没有帮助,我也找不到任何相关的搜索结果


编辑:只是一点额外的细节:我需要支持Windows Server 2003 32位/64位、Windows 7/8和Windows Server 2008 32位/64位。(基本上所有服务器都是从Windows server 2003+Windows 7及以上版本开始的。)

显然我误解了您的问题——我认为此标志是一个键选项,而不是访问说明符。
在这种情况下,我相信
NtOpenKey
应该可以使用
KEY\u WOW64\u 32KEY
作为访问掩码。当你尝试这样做时会发生什么

旧答案(错): 这就是为什么Windows Vista&后来引入了
NtOpenKeyEx

如果可用,我建议使用
NtOpenKeyEx
(确保动态链接,而不是静态链接),如果不可用,则尽可能使用
NtCreateKey
,否则使用
Wow6432Node


目前还没有其他解决方案。

本机API不提供与
KEY\u WOW64\u 32KEY
等效的解决方案。你的选择是:

  • 使用Win32 API
  • 坚持使用本机API并对路径进行硬编码
  • 混合使用Win32和本机API。使用Win32 API以
    KEY\u WOW64\u 32KEY
    打开
    HKLM\Software
    。然后调用
    NtQueryKey
    查找密钥的本机名称。然后从那里开始使用本机API。这就绕过了您对硬编码的反对

  • 选项3听起来似乎有道理,但我从未打过电话给NtQueryKey,甚至不能确定这个想法是否可行。

    谢谢你的建议,我不知道NtOpenKeyEx的事,我会查一查的。不幸的是,我还需要支持Windows Server 2003 R1和R2,所以我假设他们没有这个功能。@xxbbcc:Yup。对于pre-Vista没有好的解决方案——我能想到的最好的解决方案是使用
    NtCreateKey
    ,然后检查
    REG\u OPENED\u EXISTING\u KEY
    是否已设置,如果未设置,则删除该键。它引入了一个(不太可能的)竞争条件,但无论如何你没有太多的选择。我看不出
    NtOpenKeyEx
    有什么帮助。你能详细说明一下吗。我们如何做与
    KEY\u WOW64\u 32KEY
    等价的事情?@DavidHeffernan:Omg你说得对——我忘了
    KEY\u WOW64\u 32KEY
    是一种访问模式;我认为这是一个关键的选项参数。。。非常感谢你抓住了这个机会。@Mehrdad Lol,我只是在阅读文档的时候也在想同样的事情。:)为了回答你的评论,我还没有尝试过,主要是因为文档对这个选项特别沉默。让我想想——我想我可能早就尝试过了,但我担心即使它可以工作,它在不同的系统上的行为也可能不同。你确定本机API对重定向有任何支持吗?如果不是,答案是使用高级Win32 API。@DavidHeffernan不,我一点也不确定-文档中甚至没有提到低级API。我怀疑没有办法做到这一点,但我想知道其他应用程序如何处理这个问题。与内核级服务相比,高级注册表API相当有限。另外,我已经有了使用低级函数的现有代码,重写这些代码会很痛苦。我现在正在尝试硬编码选项,尽管我真的很讨厌这样的黑客。用高级API管理并不难。这有什么限制?是的,谢谢。但这并不是我所期望的。看来重定向器是在本机API级别实现的。@xxbbcc:我在
    NtOpenKey
    中将其称为bug。它似乎不像人们想象的那样向国旗致敬。(WOW64做到了这一点,所以很明显,它一定是有意的——假设有适当的抽象层,
    NtOpenKey
    将遵循WOW64标志。)还有一个NtQueryObject,它是另一个可以获取路径的函数。但是我很确定NtQueryKey可以工作。也要注意,可能还有其他键也需要重定向。@Mehrdad我想每次打开或创建一个键时,您都可以执行选项3洗牌。但如果是我,我会选择选项1。@DavidHeffernan我接受你的答案,尽管我实际上没有尝试过你的建议-由于时间不够,我只是选择了黑客硬编码名称解决方案。希望我能说服管理层为适当的许可产品付费,而不是我们自己的产品。