404
404

Reputation: 23

How to get a registry read function to work properly? (c++)

When I compile and run the following code snippet (in visual studio 2019), it runs but returns an incorrect value of

Key Value: 000000D1E14FF920 and actual bytes read was: 12

instead of

Key Value: 18363 and actual bytes read was: 6

here is the code

#include <Windows.h>
#include <iostream>
#include <string>
#include <tchar.h>

wchar_t value[255];
DWORD BufferSize = sizeof(value);
RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\"), _T("CurrentBuildNumber"), RRF_RT_ANY, NULL, (PVOID)&value, &BufferSize);
std::cout << "Key Value: " << value << " and actual bytes read was: " << BufferSize << std::endl;

I tried multiple methords of fixing this problem but I couldnt get it to work properly with visual studio (probably because it uses unicode)

Upvotes: 0

Views: 116

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595827

You are mixing char and TCHAR APIs. It is clear that RegGetValue() is returning a Unicode wide string, because 12 bytes is correct for a 6-character null-terminated wchar_t string. So TCHAR is mapping to wchar_t in your build, and thus RegGetValue() is calling RegGetValueW(). You are trying to print out that wide string using std::cout, which does not support wchar_t strings, so you are actually calling the void* overload of std::basic_osteam::operator<<. That is why you are seeing a memory address being printed out.

To deal with TCHAR correctly, try this instead:

#include <Windows.h>
#include <iostream>
#include <string>
#include <tchar.h>

#ifdef UNICODE
#define tcout std::wcout
#else
#define tcout std::cout
#endif

TCHAR value[255] = {};
DWORD BufferSize = sizeof(value);
RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\"), _T("CurrentBuildNumber"), RRF_RT_REG_SZ, NULL, &value, &BufferSize);

tcout << _T("Key Value: ") << value << _T(" and actual bytes read was: ") << (BufferSize / sizeof(TCHAR)) << std::endl;

However, you really should forget that TCHAR exists, it has no place in modern coding anymore. Just go full Unicode only:

#include <Windows.h>
#include <iostream>
#include <string>

WCHAR value[255] = {}
DWORD BufferSize = sizeof(value);
RegGetValueW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\", L"CurrentBuildNumber", RRF_RT_REG_SZ, NULL, &value, &BufferSize);

std::wcout << L"Key Value: " << value << L" and actual bytes read was: " << (BufferSize / sizeof(WCHAR)) << std::endl;

Upvotes: 2

Related Questions