从 C 中的 HKEY 句柄确定注册表项的路径

新手上路,请多包涵

给定 Windows 注册表项的句柄,例如由 ::RegOpenKeyEx() 设置的那些,是否可以确定该键的完整路径?

我意识到,在一个简单的应用程序中,您所要做的就是查找 5 或 10 行并阅读……但在像我正在调试的应用程序这样的复杂应用程序中,我感兴趣的密钥可以从一系列中打开的电话。

原文由 Brian Gillespie 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 841
2 个回答

使用 LoadLibraryNtQueryKey 导出函数,如以下代码片段所示。

 #include <windows.h>
#include <string>

typedef LONG NTSTATUS;

#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif

#ifndef STATUS_BUFFER_TOO_SMALL
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
#endif

std::wstring GetKeyPathFromKKEY(HKEY key)
{
    std::wstring keyPath;
    if (key != NULL)
    {
        HMODULE dll = LoadLibrary(L"ntdll.dll");
        if (dll != NULL) {
            typedef DWORD (__stdcall *NtQueryKeyType)(
                HANDLE  KeyHandle,
                int KeyInformationClass,
                PVOID  KeyInformation,
                ULONG  Length,
                PULONG  ResultLength);

            NtQueryKeyType func = reinterpret_cast<NtQueryKeyType>(::GetProcAddress(dll, "NtQueryKey"));

            if (func != NULL) {
                DWORD size = 0;
                DWORD result = 0;
                result = func(key, 3, 0, 0, &size);
                if (result == STATUS_BUFFER_TOO_SMALL)
                {
                    size = size + 2;
                    wchar_t* buffer = new (std::nothrow) wchar_t[size/sizeof(wchar_t)]; // size is in bytes
                    if (buffer != NULL)
                    {
                        result = func(key, 3, buffer, size, &size);
                        if (result == STATUS_SUCCESS)
                        {
                            buffer[size / sizeof(wchar_t)] = L'\0';
                            keyPath = std::wstring(buffer + 2);
                        }

                        delete[] buffer;
                    }
                }
            }

            FreeLibrary(dll);
        }
    }
    return keyPath;
}

int _tmain(int argc, _TCHAR* argv[])
{
    HKEY key = NULL;
    LONG ret = ERROR_SUCCESS;

    ret = RegOpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft", &key);
    if (ret == ERROR_SUCCESS)
    {
        wprintf_s(L"Key path for %p is '%s'.", key, GetKeyPathFromKKEY(key).c_str());
        RegCloseKey(key);
    }

    return 0;
}

这将在控制台上打印密钥路径:

00000FDC 的密钥路径是 ‘\REGISTRY\MACHINE\SOFTWARE\Microsoft’。

原文由 Jorge Ferreira 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以使用 RegSaveKey 并将其写入文件,然后查看该文件。

或者,您可以保留 HKEY 到 LPCWSTR 的全局映射,并在打开它们时添加条目并随时进行查找。

您也可以使用 WinDBG / NTSD 中的 !reg 命令做一些事情,但您不能只给它 HKEY。你必须做一些其他的诡计才能得到你想要的信息。

原文由 i_am_jorf 发布,翻译遵循 CC BY-SA 2.5 许可协议

推荐问题