Why does RegOpenKey sometimes (but not always) fail if I use two backslashes instead of one?

Raymond Chen

A customer reported that on Windows XP, they observed that their program would very rarely get the error ERROR_INVALID_ARGUMENT when they passed two backslashes instead of one to the Reg­Open­Key­Ex function:

RegOpenKeyEx(hk, L"Blah\\\\Oops", ...);

After removing C++ escapes, the resulting string passed to Reg­Open­Key­Ex is

Blah\\Oops

The failure was very sporadic and not reproducible under controlled conditions.

Well, first of all, doubled backslashes are not legal in registry key paths in the first place, so the first recommendation is stop doubling the backslashes. Once you fix that, the problem will go away.

But the next question is why the error was detected sometimes but not always.

When an application tries to open a registry key, the registry code first consults a cache of recently-opened keys, since registry accesses exhibit very high locality of reference. If a match is found in the cache, then the cached result is used. Otherwise, it’s a cache miss, and the registry tree is searched in the old-fashioned way. The registry tree search rejects the double-backslash since it interprets the path Blah\\Oops as “Look for a subkey called "Blah", then a subkey called "", then a subkey called "Oops".” The “subkey called ""” step fails because key cannot have an empty string as their name.

On the other hand, the code that checks the cache has a different search algorithm which happens to have the effect of collapsing consecutive backslashes, so the path Blah\\Oops is interpreted as “Look for a subkey called "Blah", then a subkey called "Oops".” (Note: “has the effect of”. There is no explicit “collapse backslashes” step; it just turns out that the way the path is parsed, consecutive backslashes end up being treated as if they were single backslashes.)

In the customer’s case, therefore, the key in question is in the cache most of the time, which is why the doubled backslash is silently corrected to a single backslash. But every so often, the key is not in the cache, and the old-fashioned search is performed. And the old-fashioned search rejects the double-backslash as an invalid path.

The discrepancy in the two parsing algorithms was resolved in Windows Vista, so you’ll see this issue only on Windows XP and earlier.

But this historical tidbit does highlight one of the hidden gotchas of optimization: If your optimized version differs from the unoptimized version in cases that are theoretically anyway illegal, you may find yourself chasing elusive bugs when somebody accidentally stumbles into those cases and managed to get away with it… until now.

0 comments

Discussion is closed.

Feedback usabilla icon