cwinapiparameter-passingregistrykey

Can't set cbData in RegSetValue


I am trying to create a registry key with type REG_SZ and with a value longer than 4 chars.

But I can't figure out the right way to pass the data as argument :

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


HKEY OpenKey(HKEY hRootKey, wchar_t* strKey)
{
    HKEY hKey;
    LONG nError = RegOpenKeyEx(hRootKey, strKey, 0, KEY_ALL_ACCESS, &hKey);

    if (nError == ERROR_FILE_NOT_FOUND)
    {
        printf("Debug: Creating registry key\n");
        nError = RegCreateKeyEx(hRootKey, strKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
    }

    if (nError) {
        printf("Error: Could not find or create\n");
    }

    return hKey;
}

void SetValSZ(HKEY hKey, LPCTSTR lpValue, LPCTSTR data)
{
    LONG nError = RegSetValueEx(hKey, lpValue, 0, REG_SZ, (const BYTE*) data, sizeof(data));

    if (nError)
        printf("Error: Could not set registry value\n");
}

int main()
{

    HKEY hKey = OpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Policies\\Microsoft\\FVE");
    const wchar_t data[] = L"AAAABBBBCCCC";
    SetValSZ(hKey, L"RecoveryKeyMessage", data);
    RegCloseKey(hKey);

    return 0;
}

When I run it, only the first 4 characters are saved. I must have a type mistake...

Do you have any idea to help me to fix it ?

Thank you.

PS: I hope my english is clear enoth, feel free to ask me more if it isn't.


Solution

  • void SetValSZ(HKEY hKey, LPCTSTR lpValue, LPCTSTR data)
    {
        RegSetValueEx(hKey, lpValue, 0, REG_SZ, (const BYTE*) data, sizeof(data));
    }
    

    data is being passed as a pointer to a function, so its actual size will be lost. sizeof(data) is translated to the size of a pointer, which is 4 bytes in this case.

    You have to either pass in the size as a parameter:

    int len = sizeof(data);
    SetValSZ(..., data, len);
    

    Or better yet, use wcslen() to calculate the string length, then multiply that by sizeof(wchar_t).

    Since you are using those T macros, the function can be written as:

    RegSetValueEx(hKey,lpValue,0,REG_SZ,(const BYTE*)data,sizeof(TCHAR)*(lstrlen(data) + 1));
    

    Edit: The size should also include the terminating null character