June 5, 2005

RegEnumKeyEx should return all keys, shouldn´t it?

At least if you have the required access, RegEnumKeyEx should return all keys which are available. In the documentation you can read: If there are no more subkeys available, the function returns ERROR_NO_MORE_ITEMS. So I assume that really no subkeys are available if this is returned…

But this is just the theory… If you have an x64-System (like Windows 2003 Server SP1-x64 Edition) and run a win32-app, only a very small number of accessible keys are returned. This feature has a name: Registry Reflection.

For example the following key cannot be enumerated by an win32-app but can be opened by this app: HKLM\SOFTWARE\Microsoft\SystemCertificates. And there are many many more examples…

If you have an x64-System you can verify this with the following example:

#include <windows.h> #include <stdio.h> #include <tchar.h> #include <string> void RecurseKeys(HKEY hKey, DWORD level, std::string &node) { DWORD dwIdx = 0; TCHAR szKeyName[ 1024 ]; DWORD dwSize = 1024; FILETIME fTime; while(RegEnumKeyEx(hKey, dwIdx, szKeyName, &dwSize, NULL, NULL, NULL, &fTime) = = ERROR_SUCCESS) { std::string node2(node); if (node2.size() > 0) node2 += "\"; node2 += szKeyName; _tprintf(_T("%sn"), node2.c_str()); dwSize = 1024; dwIdx++; HKEY hSubKey; if (RegOpenKeyEx(hKey, szKeyName, 0, KEY_READ, &hSubKey) = = ERROR_SUCCESS) { RecurseKeys(hSubKey, level + 1, node2); RegCloseKey(hSubKey); } } } int _tmain(int argc, _TCHAR* argv[]) { std::string nodeName; _tprintf(_T("** HKEY_LOCAL_MACHINE **n")); RecurseKeys(HKEY_LOCAL_MACHINE, 0, nodeName); // try to open a specifed key (which could not be enumerated!) HKEY hSubKey; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\Microsoft\SystemCertificates"), 0, KEY_READ, &hSubKey) = = ERROR_SUCCESS) { _tprintf(_T("Could open the key!n")); RegCloseKey(hSubKey); } return 0; }

You can see that you cannot find the key SystemCertificates inside the enumeration, but you can successfuly open it!

The question is now: Is this by design? If yes, is there some kind of documentation about this fact?

PS: You can try to use RegQueryReflectionKey to find a key for which this reflection is disabled (or course: starting from an x64-app)... I could not find any key! So for all keys this is enabled by default.

PPS: The documentation of RegQueryReflectionKey is still wrong. The second parameter is not BOOL, instead it should be LPBOOL. You can verify this by looking at the windows.h-header file of the latest PSDK. I also sent feedback to the MSDN-Site a couple of weeks ago… (I got a reply that they wait until the product team will clearify this feature).

Posted 2 years, 7 months ago on June 5, 2005
The trackback url for this post is http://blog.kalmbachnet.de/bblog/trackback.php/41/

Comments have now been turned off for this post