Welcome to HBH! If you had an account on hellboundhacker.org you will need to reset your password using the Lost Password system before you will be able to login.

Windows registry Using C++ and Win32 API


Windows registry Using C++ and Win32 API

By ghostghost | 28431 Reads |
0     0

DISCLAIMER : Well, this is my first article. So please forgive me for my mistakes :) END DISCLAIMER

READERS : People who have understanding of C\\C++ or any programming language or those who are interested in reading.

This is a short article on using Win32 API functions in C++ to work with Windows registry.

OK lets start then.

I guess most of you might have heard about the windows registry or atleast registry cleaners. The windows registry is basically like a store house of settings. It stores settings and options of Windows as well as the programs installed on your machine. It may contain information like which programs to run at start up, what is the current wallpaper, program preferences, …etc

So when programming in C\\C++ , you might want the settings of your program to be stored in the registry for some reason. Or sometimes, like me, you might just want to mess up with the registry. In any case you may need the Win32 API as it provides us with many functions to manipulate the registry.

The basic functions you will need to manipulate registry are : RegOpenKeyEx() RegCreateKeyEx() RegQueryValueEx() RegSetValueEx() RegDeleteValue() RegDeleteKey() RegEnumKeyEx() RegCloseKey()

But before we go and explain the functions, there are some basics to be understood.. Some points to note are :

1.Entire registry is divided in to hives called HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE ,HKEY_CURRENT_CONFIG and HKEY_USERS All other keys come under any one of these hives. For eg. HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows and so on… Much like a directory structure. Software is subkey of HKLM, Microsoft is subkey of Software ….. And the keys may contain values. Values are used to store data. So, the hives are like the partitions, keys are like folders/directories and the values are like files.

2.There are data types in registry too. They are REG_SZ (for string) , REG_DWORD (for 32bit numbers), REG_BINARY (binary ofcourse) . There are more but these 3 are enough to begin.

3.To access a registry key, you will need a handle to registry keys. This is very similar to having handles for files. Here Win32 API provides us with a typedef HKEY (same as long int)



Functions explanation :

1.RegOpenKeyEx() - Used to open a registry key.

The definition of the function according to Win32 API reference is like this :
  LONG RegOpenKeyEx(

   HKEY hKey,	// handle of open key 
   LPCTSTR lpSubKey,	// address of name of subkey to open 
   DWORD ulOptions,	// reserved 
   REGSAM samDesired,	// security access mask 
   PHKEY phkResult 	// address of handle of open key 
  );
Okay, the syntax is really self explanatory bu let me explain if you have any doubts.
First parameter is HKEY hkey. We give the name of the hive which we want to access.

ie , if I want to access HKEY_LOCAL_MACHINE, I would write that.

Second is name of Subkey. For eg, just consider that I need to acces the subkey Software\\Microsoft\\Windows Then I would write "Software\\\\Microsoft\\\\Windows"

Third parameter is ulOptions which is set 0 .

Fourth parameter is samDesired. This describes security access for the key. Some parameters you can use are KEY_ALL_ACCESS (for complete access), KEY_EXECUTE (For read access) , KEY_CREATE_SUB_KEY (permission to create sub key) and so on… For a list of complete values, please refer to MSDN library.

The fifth parameter is PHKEY , which is a pointer to the handle which receives the result of the operation.

The function returns ERROR_SUCCESS if there was no error.

Eg. Say, I wanted to access the key HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run I would write the code :

   ```markup 
    HKEY hKey;
    LONG res;

res=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run",0,KEY_ALL_ACCESS,hKey); if(res!=ERROR_SUCCESS) MessageBox(0,"Error Opening Registry Key","Error",0);


    The above example is very simple. a variable res checks the return value of RegOpenKeyEx() function and checks
    sees if it's ERROR_SUCCESS. If it was ok, then we have handle to the key in handle named hKey .

-------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------  

2.RegCreateKeyEx()    - Used to create a new subkey or open an already existing registry key.

	The Win32 API reference definition of the function is 
```markup
    LONG RegCreateKeyEx(

    HKEY hKey,	// handle of an open key 
    LPCTSTR lpSubKey,	// address of subkey name 
    DWORD Reserved,	// reserved 
    LPTSTR lpClass,	// address of class string 
    DWORD dwOptions,	// special options flag 
    REGSAM samDesired,	// desired security access 
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,	// address of key security structure 
    PHKEY phkResult,	// address of buffer for opened handle  
    LPDWORD lpdwDisposition 	// address of disposition value buffer 
   );

There are 5 new arguments here that you have not seen.

The third argument Reserved is always set as 0.

The fourth argument lpClass points to a null-terminated string that specifies the class (object type) of this key. This parameter is ignored if the key already exists. This can be ignored and set as NULL.

The dwOptions flag can be for the time being set as 0 which gives it a defualt value of REG_OPTION_NON_VOLATILE.

The seventh option pSecurityAttributes can be set as NULL as we are just starting. This is actually a pointer to a SECURITY_ATTRIBUTES structure.

The lpdwDisposition parameter is a pointr to a DWORD value. It accepts values which can be checked to see it the function has succeeded.

Eg. If I wanted to create or open a subkey HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run The code would be.

      ```markup
            DWORD dwDisposition;

HKEY hKey;

RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run", 0, NULL, 0, 0, NULL, &hKey, &dwDisposition);

if (dwDisposition != REG_CREATED_NEW_KEY && dwDisposition != REG_OPENED_EXISTING_KEY)

                          MessageBox(0,"The function failed","Error",0);
       
----------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------  

3. RegQueryValueEx() - Retrieves the type and data for the specified registry value.

    The definition is :
```markup
    LONG RegQueryValueEx(

    HKEY hKey,	// handle of key to query 
    LPTSTR lpValueName,	// address of name of value to query 
    LPDWORD lpReserved,	// reserved 
    LPDWORD lpType,	// address of buffer for value type 
    LPBYTE lpData,	// address of data buffer 
    LPDWORD lpcbData 	// address of data buffer size 
   );
 The first parameter is the handle to opened key .

 The second parameter is the pointer to name of value to be queried.

 The third parameter is lpReserved and is set as NULL

 The fourth parameter is lpType, which is pointer to variable which recevies the key's value type.

 The fifth one is lpData, which is pointer to variable that receives data of the value queried.

 The last one os lpcbData. This is a pointer to the variable that specifies the size, in bytes, of lpData.
 When the function returns, this variable contains the size of the data copied to lpData. 

Eg. Consider that I have opened the subkey
      HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run
and its handle is hKey.
I have to query the value named "abcd"
The code would be:

```markup 
DWORD res;
DWORD type =REG_DWORD;
DWORD cbData =1024;
DWORD val;

res=RegQueryValueEx(hKey,"abcd", NULL, &type, (LPBYTE)&val, &cbData);

if(res!=ERROR_SUCCESS0
    MessageBox(0,"Error reading value","Error",0);
  If the function succeeds, the data will be stored in  variable named val .

-------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------    
      

4. RegSetValueEx()  -  Used to set or change value in a registry key .
                        
                          The Win32 API reference definition :
    ```markup   
    LONG RegSetValueEx(

    HKEY hKey,	// handle of key to set value for  
    LPCTSTR lpValueName,	// address of value to set 
    DWORD Reserved,	// reserved 
    DWORD dwType,	// flag for value type 
    CONST BYTE *lpData,	// address of value data 
    DWORD cbData 	// size of value data 
   );	

Ok, now by using the last two functions, we have opened a subkey. Now its time to set or change a value inside the subkey. If you remember, the handle of subkey is in the variable hKey .

The first parameter hKey is the handle to the open subkey. So if you have used one of the first two functions, you will know that the handle used was hKey variable.

The second parameter is lpValueName . This is the name of value to be changed . You will understand more when seeing the example.

The third parameter is Reserved and is set as 0.

The fourth parameter, dwType specifies type of the value. ie, REG_BINARY or REG_SZ or REG_DWORD and so on…

The fifth parameter is lpData. It is a pointer to the data that is to be stored in the value.

The last parameter cbData is the size of data being stored. You can use the sizeof() function to find the size.

Eg. Now, I have opened the key HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run and its handle is hKey. There is a value named "abcd" and I want to set its data as 0. So lets see the example code .

DWORD res,val=0;

res=RegSetValueEx (hKey, "abcd", 0, REG_DWORD, (LPBYTE)&val , sizeof(DWORD));

if(res!=ERROR_SUCCESS)
    MessageBox(0,"Error using RegSetValueEx() function","Error",0);


  1. RegDeleteValue() – used to delete a value from a specified registry key.

    The defintion in Win32 API reference is :

   LONG RegDeleteValue(

    HKEY hKey,	// handle of key 
    LPCTSTR lpValueName 	// address of value name 
   );

The function is very simple and easy to understand. An example would be enough.

Eg. I have opened the key HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run and its handle is hKey. There is a value named "abcd" which I want to delete. The code would be


DWORD res;

 res=RegDeleteValue(hKey,"abcd");

if(res!=ERROR_SUCCEDD)
     MessageBox(0,"Error deleteing value","Error",0);



  1. RegDeleteKey() - Used to delete a registry key.

    The defintion according to Win32API reference is :

     LONG RegDeleteKey(

    HKEY hKey,	// handle of open key 
    LPCTSTR lpSubKey 	// address of name of subkey to delete 
   );

Here, hKey parameter is the parent key of the key that is to be deleted .

The lpSubKey parameter is the name of subkey to be deleted . It is not case sensitive.

Eg. Consider that I have opened a key HKEY_CURRENT_USER\\Software and the handle to it is hKey. There is a subkey named "ABCD" that I have to delete. The code would be

    ```markup 
    DWORD res;
    
    res=RegDeleteKey(hKey,"ABCD");
    
   if(res!=ERROR_SUCCESS)
      MessageBox(0,"Error deleting registry key","Error",0);

    ```

 There is another function RegDeleteKeyEx(). But we will deal with it another time.


  1. RegEnumKeyEx() - Used to enumerate all the sub keys of an open registry key.

    The defintion is :

    LONG RegEnumKeyEx(
    
    HKEY hKey,	// handle of key to enumerate 
    DWORD dwIndex,	// index of subkey to enumerate 
    LPTSTR lpName,	// address of buffer for subkey name 
    LPDWORD lpcbName,	// address for size of subkey buffer 
    LPDWORD lpReserved,	// reserved 
    LPTSTR lpClass,	// address of buffer for class string 
    LPDWORD lpcbClass,	// address for size of class buffer 
    PFILETIME lpftLastWriteTime 	// address for time key last written to 
    );
    
    

The first parameter hKey is the handle to open registry key.

The second parameter dwIndex is the index of subkey to retrieve. ie, first subkey is index 0, second is index 1. So this value is incremented to get all subkeys using a loop.

The third parameter is lpName is a pointer to receive the name of subkey of corresponding index.

The fourth parameter lpcbName points to a variable that specifies the size, in characters, of variable lpName

The fifth parameter lpReserved is reserved and is set as NULL

The sixth parameter lpClass can be set as NULL for now. It points to a buffer that contains the class of the enumerated subkey when the function returns

The seventh parameter lpcbClass points to a variable that specifies the size, in characters, of the variable lpClass. As we set lpClass NULL, we can set this parameter to be NULL too.

The last parameter is lpftLastWriteTime , which points to a variable that receives the time the enumerated subkey was last written to.

Eg. Consider I have opened HKEY_LOCAL_MACHINE\\Software key and its handle is hKey. I want to enumerate all the subkeys of this key.

      ```markup

     DWORD dwIndex=0;

     TCHAR lpName[1024];

    DWORD lpcbName=1024;

    FILETIME fTime;

    while(RegEnumKeyEx(hKey, dwIndex, lpName, &lpcbName, NULL, NULL, NULL, &fTime) == ERROR_SUCCESS)
    {
     MessageBox(0,szKeyName,"Sub Key Name",0);
     dwindex++;
     }
```
    

For this function to work, the handle hKey should have been opened with KEY_ENUMERATE_SUB_KEYS access. So when opening a subkey using the first two functions we talked about, make sure you give the correct access options.


  1. RegCloseKey() – This function closes the registry key opened and releases the handle of the specified key.

    The Win32API reference definition is :

     LONG RegCloseKey(
    
    HKEY hKey 	// handle of key to close  
    );
    

    The parameter hKey is the handle of the open subkey.

Eg. Consider I have opened the registry key HKEY_LOCAL_MACHINE\\Software and its handle is hKey.

Then to close this key, I would write

 DWORD res;
 res=RegCloseKey(hKey);
 
  if(res!=ERROR_SUCCESS)
      MessageBox(0,"Error closing registry key","Error",0);

  ```

 If you have opened a registry key using RegOpenKeyEx() or RegCreateKeyEx() function, after you are done with
 the key, you must always close it and release its handle using this function.


So I guess this might be enough for you guys to get started and work with windows registry.
There are  a lot of settings to tweak, new keys to be created and so many values to mess
with. I hope you guys liked this article.
  

Comments
ynori7's avatar
ynori7 14 years ago

I don't think it's that bad. It's a bit ugly though which is why I suggested code tags.

korg's avatar
korg 14 years ago

Very poorly written, lost my mind trying to follow it and I know the registry like the back of my hand. No way I would have accepted this shit. :angry:

ghost's avatar
ghost 14 years ago

I disagree wholeheartedly. While it's not written the best that it possibly could be, it is simply nothing worse than trite at times. It's a very informative article and will serve well as a technical point of reference for those starting out in Win32 API + Registry.

… and I would have accepted it without a second thought. :)

korg's avatar
korg 14 years ago

The information is fine and useful. The way it is presented is horrible and the structure sucks.

ghost's avatar
ghost 14 years ago

I agree on the presentation. However, the information justifies it. I think it would look better in ASCII… which means we need the ability to view articles as plain text instead of HTML formatted text. :)

ghost's avatar
ghost 14 years ago

ok..i will be careful on my next article then.. thank u guys for the comments…