Storing Data in the System Registry

[Previous] [Next]

Before I discuss how to store data in the system registry, I will revisit the topic of proper registry usage. As you know, the system registry is a shared resource. As such, it is limited and access to it is serialized. Your application can store many thousands of kilobytes of data in the registry in various data types, but it is rarely in your application's best interest to take these capabilities to the extreme.

You should ask yourself two questions when considering registry storage:

  • Is the data I am storing part of my application's configuration information, or is it general application data? (For example, it would be inappropriate for a word processor to store documents in the registry.)
  • Is the amount of data I am storing large enough (and will I be accessing the data frequently enough) to make storage in a file more efficient than storage in the registry? (For example, a spell-checking dictionary used by a word processing application would be better stored in a file.)

In making these decisions, you end up weighing the pros and cons of file system clutter vs. the inefficiencies of storing large data in the system registry. I will be further discussing efficient use of the system registry in the section "Using the System Registry Efficiently" later in this chapter.

You can use the RegSetValueEx function to store data to the registry. Here is the prototype for RegSetValueEx:

 LONG RegSetValueEx( HKEY hkey, PCTSTR pszValueName, DWORD dwReserved, DWORD dwType, CONST BYTE *pbData, DWORD cbData); 

The hkey parameter refers to the key under which the value is stored. The pszValueName is the name you want to use for the value. If you pass NULL or a pointer to an empty string for pszValueName, the system stores your data in the default value for the key. The dwType parameter should be set to one of the data type values listed in Table 5-2, depending on what type of data you are storing in this value. The pbData parameter points to the actual data to be stored in the registry. You pass the size of the data, in bytes, in the cbData parameter.

If RegSetValueEx succeeds, it returns ERROR_SUCCESS. The following code illustrates the use of RegSetValueEx by wrapping it in a function named RegSetStringValue.

 LONG RegSetStringValue(HKEY hkey, PCTSTR pszValueName, PCTSTR pszString) { // Get the length of the string int nDataSize = lstrlen(pszString); // Add one for the zero terminator nDataSize++; // Multiply by the character size nDataSize = nDataSize * sizeof(TCHAR); // Attempt to store the data to the registry return(RegSetValueEx(hkey, pszValueName, 0, REG_SZ, (PBYTE) pszString, nDataSize)); } 

NOTE
The shell registry functions include a function called SHSetValue, which, like SHGetValue, does not require your application to first obtain a handle to a key. The SHSetValue function is defined as follows:

 DWORD SHSetValue( HKEY hkey, PCTSTR pszSubKey, PCTSTR pszValue, PDWORD pdwType, PVOID pvData, PDWORD pcbData); 

As Table 5-2 shows, the registry supports many data types. You choose your type according to the needs of your application. You will likely find yourself using the REG_DWORD, REG_SZ, and REG_BINARY types most often. An application would use the REG_DWORD type to store numerical settings, REG_SZ (or REG_MULTI_SZ) to store textual settings, and REG_BINARY for other data that does not have a matching registry type. When using the REG_BINARY type, generic registry tools such as RegEdt32 will not know how to present the data other than as a block of byte values.

Before moving on, I would like to clarify two potentially confusing registry types: REG_EXPAND_SZ and REG_MULTI_SZ. The REG_EXPAND_SZ registry type is very similar to the REG_SZ type in that it is a zero-terminated Unicode or ANSI string stored in the registry. They differ in that, by convention, data stored in values of REG_EXPAND_SZ is typically passed to the ExpandEnvironmentStrings function after being extracted from the registry.

NOTE
The registry functions do not automatically expand the data in values of type REG_EXPAND_SZ. Your application is responsible for passing the string to ExpandEnvironmentStrings.

Here is the prototype for ExpandEnvironmentStrings:

 DWORD ExpandEnvironmentStrings( PCTSTR pszSrc, PTSTR pszDst, DWORD nSize); 

REG_MULTI_SZ is largely misunderstood because of its description in the documentation. The documentation states that a REG_MULTI_SZ value is "an array of zero-terminated strings terminated by two zero characters." I think the documentation should read as follows: "A REG_MULTI_SZ value is stored as a series of zero-terminated strings, with two zero characters terminating the final string in the series." Remember that when you are storing or retrieving data of this type, your buffer size must also include all terminating zero characters as well as the double zero at the end. Figure 5-3 shows an example of a multizero-terminated string registry value consisting of three strings.

click to view at full size.

Figure 5-3. A multizero-terminated string registry value consisting of three strings

The data in the example represents the words "Jason's", "Test", and "MULTI_SZ" as separate individual strings. The buffer required to hold this data would be 23 bytes in length for ANSI and 46 bytes in length for Unicode.



Programming Server-Side Applications for Microsoft Windows 2000
Programming Server-Side Applications for Microsoft Windows 2000 (Microsoft Programming)
ISBN: 0735607532
EAN: 2147483647
Year: 2000
Pages: 126

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net