{"id":6413,"date":"2012-10-04T07:00:00","date_gmt":"2012-10-04T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2012\/10\/04\/why-does-regopenkey-sometimes-but-not-always-fail-if-i-use-two-backslashes-instead-of-one\/"},"modified":"2012-10-04T07:00:00","modified_gmt":"2012-10-04T07:00:00","slug":"why-does-regopenkey-sometimes-but-not-always-fail-if-i-use-two-backslashes-instead-of-one","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20121004-00\/?p=6413","title":{"rendered":"Why does RegOpenKey sometimes (but not always) fail if I use two backslashes instead of one?"},"content":{"rendered":"<p>\nA customer reported that on Windows&nbsp;XP, they observed that\ntheir program would very rarely get the error\n<code>ERROR_INVALID_ARGUMENT<\/code> when they passed\ntwo backslashes instead of one to the\n<code>Reg&shy;Open&shy;Key&shy;Ex<\/code> function:\n<\/p>\n<pre>\nRegOpenKeyEx(hk, L\"Blah<font COLOR=\"red\">\\\\\\\\<\/font>Oops\", ...);\n<\/pre>\n<p>\nAfter removing C++ escapes, the resulting string passed to\n<code>Reg&shy;Open&shy;Key&shy;Ex<\/code> is\n<\/p>\n<pre>\nBlah<font COLOR=\"red\">\\\\<\/font>Oops\n<\/pre>\n<p>\nThe failure was very sporadic and not reproducible under\ncontrolled conditions.\n<\/p>\n<p>\nWell, first of all, doubled backslashes are not legal in\nregistry key paths in the first place,\nso the first recommendation is <i>stop doubling the backslashes<\/i>.\nOnce you fix that, the problem will go away.\n<\/p>\n<p>\nBut the next question is why the error was detected sometimes\nbut not always.\n<\/p>\n<p>\nWhen an application tries to open a registry key, the registry\ncode first consults a cache of recently-opened keys,\nsince registry accesses exhibit very high locality of reference.\nIf a match is found in the cache, then the cached result is used.\nOtherwise, it&#8217;s a cache miss,\nand the registry tree is searched in the old-fashioned way.\nThe registry tree search rejects the double-backslash since it\ninterprets the path\n<code>Blah\\\\Oops<\/code> as\n&#8220;Look for a subkey called <code>\"Blah\"<\/code>,\nthen a subkey called <code>\"\"<\/code>,\nthen a subkey called <code>\"Oops\"<\/code>.&#8221;\nThe &#8220;subkey called <code>\"\"<\/code>&#8221; step fails\nbecause key cannot have an empty string as their name.\n<\/p>\n<p>\nOn the other hand, the code that checks the cache\nhas a different search algorithm which\nhappens to have the effect of\ncollapsing consecutive\nbackslashes, so the path\n<code>Blah\\\\Oops<\/code> is interpreted as\n&#8220;Look for a subkey called <code>\"Blah\"<\/code>,\nthen a subkey called <code>\"Oops\"<\/code>.&#8221;\n(Note: &#8220;has the effect of&#8221;. There is no explicit\n&#8220;collapse backslashes&#8221; step; it just turns out that the\nway the path is parsed, consecutive backslashes end up\nbeing treated as if they were single backslashes.)\n<\/p>\n<p>\nIn the customer&#8217;s case, therefore, the key in question is\nin the cache most of the time,\nwhich is why the doubled backslash is silently corrected to a\nsingle backslash.\nBut every so often, the key is not in the cache,\nand the old-fashioned search is performed.\nAnd the old-fashioned search rejects the double-backslash\nas an invalid path.\n<\/p>\n<p>\nThe discrepancy in the two parsing algorithms\nwas resolved in Windows Vista,\nso you&#8217;ll see this issue only on Windows&nbsp;XP and earlier.\n<\/p>\n<p>\nBut this historical tidbit does highlight one of the hidden\ngotchas of optimization:\nIf your optimized version\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2012\/08\/31\/10345196.aspx\">\ndiffers from the unoptimized version<\/a>\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/09\/29\/10217910.aspx\">\nin cases that are theoretically anyway illegal<\/a>,\nyou may find yourself chasing elusive bugs\nwhen somebody accidentally stumbles into those cases\nand managed to get away with it&#8230; until now.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A customer reported that on Windows&nbsp;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&shy;Open&shy;Key&shy;Ex function: RegOpenKeyEx(hk, L&#8221;Blah\\\\\\\\Oops&#8221;, &#8230;); After removing C++ escapes, the resulting string passed to Reg&shy;Open&shy;Key&shy;Ex is Blah\\\\Oops The failure was very sporadic and not reproducible under controlled [&hellip;]<\/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-6413","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A customer reported that on Windows&nbsp;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&shy;Open&shy;Key&shy;Ex function: RegOpenKeyEx(hk, L&#8221;Blah\\\\\\\\Oops&#8221;, &#8230;); After removing C++ escapes, the resulting string passed to Reg&shy;Open&shy;Key&shy;Ex is Blah\\\\Oops The failure was very sporadic and not reproducible under controlled [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/6413","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=6413"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/6413\/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=6413"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=6413"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=6413"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}