10

There is a SafeHandleZeroOrMinusOneIsInvalid class in the .NET Framework, as well as a SafeHandleMinusOneIsInvalid class.

Why is this? In which situations is zero ever a valid handle?

user541686
  • 205,094
  • 128
  • 528
  • 886
  • I would imagine that today zero is never a valid handle; right now I'm looking in Process Explorer on Windows 7 and handle values start at 4 (Image File Execution Options registry key, interestingly). I suspect it is from the time before time where perhaps some ancient Win16 or DOS function that opened a file could return a handle or descriptor with a value of zero. Today, 0 and -1 are special invalid values so I can't imagine you would ever get a valid handle with either value. You could examine which .NET APIs use SafeHandleMinusOneIsInvalid; maybe that will give you some hints. – Luke Oct 10 '11 at 19:07
  • @Luke: Maybe... but even then, why would they have cared at all about Win16/DOS when they were designing SafeHandle in .NET 2.0? – user541686 Oct 10 '11 at 22:20
  • There was probably no direct link, but everything is built on top of everything else so backward compatibility is an important consideration. .NET 2.0 runs on Windows 98, you know; that's kind of impressive when you think about it. – Luke Oct 11 '11 at 00:57
  • I'm more confused by the fact they didn't include a `SafeHandleZeroIsInvalid` – Ray Apr 19 '19 at 23:05

3 Answers3

7

As additional lecture to the other answers, see this OldNewThing blog entry about inconsistent handle return values.

ruvim
  • 7,151
  • 2
  • 27
  • 36
MartinStettner
  • 28,719
  • 15
  • 79
  • 106
  • 2
    You should elaborate, not just past a link. – tenfour Oct 10 '11 at 16:11
  • You're perfectly right. Feel free to edit my answer, if you think anything's missing. In fact I should even have posted that as comment, since it doesn't exactly answer the question. But I would have missed my ten points :D. Also I didn't want to prevent anyone from discovering Raymond's wonderful blog (and I could only have copied text from there, which seemed a waste of time to me) – MartinStettner Oct 10 '11 at 16:29
  • @MartinStettner: That's an admittedly good link, but that doesn't say anything about the .NET wrappers, i.e. why `SafeHandleMinusOneIsInvalid` exists at all. +1 anyway, but I doubt I'll be accepting this. :P – user541686 Oct 10 '11 at 18:36
4

As put forth by Microsoft in their documentation (and demonstrated in description by Joshua,) it is implementation dependant, so to speak:

It describes the format of an invalid handle.

For example, some handles use -1 as an invalid handle value, while others use 0. Further derivations of this class (for example, file or registry handles) can specialize this further. See the SafeFileHandle class for an example of a class that derives from SafeHandleZeroOrMinusOneIsInvalid.

Community
  • 1
  • 1
Grant Thomas
  • 44,454
  • 10
  • 85
  • 129
1

I think you're reading too much into the name: all this means is that some APIs by convention return 0 to indicate failure, others return -1. For an API that returns -1, this doesn't mean that 0 will ever be a valid handle, just that the API returns -1 to indicate failure.

So this is really about the value that is typically used by an API to indicate failure; it doesn't say anything about whether any other handle values are valid or not for any given set of APIs.

BrendanMcK
  • 14,252
  • 45
  • 54
  • OK maybe, but then how come there isn't a `SafeHandleZeroIsInvalid` class? Surely there are a *lot* more APIs that return zero as an invalid value instead of -1? – user541686 Oct 12 '11 at 23:41
  • 1
    The key issue is that the same handle class needs to work with *both* types of API. "Zero *or* Minus One" in this case means *both* are considered to be invalid - not *either/or*. This allows the same base class to be used with the CreateFile API (returns INVALID_HANDLE_VALUE on failure) as with CreateMutex (returns NULL on failure). Why have two separate base classes (which can cause confusion and error if the user picks the wrong one) when one can handle both cases? – BrendanMcK Oct 13 '11 at 16:53