{"id":92892,"date":"2016-01-20T07:00:00","date_gmt":"2016-01-20T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=92892"},"modified":"2019-03-13T10:29:09","modified_gmt":"2019-03-13T17:29:09","slug":"20160120-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20160120-00\/?p=92892","title":{"rendered":"So how bad is it that I&#8217;m calling RegOpenKey instead of RegOpenKeyEx?"},"content":{"rendered":"<p>A customer had some code that called the <code>Reg&shy;Open&shy;Key<\/code> function and was concerned by the remark in MSDN: <\/p>\n<blockquote CLASS=\"q\"><p><b>Note<\/b>  This function is provided only for compatibility with 16-bit versions of Windows. Applications should use the <b>RegOpenKeyEx<\/b> function. <\/p><\/blockquote>\n<p>What are the dire consequences of using this old function instead of the new one? <\/p>\n<p>In general, not much. <\/p>\n<p>If you call <code>Reg&shy;Open&shy;Key<\/code>, then some compatibility stuff kicks in, and then it goes ahead and behaves as if you had called <code>Reg&shy;Open&shy;Key&shy;Ex<\/code>. <\/p>\n<p>In the specific case of <code>Reg&shy;Open&shy;Key<\/code>, the compatibility stuff is mentioned in the parameter documentation of <code>Reg&shy;Open&shy;Key<\/code>: <\/p>\n<blockquote CLASS=\"q\"><p><i>lpSubKey<\/i>: If this parameter is <b>NULL<\/b> or a pointer to an empty string, the function returns the same handle that was passed in. <\/p><\/blockquote>\n<p>This is different from <code>Reg&shy;Open&shy;Key&shy;Ex<\/code>, which always returns a new key. It means that if you pass <code>NULL<\/code> as the <code>lpSub&shy;Key<\/code>, then the returned registry key is the same as the one that you passed in, and therefore it does <i>not<\/i> create a new obligation to call <code>Reg&shy;Close&shy;Key<\/code>. In other words, this code has a potential bug: <\/p>\n<pre>\nvoid DoSomething(HKEY hkey, PCSTR subkeyName)\n{\n  HKEY subkey;\n  if (RegOpenKey(hkey, subkeyName, &amp;subkey) == ERROR_SUCCESS) {\n    \/\/ do something\n    RegCloseKey(subkey);\n  }\n}\n<\/pre>\n<p>The bug occurs if <code>subkeyName<\/code> is <code>NULL<\/code> or <code>\"\"<\/code>. In that case, the special <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2008\/01\/17\/7137438.aspx\">16-bit compatibility behavior<\/a> kicks in, and <code>subkey<\/code> is set to a copy of <code>hkey<\/code>. This means that when you do <code>Reg&shy;Close&shy;Key(subkey)<\/code>, you are <i>closing the original <code>hkey<\/code><\/i>, and the caller will probably be rather upset that you closed a key out from under it. <\/p>\n<p>If you know that <code>subkeyName<\/code> is never <code>NULL<\/code> or <code>\"\"<\/code>, then you can safely close the key. Otherwise, you either need to check against this special case or (better) just switch to <code>Reg&shy;Open&shy;Key&shy;Ex<\/code> so you don&#8217;t have to deal with the special case in the first place. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mostly not bad, except for the gotcha.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-92892","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Mostly not bad, except for the gotcha.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/92892","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=92892"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/92892\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=92892"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=92892"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=92892"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}