Holy cow, I wrote a book!
Here's an excerpt from a conversation on the subject of Hallowe'en
which I had with my niece some time ago.
Let's call her "Cathy".
a different Cathy from last time.)
"Cathy, what do you do on Hallowe'en?"
"You get all dressed up and people give you candy."
"What do you say when people come to the door?"
Public Service Announcement:
Daylight Saving Time ends in most parts of the United States
Windows 98/98/Me recorded the date and time at which Setup was
run in the registry under
as a binary value named FirstInstallDateTime.
What is the format of this data?
Take the binary value and treat it as a 32-bit little-endian value.
The format of the value is basically
DOS date/time format,
except that the seconds are always 0 or 1 (usually 1),
due to a programming error.
Exercise: What error would result in the seconds always being 0 or 1
Falcon is the first to post the correct answer.]
(Employing the snowclone "What this X needs is more Y.")
Each time you add a parsing pass to the batch processor,
you have to
add another layer of escaping.
This is just a special case of the more general rule of thumb:
any problem in quoting can be solved by adding another layer of escaping.
(Okay, it's not actually true, nor is it a rule of thumb,
but it's still something to keep in mind.)
When you enable delayed variable expansion, you add another parsing
pass to the batch processor.
It used to expand % variables at the time the line is ready,
but now you told it that, oh wait, just before executing the
command, expand it a second time (this time looking for ! variables.)
The ^^ collapses to a ^ during the first
On the second parsing pass, the ^! turns into a !
the batch language was not designed; it evolved.
the approach taken by commenter Nick,
in a tip of the hat to Douglas Adams:
Much like the universe,
if anyone ever does fully come to understand Batch
then the language will instantly be replaced by an
infinitely weirder and more complex version of itself.
This has obviously happened at least once before ;)
Remember, this Web site is
for entertainment purposes only.
Sometimes it takes people
a little while before they realize this:
I apologize for posting the link to the "Old New Thing" blog. [...]
I have read a few articles in the "Old New Thing" blog
and so far I have not seen much that is useful there.
When you view your pictures with
the Photo Gallery program which comes with Windows Vista,
and which is also
available for download from live.com,
you might see a colored tinge.
Where is the tinge coming from, and how do you get rid of it?
what you're actually seeing is the absence of a tinge,
but you got so used to seeing the tinge, your eyes
established the tinge as the new baseline.
Not all display devices show exactly the same color when you ask
them to display a particular RGB.
The Windows Color System
takes into account the color characteristics of output devices
so that these variations can be
taken into account when rendering to those devices.
(Not that you could have figured this out from reading the
which just rambles for two paragraphs of marketing nonsense
without actually saying what it does.)
The goal is to make the color you see on the screen
match the color that comes out on the printer,
and have both match the color the person who created the image
intended you to see.
If you don't want Windows to perform this color correction,
open your Start menu and run the Color Management tool
by typing its name into the Search box, or by hunting for it
inside your Control Panel.
Once you manage to launch it (by whatever means),
go to your display device, check Use my settings for this device
and then remove the color profile.
That was the tip.
Now come da history.
The feature now known as the Windows Color System was introduced
in Windows 95 under the name
Independent Color Management.
This explains why the color profile files have the
But Independent Color Management was not the original name for
The original name was Device-Independent Color,
but the name was changed because the original name resulted in
an unfortunate acronym that was lost on nobody.
When Device-Independent Color was being written,
one of the programmers in the user interface group reviewed
the work in progress and sent an update to the rest
of the team.
"I just looked at David's DIC, and (since I know you're
all going to ask)... it looks good."
Everybody should know by now that
it is not true that pull tabs from aluminum cans can be redeemed
for time on a dialysis machine.
Of course, not everybody actually knows this,
and then the next question is, well,
what happens to all those pull tabs collected by misinformed people?
explains that it depends on where you turn in the tabs.
They might get recycled at the going scrap rate and the proceeds donated to
the National Kidney Foundation or
the Ronald McDonald House.
But I was most fascinated by
this resourceful researcher who played the game of "follow the tabs"
from a State Police office
to a high school
to a hospital
to the Shriners
to a library
to a community college,
where the trail finally runs cold.
I related this story to a friend of mine, who did a double-take.
"Wait a second.
That guy where the trail runs cold?
I know that guy.
I used to work for him!"
That the trail runs cold was hardly surprising to my friend.
Apparently, my friend's former boss was the sort of person who would never
admit that he made a mistake,
no matter how obvious the error.
My friend speculated that when his boss discovered that nobody would
take the aluminum pull tabs,
he certainly wasn't going to admit,
"Oops, sorry everybody."
In order to keep up appearances, he had to keep collecting them,
even though he had nowhere to dispose of them.
And of course,
all the independent pull-tab collectors who couldn't find anybody to
give them to gradually learned about this guy who will take them,
which meant that more and more of them kept coming in.
My friend figured,
"He probably has an enormous pile of aluminum pull tabs just sitting
in his garage."
Some time ago, I ran across the following Freudian typo
in a mail thread discussing plans for the project after
Milestone 3, commonly abbreviated M3.
I'd like to talk with you about your plans for this area after <3.
On the US-English keyboard layout, the M and comma keys are adjacent,
and a shifted comma is a less-than sign.
A simple off-by-one-key typo resulted in M3 turning into
The powercfg utility
has been around for a while,
but in Windows 7, it gained a little bit more awesome.
will analyze your computer's power consumption
and report on things like devices that prevent the computer from sleeping,
devices which won't suspend, and
processes which are increasing your battery drain.
Another neat flag is
which will report on why your computer can't go to sleep,
for example, because it has open files on the network,
or because the clown will eat it.
requests, via the suggestion box,
"an in-depth discussion of the use of the shell's new
Desktop Window Manager (Dwm*) functions in Win32."
The desktop window manager is not actually part of the shell.
It operates at the window manager level.
(Notice that DWM is active even when Explorer isn't running.)
You probably should have posted your suggestion to
Greg Schechter's request for DWM topics which was not too old
at the time you posted your topic suggestion.
But then again,
"Best practices for applications under the DWM"
was on his list of future topics, so it looks like what you wanted
was already on his to-do list.
I don't know whether he followed up on his own to-do list, though.
If not, you can always consult the
Performance Considerations and Best Practices (for using DWM)
topic in MSDN.
A customer reported a crash inside a function we'll call
__in DWORD ConnectionType,
__in PCWSTR Server,
__in PCWSTR Target,
__out void **Handle);
// HACK - Create a dummy structure to pass to the XyzConnect
// function to avoid AV within the function.
int dummy = 0;
if ( NO_ERROR != ( XyzConnect( 0, L"", L"", (PVOID*)&dummy ) )
TRACE( L"XyzConnect failed." );
The title of today's entry gives the answer away.
(The title is also an exaggeration, but it's a pun on
If you have to ask, you can't afford it.)
The last parameter to the XyzConnect function is
declared as a void**: A pointer to a generic pointer.
Note that it is not itself a generic pointer, however.
A generic pointer can point to anything, possibly unaligned.
But this is an aligned pointer to a generic pointer.
Therefore, the memory for the generic pointer must be aligned
in a manner appropriate to its type.
But this caller didn't pass a pointer to a pointer;
the caller passed a pointer to an int,
and an int has different alignment requirements
from a pointer on 64-bit systems.
(You might conclude that this decision was the stupidest decision
on the face of the planet, but that's a different argument for
a different time. For example, I can think of decisions far stupider.)
When the XyzConnect function tries to dereference this
purported void ** pointer,
it encounters an alignment fault, because it does not in fact
point to a void * as the type claims,
but rather points to a DWORD.
A DWORD requires only 32-bit alignment,
so you have a 50% chance that the DWORD*
is not suitably aligned to be a void*.
Mind you, you also have a 100% chance of a buffer overflow,
because a DWORD is only four bytes,
whereas a void* is eight bytes.
The function is going to write eight bytes
into your four-byte buffer.
When this question was posed, one person suggested changing
the DWORD to a __int64,
since the __int64 is an 8-byte value, which is
big enough to hold a pointer on both 32-bit and 64-bit Windows.
Then again, it's overkill on 32-bit systems, since you allocated
eight bytes when you only needed four.
Another suggestion was to use DWORD_PTR,
since that type changes in size to match
the size of a void*.
Well, yeah, but here's another type that matches the size
of a void*: It's called void*.
Just declare void *dummy and get rid of the cast.
And get rid of the comment while you're at it.
If you do it right, you don't need the cast or the hack.
void *handle = 0;
if ( NO_ERROR != ( XyzConnect( 0, L"", L"", &handle ) )
TRACE( L"XyzConnect failed." );
A large number of porting problems can be traced to incorrect casts.
The original author probably
inserted the cast to "shut up the compiler"
but the compiler was trying to tell you something.
Any time you see a function cast or see a cast to/from something
other than void* or BYTE*,
then you should be suspicious,
because there's a chance somebody is simply trying to shut up