{"id":5033,"date":"2013-03-07T07:00:00","date_gmt":"2013-03-07T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2013\/03\/07\/what-are-the-conventions-for-managing-standard-handles\/"},"modified":"2013-03-07T07:00:00","modified_gmt":"2013-03-07T07:00:00","slug":"what-are-the-conventions-for-managing-standard-handles","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130307-00\/?p=5033","title":{"rendered":"What are the conventions for managing standard handles?"},"content":{"rendered":"<p><P>\nConsider this function:\n<\/P>\n<PRE>\nvoid ChangeConsoleColor(WORD wColor)\n{\n HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);\n if (h != INVALID_HANDLE_VALUE) {\n  SetConsoleTextAttribute(h, wColor);\n  CloseHandle(h);\n }\n}\n<\/PRE>\n<P>\n&#8220;When I call this function, it works the first time,\nbut when I call it a second time,\n<CODE>Get&shy;Std&shy;Handle<\/CODE> returns a handle\nnumerically identical to the one returned by the first call,\nbut the handle is now invalid,\npresumably because I closed it.\nI closed it because I was taught to clean up after myself.\nIs this a case where I shouldn&#8217;t?&#8221;\n<\/P>\n<P>\nYes, you should clean up after yourself,\nbut you should also have been taught to\nbe respectful of community property.\nIn this case, you walked into the TV room of your dormitory,\nwatched an episode of <I>Friends<\/I>,\nand then smashed the television with a baseball bat.\nLater, you came back to the room to watch another episode of <I>Friends<\/I>\nand said,\n&#8220;Hey, what happened to our television?&#8221;\n(You can tell I&#8217;m old because I&#8217;m talking about the TV room\nof a dormitory.)\n<\/P>\n<P>\nThe standard handle values are sort of like a global variable\nfor your process.\nAnybody can call\n<CODE>Get&shy;Std&shy;Handle<\/CODE> to read the variable,\nand anybody can call\n<CODE>Set&shy;Std&shy;Handle<\/CODE> to set it.\nBut as with any other global handle variable,\nyou need to observe certain rules to ensure that the\nvalue is always valid.\n<\/P>\n<P>\nSuppose you had a global variable called\n<CODE>HANDLE hSomeFile<\/CODE>.\nWhat invariants would you want to apply?\n<\/P>\n<UL>\n<LI>If the value is\n    <CODE>INVALID_HANDLE_VALUE<\/CODE>,\n    then there is no active file.\n    (You might also have decided to use\n    <CODE>NULL<\/CODE> as your special value,\n    but <CODE>INVALID_HANDLE_VALUE<\/CODE> works better here\n    <A HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/03\/02\/82639.aspx\">\n    because that is the conventional sentinel value for file handles<\/A>.)\n<LI>If the value is not the special value above, then it refers\n    to a valid file handle.\n<\/UL>\n<P>\nThat second invariant above already establishes a rule:\n<\/P>\n<UL>\n<LI>If you close the handle held in the global variable,\n    you must also set the global variable to a new valid value.\n<\/UL>\n<P>\nAs I noted some time ago,\n<A HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2009\/11\/13\/9921676.aspx\">\nprogramming is a game of stepping-stone from one island of consistency\nto another<\/A>.\nYou start with a consistent system,\nyou perturb it (temporarily violating consistency),\nand then you re-establish consistency.\nClosing the handle makes the value invalid,\nso you need to follow up by making the value valid again.\nOtherwise you left your system in an inconsistent state.\n<\/P>\n<P>\nOkay, now instead of talking about that global variable\n<CODE>hSomeFile<\/CODE>,\nlet&#8217;s talk about the global handle hidden behind\n<CODE>Get&shy;Std&shy;Handle<\/CODE> and\n<CODE>Set&shy;Std&shy;Handle<\/CODE>.\nCongratulations, we just established the rules for \nmanaging standard handles.\n<\/P>\n<UL>\n<LI>If <CODE>Get&shy;Std&shy;Handle<\/CODE> returns\n    <CODE>INVALID_HANDLE_VALUE<\/CODE>,\n    then there is no active file.\n<LI>If the value is not the special value above, then it refers\n    to a valid file handle.\n    (Note that file handles can refer to things that aren&#8217;t\n    files. In our case, it often will refer to a console.)\n<LI>If you call <CODE>Close&shy;Handle<\/CODE> on a standard\n    handle, then you must also call\n    <CODE>Set&shy;Std&shy;Handle<\/CODE> to set a new value\n    for the standard handle.\n<\/UL>\n<P>\nNote that these rules are just conventions.\nIf you want to violate them by, say, closing the handle\nand then leaving a garbage handle in the hidden global variable\nfor the next guy to trip over,\nthen that&#8217;s your problem.\nFor example, you might choose to violate the rules temporarily,\nand then fix things up before anybody notices.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Consider this function: void ChangeConsoleColor(WORD wColor) { HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); if (h != INVALID_HANDLE_VALUE) { SetConsoleTextAttribute(h, wColor); CloseHandle(h); } } &#8220;When I call this function, it works the first time, but when I call it a second time, Get&shy;Std&shy;Handle returns a handle numerically identical to the one returned by the first call, but the [&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-5033","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Consider this function: void ChangeConsoleColor(WORD wColor) { HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); if (h != INVALID_HANDLE_VALUE) { SetConsoleTextAttribute(h, wColor); CloseHandle(h); } } &#8220;When I call this function, it works the first time, but when I call it a second time, Get&shy;Std&shy;Handle returns a handle numerically identical to the one returned by the first call, but the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/5033","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=5033"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/5033\/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=5033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=5033"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=5033"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}