Windows registry Using C++ and Win32 API
Windows registry Using C++ and Win32 API
- Functions explanation :
- 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 correctaccess options.
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);
-
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);
-
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.
-
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.
-
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.
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 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 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 14 years ago
The information is fine and useful. The way it is presented is horrible and the structure sucks.
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. :)