Reading and Writing registry keys. C++ MFC MBCS.

user1311286 picture user1311286 · Apr 17, 2013 · Viewed 11.2k times · Source

I would like to detect, and if possible read to a CString, a registry key starting with "HKEY_LOCAL_MACHINE\SOFTWARE\blah\SetupPath".

I see the MSDN on RegOpenKeyEx function

LONG WINAPI RegOpenKeyEx(
  _In_        HKEY hKey,
  _In_opt_    LPCTSTR lpSubKey,
  _Reserved_  DWORD ulOptions,
  _In_        REGSAM samDesired,
  _Out_       PHKEY phkResult
);

So for this it looks like I need to setup a few things.

HKEY hKey = HKEY_LOCAL_MACHINE;
LPCTSTR lpSubKey = "SOFTWARE\blah\SetupPath";

And to see if the key exists just do

LONG res = RegOpenKeyEx(hKey, lpSubKey, 0, 0, 0);
if(res == ERROR_SUCCESS)
    // The key exists

Now if the key exists I want to read what is there, into a CString. I also see the RegQueryValueEx

LONG WINAPI RegQueryValueEx(
  _In_         HKEY hKey,
  _In_opt_     LPCTSTR lpValueName,
  _Reserved_   LPDWORD lpReserved,
  _Out_opt_    LPDWORD lpType,
  _Out_opt_    LPBYTE lpData,
  _Inout_opt_  LPDWORD lpcbData
);

It also looks like I need some setup before I call this function too.

HKEY hKey = HKEY_LOCAL_MACHINE;
lpSubKey = "SOFTWARE\blah\SetupPath";
LPDWORD type = null;
LPDWORD data = null;

Now I can call it

LONG res2 = RegValueQueryEX(hKey, lpSubKey, 0, type, data,0);

Then I think I can check to see the type and then cast to a string?

CString regVal;
if(res2 == ERROR_SUCCESS)
   if(type == REG_SZ)
      if(data != null)
          regVal = new CString((LPSTR)data);

Is this all correct? What might I be missing or need to do?

Answer

john picture john · Apr 17, 2013

No that's not correct. Your main misunderstanding is how pointers work in C++. It's not enough to supply NULL for a pointer argument, you must supply a pointer to a variable so that the RegOpenKeyEx or RegValueQueryEx routine can return a value to that variable. You also seem to be misunderstanding how to assign to a CString (no need for new). Finally although it's not an error you don't need to do 'setup' you just pass the values directly to the function.

First open the key

HKEY key;
RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\blah", 0, 0, &key);

then get the value

DWORD type, size;
char data[99];
size = sizeof(data);
RegQueryValueEx(key, "SetupPath", 0, &type, (BYTE*)data, &size);

then assign the value to your CString

CString regval(data);

finally close the key

RegCloseKey(key);

No error checking in that code, you should add it. Also I'm assuming that any value you could get will fit in 99 bytes, that might not be true.

Note how I pass a pointer to the key variable, so that RegOpenKeyEx can return the key. I then use that key in the call to RegValueQueryEx and RegCloseKey. Same for the type and size variables. Also note that I've split the path between the calls to RegOpenKeyEx and RegValueQueryEx. I think that is correct.

Not 100% sure that is correct, I haven't tested it but should be quite a bit closer.