November, 2004

  • The Old New Thing

    Will dragging a file result in a move or a copy?


    Some people are confused by the seemingly random behavior when you drag a file. Do you get a move or a copy?

    And you're right to be confused because it's not obvious until you learn the secret. Mind you, this secret hasn't changed since 1989, but an old secret is still a secret just the same. (Worse: An old secret is a compatibility constraint.)

    • If Ctrl+Shift are held down, then the operation creates a shortcut.
    • If Shift is held down, then the operation is a move.
    • If Ctrl is held down, then the operation is a copy.
    • If no modifiers are held down and the source and destination are on the same drive, then the operation is a move.
    • If no modifiers are held down and the source and destination are on different drives, then the operation is a copy.

    This is one of the few places where the fact that there are things called "drives" makes itself known to the end user in a significant way.

  • The Old New Thing

    Advantages of knowing your x86 machine code


    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:

    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.

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

    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.

    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.

    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.

    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.

  • The Old New Thing

    Why can't you drop directly onto a taskbar button?


    If you drag a object and drop it onto a taskbar button, you get an error message that says,

    You cannot drop an item onto a button on the taskbar.

    However, if you drag the item over a button without releasing the mouse button, the window will open after a moment, allowing you to drop the item inside the window.

    Why doesn't the taskbar let you drop directly onto a taskbar button?

    Ideally, if the taskbar receives a IDropTarget::Drop, it could do something like this:

    // imaginary code
    IDropTarget *pdt;
    if (SUCCEEDED(GetDropTargetFromWindow(hwndButton, &pdt))) {

    (Warning: I said "something like" this. Forwarding a drop is actually more complicated than this.)

    The reason why the taskbar doesn't do this is that there is no such function GetDropTargetFromWindow function. The taskbar can't forward the drop operation even if it wanted to.

    Why is there no GetDropTargetFromWindow function? I have no idea. You'll have to ask the OLE folks. If I had to guess (and I know I have to because you folks will just keep badgering me until I come up with a guess), it's because that would create the problem of how to prevent somebody from screwing with a program by grabbing its drop target and never releasing it.

    Now of course people will criticize my explanation, so I'm going to say it again: I don't know the answer. I'm just guessing. My guess is probably wrong.

  • The Old New Thing

    A sample of desktop icon text effects


    It seems everybody and his brother has an obvious solution to the desktop background problem. Of course, none of these people actually tested their solution to see if it actually was usable. Because geniuses don't need to test their grand pronouncements. That's why they're called geniuses.

    Let's see how well these geniuses fared. I sat down and implemented their brilliant suggestions since I am myself not a genius.

    From left to right, the effects are as follows:

    • Solid background + text. (This is what Windows uses.)
    • Black text, no effects. (As a baseline.)
    • Xor.
    • Simple drop shadow, drawing black at (+1,+1), black at (0,0) then white at (0,0).
    • One-pixel wide outline.
    • Two-pixel wide outline.
    • 50% alpha.

    To my untrained eye, the only readable ones are the first one and the "two-pixel wide outline" (which nobody suggested but which I just made up). The enormously popular Xor is completely useless.

    Of course, all but the first three are expensive operations, requiring multiple drawing passes, so they are unsuitable for the "high performance" drawing scenario that I described in the original article.

    Therefore, the only drawing method that looks good and is also fast is the first one. And it so happens that's what Windows uses when it needs to be fast.

  • The Old New Thing

    Why does Windows not recognize my USB device as the same device if I plug it into a different port?


    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 Old New Thing

    Why doesn't the RunAs program accept a password on the command line?


    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.

    (I'm told that there is a tool available for download which domain administrators might find useful, though it solves a slightly different problem.)

  • The Old New Thing

    The various ways of sending a message


    There are several variations on the SendMessage function, but some are special cases of others.

    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.

  • The Old New Thing

    Why do folders like "My Pictures" come back after I delete them?


    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.

    However, any program can ask for the folder to be re-created. For example, if a program passes the CSIDL_FLAG_CREATE to the SHGetFolderPath function, then Windows will create the specified folder if it doesn't exist. Similarly if it passes pass fCreate = TRUE to the SHGetSpecialFolderPath function.

    If it really troubles you, you can set a creation audit on the My Pictures folder and see which program is re-creating it.

  • The Old New Thing

    What is this Xerox directory doing in Program Files?


    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.

  • The Old New Thing

    Poking at diploma mills: Kennedy-Western University


    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)?

    My personal favorite diploma mill is Harrington University. It's fun kicking off a Google search to see how many people put a degree from that institution on their résumé.

    If you scroll down a bit on this Swedish web page, you'll find a picture of the building that houses so-called Brentwick University. The photo caption reads,

    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".

    It's a somewhat regular scandal in the United States that somebody well-known will be exposed to have been claiming a degree that was obtained by dubious means.

Page 1 of 3 (27 items) 123