views:

3229

answers:

3

Hello,

I'm trying to create a new registry key in the windows registry using C++. Here is the code I have so far:

HKEY hKey;
    LPCTSTR sk = TEXT("SOFTWARE\\OtherTestSoftware");

    LONG openRes = RegCreateKeyEx(
      HKEY_LOCAL_MACHINE,
      sk,
      0,
      NULL,
      REG_OPTION_BACKUP_RESTORE,
      KEY_ALL_ACCESS,
      NULL,
      &hKey,
      NULL);

    if (openRes==ERROR_SUCCESS) {
     printf("Success creating key.");
    } else {
     printf("Error creating key.");
    }

    LPCTSTR value = TEXT("OtherTestSoftwareKey");
    LPCTSTR data = "OtherTestData\0";

    LONG setRes = RegSetValueEx (hKey, value, 0, REG_SZ, (LPBYTE)data, strlen(data)+1);

    if (setRes == ERROR_SUCCESS) {
     printf("Success writing to Registry.");
    } else {
     printf("Error writing to Registry.");
    }

    //RegDeleteKey(hKey, sk);

    LONG closeOut = RegCloseKey(hKey);

    if (closeOut == ERROR_SUCCESS) {
     printf("Success closing key.");
    } else {
     printf("Error closing key.");
    }

I'm able to successfully open an existing key using a very similar code snippet (basically replace RegCreateKeyEx with RegOpenKeyEx). I would imagine that one or more of the arguments I'm passing into RegCreateKeyEx is causing the trouble. I'm honestly not sure where things might be getting fouled up since all of the error codes i've trapped show success. For reference, here is the function signature for RegCreateKeyEx:

/*
 * LONG WINAPI RegCreateKeyEx(
   __in        HKEY hKey,
   __in        LPCTSTR lpSubKey,
   __reserved  DWORD Reserved,
   __in_opt    LPTSTR lpClass,
   __in        DWORD dwOptions,
   __in        REGSAM samDesired,
   __in_opt    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
   __out       PHKEY phkResult,
   __out_opt   LPDWORD lpdwDisposition
 );
 */

Any thoughts would be great!

thanks, brian

+1  A: 

The first clue is your use of REG_OPTION_BACKUP_RESTORE. You probably don't want to use that flag, as I believe it requires a special "backup" privilege that you need to enable beforehand. Normal applications won't want to do that.

Greg Hewgill
Yes; not only do you need the privilege, but you need to explicitly enable it through a security API call; unless you knew that already, you probably don't want to be using it. :)
Nick
Changed to REG_OPTION_NON_VOLATILE, does not seem to have fixed it.
sweeney
A: 

As already mentioned, you've specified the REG_OPTION_BACKUP_RESTORE option in the call to RegCreateKeyEx, which means that you're opening the key in order to perform a backup or restore. Ordinarily, you would use REG_OPTION_NON_VOLATILE instead.

What operating system are you running? In Windows 2000/XP, the HKEY_LOCAL_MACHINE registry hive is not writeable by non-administrator users, so RegCreateKeyEx will fail with an access denied error (error 5). This also applies to Vista, if your application has a requestedExecutionLevel entry in its manifest. If you're running Vista, and your application doesn't specify a requestedExecutionLevel (or if it doesn't have a manifest at all), access to HKEY_LOCAL_MACHINE will be virtualised, so RegCreateKeyEx should succeed. See Registry Virtualization in Windows Vista in MSDN for more details.

There are some more problems with the code you've posted, which will only become apparent if you compile your project with UNICODE defined. This line:

LPCTSTR data = "OtherTestData\0";

should be

LPCTSTR data = TEXT("OtherTestData\0");

and this line:

LONG setRes = RegSetValueEx(hKey, value, 0, REG_SZ,
    (LPBYTE)data, _tcslen(data)+1);

should be:

LONG setRes = RegSetValueEx(hKey, value, 0, REG_SZ,
    (LPBYTE)data, (_tcslen(data)+1) * sizeof(TCHAR));

because the cbData parameter in RegSetValueEx is the length of the data in bytes, not characters.

I hope this helps!

ChrisN
I made your changes with one exception: (_tcslen(data)+1) * sizeof(TCHAR) changed to (strlen(data)+1) * sizeof(TCHAR) as it wouldn't compile the first way. Again, no error codes returned, just doesn't do what I expect it to. Thanks for the hints though, seems like I may be getting closer!
sweeney
Add #include <tchar.h> to use _tcslen().
ChrisN
+3  A: 

I've been compiling my own personal Function Library for years. One part of this deals entirely with registry access, see the CreateRegistryKey function the Registry.Cpp file.

If your interested, You can grab the entire library here.

NTDLS
I'm actually gonna take a stab with this - looks very friendly thanks!
sweeney