Accessing the Registry from Code

Back ] Development Home ] Next ]

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


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


 

Back ] Development Home ] Next ]

Questions? Use the MAIN PAGE anonymous FORM. And ask Away