Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert std::string to const BYTE* for RegSetValueEx()

I have a function that gets a std::string. That function calls

RegSetValueEx

the 5th parameter is the value of the registry value and expects a variable of type const BYTE*. So I have to convert the std::string to const BYTE* and also give the length of the resulting array as the 6th parameter.

I have found a way to do it, but it feels ugly and I don't really understand what is going on. Here is a slimmed down version of that function:

void function(const std::string& newValue)
{
    HKEY keyHandle;
    if(RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("some key"),0,KEY_ALL_ACCESS,&keyHandle) == ERROR_SUCCESS)
    {
        std::wstring wNewValue;
        wNewValue.assign(newValue.begin(),newValue.end());

        if (RegSetValueEx(keyHandle, TEXT("some value"), NULL, REG_SZ, (const BYTE*)(LPCTSTR)(wNewValue.c_str()), wNewValue.size()*2)==ERROR_SUCCESS)
        {
            //do something
        }
        RegCloseKey(keyHandle);
    }
}

As you can see, i first make a wide string (UNICODE is defined), then use a double cast, and for the length i have to do *2, else it will only set half of the input string.

Is this form of cast the normal/best way to do it?

Why the * 2, what would be a better way?

like image 962
Emile Vrijdags Avatar asked Dec 07 '22 07:12

Emile Vrijdags


2 Answers

void function(const std::string& newValue)
{
    HKEY keyHandle;
    if(RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("some key"),0,KEY_ALL_ACCESS,&keyHandle) == ERROR_SUCCESS)
    {

        if (RegSetValueExA(keyHandle, "some value", NULL, REG_SZ, (const BYTE*)newValue.c_str(), newValue.size() + 1)==ERROR_SUCCESS)
        {
                //do something
        }
        RegCloseKey(keyHandle);
    }
}

I removed the part where you convert your string to a wstring, instead you'll be using the ANSI version of RegSetValueEx explicitly.

quote from RegSetValueEx remarks in MSDN:

If dwType is the REG_SZ, REG_MULTI_SZ, or REG_EXPAND_SZ type and the ANSI version of this function is used (either by explicitly calling RegSetValueExA or by not defining UNICODE before including the Windows.h file), the data pointed to by the lpData parameter must be an ANSI character string. The string is converted to Unicode before it is stored in the registry.

Also note that the cbData parameter should include the size of the null termination aswell.

like image 94
Idan K Avatar answered Dec 09 '22 20:12

Idan K


The * 2 is because RegSetValueEx wants to know the number of bytes to write und each char (wchar_t) in a wstring is two bytes wide. So the resulting byte-array has twice the size!

like image 36
Dario Avatar answered Dec 09 '22 21:12

Dario