For those occasions when you must work with the Registry via code, this chapter provides a
brief overview of the heart of Registry automation: the Registry API. The Registry API portion of the Windows
Platform SDK provides all of the functions you need to check Registry values, delete keys, write new entry
values, load and unload hives, and more.
REGISTRY API FUNCTIONS OVERVIEW
Microsoft generally recommends that Windows 2000 users not access the Registry directly, such as from the
REGEDIT and REGEDT32 editors. Microsoft recommends using the user interface components provided in Windows 2000,
such as the array of tools in Control Panel and the folder of administrative options, to change settings in the
operating system. Regardless, and in contrast to Microsoft's recommendations, this book is written to show how
to use and modify the Registry. Also, Microsoft provides the two editors mentioned earlier, practically begging
you to tour and tune the Registry. So, if modifying the Registry by hand is frowned upon by Microsoft (even with
a wink), imagine the attitude toward writing a software program that opens and tweaks the Registry! Though most
software developers need to work with the Registry in order for Windows 2000 to support their applications, it
is rare to find a system administrator or help desk engineer who must work with the Registry via code. Still,
there may be the occasion when the automation provided by a coded solution is the best way to solve a problem,
such as an automated way to be notified when certain keys change. For those occasions, this chapter provides a
brief overview of the heart of Registry automation: the Registry API. The Registry API portion of the Windows
Platform SDK provides all of the functions you need to check Registry values, delete keys, write new entry
value, load and unload hives, and more. This chapter will not teach you to program if you haven't before, nor
will you find tips and tricks for Perl, Visual Basic, or C++. Instead, you'll find an overview of the Registry
support in the Windows Platform SDK.
The best way to understand the support an API provides for a particular set of tasks or requirements, next to
actually coding with the API, is to review a list of the functions and the service each provides. Table 1
(below) provides a summary of the use of each Registry function.
TABLE 1: REGISTRY FUNCTIONS |
Function |
Description |
RegCloseKey |
Closes the Registry specified by the handle passed in.
Returns ERROR_SUCCESS on completion. |
RegConnectRegistry |
Opens the Registry on a remote computer; returns a handle
that can then be used with other functions to manipulate the remote Registry. You specify the remote
computer by preceding its name with \\. |
RegCreateKeyEx |
Creates a key in the location and with the name you
specify. You can specify a number of options for the new key with this version of the function, such
as its data type and whether the key should be deleted when the system is restarted. If the key
already exists, this function opens it. |
RegCreateKey |
Creates a key. This version of the RegCreateKey function
is intended for use only with applications running on 16-bit versions of Windows. |
RegDeleteKey |
Deletes a subkey. You specify the subkey by passing in
the name of the key and the handle of the key opened where the key is located. This function will not
delete subkeys or values when run on a Windows 2000 platform. To delete all subkeys, you one of the
enumeration functions to walk through each subordinate key. |
|
RegDeleteValue |
Deletes the entry whose name is passed to the function.
This function also requires the handle of the key where the entry is located. If a NULL value is
passed in place of he Value name, the entry specified by the RegSetValue function is deleted. |
RegEnumKeyEx |
Enumerates every subordinate key of the key specified,
retrieving key name, class, and the date and time the key was last written. |
RegEnumKey |
Very similar to RegEnumKeyEx, though missing many of the
options. It should be used for applications intended to run on 16-bit versions of Windows. |
RegEnumValue |
Enumerates each entry of the open key specified by the
handle passed in. The function returns the name of the entry, the data type, and its value. |
RegFlushKey |
Forces all pending Registry changes to be written to
disk. While the Registry automatically flushes the buffer and writes to disk any pending changes, this
function can be used to write changes immediately. |
RegLoadKey |
Duplicates the Load key feature available in the RegEDT32
editor. Loads a hive from an external file to a target key. |
RegNotifyChangeKeyValue |
Notifies the application using it when either a key or
one of its attributes changes. An example of an attribute is the permissions assigned to the key. |
RegOpenCurrentUser |
New with the Windows 2000 version of the Platform SDK.
This function returns a handle to the current user's key in the Registry from the HKEY_CURRENT_USERS
rootkey. To use this function, you must pass it the type of access you need to the key. |
RegOpenKey |
Opens the specified key whose name is passed in. Similar
to RegOpenKeyEx, but is designed for use with 16-bit version of Windows. The root key where the target
key is located also must be passed in. A handle to the key opened is returned from this function. All
Registry functions rely on such a handle to identify the key to be operated on, so this function is
critical. This function is very similar to RegOpenKeyEx. This one should be used only with
applications running on 16-bit versions of Windows. |
RegOpenKeyEx |
Opens the specified key whose name is passed in. The root
key where the target key is located also must be passed in. A handle to the key opened is returned
from this function. All Registry functions rely on such a handle to identify the key to be operated
on, so this function is critical. This function is designed for use with the new version of Windows.
This function's companion function, RegOpen-Key, is designed for use with 16-bit version of Windows. |
RegOpenUserClassesRoot |
New with the Windows 2000 version of the Platform SDK.
This function returns a handle to the current user's key in the Registry from the HKEY_CLASSES_ROOT
rootkey. To use this function, you must pass it the type of access you need to the key. |
RegQueryInfoKey |
Retrieves information about a key, including the last
time it was written to, the number of entries, the number of subordinate keys, the length of the key
with the longest name, and more. RegQueryMultipleValues Retrieves the value and data type for the list
of entries you pass in for an open key, whose handle you also pass in. |
RegQueryValueEx |
Retrieves the value for the entry you specify. You pass
to this function a handle to the key where the entry is housed, the name of the entry, the buffer
where the value is loaded, and its size. |
RegReplaceKey |
Replaces the key specified by the handle passed in with
the contents of an external, whose name and location also are passed in. |
RegRestoreKey |
Behaves like the Restore key feature in the RegEDT32
editor. You pass a handle to an open key and the name and location of file created with the Save key
feature (API or editor). The function restores the key. |
RegSaveKey |
Completes the same task as the Save Key feature in
RegEDT32. The function writes to an external file all of the data in the subkey whose handle is passed
to this function. The function also requires the name of the file to be created, as well as a security
attribute structure. |
RegSetValue |
Sets the value of a Registry entry. This function is
designed for use with 16-bit Windows applications. |
RegSetValueEx |
Sets the value for the entry you specify. The entry is
created if it does not exist. This version of the function should be used with Windows 2000
applications. |
RegUnloadKey |
Has the same use as the Unload key feature available from
the RegEDT32 Registry editor. With a handle to an open key and the name of the key to unload, this
function drops from the Registry a key that had been previously loaded. As a refresher, the load and
unload functions are used to review subkeys extracted from another computer's Registry without
impacting the Registry of the computer where the key is being reviewed. |
REGISTRY API DATA TYPES, STRUCTURES, AND CONSTANTS
Handling Errors
Each of the functions listed in Table 1 returns a result code. These codes are known as error codes, although
the first on the list below actually is a success code. Nonetheless, you should always check the return result
from any function you call. If the function does not return a success, you may want to terminate the program
based on the error code you receive. Not doing so could result in a crash of your program. Checking for a return
code is a habit you should practice during the development of your program as well as in the final version of
your application. Table 2 (below) shows the error codes you will most likely encounter in working with the
Registry API.
TABLE 2: TYPICAL REGISTRY API ERROR
CODES |
Value |
Description |
Code |
0 |
The function completed successfully. |
ERROR_SUCCESS |
1 |
Bad function call. |
ERROR_INVALID_FUNCTION |
2 |
The system cannot find the file specified. |
ERROR_FILE_NOT_FOUND |
5 |
The permissions of the individual logged on and running
the program are not sufficient for the task attempted by the function. |
ERROR_ACCESS_DENIED |
6 |
Handle to the key passed to the function is not valid. |
ERROR_INVALID_HANDLE |
12 |
The access parameter passed to the function is not valid. |
ERROR_INVALID_ACCESS |
14 |
There is not enough memory to properly handle the return
data the function requested. |
ERROR_OUTOFMEMORY |
64 |
Network name is no longer available. |
ERROR_NETNAME_DELETED |
65 |
Network access is denied. |
ERROR_NETWORK_ACCESS_DENIED |
69 |
Network BIOS session limit was exceeded. |
ERROR_TOO_MANY_SESS |
87 |
One of the parameters supplied is invalid. |
ERROR_INVALID_PARAMETER |
161 |
The specified path is invalid. |
ERROR_BAD_PATHNAME |
167 |
A Region of the file cannot be locked. |
ERROR_LOCK_FAILED |
234 |
More data is available. |
ERROR_MORE_DATA |
259 |
No more data is available. |
ERROR_NO_MORE_ITEMS |
1009 |
Corrupt configuration Registry database. |
ERROR_BADDB |
1010 |
Invalid Registry key. |
ERROR_BADKEY |
1011 |
Problem opening configuration Registry key. |
ERROR_CANTOPEN |
1012 |
Problem reading configuration Registry key. |
ERROR_CANTREAD |
1013 |
Problem writing configuration Registry key. |
ERROR_CANTWRITE |
1014 |
Registry was recovered successfully. |
ERROR_REGISTRY_RECOVERED |
1015 |
The Registry is corrupted. |
ERROR_REGISTRY_CORRUPT |
1016 |
An I/O operation initiated by the Registry failed
unrecoverably. The Registry could not read in, or write out, or flush, one of the files that contain
the system's image of the Registry. |
ERROR_REGISTRY_IO_FAILED |
1017 |
The file intended in to be loaded or restored is not in
the Registry file format. |
ERROR_NOT_REGISTRY_FILE |
1018 |
Target key has been marked for deletion. |
ERROR_KEY_DELETED |
1019 |
Could not allocate enough space in Registry. |
ERROR_NO_LOG_SPACE |
1020 |
There is a problem with one of the subkeys. |
ERROR_KEY_HAS_CHILDREN |
1369 |
The target Registry subtree is involved in a transaction
incompatible with the requested operation. |
ERROR_RXACT_INVALID_STATE |
7005 |
A problem was detected when the system tried to create a
Registry key for event logging. |
ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY |
Registry Data Types
Some of the Registry API functions require you to pass in a data type, while others will return a data type
value that you then need to interpret. The Registry data type definitions can help you in both cases. For
projects built with the Windows 2000 Platform SDK, the definitions are located in WINNT.H. Table 3 shows the
valid Registry data type definitions and their decimal value.
Registry Key Access Constants
You are required to specify the type of access you need to a key when you first open the Registry. This data is
passed in the form of a key access value. Declarations for this parameter are found in WINNT.H. The following
list shows the possible values for this type of constant:
KEY_QUERY_VALUE
KEY_SET_VALUE
KEY_CREATE_SUB_KEY
KEY_ENUMERATE_SUB_KEYS
KEY_NOTIFY
KEY_CREATE_LINK
KEY_READ
KEY_WRITE
KEY_EXECUTE
KEY_ALL_ACCESS
KEY_QUERY_VALUE
KEY_SET_VALUE
KEY_CREATE_SUB_KEY
KEY_ENUMERATE_SUB_KEYS
KEY_NOTIFY
KEY_CREATE_LINK
TABLE 3: REGISTRY API DATA TYPE
CONSTANTS |
Declaration |
Value |
Reg_NONE |
0 |
Reg_SZ |
1 |
Reg_EXPAND_SZ |
2 |
Reg_BINARY |
3 |
Reg_DWORD |
4 |
Reg_DWORD_LITTLE_ENDIAN |
4 |
Reg_DWORD_BIG_ENDIAN |
5 |
Reg_LINK |
6 |
Reg_MULTI_SZ |
7 |
Reg_RESOURCE_LIST |
8 |
Reg_FULL_RESOURCE_DESCRIPTOR |
9 |
Reg_RESOURCE_REQUIREMENTS_LIST |
10 |
Reg_QWORD |
11 |
Reg_QWORD_LITTLE_ENDIAN |
11 |
Registry Root Key Constants
The root key is a parameter used in many functions. The definition for the root key values is found in WINReg.H.
Table 4 shows the value for these constants
TABLE 4: ROOT KEY CONSTANT VALUES |
Declaration |
Value |
HKEY_CLASSES_ROOT |
0x80000000 |
HKEY_CURRENT_USER |
0x80000001 |
HKEY_LOCAL_MACHINE |
0x80000002 |
HKEY_USERS |
0x80000003 |
HKEY_PERFORMANCE_DATA |
0x80000004 |
HEY_CURRENT_CONFIG |
0x80000005 |
HKEY_DYN_DATA |
0x80000006 |