December, 2009

  • The Old New Thing

    2009 year-end link clearance


    Time for the semi-annual link clearance.

    And, as always, the obligatory plug for my column in TechNet Magazine:

  • The Old New Thing

    Why does COM require output pointers to be initialized even on failure?


    One of the rules of COM is that if a parameter is marked as an output pointer, then you have to initialize the thing it points to, even if your function failed and you have nothing to return. For example, we saw the problems that can occur if you forget to set the output pointer to NULL in the IUnknown::QueryInterface method. Why does COM have this rule? Doesn't it know that a failure is a failure?

    Because there are failures and there are sort-of failures.

    A function can return an error code despite having partially succeeded. For example, if a function receives a buffer that is too small to hold all the data that is available, it might fill the buffer as much as possible, and then return an error like ERROR_MORE_DATA to say, "Hey, I gave you what I could, but there's more out there." The COM enumerator pattern specifies that if the caller asks for more items than there are remaining in the enumeration, then the IEnumXXX::Next method should return as many items as it can and return S_FALSE.

    The COM library itself doesn't know the details and semantics of every method and interface. It doesn't know that your IFlipper::Frob method has a special return value of E_PENDING which means "I started the operation and here is a provisional result, but the final result will come later."

    Why does COM even care about your method calls anyway? After all, isn't a COM method just a C++ virtual function? I'm just calling a function in some other part of my program; why does COM get involved?

    COM indeed doesn't get involved, except when it needs to, such as when the object is being marshalled between apartments or processes. In those cases, a COM method call does not go directly to the C++ virtual method of the target object but rather goes through a proxy which packages up the input parameters and ships them to the final destination, a process known as marshalling. On the other side, a receiver proxy unpacks the parameters (unmarshals) and calls the destination object. When the destination object completes executing the method, the process repeats but this time with the output parameters: The output parameters are packaged up and sent back to the calling thread, where they are unpackaged and returned to the original caller. (Parameters which are in/out end up being marshalled in both directions.)

    The code that does the marshalling and unmarshalling doesn't know any special behaviors of your method. It doesn't know that when the method returns E_PENDING then the first and third output parameters contain values that should be returned to the caller, but the second does not. It just packages up all the output parameters and sends them back.

    A related scenario is the method where one input parameter controls whether another input parameter is ignored. In those cases, you still can't pass garbage as the second input parameter even though it is ignored, because the COM marshaller doesn't know the special semantics of the first parameter with respect to the interpretation of the second.

    Now, you might say, "Well, I know that I'm not using any of the cases where the COM marshaller gets involved, so I'm going to break these rules because there is nobody around to enforce them!"

    Except that you yourself are relying on this behavior; you just don't realize it. More about that next time.

  • The Old New Thing

    Join the Seattle Symphony for a New Year Eve's performance of Beethoven's Nin... wait a second...


    One of the regular events of the Seattle Symphony season is a New Year's Eve late night performance of Beethoven's Ninth Symphony followed by a post-concert party to ring in the new year. Last year I received an advertisement in the mail promoting that year's concert, and one page of the brochure contained the message {Ring in the New Year} printed atop a photo of an impressive array of musical forces crammed onto the Benaroya Hall stage.

    But if you look closely at the instruments being played and the composition of the chorus, you quickly realize that they aren't performing Beethoven's Ninth Symphony. Beethoven's Ninth Symphony does not call for eight vocal soloists, a harp, a piano, a mandolin, a celesta, or an organ. Nope, the photo is from a performance of Mahler's Eighth Symphony.

    But hey, it looks more impressive in the photo. Nobody will notice.

  • The Old New Thing

    Even your folder icons can be used as a Rorschach test


    Jenny Lam (now at Jackson Fish Market) forwarded me this picture of a USB thumb drive. She also reminded me of another one of those Windows as Rorschach test incidents that surrounded the Windows Vista folder icons.

    It was reported during one of the betas that the 16×16 folder icon looked like someone flipping the bird. Sure, this interpretation required some creativity, and it perhaps reflects more on the person making the observation than on the folder icon itself, but the report still had to be taken seriously, because one thing you don't want is a newspaper headline saying that your product uses crudely offensive imagery. And yes, we went back and changed the icon to avoid the problem.

    Now, if you take that Folderix flash drive and tilt your head to the right about 60°, you can turn it into somebody giving you the finger with their right hand: The folder tab is the thumb, the folder body is the back of the hand, and the USB connector is the extended middle finger.

    Who knows, maybe that was intentional after all.

  • The Old New Thing

    How do I minimize a group of windows in Windows 7 from the taskbar?


    The Windows 7 taskbar automatically groups similar windows, and when you right-click on the grouped icon, you may get fancy stuff like a jump list or a task list, but you will also get a very small repertoire of window management options. In particular, the only option that operates on the group is Close all windows. What about the other group options?

    To get a list of more group window options, hold the shift key when you right-click on the grouped icon. Then you'll get more options like Cascade and Minimize all windows.

    Since the contents of the regular right-click pop-up window are dynamic, when you hit "C" for Close all windows, it still waits for you to confirm by hitting Enter. On the other hand, the shift+right-click menu auto-executes Close all windows when you hit the "C" hotkey. Doesn't save you any more keystrokes (trading an Enter for a shift key), but you do get predictability since the shift+right-click menu is pretty stable.

    Bonus tip: To get the System menu for a window, you can right-click on its pop-up thumbnail.

  • The Old New Thing

    How does the keyboard autorepeat setting work?


    Commenter eric johnson wonders how that control panel keyboard autorepeat setting works.

    This is one of those questions that has many answers, depending on how deep you want to dig.

    The first layer of the question is how the control panel changes the keyboard autorepeat rate. That's simple: It uses SystemParametersInfo(SPI_SETKEYBOARDSPEED). From the documentation, you can see that the keyboard speed is an integer in the range 0..31, where 0 indicates 2 characters per second and 31 indicates approximately 30 characters per second.

    The next layer of the question is why the SystemParametersInfo expresses the keyboard autorepeat setting in a 0..31 range, and why the upper end of the range is 30 characters per second. Well, the SystemParametersInfo function is merely passing the buck; that is the format that the Windows keyboard driver uses.

    Okay, so why does the Windows keyboard driver use this representation for the keyboard speed? Because that's how the hardware keyboard autorepeat setting works. Command 0xF3 sets the keyboard autorepeat, and it takes a single byte argument, of which the bottom five bits encode the autorepeat speed, ranging from 2 characters per second up to 30. (That document describes the PS/2 keyboard interface, but the PS/2 command interface was based on the AT interface, for which the typematic control commands were the same. The XT keyboard did not have a configurable autorepeat as far as I can tell. Note that typematic was implemented in the hardware, not in the BIOS.)

    So at the end of the day, it all goes back to the 8042 keyboard controller chip. The hardware interface was reflected in the driver interface, which was reflected in the application interface. And when you issued the application call to change the keyboard autorepeat speed, that call went to the hardware; it was the hardware that actually did the autorepeating.

    Since the semantics were codified in the application interface, they were locked into the SystemParametersInfo function even as the driver model and the keyboard hardware changed around it. (But I believe that if you're using a PS/2 keyboard, then the PS/2 keyboard driver will still defer the actual work of autorepeat to the physical hardware, so at least the semantics are still applicable.)

  • The Old New Thing

    Merry Christmas to me: Zune headphones


    My article some time back about accidentally destroying my beloved Zune headphones resulted in a number of people sending me their unwanted Zune headphones via inter-office mail. This was not my intention when I posted the article—if that were my goal, I would have posted the article immediately instead of waiting a year and a half!—but it was nevertheless a pleasant surprise. Every so often strangers come through.

    Thanks, everybody.

  • The Old New Thing

    No, you didn't win the Jethro Tull box set, and please tell everybody else in your area code to stop calling me


    Some time ago, a fellow employee started receiving mysterious fax calls at the office four or five times a day and had to call the Microsoft telephone services folks to block the caller. But this reminded another colleague of a much more annoying problem, and one for which caller-block would not have worked.

    A local radio station had a contest line in the 206 area code. If someone in the 425 area code dialed this number without dialing the 206 area code prefix, they rang the phone of a new Microsoft employee. That employee's phone was set up incorrectly, and the calls ended up auto-forwarded to my phone. Every time the radio station ran a contest, my phone lit up like a Christmas tree.

    The telephone services department had to retire the phone number that matched the radio station's number.

    It's a pretty funny story, but only in retrospect.

    Background information (simplified) for those unfamiliar with United States telephone dialing rules: To make a call within an area code, you just dial the last seven digits. To make calls between area codes, you dial all ten digits. The contest number was (206) 555-1212, and people in the 425 area code who forgot to dial the 206 prefix ended up calling (425) 555-1212 by mistake. (In parts of the country with ten-digit dialing, the area code is mandatory even for calls originating from the same area code.)

    Forgot to knock on wood: Barely a week after my colleague told the story of the radio station contest line, it happened again. The telephone department once again assigned the troublesome number to a new Microsoft employee, and due to the incorrect set-up, my colleague's phone once again started ringing whenever the local radio station announced a call-in contest.

    This time, the telephone support people placed a permanent block on the troublesome phone number, so it will never be used for anything again. Well, more accurately, they tried three times, and the third time it finally worked (knock on wood). And nobody ever figured out why the number forwarded to my colleague's phone. Some things will always be a mystery...

  • The Old New Thing

    The NPR Planet Money one-hour story competition: The shopping mall convention


    Voting closed last night on the second NPR Planet Money one-hour story competition. Three reporters were sent into a convention (this time, the International Council of Shopping Centers conference) and given one hour to collect tape for a story. Listen to the results, either in the full podcast format or just to the three individual stories.

    Each of the stories was interesting in its own way. From Adam Davidson, I learned some mall restaurant jargon. From Chana Joffe-Walt, I learned about the pursuit of the cool kids. And from Alex Blumberg, I learned why a guy dressed in a bright red blazer known only as McGuire is the most popular guy at the convention.

    My vote went to Chana's story.

    Bonus link: The Six Guys' Blog, the blog of Five Guys. (This will make sense after you listen to Alex's story.)

  • The Old New Thing

    Why don't we create a special class of programs which can break the normal rules?


    In response to a discussion of why the window handle limit is 10,000, commenter Juan wondered why we don't create a special class of programs which can exceed the 10,000 handle limit and otherwise bypass the normal operation of the system.

    This is another case of the tragedy of special treatment: Eventually, nothing is special any more.

    If there were a way for an application to say, "Hey, I don't want to be constrained by the normal rules that apply to your everyday boring applications," then every application would simply say it, and the net effect would be that the constraint no longer applies to anybody.

    Task Manager conforms to the normal rules for GUI programs because if it marked itself as special, soon everybody would mark themselves as special in order to get the same special treatment. (Besides, the special treatment doesn't help Task Manager at all, since Task Manager doesn't create 10,000 handles. The specific issue in the comment is not something Task Manager even knows that it needs to opt out of. All it did was call CreateWindow; Task Manager shouldn't need to know about the internal implementation of CreateWindow.)

    Bonus chatter: There is already one mechanism for applications to say that a particular class of restrictions should not apply to them.

Page 1 of 4 (40 items) 1234