Abstract
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 |
|
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 |
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.
|