Holy cow, I wrote a book!
For functions that return data,
the contents of the output buffer if the function fails are typically
If the function fails, callers should assume nothing about the contents.
But that doesn't stop them from assuming it anyway.
I was reminded of this topic after reading
Michael Kaplan's story of one customer who wanted the output buffer
contents to be defined even on failure.
The reason the buffer is left untouched is because many
programs assume that the buffer is unchanged on failure,
even though there is no documentation supporting this behavior.
Here's one example of code I've seen (reconstructed) that relies
on the output buffer being left unchanged:
HKEY hk = hkFallback;
if (hk != hkFallback) RegCloseKey(hk);
This code fragment starts out with a fallback key then tries
to open a "better" key,
assuming that if the open fails,
the contents of the hk variable will be left unchanged
and therefore will continue to have the original fallback value.
This behavior is not guaranteed by the specification for
the RegOpenKeyEx function, but that doesn't stop people
from relying on it anyway.
Here's another example
from actual shipping code.
Observe that the CRegistry::Restore method is documented
as "If the specified key does not exist, the value of 'Value' is unchanged."
(Let's ignore for now that the documentation uses registry
terminology incorrectly; the parameter specified is a value name,
not a key name.)
If you look at what the code actually does,
it loads the buffer with the original value of "Value",
the RegQueryValueEx function twice
and ignores the return value both times!
The real work happens in the CRegistry::RestoreDWORD
At the first call, observe that it initializes
the type variable, then calls
the RegQueryValueEx function and assumes that
it does not modify the
&type parameter on failure.
Next, it calls
the RegQueryValueEx function a second time,
this time assuming that the output buffer
&Value remains unchanged in the event of failure,
because that's what CRegistry::Restore expects.
I don't mean to pick on that code sample.
It was merely a convenient example
of the sorts of abuses that Win32 needs to sustain
on a regular basis for the sake of compatibility.
Because, after all, people buy computers in order to
run programs on them.
One significant exception to the "output buffers are undefined on failure"
rule is output buffers returned by COM interface methods.
COM rules are that output buffers are always initialized, even on failure.
This is necessary to ensure that the marshaller doesn't crash.
For example, the last parameter to the IUnknown::QueryInterface method
must be set to NULL on failure.
A few years ago,
American RadioWorks ran
a story on
the consequences to New Orleans of a Category 5 hurricane
[NPR part 1]
[NPR part 2].
I had been hoping that the city would escape
the worst-case scenario of the water
topping the levees and submerging the city in twenty feet of water,
appear to have taken us one step closer...
As you probably know, I'm fascinated by language,
particularly the slang terms of various professions,
the rich acronym soup of the emergency medical field
(my sick favorite being "CTD").
In the hurricane story, we hear the director of emergency management
use the acronym
which stands for "Kiss your..."
On more than one occasion, I've seen someone ask a question like this:
I have some procedure that generates strings dynamically,
and I want a formula that takes a string and produces a
small unique identifer for that string (a hash code),
such that two identical strings have the same identifier,
and that if two strings are different, then they will have different
I tried String.GetHashCode(), but there were occasional collisions.
Is there a way to generate a hash code that guarantees uniqueness?
If you can restrict the domain of the
strings you're hashing, you can sometimes squeak out uniqueness.
For example, if the domain is a finite set, you can develop
which guarantees no collisions among the domain strings.
In the general case, where you do not know what strings you are
going to be hashing, this is not possible.
Suppose your hash code is a 32-bit value.
This means that there are 232 possible hash values.
But there are more than 232 possible strings.
Therefore, by the pigeonhole principle, there must exist at least
two strings with the same hash code.
One little-known fact about
the pigeonhole principle
is that it has nothing to do with pigeons.
The term "pigeonhole" refers to
a small compartment in a desk
into which items such as papers or letters are distributed.
(Hence the verb "to pigeonhole": To assign a category, often based on
The pigeonhole principle, then, refers to the process of sorting
papers into pigeonholes, and not the nesting habits of
members of the family Columbidae.
Only a Game
recently covered the rise of
tenth birthday party last week,
there was a wide variety of entertainment options,
the highlight of which appeared to be an organized dodgeball tournament.
It was very well attended
and didn't have the ego-damaging overtones
you got from elementary school.
A good time was had by all.
Senior Vice President of MSN
happens also to have been the
development manager of Windows 95,
so he made the generous gesture of inviting the members
of the Windows 95 team to his group's birthday party.
(Since the remaining members of the
Windows 95 team are outnumbered forty-to-one by the current members
of the MSN team, it gave the impression that Windows 95
was merely an after-thought to MSN!
"Ten years ago, MSN 1.0 went live!
And if I recall correctly,
some little operating system rode our coattails.")
Most people probably haven't noticed this,
but there was a change to the requirements for file type handlers
that arrived with Windows XP SP 2:
Paths to programs now must be fully-qualified
if they reside in a directory outside of
the Windows directory and the System directory.
The reason for this is security with a touch of predictability
Security, because one of the places that
the SearchPath function
searches is the current directory,
and it searches the current directory before searching standard
system directories or the PATH.
This means that somebody can attack you by creating a file like
say "Super secret information.txt" and
creating a hidden NOTEPAD.EXE file in the same directory.
The victim says, "Oh wow, look, super secret information, let me
see what it is," and when they double-click it, the trojan
NOTEPAD.EXE is run instead of the one in the Windows directory.
Requiring paths to be fully-qualified
removes the current directory attack.
Predictability, because the contents of the PATH environment variable
can vary from process to process.
Consequently, the relative path could resolve to different programs
depending on who is asking.
This in turn results in having to troubleshoot problems like
"It works when I double-click it from Explorer, but not
if I run it from a batch file."
what program he got
out of the back of a pick-up truck.
Last year, we learned that
the ANSI code page isn't actually ANSI.
Indeed, the OEM code page isn't actually OEM either.
Back in the days of MS-DOS, there was only one code page,
namely, the code page that was provided by the
original equipment manufacturer
in the form of glyphs embedded in the character generator
on the video card.
When Windows came along,
the so-called ANSI code page was introduced
and the name "OEM" was used to refer to the MS-DOS code page.
Michael Kaplan went into more detail earlier this year
on the ANSI/OEM split.
Over the years, Windows has relied less and less on the character
generator embedded in the video card, to the point where the
term "OEM character set" no longer has anything to do with the
original equipment manufacturer.
It is just a convenient term to refer to "the character set used
by MS-DOS and console programs."
Indeed, if you take a machine running US-English Windows
(OEM code page 437) and install,
say, Japanese Windows,
then when you boot into Japanese Windows,
you'll find that you now have
an OEM code page of 932.
Marymoor Park just keeps getting better.
Just this year, they added
a little Subway sandwich shop,
so you don't even have to pack for a picnic in the park.
(sponsored by MSN).
movies in the park
First Tech Credit Union).
The latest addition is
(sponsored by Dasani).
Show a photo ID and you get a cardkey that gives you access
to one-speed coaster-brake bicycles you can borrow for the day.
Late Tuesday night,
Jenny Lam, the creative director for
this year's PDC,
came by our hallway
and asked for permission to rummage through our offices for "stuff".
They were looking for props to use to decorate a developer's cubicle
in a video they were filming for the conference.
I was able to loan her a framed letter of appreciation and my
pass to the Windows 2000 launch.
I used to have a lot more junk in my office, but I went on a cleaning
binge during our last office move and the really cool mementos ended up
at my house.
If you watch the movie and squint you might be able to make out my name
on the personalized items,
but I wouldn't hold my breath.
My stuff will be on screen for probably a quarter of a second,
and I'm guessing it
won't be big enough to read anything of significance.
(Jenny tells me that
one of the things in the cubicle is a forgery. See if you can spot it.)
They were able to get much cooler stuff from
my neighbor's office.
Among other things, he had a chemical model of
the caffeine molecule.
Incidentally, Jenny puts my Martha number at two.
I've met Jenny, and Jenny was personally interviewed by
I just think that's so neat, being two steps away from The Martha.
Not everything related to the Windows 95 launch went well.
The St. Louis Post-Dispatch reported that
a local CompUSA store found that their cash
registers crashed at midnight,
forcing eager customers to wait ninety minutes before the problem
could be resolved.
A bug in the cash register software which had lain undiscovered because
the store had never stayed open past midnight before!
And there was the
the launch of Mindows 95 in Hong Kong.
Not one to sit by and miss out on all the attention,
Apple responded with its
absolutely brilliant counter-advertisement.