The
computer I bought not a year and a half ago
decided to keel over last week.
When I push the power button, the power light goes on,
the drives spin up, but there is nothing out the video card
and not even a reassuring beep from the power-on self test.
I've disconnected all the external peripherals as well as all the
IDE devices, and no change.
The problem might be a fried motherboard connection or something.
I'm not a hardware person, so I'm not sure how to diagnose it.

This is easily the shortest life for a computer I've owned
(not counting the ones that were dead on arrival).
I feel kind of bad buying a replacement for a computer that's
barely fifteen months old,
but I also can't think of what else I can do.
All the stuff I can easily swap out I think I've already swapped out.
And I don't know if I can find a new power supply or motherboard
that fits the custom case.

So it's back down to Fry's to buy some random bottom-feeder computer
just so I can whack my hard drives into it and get back in business.
But man, is that machine going to inherit a lot of memory!

Shell policies control how Explorer and other shell components behave,
but that's just blocking the front door.
For example, there is a shell policy to prevent the user from changing
the wallpaper from the Desktop control panel.
This disables the controls on the Desktop control panel for changing
the wallpaper, but there are ways to change the wallpaper other than that.
If users can run an arbitrary program, then they can run a program
that calls
SystemParametersInfo(SPI_SETDESKWALLPAPER) to change
the wallpaper directly, bypassing the shell.
The purpose of the shell policies is merely to make it more difficult
for users to perform various categories of operations by removing
them from the shell interface.
But, of course, if the users are allowed to write their own program
with its own user interface,
then they can still access the underlying functionality.

Setting a policy to remove the user interface for a feature is
like removing the staircase that leads to the second floor to
keep people out.
If you let them bring a ladder, then they can still get up there.

Mark Russinovich points out that policies are enforced at the
application level, and since applications run as the user,
the user can run a program that commandeers the application and
patches out the code that checks the policy setting.

Shell policies are just for modifying the user interface.
If you want to block an operation even from users who bypass the
normal user interface,
you have to block it at a level below the user interface.
For example,
you might revoke write permission to the relevant registry key;
that way, even if the user manages to run their own code on the
machine, they still can't change the underlying setting.

Every so often, somebody who doesn't understand the difference
between shell policy and security submits a security vulnerability
report to MSRC saying, "Check this out, I can set the policy to
prevent the user from changing the desktop wallpaper via the shell,
but through this clever technique of injecting code into
Explorer and patching the binary in memory,
I can change the desktop anyway!"
Well yeah, but why go to all that effort?
Just write a program that changes the desktop wallpaper already.

Even without a nitpicker's corner, I have to worry about nitpickers.
I just have to do it in a more subtle way.

Here are some examples of changes I've made to upcoming entries
in order to forestall nitpicking:

Original text

Revised text

Reason

... entries in our list...

... entries in our table...

The entries are kept in an array, but writing "list" may cause
some people to nitpick that an array is not a list.

... this function returns X...

... this function can be asked to return X...

The function returns different things based on what the caller
requests, but the only case we're interested in right now
is the case of X.

... X affects only Y.

... X typically affects only Y.

Again, I have to add the qualifier to protect against the case
where a program intentionally broadens the scope of X.

... X isn't a problem because...

... X isn't usually a problem because...

There can be cases where X is a problem because the program
explicitly created the problem for itself,
so I have to put in a qualifier.
Indeed, later in the article I give an example of how a program
can cause this problem, so I'd better leave myself some wiggle
room at the expense of rhetorical power.

... a holiday....

... a holiday
in the United States...

Otherwise somebody would make some smart-alec remark like
"It's not a holiday where I live."
[Typo fixed: 10am]

What's scary is that I've noticed that I begun pre-emptively
nitpicking my own entries while I'm writing them.
In the balance between writing something that reads more naturally
and something that is more resiliant to nitpicking,
I've unfortunately started preferring the latter.

Observant readers may have noticed that I've slowly introduced
a section called
"Pre-emptive snarky comment" wherein I try to anticipate
drive-by "Hey wouldn't it be hilarious if I
ridiculed Microsoft on a Microsoft employee's blog?" comments.
It seems to be largely successful,
although sometimes people will post the identical snarky comment
that I pre-empted.
These are probably the people who talk just to enjoy the sound of their
own voice.

An extension of this is the "Now that you brought up something that sucks,
I'm going to tell you that it sucks" phenomenon.
This is pretty much guaranteed whenever I bring up anything that
is related to UAC and security,
since it appears that everybody agrees that UAC sucks,
so any blog entry that talks about elevation
invariably leads to comments about
how UAC
sucks.
There are also popular tangents, such as any article that mentions
installing software turning into a
"post your complaints about setup here" thread.

(That article about how people fail to process information that they see
was indeed an unmitigated disaster.
Everybody got into arguing over how the message should have been presented
so the user would be more likely to see it,
but that completely misses the point.
The user positively confirmed, "I see the yellow warning."
The problem wasn't that the user didn't see the message;
the response confirmed that the user saw the message just fine.
What the user didn't do was process the information.
It's my fault for choosing a bad title.
Instead of "People can't see things that are right in front of them,"
I should have titled it "People see things but don't pay attention to them,"
opting for precision even though it meant I couldn't use the idiomatic
phrase can't see what's right in front of you.
What made it worse is that I fell for the trap.
I responded to the details instead of saying,
"Whether your suggestion would have helped the user see the message or not
is totally irrelevant to the point of the article.")

I also hadn't predicted that my discussion of
how reasonable people can disagree about how a setting should be exposed
would turn into a discussion of how to shut down your computer,
turning a footnote into the primary topic of discussion.
But that's a fairly common occurrence:
People focus on a side detail (which I added for color)
and ignore the point of the story.
Sometimes I think I'd be better off if I didn't give examples.
That way nobody could be distracted by them.

In the beginning, there was one control library,
namely USER,
the window manager itself,
which provided buttons, static controls, edit controls,
scroll bars, list boxes, and combo boxes.
These controls were under the purview of the window manager team.

In Windows 3.1
a second control library known as the shell common controls was added,
but the library really didn't come into it own until Windows 95,
where it consisted
of the list view, header, tree view, tooltip,
toolbar, status bar, track bar, tab, updown, progress, hotkey,
and animation controls.
These controls were originally custom controls
written by the shell team for use in Explorer,
but since they seemed to be generally useful,
time was budged to do the
extra work to make the controls more suitable for general use,
testing the controls in combinations and scenarios
that Explorer itself didn't use,
and putting together formal documentation.

The shell common controls library underwent many changes over
the years, whereas the core intrinsic controls in the window manager
changed much more conservatively.

With Windows XP, the visual design team wanted to give the
look of Windows a new life.
Changing the non-client area (such as the window frame) was comparatively
straightforward, since programs didn't have much
control over that part of the window anyway.
As a result, they get the Windows XP look "for free".

The client area is another story.
Programs are in control of their client area,
where they can place controls that come with Windows,
their own custom controls,
or controls obtained from a third party library.
Making major changes to the core controls or the common controls
would be a high-risk endeavor
since there are thousands upon thousands of Windows program that
not only use them,
but use them in all sorts of crazy ways.

The initial stab at resolving these two conflicting goals
(making major changes to these controls to increase visual appeal
and functionality
while simultaneously not changing them to maintain compatibility)
was to create a new DLL that would contain the "fancy new version"
of the core controls as well as the shell common controls.
The old DLLs USER32 and COMCTL32 stayed
where they were, so that old programs continued to get the behavior
they were expecting,
and the new XP-style controls were placed in a DLL named
UXCTRL.DLL.
UX stands for user experience,
which was the hot new buzzword at the time.
To avoid name collision with the old style controls,
the new controls got new names beginning with Ux.
For example, the UXCTRL version of the button control
was called UxButton.

New features could be added to these new Ux controls with wild abandon
without heed for backward compatibility since they were brand new controls.
There was nothing they had to be compatible with.
Explorer was changed to use these new controls instead of the old stodgy
controls,
and everything worked great.

Or so it seemed.

We thought we had cleverly sidestepped the backward compatibility problem
by creating entirely new controls,
but doing that created a whole new category of compatibility bugs.
Even though it's completely undocumented and unsupported,
programs like to
grovel into the internal data structures of other programs
or otherwise
manipulate those programs' windows.
In Explorer's case, it turns out that a lot of programs like to
go spelunking around Explorer's window hierarchy and use functions
like FindWindow and
EnumChildWindows
to find the object of their affections.
For example, a program might use EnumChildWindows to
enumerate all the child windows of an Explorer browser,
and then use GetClassName
and lstrcmpi(szClassName, TEXT("button"))
to look for a specific control.
In this example, the target was a button,
but it could have been a list view or a tool bar.
Since all the new XP-style controls were named
things like UxButton and UxListView,
these programs which looked for a button by comparing against
the string "button" stopped working.

Of course, there was no guarantee that Explorer would even use
buttons at all;
Explorer was completely within its rights to revamp its user interface.
But that's not much consolation to the customers who paid good money
for these programs,
especially since magazine columnists are the types of people most
likely to be running (or indeed even writing!)
strange off-the-wall programs that pull these
sorts of nasty stunts in the first place.

Okay, so it is now a compatibility requirement that all the new window
classes have the same names as their old counterparts.
This created an impasse, since these controls needed to be created
by dialog boxes, and therefore they had to be globally-registered
window classes.
But you can't have two global window classes with the same name,
because that would create ambiguity over which one the caller was
asking for.

More brainstorming ensued, and a Plan C emerged.
The common controls library would take advantage of
side-by-side assemblies
and use the application manifest to control which
DLL a given window class name would resolve to.
Thus was born a new DLL also called COMCTL32,
but with a new version number—version 6.
Old programs would get version 5.82 just like they did
in Windows 2000.
New programs would have to use a manifest to specify that they wanted
version 6.

Once again, the solution came with a new problem.
Since the entire COMCTL32 library got split
into two versions,
this meant that there were two versions of the image list code.
Whole new scenarios emerged, such as
putting a version 5 image list in a
version 6 tree view, or vice versa.
(As the linked thread notes illustrates, not all of the problems with
cross-version scenarios were caught in the initial release and had
to wait for a service pack for the fix to become available.)

Some time a few years ago, some folks on the security team were
swapping crackpots stories, and this one somehow lodged in my mind.
The story below is paraphrased, but the essense remains intact.

"We had a crazy guy call into the security support line many years ago.
He was going through a messy divorce and was convinced that his wife's
lawyers were hacking into his computer in order to frame him,
thereby gaining the upper hand during divorce proceedings.
He wanted to know how to protect his computer against them.
We played along and told him to keep the computer unplugged from
the Internet, and he laughed a triumphant laugh and
said condescendingly,
'They're coming in through the power lines, man!
Don't you know anything?'
Now, yeah, today we do have Internet access over the power
lines, but still, that guy was crazy!"

The annual
Miss America Pageant
struggles for survival tomorrow.
And what makes it different from Donald Trump's
Miss USA and
Miss Universe is the talent competition.
(Yes,
Miss World also has a talent competition,
but nobody in the United States
pays any attention to Miss World,
probably because of the aforementioned Donald Trump.)

It's not that I go out of my way to watch these pageants,
but if it's convenient, a bunch of us will get together to enjoy
the festivities.
During the opening parade of the Miss Universe pageant,
we scream in horror at the hideous national costumes or the unflattering
evening gowns.
During the swimsuit Lifestyle and Fitness competition
(Whom do they think they're kidding?)
the women play the game
"Real or
Fake?"
(I recuse myself from that game citing lack of expertise.)
But my favorite part is always the talent competition.

The talents are mostly musical, primarily singing, with a decent amount
of instrumental performance—I enjoy these,
particularly the instrumental ones, since I actually know something
about the subject.
The ones that aren't musical are dancing—I'm not particularly
knowledgeable about dance and usually don't know what to make of the
performance.
Extremely rarely you'll encounter a dramatic reading
(which to me feels like a cheat).
As accomplished as the contestants are, these talents all feel kind
of "squishy".
(Indeed, back in the Regency era,
the term
accomplished
was used to refer to proficiency at these sorts of talents,
and it was an open secret
that the reason for developing these skills was simply to secure
a husband.)
But where are the real talents?

If only we had contestants demonstrating other talents like
consensus building,
project management,
electronics repair,
chicken plucking, or
suitcase packing.

In Windows 95,
the Find option took its place on the Start menu
between Settings and Help.
In Windows 2000, the option was still there,
but its name changed to Search,
a name which persist today if you use the classic Start menu.

When the menu option changed its name, the keyboard accelerator
changed accordingly.
Whereas Find used F as its accelerator,
Search uses C.
Here's a secret:
The classic Start menu still responds to F as the keyboard
accelerator for Search.
The work to make this happen was undertaken as a concession to
people who imprinted on the old Start menu and whose "muscle memory"
still wants to press F to open what used to be the Find menu.

The totally redesigned Start menu for Windows XP
changed the keyboard model radically,
but if you're still attached to your muscle memory,
you can switch to the classic Start menu and keep using
all the old keyboard shortcuts from Windows versions past.

Saying "Somebody should do X" is easy,
but without some sort of suggestion as to how that could be accomplished,
the suggestion rarely gets off the drawing board.
It's like saying
"Somebody should solve world hunger."

Let's look at that first example again.
The topic at hand was window procedures which fail to pass unhandled messages
to the DefWindowProc function.
How would one "test for this"?
Would the test walk through every code path in the program that
creates a window, and then send each of those windows a fake
WM_QUERYENDSESSION or a fake
WM_APPCOMMAND message to see what happens?
First of all, it's unclear how a test could exercise all the window-creation
code paths of a program without insider knowledge of that program.
Therefore, this test would have to be written by the authors of
the program.

Next, even if you sent the message and saw that the message
was passed to the DefWindowProc function,
that wouldn't actually prove that the message was handled
properly.
Maybe the window procedure for a window goes something like this:

Even if you managed to get this window created,
if you send it a fake WM_QUERYENDSESSION,
you'll catch the issue only half the time.
It's not enough just to exercise every window procedure;
you also have to exercise every code path.

But wait, there's more.
What if the program really wanted to prevent the user from logging off?

In this case, there is a code path that cancels the logoff,
and it is legitimate, since it was done as the result of
a user decision.
Your test would somehow have to know this and consider
that case to be a pass and not a failure.
This sort of reasoning is hardly something that a generic
test suite can do; it has to be tailored for each program.

It's one thing to say that something should be tested,
but without an idea as to how it should be tested,
the suggestion is much less valuable.
I may as well say,
"Programs should have to pass a test that verifies that there
are no bugs."