views:

943

answers:

4

Given a handle to a Windows Registry Key, such as the ones that are set by ::RegOpenKeyEx(), is it possible to determine the full path to that key?

I realize that in a simple application all you have to do is look up 5 or 10 lines and read... but in a complex app like the one I'm debugging, the key I'm interested in can be opened from a series of calls.

+1  A: 

Nominally no because it's just a handle and there is no API that I know of to let you do this in the normal Windows API's.

HOWEVER the Native API has lots of functions some of which can give you handles open for given files and the like so there maybe something similar for the Registry. That and RegMon by SysInternals may do something like this but you'll have to Google I'm afraid :/

Lloyd
A: 

You can use RegSaveKey and write it to a file, then look at the file.

Alternatively you can keep a global map of HKEYs to LPCWSTRs and add entries when you open them and do lookups whenever.

You may also be able to do something with the !reg command in WinDBG / NTSD, but you can't just give it the HKEY. You'll have to do some other trickery to get the info you want out of it.

jeffamaphone
+8  A: 

Use LoadLibrary and ZwQueryKey exported function as in the following code snippet.

#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 *ZwQueryKeyType)(
       HANDLE  KeyHandle,
       int KeyInformationClass,
       PVOID  KeyInformation,
       ULONG  Length,
       PULONG  ResultLength);

      ZwQueryKeyType func = reinterpret_cast<ZwQueryKeyType>(::GetProcAddress(dll, "ZwQueryKey"));

      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];
        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;
}

This will print the key path on the console:

Key path for 00000FDC is '\REGISTRY\MACHINE\SOFTWARE\Microsoft'.

smink
A: 

ntsd/windbg:

!handle yourhandle 4

nicogui