Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RegGetValue Question

I'm trying to write(what I thought would be) a simple script in C++ to search through the registry(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall specifically) and return the value of the DisplayName value.

I have gone through the MSDN docs, and hours of searching on google, unfortunately I'm stuck.

#define BUFFER 8192
char value[255];
DWORD BufferSize = BUFFER;

if(RegGetValue(HKEY_LOCAL_MACHINE,
    _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"),
    _T("DisplayName"),
    RRF_RT_ANY,
    NULL,
    (PVOID)&value,
    &BufferSize)
    )
{
    _tprintf(TEXT("(%d) %s - %s\n"), i+1, achKey, value);
}

Now, I need to be able to append achKey to the 2nd parameter of RegGetValue, so that it grabs the correct values when looping through each subkey.

I've tried a million different things, unfortunately my experience in C++ is pretty limited and my google skills apparently need some work as well.

Edit: achKey is the name of the key: Ex: NVIDIA Drivers

So when appended, the 2nd param should read:

SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\NVIDIA Drivers

Here's the MSDN reference on RegGetValue: http://msdn.microsoft.com/en-us/library/ms724868%28v=vs.85%29.aspx

I have also tried something like:

wcscat(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"), achKey)

It will compile, but then when run, it crashes.

like image 618
Josh Avatar asked Jun 06 '26 21:06

Josh


1 Answers

There are two main issues with your original code that I can see:

  1. Mixing Unicode/ACSII Strings : From your comments it appears you are compiling the project with Unicode strings but you are using a char value[255]. Use a wchar_t or TCHAR instead of char. the RegGetValue() function will be automatically 'forwarded' to the RegGetValueW() or RegGetValueA() functions depending on the project Unicode settings. If you wish to force a particular character set you can use those functions directly but it is generally better to just use the RegGetValue() function directly.
  2. Buffer Overflow: You are use a 255 element char buffer but passing the buffer's size as 8192. If the registry key is more than 255 bytes (not characters) then you'll overflow that buffer and bad things will happen. Make sure you pass the exact buffer size or smaller. Also be aware of the differences between bytes and characters with Unicode strings. Some functions may expect or return a buffer size in bytes and some in characters.

The following code is an example of using wide-strings in the manner you desire:

#include <iostream>
#include <string>

    ...
std::wstring BaseKey(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"));
std::wstring achKey(_T("DisplayName"));
std::wstring NewKey;

NewKey = BaseKey + achKey;
wcout << NewKey << _T("\n");
NewKey = BaseKey + _T("AnotherName");
wcout << NewKey << _T("\n");

Edit: LPCWSTR Notes

A LPCWSTR in Windows is simple a pointer to a constant wide string, or more directly a const wchar_t * which is the same thing as a TCHAR * in a Unicode project. Note that if you changed your project to a MultiByte character set then the function declaration of RegGetValue() (and a host of other Windows functions) would change to using a LPCSTR instead and a TCHAR would simply be a char.

The nice thing about using std::string/wstring is that they are directly compatible with a LPCWSTR and a LPCSTR. Thus your call to RegGetValue() can use the std::wstring variables directly like:

std::wstring BaseKey(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"));
std::wstring Value(_T("DisplayName"));
RegGetValue(HKEY_LOCAL_MACHINE, BaseKey, Value, ...).
like image 87
uesp Avatar answered Jun 10 '26 19:06

uesp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!