February, 2008

  • The Old New Thing

    Bands of Valentine minstrels roaming campus

    • 10 Comments

    One of the minor Valentine's Day traditions at Microsoft is the charity fundraiser based on identifying targets and embarrassing them in front of all their colleagues. In exchange for a charitable donation to the American Heart Association (get it?) an a cappella group will travel to an office or conference room of your designation (conference room is much better, of course) and sing a sappy song to your Valentine. (Singing Valentines are also common on college campuses.)

    This can get tricky when the victim's spouse/boyfriend/girlfriend/whatever you want to call it doesn't work at Microsoft, because said potential prankster (1) needs to know about this tradition in the first place, and (2) needs to know some other Microsoft employee who can arrange the prank on their behalf.

  • The Old New Thing

    Follow-up: Politically motivated armed robber being sent back to the U.S.

    • 4 Comments

    The accused armed robber who is using political asylum as his defense has been re-apprehended and will not fight being returned to the United States. I guess he needs to update the "About Me" section of his blog.

  • The Old New Thing

    Controlling which devices will wake the computer out of sleep

    • 62 Comments

    I haven't experienced this problem, but I know of people who have. They'll put their laptop into suspend or standby mode, and after a few seconds, the laptop will spontaneously wake itself up. Someone gave me this tip that might (might) help you figure out what is wrong.

    Open a command prompt and run the command

    powercfg -devicequery wake_from_any

    This lists all the hardware devices that are capable of waking up the computer from standby. But the operating system typically ignores most of them. To see the ones that are not being ignored, run the command

    powercfg -devicequery wake_armed

    This second list is typically much shorter. On my computer, it listed just the keyboard, the mouse, and the modem. (The modem? I never use that thing!)

    You can disable each of these devices one by one until you find the one that is waking up the computer.

    powercfg -devicedisablewake "device name"

    (How is this different from unchecking Allow this device to wake the computer from the device properties in Device Manager? Beats me.)

    Once you find the one that is causing problems, you can re-enable the others.

    powercfg -deviceenablewake "device name"

    I would start by disabling wake-up for the keyboard and mouse. Maybe the optical mouse is detecting tiny vibrations in your room. Or the device might simply be "chatty", generating activity even though you aren't touching it.

    This may not solve your problem, but at least's something you can try. I've never actually tried it myself, so who knows whether it works.

    Exercise: Count how many disclaimers there are in this article, and predict how many people will ignore them.

  • The Old New Thing

    Thank you, people sitting behind me, for explaining what the conductor is doing

    • 31 Comments

    I didn't get a chance to thank you after the concert, but I did want to express my appreciation for the running commentary you provided during the performance of last week's concert of Debussy, Schönberg and Brahms.

    Most people wait until the break between pieces, some may even dare to exchange information in whispers during the performance, but you were smart. You realized that whispered information is barely audible to anyone more than a seat away, so you spoke in a normal voice, allowing audience members like me to hear your insightful commentary. Here's an example of your astute observational skills:

    Person 1: "The conductor is quite animated."

    Person 2: "That's because the music is loud."

  • The Old New Thing

    If you ask whether I'll be at a conference, the answer is usually No

    • 20 Comments

    It seems that whenever there is a technology conference, there's a decent chance that somebody will ask me via email or a comment whether I'm going.

    The default answer to Are you going to this conference? is No.

    You may find it hard to believe, but going to conferences around the world is not part of my job. My job is to sit in front of a computer and read ema^W^Wwork on code. I'm not a marketing person or a program manager who goes around promoting some feature or service. I'm the person back in Redmond actually implementing it.

    The answer to "Why isn't Raymond at TechEd?" is "Hm, let's see. Spend a few vacation days and a few thousand dollars of my own money on travel, accommodations, and registration for a conference I will derive no benefit from? For some reason, that's not my idea of a fun time."

    In other words, if you want me to attend your conference, you have to invite me. That's what the folks at XV Semana Informática do Instituto Superior Técnico did. I'll be there on March 11th to tell stories about Windows history. I don't have a specific list of stories set up yet, so if you want to suggest something, you can post a comment and I'll see if I can work it in. I've got 90 minutes to fill, so that's going to be a lot of stories. I'm usually game for burning some vacation days if the conference is held somewhere interesting, because I can tack on a little vacation after the conference is over.

    (It also means that this Web site will be on autopilot from March 10th to the 20th because I'll be out of the country and unlikely to log on just to moderate comments.)

    The conference organizers have reassured me that I will not have to give my talk in Portuguese.

    You can save having to foot my travel and lodging expenses if you hold your conference in Seattle. Then again, I'm not actually an invited speaker or anything at TechReady, so I won't be able to get into the conference center. I'm just showing up at tonight's blogger geek dinner offsite.

    Pre-emptive snarky comment: "Blogger" and "geek" are redundant.

  • The Old New Thing

    Why does Ctrl+ScrollLock cancel dialogs?

    • 49 Comments

    Commenter Adam Russell asks why Ctrl+ScrollLock cancels dialogs.

    Easy. Because Ctrl+ScrollLock is the same as Ctrl+Break, and Ctrl+Break cancels dialogs.

    Okay, that answer actually raises two more questions. First, why is Ctrl+ScrollLock the same as Ctrl+Break? This is a consequence of the backward compatibility designed into the Enhanced Keyboard layout which is in widespread use today. If you go back and look at the original PC/XT keyboard layout, you'll see that many of the keys we're familiar with today simply didn't exist back then, and one key (PrtSc) existed in a very different form.

    Let's start with PrtSc. Observe that it was originally a shifted key, atop the asterisk. In the PC/AT keyboard layout, the PrtSc/* key migrated into the numeric keypad, and with the introduction of the enhanced keyboard layout, the two functions PrtSc and multiplication were split into two separate keys. The asterisk stayed with the numeric keypad, while the PrtSc function moved to the top row as a function key (sharing a key with the SysRq key).

    Okay, that's all nice, but what about Ctrl+ScrollLock and Ctrl+Break? Well, in the original PC/XT keyboard layout, there was no Break key. The key sequence for Break was Ctrl+ScrollLock. (And for completeness, the key sequence for Pause was Ctrl+NumLock.) Even though the enhanced keyboard moved the Pause and Break functions to their own key, pressing the Pause key internally generated scan codes that simulated a press of Ctrl+NumLock. In other words, when you pressed Pause, the keyboard hardware actually tells the computer, "The user pressed the Ctrl key and then pressed the NumLock key." Similarly, when you pressed Ctrl+Break, the keyboard hardware tells the computer, "The user pressed the Ctrl key and then pressed the ScrollLock key."

    Therefore, Ctrl+ScrollLock acts like Ctrl+Break because at the hardware level, they are the same thing. That the two functions exist on separate keys is just a fake-out by the keyboard hardware.

    Okay, so now that we understand why Ctrl+ScrollLock is the same as Ctrl+Break, the next question is why Ctrl+Break cancels a dialog box. If you look at the list of virtual key codes in winuser.h, you'll find lots of virtual keys that don't exist on the PC keyboard: VK_CLEAR, function keys VK_F13 through VK_F24, and the long-forgotten VK_PA1. What are all these things?

    In the beginning, Windows and MS-DOS ran on more than just the IBM PC. I know for certain that it also ran on the NEC PC-98, and there were probably other architectures that were either explicitly supported or for which support was planned or reserved. The designers of the original Windows keyboard input driver model wanted to cover all of the likely bases and included support for keys beyond the basic 84-key PC/XT keyboard, keys that could be found on then-popular keyboard layouts such as the VT-100 and even the 3270. I don't know which keyboard had a Cancel key, but presumably one did, or at least the people who designed the input driver model wanted to be prepared for the possibility of one showing up.

    Given that you had a Cancel key, it seemed natural for the dialog manager to support it by treating a press of the Cancel key as the same as clicking the Cancel button on a dialog.

  • The Old New Thing

    Why couldn't you have more than one instance of a 16-bit multi-DS program?

    • 21 Comments

    Recall that the HINSTANCE identified a set of variables. This causes a bit of a problem if your program has multiple data segments; in other words, multiple sets of variables. In such a program, the code would load the data segment of whatever variable it needed each time it needed to access a variable from a different segment.

    This was no problem at all for a DLL, since 16-bit DLLs were single-instance. Go ahead, load your selectors whenever you want. Since there's only one copy of each data segment, you can just use them in your code and let the loader fix them up. No matter which processes calls your DLL, you're still good.

    But if you are doing this in a program, you run into trouble once the user runs a second copy of the program. All you get is an HINSTANCE to pass to MakeProcInstance (or to infer from your stack selector). In other words, you get one set of variables. If your program uses multiple sets of variables, you don't have a way to access those other variables, and the operating system has no way of telling you where they are.

    Now, a sufficiently clever compiler could work around this failure of mathematics. It could store the selectors of the extra data segments into the data segment specified by the HINSTANCE. When the program needed to access a variable from another data segment, it could access them by loading the appropriate selector from the stack segment register (since SS == DS). I don't know whether anybody actually bothered to write a compiler that did this.

    Not that writing one today will win you any accolades since nobody writes 16-bit Windows programs any more. It's one of those things that may have been a neat idea back in its day but today will just get you quizzical looks. Think of it as the computer version of inventing a higher-capacity eight-track cartridge.

  • The Old New Thing

    Grass jelly may be an Asian drink, but it's not crazy

    • 13 Comments

    Chris Pirillo discovered Crazy Asian Drinks, a Web site devoted to the beverage preferences of people from the eastern part of Asia. Now, the text is really funny (which is important), but I would like to come to the defense of grass jelly drink.

    First of all, when I was growing up, grass jelly wasn't a drink. It was a dessert. It came in a block, and you diced it up into pieces about one cubic centimeter in size—not the microscopic flecks that you end up in the beveragicized version. You put a few spoonfuls of it in a bowl and stirred in some sugar water and crushed ice. Of course, you had to crush the ice yourself by hand, because that's the way it was done; it built up the anticipation. (You had to crush it uphill both ways.) When you assembled the dessert, you ate it with a spoon.

    This grass jelly drink is just a pale imitation of the original. It's like if somebody mocked Jell-O gelatin because it was served to them pureed in a shot glass.

    (And Happy New Year, everybody.)

  • The Old New Thing

    What did MakeProcInstance do?

    • 15 Comments

    MakeProcInstance doesn't do anything.

    #define MakeProcInstance(lpProc,hInstance) (lpProc)
    

    What's the point of a macro that doesn't do anything?

    It did something back in 16-bit Windows.

    Recall that in 16-bit Windows, the HINSTANCE was the mechanism for identifying a data segment; i.e., a bunch of memory that represents the set of variables in use by a module. If you had two copies of Notepad running, there was one copy of the code but two sets of variables (one for each copy). It is the second set of variables that establishes the second copy of Notepad.

    When you set up a callback function, such as a window procedure, the callback function needs to know which set of variables it's being called for. For example, if one copy of Notepad calls EnumFonts and passes a callback function, the function needs to know which copy of Notepad it is running in so that it can access the correct set of variables. That's what the MakeProcInstance function was for.

    The parameters to MakeProcInstance are a function pointer and an instance handle. the MakeProcInstance function generated code on the fly which set the data segment register equal to the instance handle and then jumped to the original function pointer. The return value of MakeProcInstance is a pointer to that dynamically-generated code fragment (known as a thunk), and you used that code fragment as the function pointer whenever you needed another function to call you back. That way, when your function was called, its variables were properly set up. When you no longer needed the code fragment, you freed it with the FreeProcInstance function.

    Those who have worked with ATL have seen this sort of code fragment generation already in the CStdCallThunk class. The operation is entirely analogous with MakeProcInstance. You initialize the CStdCallThunk with a function pointer and a this parameter, and it generates code on the fly which converts a static function into a C++ member function by setting the this pointer before calling the function you used to initialize the thunk.

    The creation of these code fragments on 16-bit Windows had to be done by the kernel because the 8086 processor did not have a memory management unit. There was no indirection through a translation table; all addresses were physical. As a result, if the memory manager had to move memory around, it also had to know where all the references to the moved memory were kept so it can update the pointers. If a data segment moved, the kernel had to go fix up all the MakeProcInstance thunks so that they used the new instance handle instead of the old one.

    It was Michael Geary who discovered that all this MakeProcInstance work was unnecessary. If the callback function resided in a DLL, then the function could hard-code its instance handle and just load it at the start of the function; this technique ultimately became known as __loadds. Since DLLs were single-instance, the DLL already knew which set of variables it was supposed to use since there was only one set of DLL variables to begin with! (Of course, the hard-coded value had to be recorded as a fix-up since the instance handle is determined at run time. Plus the kernel needed to know which values to update if the instance handle changed values.) On the other hand, if the callback function resided in an executable, then it could obtain its instance handle from the stack selector; this technique ultimately became known as __export. Each program ran on a single stack (no multi-threading here), and the stack, data segment, and local heap all resided in the same selector by convention. And in a strange bit of coming full circle which I discovered as I wrote up this reminiscence, Michael Geary's copy of the original readme for his FixDS program that brought this technique to the public contains an introduction which links back to me...

  • The Old New Thing

    Otaku cosplay culture makes another inroad into North America

    • 8 Comments

    In the summer of 2006, a Japanese-inspired maid café opened in Toronto. Known as the iMaid Cafe, it offers Chinese food served by young Chinese women in French maid costumes, while Japanese pop music plays in the background. Owner Aaron Wang explains the concept to Canadian television.

Page 3 of 4 (37 items) 1234