5

I´m currently using the following C++ code to get the MachineGuid from the windows registry and use that information for my licensing algorithm:

std::wstring key = L"SOFTWARE\\Microsoft\\Cryptography";
std::wstring name = L"MachineGuid";

HKEY hKey;

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
    throw std::runtime_error("Could not open registry key");

DWORD type;
DWORD cbData;

if (RegQueryValueEx(hKey, name.c_str(), NULL, &type, NULL, &cbData) != ERROR_SUCCESS)
{
    RegCloseKey(hKey);
    throw std::runtime_error("Could not read registry value");
}

if (type != REG_SZ)
{
    RegCloseKey(hKey);
    throw "Incorrect registry value type";
}

std::wstring value(cbData/sizeof(wchar_t), L'\0');
if (RegQueryValueEx(hKey, name.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&value[0]), &cbData) != ERROR_SUCCESS)
{
    RegCloseKey(hKey);
    throw "Could not read registry value";
}

RegCloseKey(hKey);

This works pretty well on a x86 system (32 bit). Now I´ve migrated the whole code to x64 (64bit) Windows and the RegQueryValueEx call is returning error.

Among some other posts, this link explains very clearly why this does not work on 64bit machines, and offers an alternative for both 32bit and 64bit using the ManagementObject class from System.Management.dll. The problem is that this solution works on C#, not on C++. I can´t find out a C++ equivalent of the ManagementObject class.

So, what is the correct solution for the problem: Getting the window serial number (MachineGuid) on both x86 and x64 machines using C++.

Thanks for helping.

Community
  • 1
  • 1
Mendes
  • 17,489
  • 35
  • 150
  • 263
  • 1
    WMI is available to C++ applications through COM APIs. I recommend looking at [Creating a WMI Application using C++](https://msdn.microsoft.com/en-us/library/aa389762(v=vs.85).aspx). You'll be looking to execute a WQL Query (similar to SQL) to query one of the [Win32_Provider](https://msdn.microsoft.com/en-us/library/dn792258(v=vs.85).aspx) classes. What I can't tell you at this point is which one contains the equivalent of the `MachineGuid`. [Win32_ComputerSystem](https://msdn.microsoft.com/en-us/library/aa394102(v=vs.85).aspx) may be your starting point. – Jonathon Ogden Jul 12 '16 at 15:24
  • Should you continue to pursue a WMI solution, [Win32_ComputerSystemProduct](https://msdn.microsoft.com/en-us/library/aa394105(v=vs.85).aspx) `UUID` which relates to UUIDs found in the Windows OS System Information application is what I could find at a quick glance that may relate to the `MachineGuid`. – Jonathon Ogden Jul 12 '16 at 15:35

1 Answers1

6

Add KEY_WOW64_64KEY bit to your RegOpenKeyEx argument. Like this:

RegOpenKeyEx( HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hKey )

The documentation says it’s ignored on 32-bit OSes, so you don’t even need to detect WOW64.

P.S. I don’t recommend WMI, it’s too slow. I currently have i5-4460 CPU, 16GB RAM, relatively fast SSD, and yet WMI takes 1-2 seconds to initialize and run even a simple query.

Soonts
  • 20,079
  • 9
  • 57
  • 130
  • Thanks... Should I add the `KEY_WOW64_64KEY` for both 32bit and 64bit implementations of only for 64-bit option and keep the 32bit without it ? – Mendes Jul 12 '16 at 16:01
  • Just for 32 bit will work, but it's harmless to add for both. – Soonts Jul 12 '16 at 16:05