CWindowsRegistry

Provides an easier access to the Windows Registry.

[ WhoSLocking | Source | Keywords | Summary | Ancestors | All Members | Descendants ]

Quick Index

DESCRIPTION
USAGE
EXAMPLE
TO DO
ADMINISTRATIVE
SEE ALSO

Class Summary

class CWindowsRegistry

{

public:
CWindowsRegistry();
CWindowsRegistry(LPCTSTR pSubKeyName, HKEY pBaseKey , REGSAM SecurityAccessMask );
~CWindowsRegistry();
LONG OpenKey(LPCTSTR pSubKeyName, HKEY pBaseKey , REGSAM SecurityAccessMask );
BOOL IsOpen();
LONG CloseKey();
LONG CreateKey(LPCTSTR pSubKeyName, HKEY pBaseKey , REGSAM nSecurityAccessMask );
LONG DeleteKey(LPCTSTR pSubKeyName, HKEY pBaseKey , BOOL bRecursive );
LONG QueryValue(LPCTSTR pValueName, char **readValue, LPDWORD pValueType );
LONG QueryValue(LPCTSTR pValueName, DWORD &readValue, LPDWORD pValueType );
LONG QueryValue(LPCTSTR pValueName, char **readValue, int &KeyArraySize, LPDWORD pValueType );
LONG WriteValue(LPCTSTR pValueName, LPCTSTR pValueToWrite, DWORD nValueType );
LONG WriteValue(LPCTSTR pValueName, int valueToWrite, DWORD nValueType );
BOOL EnumerateSubKeys( const DWORD subkeyIndex, char *pSubKeyName);
BOOL EnumerateValues( const DWORD subValueIndex, char *pSubValueName);
static LONG CopyKeys( LPCTSTR srcKey, LPCTSTR destKey );
static const size_t MaximumWriteSize;
define FWR_MAXIMUM_KEY_SIZE 2048
protected:
}; // CWindowsRegistry

Back to the top of CWindowsRegistry


DESCRIPTION

This class provides an easy access to the Windows Registry (much easier than the WIN32 API).

Back to the top of CWindowsRegistry


USAGE

To access the Windows Registry via this class, follow these steps:

There's a class constructor which automatically opens the registry (the key must exists).

The class destructor automatically closes the registry.

When you delete a key, this class can recursively delete all sub-keys (on Windows NT, the WIN32 function ::RegDeleteKey does NOT recursively deletes the keys) if you specify the proper parameter (see function DeleteKey()).

You can keep a single instance of this class for a given application and use only function QueryValue to access the registry (if you don't need to switch to another registry base key).

Back to the top of CWindowsRegistry


EXAMPLE

// At the application initialization: create object (without opening registry) CWindowsRegistry MyRegistry;

// Open the registry via the object instance if (!MyRegistry.IsOpen()) { // Build key name CString KeyName = "\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSMQ\\1.0";

// Open Registry (note: the base key "LOCAL_MACHINE" is part of the KeyName) LONG nResult=MyRegistry.OpenKey(KeyName); if (nResult != ERROR_SUCCESS) { // Here we could CREATE the registry entries for the application cerr << "Cannot open registry!\n"; } }

[...]

// At some point in the application, read values (several times, if needed) char *TemporaryValue; CString RealValue; BOOL bTemporaryValue,bRealValue; int nTemporaryValue,nRealValue;

// Reads the value in "\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSMQ\\1.0\\MyStringKey" if (MyRegistry.QueryValue("MyStringKey",&TemporaryValue) == ERROR_SUCCESS) { RealValue=TemporaryValue; // For a string value, the pointer has been allocated: do not forget to free it if (TemporaryValue) { // CAUTION: use delete [], not free or LocalFree delete [] TemporaryValue; } }

// Reads the value in "\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSMQ\\1.0\\MyBooleanKey" if (MyRegistry.QueryValue("MyBooleanKey",bTemporaryValue) == ERROR_SUCCESS) { bRealValue=bTemporaryValue; }

// Reads the value in "\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSMQ\\1.0\\MyIntegerKey" if (MyRegistry.QueryValue("MyIntegerKey",nTemporaryValue) == ERROR_SUCCESS) { nRealValue=nTemporaryValue; }

[...]

// At some point in the application, write values (several times, if needed) LPCTSTR RealValue = "MyString"; BOOL bRealValue = TRUE; int nRealValue = 357;

if (MyRegistry.WriteValue("MyStringKey", RealValue) != ERROR_SUCCESS) { // Process Write Error... }

if (MyRegistry.WriteValue("MyBooleanKey", bRealValue) != ERROR_SUCCESS) { // Process Write Error... }

if (MyRegistry.WriteValue("MyIntegerKey", nRealValue) != ERROR_SUCCESS) { // Process Write Error... }

[...]

// At some point in the application (usually startup), copy keys from LOCAL_MACHINE to CURRENT_USER LONG nResult = ERROR_SUCCESS; nResult = CWindowsRegistry::CopyKeys("\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSMQ\\1.0", "\\HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\MSMQ\\2.0");

if (nResult != ERROR_SUCCESS) { // Process Copy error }

[...]

// At some point in the application, create a new SUBKEY // Create the key "\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSMQ\\1.0\\SubKey1" MyRegistry.CreateKey("SubKey1"); // Note that the currently open key is still "\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSMQ\\1.0"

[...]

// At some point in the application, create a complete new key MyRegistry.CloseKey(); MyRegistry.CreateKey("\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSMQ\\Dummy\\1.0"); // We must open this key if we want to use it MyRegistry.OpenKey("\\HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSMQ\\Dummy\\1.0");

[...]

// At some point in the application, loop on all subkeys char subKey[FWR_MAXIMUM_KEY_SIZE]; for (int i=0; MyRegistry.EnumerateSubKeys(i, subKey)==TRUE; i++) { // Here you should see "SubKey1" cout << "Key #" << i << ": " << subKey << eol; }

[...]

// At the end of the application: close registry // Note that the object's destructor automatically closes the registry MyRegistry.CloseKey();

Back to the top of CWindowsRegistry


TO DO

This class may be improved to:

Back to the top of CWindowsRegistry


ADMINISTRATIVE

Author Emmanuel KARTMANN

Date Tuesday 9/21/99 2:47:45 PM

Back to the top of CWindowsRegistry


SEE ALSO

RegOpenKeyEx RegCloseKey RegQueryValueEx RegCreateKeyEx

Back to the top of CWindowsRegistry


CWindowsRegistry();

Purpose: create an instance of the class (empty)

Parameters: none

Return value : none

Description : Before using this instance, the application must call function OpenKey().

    CWindowsRegistry();

Back to the top of CWindowsRegistry


CWindowsRegistry(LPCTSTR pSubKeyName, HKEY pBaseKey , REGSAM SecurityAccessMask );

Purpose: create an instance of the class and opens the registry.

Parameters:

in pSubKeyName
name of the subkey, e.g. "SYSTEM\\CurrentControlSet\\Services\\"
in pBaseKey
Handle to a currently open key or any of the predefined reserved handle values (see function OpenKey() for a list).
in SecurityAccessMask
Security access mask for the key to open. (see function OpenKey() for a list).

Return value : none

Description : calls function OpenKey() with the given parameters

    CWindowsRegistry(LPCTSTR pSubKeyName, HKEY pBaseKey = NULL, REGSAM SecurityAccessMask = KEY_QUERY_VALUE);

Back to the top of CWindowsRegistry


~CWindowsRegistry();

Purpose: delete an instance of the class

Parameters: none

Return value : none

Description : This function simply close the registry (see function CloseKey())

    virtual ~CWindowsRegistry();

Back to the top of CWindowsRegistry


LONG OpenKey(LPCTSTR pSubKeyName, HKEY pBaseKey , REGSAM SecurityAccessMask );

Purpose: open the specified key in the Windows Registry

Parameters:

in pSubKeyName
name of the subkey, e.g. "SYSTEM\\CurrentControlSet\\Services\\"
in pBaseKey
Handle to a currently open key or any of the following predefined reserved handle values:
  • NULL[the default]
  • HKEY_CLASSES_ROOT
  • HKEY_CURRENT_CONFIG
  • HKEY_CURRENT_USER
  • HKEY_LOCAL_MACHINE
  • HKEY_USERS
in SecurityAccessMask
Security access mask for the key to open. This parameter can be a combination of the following values:
  • KEY_ALL_ACCESS: Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK, and KEY_SET_VALUE access.
  • KEY_CREATE_LINK: Permission to create a symbolic link.
  • KEY_CREATE_SUB_KEY: Permission to create subkeys.
  • KEY_ENUMERATE_SUB_KEYS: Permission to enumerate subkeys.
  • KEY_EXECUTE: Permission for read access.
  • KEY_NOTIFY: Permission for change notification.
  • KEY_QUERY_VALUE: Permission to query subkey data. [the default]
  • KEY_READ: Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY access.
  • KEY_SET_VALUE: Permission to set subkey data.
  • KEY_WRITE: Combination of KEY_SET_VALUE and KEY_CREATE_SUB_KEY access.

Return value : LONG = ERROR_SUCCESS in case of success, otherwise an error occured.

Description : this function open the registry and keeps a handle in the member variable m_pKey for further use with the other member functions: QueryValue, WriteValue...

Unlike the CreateKey function, the OpenKey function does not create the specified key if the key does not exist in the registry (it issues an error).

If the pBaseKey is NULL, this function reuse the handle previously open (it opens the subkey pSubKeyName).

    LONG OpenKey(LPCTSTR pSubKeyName, HKEY pBaseKey = NULL, REGSAM SecurityAccessMask = KEY_QUERY_VALUE);

Back to the top of CWindowsRegistry


BOOL IsOpen();

Purpose: check if the registry is open

Parameters: none

Return value : BOOL

Description : if the registry is not open, many function are not available: QueryValue, WriteValue...

    BOOL IsOpen();

Back to the top of CWindowsRegistry


LONG CloseKey();

Purpose: close the registry (if opened with function OpenKey()).

Parameters: none

Return value : LONG = ERROR_SUCCESS in case of success, otherwise an error occured.

Description : -

    LONG CloseKey();

Back to the top of CWindowsRegistry


LONG CreateKey(LPCTSTR pSubKeyName, HKEY pBaseKey , REGSAM nSecurityAccessMask );

Purpose: create a key in the registry

Parameters:

in pSubKeyName
name of the subkey, e.g. "SYSTEM\\CurrentControlSet\\Services\\MyService\\Parameters"
in pBaseKey
Handle to a currently open key or any of the following predefined reserved handle values:
  • NULL[the default]
  • HKEY_CLASSES_ROOT
  • HKEY_CURRENT_CONFIG
  • HKEY_CURRENT_USER
  • HKEY_LOCAL_MACHINE
  • HKEY_USERS
in nSecurityAccessMask
Security access mask for the key to open. This parameter can be a combination of the following values:
  • KEY_ALL_ACCESS: Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK, and KEY_SET_VALUE access. [the default]
  • KEY_CREATE_LINK: Permission to create a symbolic link.
  • KEY_CREATE_SUB_KEY: Permission to create subkeys.
  • KEY_ENUMERATE_SUB_KEYS: Permission to enumerate subkeys.
  • KEY_EXECUTE: Permission for read access.
  • KEY_NOTIFY: Permission for change notification.
  • KEY_QUERY_VALUE: Permission to query subkey data.
  • KEY_READ: Combination of KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY access.
  • KEY_SET_VALUE: Permission to set subkey data.
  • KEY_WRITE: Combination of KEY_SET_VALUE and KEY_CREATE_SUB_KEY access.

Return value : LONG = ERROR_SUCCESS in case of success, otherwise an error occured.

Description : If the pBaseKey is NULL, this function reuse the handle previously open (it creates the subkey pSubKeyName).

    LONG CreateKey(LPCTSTR pSubKeyName, HKEY pBaseKey = NULL, REGSAM nSecurityAccessMask = KEY_ALL_ACCESS);

Back to the top of CWindowsRegistry


LONG DeleteKey(LPCTSTR pSubKeyName, HKEY pBaseKey , BOOL bRecursive );

Purpose: delete a key from the registry

Parameters:

in pSubKeyName
name of the subkey, e.g. "SYSTEM\\CurrentControlSet\\Services\\MyService\\Parameters"
in pBaseKey
Handle to a currently open key or any of the following predefined reserved handle values:
  • NULL[the default]
  • HKEY_CLASSES_ROOT
  • HKEY_CURRENT_CONFIG
  • HKEY_CURRENT_USER
  • HKEY_LOCAL_MACHINE
  • HKEY_USERS
in bRecursive
Boolean Flag: TRUE if the deletion must be recursive.

Return value : LONG = ERROR_SUCCESS in case of success, otherwise an error occured.

Description :

If the pBaseKey is NULL, this function reuse the handle previously open (it opens the subkey pSubKeyName).

    LONG DeleteKey(LPCTSTR pSubKeyName, HKEY pBaseKey = NULL, BOOL bRecursive=TRUE);

Back to the top of CWindowsRegistry


LONG QueryValue(LPCTSTR pValueName, char **readValue, LPDWORD pValueType );

Purpose: get a value in the registry (a string)

Parameters:

in pValueName
name of the value
out readValue
value read (a string)
out pValueType
effective type of value, i.e.:
  • REG_SZ: A null-terminated string.
  • REG_EXPAND_SZ: A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%").

Return value : LONG = ERROR_SUCCESS in case of success, otherwise an error occured.

Description : If the registry is not open (via function OpenKey()), this function returns "ERROR_INVALID_HANDLE".

If the key type is not compatible with a string, this function returns "ERROR_INVALID_DATA"

This function allocates memory for its result (readValue). The calling application is responsible for freeing this memory (delete [] (*readValue)).

    LONG QueryValue(LPCTSTR pValueName, char **readValue, LPDWORD pValueType = NULL);

Back to the top of CWindowsRegistry


LONG QueryValue(LPCTSTR pValueName, DWORD &readValue, LPDWORD pValueType );

Purpose: get a value in the registry (an integer)

Parameters:

in pValueName
name of the value
out readValue
value read (a 32-bit integer)
out pValueType
effective type of value, i.e.:
  • REG_DWORD: A 32-bit number.
  • REG_DWORD_LITTLE_ENDIAN: A 32-bit number in little-endian format. This is equivalent to REG_DWORD.
  • REG_DWORD_BIG_ENDIAN: A 32-bit number in big-endian format.

Return value : LONG = ERROR_SUCCESS in case of success, otherwise an error occured.

Description : If the registry is not open (via function OpenKey()), this function returns "ERROR_INVALID_HANDLE".

If the key type is not compatible with an integer, this function returns "ERROR_INVALID_DATA"

    LONG QueryValue(LPCTSTR pValueName, DWORD &readValue, LPDWORD pValueType = NULL);

Back to the top of CWindowsRegistry


LONG QueryValue(LPCTSTR pValueName, char **readValue, int &KeyArraySize, LPDWORD pValueType );

Purpose: get a value in the registry (an array of strings)

Parameters:

in pValueName
name of the value
out readValue
value read (an array of char *)
out KeyArraySize
size of the returned array
out pValueType
effective type of value, i.e.:
  • REG_MULTI_SZ

Return value : LONG = ERROR_SUCCESS in case of success, otherwise an error occured.

Description : This function is not implemented yet.

If the registry is not open (via function OpenKey()), this function returns "ERROR_INVALID_HANDLE".

If the key type is not compatible with an array of string objects, this function returns "ERROR_INVALID_DATA"

This function allocates memory for its result (readValue). The calling application is responsible for freeing this memory (loop on KeyArraySize and delete [] (readValue[x])).

    LONG QueryValue(LPCTSTR pValueName, char **readValue, int &KeyArraySize, LPDWORD pValueType = NULL);

Back to the top of CWindowsRegistry


LONG WriteValue(LPCTSTR pValueName, LPCTSTR pValueToWrite, DWORD nValueType );

Purpose: set a value in the registry (a string)

Parameters:

in pValueName
name of the value
in pValueToWrite
value yo write (a string)
in ValueType
effective type of value, i.e.:
  • REG_SZ: A null-terminated string.
  • REG_EXPAND_SZ: A null-terminated string that contains unexpanded references to environment variables (for example, "%PATH%").

Return value : LONG = ERROR_SUCCESS in case of success, otherwise an error occured.

Description : If the registry is not open (via function OpenKey()), this function returns "ERROR_INVALID_HANDLE".

If the string pointer is NULL, nothing is written in the registry (the key is not created) and the function succeeds.

If the value name is a relative path (if it contains backslashes), this function will write the value in the appropriate sub-keys (unlike the WIN32 function ::RegSetValueEx which doesn't support sub-key names).

If the value name is an empty string (""), the default value of the opened KEY will be set.

    LONG WriteValue(LPCTSTR pValueName, LPCTSTR pValueToWrite, DWORD nValueType = REG_SZ);

Back to the top of CWindowsRegistry


LONG WriteValue(LPCTSTR pValueName, int valueToWrite, DWORD nValueType );

Purpose: set a value in the registry (an integer)

Parameters:

in pValueName
name of the value
in valueToWrite
value to write (an 'int')
in ValueType
effective type of value, i.e.:
  • REG_DWORD: A 32-bit number.
  • REG_DWORD_LITTLE_ENDIAN: A 32-bit number in little-endian format. This is equivalent to REG_DWORD.
  • REG_DWORD_BIG_ENDIAN: A 32-bit number in big-endian format.

Return value : LONG = ERROR_SUCCESS in case of success, otherwise an error occured.

Description : If the registry is not open (via function OpenKey()), this function returns "ERROR_INVALID_HANDLE".

If the key name is a relative path (if it contains backslashes), this function will write the value in the appropriate sub-keys (unlike the WIN32 function ::RegSetValueEx which doesn't support sub-key names).

    LONG WriteValue(LPCTSTR pValueName, int valueToWrite, DWORD nValueType = REG_DWORD);

Back to the top of CWindowsRegistry


BOOL EnumerateSubKeys( const DWORD subkeyIndex, char *pSubKeyName);

Purpose: list all keys located under current key

Parameters:

in subkeyIndex
the index of the subkey to retrieve (this value should be zero for the first call to this function and then incremented for subsequent calls).
in/out pSubKeyName
pointer to a buffer that receives the name of the subkey

Return value : BOOL = FALSE if no more keys are found, TRUE otherwise

Description : The calling application should have allocated (at least) FWR_MAXIMUM_KEY_SIZE bytes in the buffer referenced by the pSubKeyName pointer.

The values located under the currently open key are NOT returned by this function (it only enumerates the KEYS, not the VALUES). To enumerate the values, use EnumerateValues instead.

    BOOL EnumerateSubKeys( const DWORD subkeyIndex, char *pSubKeyName);

Back to the top of CWindowsRegistry


BOOL EnumerateValues( const DWORD subValueIndex, char *pSubValueName);

Purpose: list all values located under current key

Parameters:

in subValueIndex
the index of the subvalue to retrieve (this value should be zero for the first call to this function and then incremented for subsequent calls).
in/out pSubValueName
pointer to a buffer that receives the name of the value

Return value : BOOL = FALSE if no more values are found, TRUE otherwise

Description : The calling application should have allocated (at least) FWR_MAXIMUM_KEY_SIZE bytes in the buffer referenced by the pSubValueName pointer.

The keys located under the currently open key are NOT returned by this function (it only enumerates the VALUES, not the KEYS). To enumerate the keys, use EnumerateSubKeys instead.

    BOOL EnumerateValues( const DWORD subValueIndex, char *pSubValueName);

Back to the top of CWindowsRegistry


LONG CopyKeys( LPCTSTR srcKey, LPCTSTR destKey );

Purpose: Copy a registry hierarchy from one key to another

Parameters:

in srcKey
the source key from which is loaded the hierarchy
in destKey
the destination key where to copy the hierarchy

Return value : LONG = ERROR_SUCCESS in case of success, otherwise an error occured.

Description : This method is static.

The keys are copied recursively (i.e. subkeys AND values are copied).

If the destination key doesn't exists, it is created by this function.

    static LONG CopyKeys( LPCTSTR srcKey, LPCTSTR destKey );

Back to the top of CWindowsRegistry


const size_t MaximumWriteSize;

Maximum size of the buffer during a WRITE access to the registry (function WriteValue()).

I created this variable because the WIN32 API recommend that the data stored in the Registry shouldn't exceed 2048 bytes (bigger data should be stored in files instead).

    static const size_t MaximumWriteSize;

Back to the top of CWindowsRegistry


define FWR_MAXIMUM_KEY_SIZE 2048

Maximum size of the key name.

#define FWR_MAXIMUM_KEY_SIZE 2048

Back to the top of CWindowsRegistry


All Members

public:
LONG OpenKey(LPCTSTR pSubKeyName, HKEY pBaseKey , REGSAM SecurityAccessMask );
BOOL IsOpen();
LONG CloseKey();
LONG CreateKey(LPCTSTR pSubKeyName, HKEY pBaseKey , REGSAM nSecurityAccessMask );
LONG DeleteKey(LPCTSTR pSubKeyName, HKEY pBaseKey , BOOL bRecursive );
LONG QueryValue(LPCTSTR pValueName, char **readValue, LPDWORD pValueType );
LONG QueryValue(LPCTSTR pValueName, DWORD &readValue, LPDWORD pValueType );
LONG QueryValue(LPCTSTR pValueName, char **readValue, int &KeyArraySize, LPDWORD pValueType );
LONG WriteValue(LPCTSTR pValueName, LPCTSTR pValueToWrite, DWORD nValueType );
LONG WriteValue(LPCTSTR pValueName, int valueToWrite, DWORD nValueType );
BOOL EnumerateSubKeys( const DWORD subkeyIndex, char *pSubKeyName);
BOOL EnumerateValues( const DWORD subValueIndex, char *pSubValueName);
static LONG CopyKeys( LPCTSTR srcKey, LPCTSTR destKey );
static const size_t MaximumWriteSize;
define FWR_MAXIMUM_KEY_SIZE 2048
protected:

Back to the top of CWindowsRegistry


Ancestors

Class does not inherit from any other class.

Back to the top of CWindowsRegistry


Descendants

Class is not inherited by any others.

Back to the top of CWindowsRegistry


Generated from source by the Cocoon utilities on Thu Feb 10 12:02:42 2000 .

Report problems to jkotula@stratasys.com