Search code examples
c++registry

C++: Trying to create a Run key, All i get is Chinese characters in registry.


Please save me! I am new to this, trying to figure this out. I would like to have my program add a run key to run itself on startup . Here is "my" code:

HKEY hKey = 0;
RegOpenKeyEx( HKEY_LOCAL_MACHINE,
                L"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
                0,
                KEY_ALL_ACCESS,
                &hKey );
const unsigned char Path[ MAX_PATH ] = "C:\\test.exe";
RegSetValueEx( hKey, L"Testing", 0, 1, Path, strlen("C:\\test.exe") );
RegCloseKey(hKey);

This "works" except they key added reads "㩃瑜獥⹴硥" under data . Took me a while to figure out that the key is going to WoW6432Node too, thought it complied but wasn't working for the first 5 hours, much head to wall action there...

I am sure this has something to do with the way my string is formatted, ANSII vs ASCII vs the other 10 types of strings C++ doesn't seem to be able to convert between... I've tried using (BYTE*)"C:\virus.exe" and anything else i could think of... If i set the length to 1, the first character shows fine. But if its any other length, Chinese starts to show again.

Please help! I am about ready to start choking kittens here!


Solution

  • The problem is this:

    const unsigned char Path[ MAX_PATH ] = "C:\\test.exe";
    

    You have defined an ANSI string and then attempted to use the Unicode (UTF-16) version of RegSetValueEx:

    RegSetValueEx( hKey, L"Testing", 0, 1, Path, strlen("C:\\test.exe") );
    

    Under the hood, RegSetValueEx is a macro that aliases to RegSetValueExW because you defined the macro UNICODE.

    The correct solution is to use a Unicode string literal:

    const wchar_t Path[] = L"C:\\test.exe";
    RegSetValueEx( hKey, L"Testing", 0, 1, (const BYTE *) Path, sizeof(Path) );
    

    Here I used sizeof because the string is an array of characters whose size is known at compile time. For dynamic strings, use (wcslen(Path) + 1) * sizeof(*Path) instead.

    Note: There is no need to specify the length of a constant literal in the declaration because the compiler can automatically deduce that in this specific scenario. It's also bad idea to duplicate the string literal inside your strlen/wcslen because if it goes out of sync your code could be broken and trigger undefined behavior.