Advanced Windows Registry Access

If you are interested in how to access arbitrary locations in the Windows registry, this is the article for you. However, if you would prefer to learn a simpler method of registry access to store and retrieve program settings, consult my simple registry access article.

Opening (Reading) Keys

Unlike the simpler, application based method, we don’t need to enable registry access via a special function call. Instead, the functions we will be using interface directly with the registry itself. Let’s look at the code required to open an arbitrary key value:

HKEY hKey;
RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Control Panel\\Desktop"),
             0, KEY_QUERY_VALUE, &hKey);

As you can see, we are using the RegOpenKeyEx() function. Let’s take a look at its various parameters:

As can be seen in the example code provided above, we are opening a registry key in the HKEY_CURRENT_USER branch. What’s more is that we’re explicitly opening the "Control Panel\Desktop" sub-key. We want to have permission to query sub-key data values (hence the value of KEY_QUERY_VALUE for parameter 4), and we store the resulting handle in the hKey variable.

The RegOpenKeyEx() method returns a value indicating success or failure, so make sure you test it appropriately. Let’s assume that the key was opened successfully and see how to query its value:

unsigned char buffer[_MAX_PATH];
unsigned long datatype;
unsigned long bufferlength = sizeof(buffer);

RegQueryValueEx(hKey, "Wallpaper", NULL, &datatype, buffer, &bufferlength);

Again, let’s take a look at the parameters for this new RegQueryValueEx() function:

The first parameter accepts the same handle we got from the RegOpenKeyEx() function. The second parameter in this example is the string "Wallpaper", which means this is the specific key we will be querying. The fourth parameter is an unsigned long that accepts the data type, but we won’t ever actually use its value. Next is an unsigned character buffer, into which the value of the registry key will be read. I use the Windows constant _MAX_PATH to create a buffer large enough to store the longest possible file path (since this particular key I’m querying stores a file path value). We finally pass in the length of the buffer that we just created.

One last step is required before we can successfully say we have read a registry key. The key that got opened must be closed (after we read its value, of course), so that its handle gets freed. The code we use to do this is:

RegCloseKey(hKey);

Using all of the methods just mentioned, you can read any value from the registry.

Creating (Writing) Keys

So now we know how to read a value. But what about writing a value? The process is slightly different. First, we open the key we want to write (whether it exists or not) using the RegCreateKeyEx() function:

HKEY hKey;
unsigned long dwDisp;

RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("Control Panel\\Desktop"),
               0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
               NULL, &hKey, &dwDisp);

Let’s examine this function’s parameters:

Once the desired key is opened, we can set its value with the RegSetValueEx() function:

unsigned char tilewallpaper[2];
tilewallpaper[0] = '0';
tilewallpaper[1] = '\0';

RegSetValueEx(hKey, TEXT("TileWallpaper"), NULL, REG_SZ, tilewallpaper, 1);

Let’s look a little closer at this final function’s parameter list:

Here we are explicitly writing a value to the TileWallpaper key (we are going to write a value of ‘0′ so that our wallpaper is not tiled). We use the hKey as before, and an unsigned character buffer. Fairly straightforward.

Don’t forget to close the key once you’ve finished:

RegCloseKey(hKey);

I’ve now shown you how to read and write to any location in the registry. This is a powerful means of programming, so be careful! You don’t want to accidentally remove or overwrite anything that you shouldn’t.