So how bad is it that I’m calling RegOpenKey instead of RegOpenKeyEx?


A customer had some code that called the Reg­Open­Key function and was concerned by the remark in MSDN:

Note This function is provided only for compatibility with 16-bit versions of Windows. Applications should use the RegOpenKeyEx function.

What are the dire consequences of using this old function instead of the new one?

In general, not much.

If you call Reg­Open­Key, then some compatibility stuff kicks in, and then it goes ahead and behaves as if you had called Reg­Open­Key­Ex.

In the specific case of Reg­Open­Key, the compatibility stuff is mentioned in the parameter documentation of Reg­Open­Key:

lpSubKey: If this parameter is NULL or a pointer to an empty string, the function returns the same handle that was passed in.

This is different from Reg­Open­Key­Ex, which always returns a new key. It means that if you pass NULL as the lpSub­Key, then the returned registry key is the same as the one that you passed in, and therefore it does not create a new obligation to call Reg­Close­Key. In other words, this code has a potential bug:

void DoSomething(HKEY hkey, PCSTR subkeyName)
{
  HKEY subkey;
  if (RegOpenKey(hkey, subkeyName, &subkey) == ERROR_SUCCESS) {
    // do something
    RegCloseKey(subkey);
  }
}

The bug occurs if subkeyName is NULL or "". In that case, the special 16-bit compatibility behavior kicks in, and subkey is set to a copy of hkey. This means that when you do Reg­Close­Key(subkey), you are closing the original hkey, and the caller will probably be rather upset that you closed a key out from under it.

If you know that subkeyName is never NULL or "", then you can safely close the key. Otherwise, you either need to check against this special case or (better) just switch to Reg­Open­Key­Ex so you don't have to deal with the special case in the first place.

Comments (7)
  1. Ray Koopa says:

    I wonder what the use-case scenario was in 16-bit Windows for the RegOpenKey function to behave like that.

    1. As noted in the linked article, Win16 had a different handle model.

  2. Cesar says:

    For compatibility functions like that, it would be cool if the equivalence with the new function was stated more explicitly, preferentially in source code form. Something like:

    {
    if (lpSubKey == NULL || lpSubKey[0] == ”) {
    *phkResult = hKey;
    return ERROR_SUCCESS;
    }
    return RegOpenKeyEx(…);
    }

    That would make special compatibility cases obvious, and also would show what to pass to the new function if you want it to behave like the old function for the normal cases.

  3. skSdnW says:

    I seem to recall that the Ex version might not always give you a new handle on Win9x. If you want to make your own (working) version of shlwapi!SHRegDuplicateHKey you have to do something special?

  4. Joshua says:

    Link “16-bit compatibility behavior” is a 404. More import trouble?

    1. See yesterday’s article for an explanation and workaround.

  5. MarcK4096 says:

    I bet it wasn’t, but one could have made a case to drop Reg­Open­Key completely from the 64-bit version of Advapi32.dll.

Comments are closed.

Skip to main content