0

I'm getting an error 2 trying to read the MachineGUID from the registry here is the code that I'm currently using:

LSTATUS l = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", 0, KEY_READ | KEY_WOW64_64KEY, &hResult);
CString csError;
if (l == ERROR_SUCCESS)
{
    l = RegGetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", "MachineGUID", RRF_RT_ANY | RRF_SUBKEY_WOW6464KEY, NULL, szGUID, &lSize);
    if (l != ERROR_SUCCESS)
    {
        l = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", 0, KEY_READ | KEY_WOW64_32KEY, &hResult);
        if (l == ERROR_SUCCESS)
        {
            l = RegGetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", "MachineGUID", RRF_RT_ANY | RRF_SUBKEY_WOW6432KEY, NULL, szGUID, &lSize);
            if (l != ERROR_SUCCESS)
            {
                l = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", 0, KEY_READ, &hResult);
                if (l == ERROR_SUCCESS)
                {
                    l = RegGetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", "MachineGUID", RRF_RT_ANY, NULL, szGUID, &lSize);
                    if (l != ERROR_SUCCESS)
                    {
                        csError.Format("Error %lu reading machine ID.", l);
                        MessageBox(csError);
                    }
                }
                else
                {
                    csError.Format("Error %lu opening machine ID with KEY_READ.", l);
                    MessageBox(csError);
                }
            }
        }
        else
        {
            csError.Format("Error %lu opening machine ID with KEY_READ | KEY_WOW64_32KEY.", l);
            MessageBox(csError);
        }
    }
}
else
{
    csError.Format("Error %lu opening machine ID with KEY_READ | KEY_WOW64_64KEY.", l);
    MessageBox(csError);
}

All of the RegOpenKeyEx calls were put in for debugging purposes; yes I know the key should be closed. I just wanted to see if there would be an issue with the open access and there is none. The code drops all the way through to the innermost error message, the read error message.

The code was built using VS 2017 as 32-bit code. This works fine on windows 10. Can anyone tell me what the problem is?

This code should generate the problem. It uses MBCS rather than unicode.

#include <windows.h>
#include <winreg.h>
#include <stdio.h>

int main()
{
  char szGUID[37];
  memset(szGUID, 0, 37);
  DWORD lSize = 37;

  ULONG ulResult = RegGetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", "MachineGUID", RRF_RT_ANY | RRF_SUBKEY_WOW6464KEY, NULL, szGUID, &lSize);
  if (ulResult != ERROR_SUCCESS)
  {
    lSize = 37;
    ulResult = RegGetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", "MachineGUID", RRF_RT_ANY | RRF_SUBKEY_WOW6432KEY, NULL, szGUID, &lSize);
    if (ulResult != ERROR_SUCCESS)
    {
      lSize = 37;
      ulResult = RegGetValue(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", "MachineGUID", RRF_RT_ANY, NULL, szGUID, &lSize);
      if (ulResult != ERROR_SUCCESS)
      {
        printf("Error %lu opening SOFTWARE\\Microsoft\\Cryptography\\MachineGUID.\n", ulResult);
      }
      else
        printf("Key SOFTWARE\\Microsoft\\Cryptography\\MachineGUID value %s\n", szGUID);
    }
    else
      printf("Key SOFTWARE\\Microsoft\\Cryptography\\MachineGUID (RRF_SUBKEY_WOW6432KEY) value %s\n", szGUID);
  }
  else
    printf("Key SOFTWARE\\Microsoft\\Cryptography\\MachineGUID (RRF_SUBKEY_WOW6464KEY) value %s\n", szGUID);
  return 0;
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115

1 Answers1

1

The RRF_SUBKEY_WOW6432KEY flag has been introduced in Windows 10. It is ignored on previous Windows versions. So when you use RegGetValue using this flag on Windows 7 and 8, you are actually reading the SOFTWARE\\Wow6432Node\Microsoft\\Cryptography key which doesn't have the MachineGUID value.

What you can do is open the "SOFTWARE\\Microsoft\\Cryptography" key explicitely with RegOpenKeyEx and the KEY_WOW64_64KEY flag and then use RegGetValue upon that key.

The sample program below demonstrates this. I haven tested it on a true 32 bit version, but it should work as per this SO question.

#include <windows.h>
#include <winreg.h>
#include <stdio.h>

int main()
{
  char szGUID[37];
  memset(szGUID, 0, 37);
  DWORD lSize = 37;
  ULONG ulResult;

  HKEY hkey;
  ulResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", 0, KEY_WOW64_64KEY + KEY_READ, &hkey);
  if (ulResult == 0)
  {
    ulResult = RegGetValue(hkey, "", "MachineGUID", RRF_RT_ANY, NULL, szGUID, &lSize);
    if (ulResult == 0)
    {
      printf("Key SOFTWARE\\Microsoft\\Cryptography\\MachineGUID value %s\n", szGUID);
    }
    else
    {
      printf("Error %lu during RegGetValue of MachineGUID", ulResult);
    }

    RegCloseKey(hkey);
  }
  else
  {
    printf("Error %lu opening HKEY_LOCAL_MACHINE, SOFTWARE\\Microsoft\\Cryptography\\MachineGUID.\n", ulResult);
  }
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115