{"id":21073,"date":"2008-08-27T10:00:00","date_gmt":"2008-08-27T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2008\/08\/27\/what-possible-use-are-those-extra-bits-in-kernel-handles-part-1-sentinels\/"},"modified":"2008-08-27T10:00:00","modified_gmt":"2008-08-27T10:00:00","slug":"what-possible-use-are-those-extra-bits-in-kernel-handles-part-1-sentinels","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080827-00\/?p=21073","title":{"rendered":"What possible use are those extra bits in kernel handles? Part 1: Sentinels"},"content":{"rendered":"<p><P>\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2005\/01\/21\/358109.aspx\">\nKernel handles are always a multiple of four<\/A>;\nthe bottom two bits are available for applications to use.\nBut why would an application need those bits anyway?\n<\/P>\n<P>\nThe short answer is <I>extending the handle namespace<\/I>.\nThe long answer will take a few days to play out.\n(This series was written in response to\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2008\/02\/28\/7925962.aspx#7939157\">\nIgor Levicki being unable to imagine &#8220;how this can save anything\n(in terms of performance)&#8221;<\/A>.\nThen again, who said that it had anything to do with performance?\nActually, I&#8217;m surprised that my dear readers weren&#8217;t familiar\nwith the techniques described in this series.\nPerhaps I shouldn&#8217;t have written this series and merely replied,\n&#8220;If you can&#8217;t think of how this could be useful, then you are not\nmy target audience.&#8221;\nOn the other hand, reader Aaargh! believes that\nwhoever thought to make the bottom two bits of handles available to\napplications\n<A HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2008\/06\/06\/8576557.aspx#8578571\">\nshould receive an asswhooping<\/A>.)\n<\/P>\n<P>\nBut we&#8217;ll start with a warm-up.\nIf you need some sentinel values for a <CODE>HANDLE<\/CODE>,\nyou need to make sure your chosen sentinel value will never\nconflict with a valid <CODE>HANDLE<\/CODE> value.\nIf you decide that your sentinel value is something like\n<\/P>\n<PRE>\n<I>\/\/ code in italics is wrong\n#define DEBUGWINDOW_HANDLE ((HANDLE)0x1234)<\/I>\n<\/PRE>\n<P>\nthen your program is going to start acting really strange\nif the kernel ever gave you handle value of 0x1234.\nKnowing that kernel handles are always multiples of four\nmeans that you can choose a value that <I>isn&#8217;t<\/I>\na multiple of four and use it as your sentinel value.\n<PRE>\n#define DEBUGWINDOW_HANDLE ((HANDLE)0x1233)\n<\/PRE>\n<P>\nSince 0x1233 is not a multiple of four, you can rest assured\nthat no actual kernel handle will have this value,\nand you can write your logging function like this:\n<\/P>\n<PRE>\nvoid LogOutput(HANDLE hOutput, LPCVOID pv, DWORD cb)\n{\n if (hOutput == NULL) {\n   \/\/ logging disabled\n } else if (hOutput == DEBUGWINDOW_HANDLE) {\n  AddToDebugWindow(pv, cb);\n } else {\n  DWORD cbWritten;\n  WriteFile(hOutput, pv, cb, NULL, &amp;cbWritten);\n }\n}\n<\/PRE>\n<P>\nSince you can&#8217;t <CODE>WriteFile<\/CODE> to a window handle,\nyour logging function has to do something special if somebody\ndecided that their output should go to the debug window.\nBut if they chose to log to a normal kernel object (a file,\nthe console, a serial port, whatever) then you can just write\nthe data to that kernel object.\n<\/PRE>\n<P>\nYou&#8217;ve already seen this before; you just didn&#8217;t realize it.\nThe special values for <CODE>INVALID_HANDLE_VALUE<\/CODE> and\nkernel pseudo-handles \n<A HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/dllproc\/base\/getcurrentprocess.asp\">\nsuch as <CODE>GetCurrentProcess<\/CODE><\/A>\nare not multiples of four for exactly this reason.\n<\/P>\n<P>\nNow, sure, you could have defined your own <CODE>LogHandle<\/CODE>\ntype and have all the logging go through that type instead of just\nlogging to <CODE>HANDLE<\/CODE>s:\n<\/P>\n<PRE>\nclass LogHandle {\npublic:\n  static LogHandle *GetDebugLogHandle();\n  BOOL IsDebugWindow();\n  HANDLE GetKernelHandle();\n  static LogHandle *CreateFromKernelHandle(HANDLE KernelHandle);\n  ~LogHandle() { }<\/p>\n<p>private:\n  LogHandle(BOOL IsDebugWindow, HANDLE KernelHandle);\n  static LogHandle DebugWindow;<\/p>\n<p>  BOOL IsLogToDebugWindow;\n  HANDLE RegularKernelHandle;\n};\n<\/PRE>\n<P>\nThroughout, your program would use pointers to\n<CODE>LogHandle<\/CODE>s instead of actual handles,\nusing functions like these to convert between them:\n<\/P>\n<PRE>\n\/\/ Does not take ownership of the handle\nLogHandle::LogHandle(BOOL IsDebugWindow, HANDLE KernelHandle)\n    : IsLogToDebugWindow(IsDebugWindow)\n    , RegularKernelHandle(KernelHandle)\n{\n}<\/p>\n<p>LogHandle LogHandle::DebugWindow(TRUE, NULL);<\/p>\n<p>LogHandle* LogHandle::GetDebugWindowLogHandle()\n{\n  return &amp;DebugWindow;\n}<\/p>\n<p>BOOL LogHandle::IsDebugWindow()\n{\n  return IsLogToDebugWindow;\n}<\/p>\n<p>HANDLE LogHandle::GetKernelHandle()\n{\n  assert(!IsDebugWindow());\n  return RegularKernelHandle;\n}<\/p>\n<p>LogHandle *LogHandle::CreateFromKernelHandle(HANDLE KernelHandle)\n{\n  return new LogHandle(FALSE, KernelHandle);\n}\n<\/PRE>\n<P>\nOr you could make everybody pass two parameters instead of one.\nFor example, a class that went\n<\/P>\n<PRE>\nclass SomeObject {\npublic:\n  SomeObject(int SomeParameter, BOOL SomeParameter,\n             HANDLE LogHandle);\n&#8230;\nprivate:\n  &#8230;\n  HANDLE LogHandle; \/\/ log to this handle\n};\n<\/PRE>\n<P>\nwould have to change to\n<\/P>\n<PRE>\nclass SomeObject {\npublic:\n  SomeObject(int SomeParameter, BOOL SomeParameter,\n             BOOL LogToDebugWindow, HANDLE LogHandle);\n&#8230;\nprivate:\n  &#8230;\n  BOOL LogToDebugWindow; \/\/ if TRUE, log to window\n  HANDLE LogHandle; \/\/ if not logging to window, then log to here\n};\n<\/PRE>\n<P>\nEither way is an awful lot of work just to define a sentinel value.\nBut still, at least you can avoid the need for a sentinel value\nby just passing more parameters.\nBut sometimes that option isn&#8217;t available.\nWe&#8217;ll look at that next time.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Kernel handles are always a multiple of four; the bottom two bits are available for applications to use. But why would an application need those bits anyway? The short answer is extending the handle namespace. The long answer will take a few days to play out. (This series was written in response to Igor Levicki [&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-21073","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Kernel handles are always a multiple of four; the bottom two bits are available for applications to use. But why would an application need those bits anyway? The short answer is extending the handle namespace. The long answer will take a few days to play out. (This series was written in response to Igor Levicki [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21073","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=21073"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21073\/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=21073"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=21073"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=21073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}