Skip to content

WinReg v6.2.0 Header-only Stable Release

Compare
Choose a tag to compare
@GiovanniDicanio GiovanniDicanio released this 22 Feb 20:32
· 2 commits to master since this release
39f1a61

Modified some library implementation code to avoid a potential race condition when reading some data from the Registry.

Detailed Explanation
Before this change, to get values of types like strings, multi-strings or binary data, two successive calls were made to the RegGetValue Windows Registry API. The first call was made to get the destination buffer size; then a buffer of that size was allocated to read the actual data; and, finally, a second call to RegGetValue was made to read the data in the previously allocated buffer.
Schematically:

  1. Invoke RegGetValue the get the output buffer size
  2. Allocate a buffer of that size
  3. Invoke RegGetValue again to read the data from the registry in the above output buffer

The race condition that may happen (but has never happened during my use of the library) is a modification of the registry value between the two calls to RegGetValue, such that the buffer size is not large enough to store the new data. To prevent this situation, a while loop is used instead. For example, in RegKey::GetStringValue, I wrote some new code like this:

  LSTATUS retCode = ERROR_MORE_DATA;
  while (retCode == ERROR_MORE_DATA)
  {
      // Get the size of the result string
      retCode = ::RegGetValueW( ... );

      // Check for error...

      // Allocate a string of proper size
      result.resize(dataSize / sizeof(wchar_t));

      // Call RegGetValue for the second time to read the string's content
      retCode = ::RegGetValueW( ... );
  }