WinReg v6.2.0 Header-only Stable Release
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:
- Invoke RegGetValue the get the output buffer size
- Allocate a buffer of that size
- 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( ... );
}