You may have noticed that if you take a USB device and plug it into your computer, Windows recognizes it and configures it. Then if you unplug it and replug it into a different USB port, Windows gets a bout of amnesia and thinks that it's a completely different device instead of using the settings that applied when you plugged it in last time. Why is that?

The USB device people explained that this happens when the device lacks a USB serial number.

Serial numbers are optional on USB devices. If the device has one, then Windows recognizes the device no matter which USB port you plug it into. But if it doesn't have a serial number, then Windows treats each appearance on a different USB port as if it were a new device.

(I remember that one major manufacturer of USB devices didn't quite understand how serial numbers worked. They gave all of their devices serial numbers, that's great, but they all got the same serial number. Exciting things happened if you plugged two of their devices into a computer at the same time.)

But why does Windows treat it as a different device if it lacks a serial number and shows up on a different port? Why can't it just say, "Oh, there you are, over there on another port."

Because that creates random behavior once you plug in two such devices. Depending on the order in which the devices get enumerated by Plug and Play, the two sets of settings would get assigned seemingly randomly at each boot. Today the settings match up one way, but tomorrow when the devices are enumerated in the other order, the settings are swapped. (You get similarly baffling behavior if you plug in the devices in different order.)

In other words: Things suck because (1) things were already in bad shape—this would not have been a problem if the device had a proper serial number—and (2) once you're in this bad state, the alternative sucks more. The USB stack is just trying to make the best of a bad situation without making it any worse.

The RunAs program demands that you type the password manually.
Why doesn't it accept a password on the command line?

This was a conscious decision.
If it were possible to pass the password on the command line,
people would start embedding passwords into batch files
and logon scripts, which is laughably insecure.

In other words, the feature is missing to remove the temptation
to use the feature insecurely.

If this offends you and you want to be insecure and pass the password
on the command line anyway (for everyone to see in the command window
title bar), you can write your own program that calls
the CreateProcessWithLogonW function.

If you go snooping around, you may find an empty
C:\Program Files\Xerox directory.
What's that for?

This directory is being watched by Windows File Protection,
because it needs to protect the file
xrxflnch.exe should it ever show up.
(Why does the directory have to exist in order for Windows File
Protection to be able to watch it?
I'm told it's a limitation of the Windows File Protection engine.
I suspect it may have something to do with the fact that
the FindFirstChangeNotification function
can't watch a directory that doesn't exist.)

Why is xrxflnch.exe so special?
I don't know.
My guess is that it's some file that is frequently overwritten
by setup programs and therefore needs to be protected.

Some people are offended by the special folders like "My Pictures" and "My Music" and delete them, only to find them being re-created. What's going on?

Windows itself is okay with you deleting those folders. Some corporations, for example, remove those folders from their employees' machines because they don't want the employees looking at pictures and listening to music while on the job. (Go figure.) And if the folder is deleted, Windows doesn't try to bring it back.

Next time you find yourself debugging in assembly language
(which for some of us is the only way we debug),
here are some machine code tricks you may wish to try out:

90

This is the single-byte NOP opcode.
If you want to patch out code and don't want to think about it,
just whack some 90's over it.
To undo it, you have to patch the original code bytes back in,
of course.

CC

This is the single-byte INT 3 opcode, which
breaks into the debugger.

74/75

These are the opcodes for JZ and JNZ. If you want to reverse
the sense of a test, you can swap one for the other.
Other useful pairs are
72/73 (JB/JNB), 76/77 (JBE/JA), 7C/7D (JL/JGE), and 7E/7F (JLE/JG).
You don't have to memorize any of these values;
all you have to recognize is that toggling the bottom bit
reverses the sense of the test.
To undo this, just flip the bit a second time.

EB

This is the unconditional short jump instruction.
If you want to convert a conditional jump to an unconditional
one, change the 74 (say) to EB.
To undo this, you have to remember what the original byte was.

00

On the other hand, if you want to convert a conditional short jump
to a never-taken jump, you can patch the second byte to zero.
For example, "74 1C" becomes "74 00". The jump is still there;
it just jumps to the next instruction and therefore has no effect.
To undo this, you have to remember the original jump offset.

B8/E8

These are the opcodes for the "MOV EAX,immed32" and the "CALL"
instructions. I use them to patch out calls.
If there's a call to a function that I don't like, instead of
wiping it all to 90's, I just change the E8 to a B8.
To undo it, change the B8 back to an E8.

It has been pointed out that this works only for functions
that take zero stack parameters; otherwise,
your stack gets corrupted.
More generally, you can use 83 C4 XX 90 90
(ADD ESP, XX; NOP; NOP) where XX is the number of bytes
you need to pop. Personally, I don't remember the machine
code for these instructions so I tend to rewrite the CALL
instruction so it calls the "RETD" at the end of the function.

I prefer these single-byte patches to wholesale erasure with 90
because they are easier to undo if you realize that you want to
restore the code to the way it was before you messed with it.

This is a little program that takes two parameters,
the first being the verb and the second the file upon which
to execute the verb. Notice that since we exit immediately,
we need to set the SEE_MASK_FLAG_DDEWAIT flag:
Normally, the ShellExecuteEx function assumes that there will
be a message pump running after it returns.
This allows it to return quickly and continue any necessary
DDE conversations as the responses arrive from the DDE server.
But if the thread is exiting or if the thread is not a GUI thread
(both of which are true here), you want to suppress this behavior
because there is no message pump around to complete the DDE
conversation. Setting the SEE_MASK_FLAG_DDEWAIT flag
indicates that the ShellExecuteEx function should finish its
DDE conversation before it returns.

Anyway, I wrote this little program to illustrate two of the
canonical verbs that you can use.
It seems the people don't realize that ShellExecuteEx can be
used to perform these actions, since it gets asked a lot...

I enjoy poking around diploma mills. Especially the ones that spam my inbox. Like Kennedy-Western University, which describes itself like so:

Since 1984 Kennedy-Western University (KWU) has provided distance and online degree programs to over 30,000 students. KWU is one of the largest non-accredited online universities in the United States. ...

Ah, the magic word: "non-accredited". Translation: "Bogus".

But hey, being non-accredited can't be all bad, right? After all, KWU seems to be proud of the fact that it isn't accredited.

Read on:

Three of four of its faculty of 140 credentialed professors - who are simultaneously employed by major traditional universities throughout the country - hold Ph.D. degrees from accredited universities.

Oops, they're undermining their own statement. Isn't it kind of suspicious that they are bragging that their faculty is so good, they got their degrees from real universities (unlike this one)?

Brentwick University claims to be on 196 High Street in northern London. This is what it looks like. On the second floor, over the dry cleaner's, lies Cordon Bell Accomodation Agency, a firm which serves as a maildrop and forwards mail on behalf of a series of camera-shy companies, among them "Brentwick University".

GetKeyState returns the virtual key state.
In other words,
GetKeyState reports the state of the keyboard
based on the messages you have retrieved from your input queue.
This is not the same as the physical keyboard state:

If the user has switched to another program,
then
the GetKeyState function will not see the input
that the user typed into that other program, since that input
was not sent to your input queue.

When should you use GetKeyState and when should
you use GetAsyncKeyState?

For user interface work, you nearly always want
GetKeyState.

If you are responding to an input message and want to know what
keys were pressed at the time that input was generated, then
you want to use GetKeyState.
For example, if you want to distinguish a left-click of the mouse
from an Alt+LeftClick, you must use
GetKeyState to query the state of the Alt key
(known as VK_MENU for historical reasons).
That's because you want to know whether the Alt key was down
when the user clicked the mouse, not whether the key is
down this very instant.
Whether the user released the Alt key between the time
they clicked and the time you processed the message is
irrelevant. You care that the Alt key was down at the time
of the click.

Note that if you are implementing a context menu handler,
then you shouldn't be using either GetKeyState
or GetAsyncKeyState,
because the context menu can be invoked programmatically
without any user action.
For
IContextMenu::QueryContextMenu,
you should test for the CMF_EXTENDEDVERBS flag
to detect whether you should display extended commands
rather than querying the keyboard directly.
Similarly, for
IContextMenu::InvokeCommand,
you should be testing the
CMIC_MASK_CONTROL_DOWN
and
CMIC_MASK_SHIFT_DOWN flags
if you want to alter your behavior based on the shift states.

The simplest version is SendMessage itself,
which sends a message and waits indefinitely for the response.

The next level up is
SendMessageTimeout
which sends a message and waits for the response or until
a certain amount of time has elapsed.
SendMessage is just SendMessageTimeout with an INFINITE timeout.

Another version of SendMessage is
SendNotifyMessage,
which is like SendMessage except that it doesn't wait for
the response. It returns immediately and ignores the result
produced by the receiving window.

The last SendMessage-style functions is
SendMessageCallback.
This sends a message and then returns immediately.
When the recipient finally returns a response, the callback
is called.

SendNotifyMessage is SendMessageCallback with a callback that does nothing.

That's how the four message-sending functions fit together.

Bonus remark:
If you use any of the above send-type functions to send a message
to a window that belongs to the sending thread, the call is made
synchronously.

If I had a nickel each time somebody asked for a feature
that was a security hole...

I'd have a lot of nickels.

For example,
"I want a file that all users can write to.
My program will use it as a common database of goodies."

This is a security hole.
For a start, there's an obvious denial of service attack
by having a user open the file in exclusive mode and never
letting go.
There's also a data tampering attack, where the user
opens the file and write zeros all over it or
merely alter the data in subtle ways.
Your music index suddenly lost all its Britney Spears songs.
(Then again, maybe that's a good thing.
Sneakier would be to edit the index so that when somebody
tries to play a Britney Spears song, they get Madonna instead.)
[Minor typo fixed. 10am]

A colleague from the security team pointed out another problem
with this design: Disk quotas. Whoever created the file is charged
for the disk space consumed by that file,
even if most of the entries in
the file belong to someone else.
If you create the file in your Setup program, then it will most
likely be owned by an administrator. Administrators are exempt
from quotas, which means that everybody can party their data
into the file for free! (Use alternate data streams so you can
store your data there without affecting normal users of the file.)
And if the file is on the system partition (which it probably is),
then users can try to fill up all the available disk space and crash
the system.

If you have a shared resource that you want to let people mess
with, one way to do this is with a service. Users do not access
the resource directly but rather go through the service.
The service decides what the user is allowed
to do with the resource. Maybe some users are permitted only
to increment the "number of times played" counter, while others
are allowed to edit the song titles.
If a user is hogging the resource, the server might refuse connections
for a while from that user.

A file doesn't give you this degree of control over what people
can do with it.
If you grant write permission to a user, then that user can write
to any part of the file.
The user can open the file in exclusive mode and prevent anybody
else from accessing it.
The user can put fake data in the file in an attempt to confuse
the other users on the machine.

In other words, the user can make a change to the system that impacts
how other users can use the system. This sort of "impact other users"
behavior is something that is reserved for administrators.
An unprivileged user should be allowed only to mess up his own life;
he shouldn't be allowed to mess up other users' lives.