August, 2009

  • The Old New Thing

    And they don't take American Express

    • 7 Comments

    A conversation between two friends of mine.

    Friend 1: Here's the fifteen dollars I owe you. Oh wait, I only have a twenty. Do you have a five?

    Friend 2: I don't carry cash. Everybody takes credit cards.

    Friend 1: I don't take credit cards.

    In my imagination, Friend 1 would have responded to "Everybody takes credit cards" with "Well, in that case, here ya go. Put it on my credit card."

    (The title is a tag line from a Visa credit card advertising campaign from years past.)

  • The Old New Thing

    Why do new controls tend to use COM instead of window messages?

    • 25 Comments

    Commenter David wonders why new controls tend to use COM instead of window messages. "It seems that there must have been a decision to only develop COM controls after the invention of COM."

    There have been plenty of Win32 controls invented after the invention of COM. In fact, the entire common controls library was developed after the invention of COM. All your old friends like the list view, tree view, and property sheets are good old Win32 controls. But it's true that the newer stuff tends to use COM. Why is that?

    I am not aware of any grand pronouncement on this subject. Each team makes a decision that they feel is best for their customers. But if you think about it, it's not an unreasonable choice: Suppose you were writing a new C++ object. Would you prefer to use this:

    class Thing {
    public:
      enum MESSAGENUMBER {
      MESSAGE_INSERTITEM,
      MESSAGE_DELETEITEM,
      MESSAGE_DELETEALLITEMS,
      MESSAGE_SETLABELTEXT,
      MESSAGE_GETNEXTITEM,
      MESSAGE_ADDBITMAP,
      ...
      };
      LRESULT Message(MESSAGENUMBER m, WPARAM wParam, lPARAM lParam);
    private:
      ...
    };
    

    or would you rather use this:

    class Thing {
    public:
      BOOL InsertItem(Item *item, Item *itemParent, Item *itemInsertAfter);
      BOOL DeleteItem(Item *item);
      BOOL DeleteAllItems();
      BOOL SetLabelText(Item *item, PCWSTR pszText);
      Item *GetNextItem(Item *item);
      BOOL AddBitmap(HINSTANCE hinst, PCWSTR pszResource, COLORREF crTransparent);
      ...
    private:
      ...
    };
    

    It's just less of a hassle using separate member functions, where you don't have to try to pack all your parameters into two parameters (cryptically named WPARAM and LPARAM) on the sending side, and then unpack the parameters on the window procedure side.

    The overhead of sending a message can add up for high-traffic messages. A C++ method call is pretty direct: You set up the parameters and call the method. Whereas when you send a window message, it bounces around inside the window manager until it magically pops out the other side.

    Again, these are my personal remarks and are not the official position of Microsoft on anything. But if you were writing a control, which would you prefer to have to implement? And if you were using a control, which interface would you rather use?

    (That said, I can't think of many common controls that are COM-based. All the ones I know about still use boring window messages.)

  • The Old New Thing

    A different perspective from the first row of the symphony

    • 7 Comments

    On the weekend of November 10 during the 2007–2008 Seattle Symphony season, the symphony performed both Brahms piano concerti and two of his symphonies in consecutive concerts. My subscription included one of them, and I bought a separate ticket to the other one, and the seat I was given was in the very front row.

    You notice all sorts of things when you're in the very front row, things that elude your notice from even the second or third row. When you're that close, you're within an arm's reach of the musicians. I had to look away when the concertmaster bent over to tune the orchestra; otherwise I would've been looking up her dress. During the performance, I could read the music on the first violin's music stand. I could hear the pianist hum to himself. (And for some reason, pianists who hum also hum out of tune. Why is that?) And I could hear the conductor exhale through his teeth. It sounded like he was making quiet "choo choo" noises.

    Then again, the "choo choo" noises might have been on purpose. He took the Brahms Fourth Symphony faster than I remember ever hearing it before. For all I know, the train noises were his way to get the orchestra to play faster.

  • The Old New Thing

    The great thing about naming conventions is that not everybody will follow them

    • 5 Comments

    The naming convention for HRESULT is «facility»_«severity»_«name», where the facility portion (and the underscore) is omitted if the facility is FACILITY_NULL or FACILITY_WIN32.

    Good luck finding anybody who follows this naming convention.

    Okay, fine, if you look closely you might be able to find some people who do.

    COM   CO_ E_ NOTINITIALIZED
    CO_ S_ MACHINENAMENOTFOUND
    Structured storage   STG_ E_ SHAREVIOLATION
    STG_ S_ CONVERTED
    SETUPAPI   SPAPI_ E_ EXPECTED_SECTION_NAME
    Data and view   DV_ E_ TYMED
    DV_ E_ FORMATETC
    Class factory   CLASS_ E_ NOAGGREGATION
    Class registry   REGDB_ E_ CLASSNOTREG
    OLEDB   DB_ E_ DELETEDROW

    Actually, I guess I was a bit too pessimistic when I said nobody follows it. It seems that the majority of Windows components do follow this convention, although there are some notable exceptions.

    DirectDraw   DDERR_UNSUPPORTEDFORMAT
    ADSI   E_ADS_INVALID_DOMAIN_OBJECT

    There are also some people who decided to confuse matters further by using the HRESULT convention for error codes returned by GetLastError()!

    RPC   RPC_S_OBJECT_NOT_FOUND
    SmartCard   SEC_E_SMARTCARD_CERT_REVOKED
    Task scheduler   SCHED_E_SERVICE_NOT_LOCALSYSTEM
    Winsock   WSA_E_NO_MORE

    I apologize for the confusion this has caused.

    Pre-emptive clarifying remark: The examples given in this article are merely illustrative and are not intended to be comprehensive.

  • The Old New Thing

    Isn't every dinner at a technology conference a geek dinner?

    • 8 Comments

    I'm always amused when somebody announces that they're having a geek dinner at a technology conference. I mean, at a conference like that, every dinner is a geek dinner. The geek density is so high, +4 enchanted vorpal swords quiver in fear.

    [Update 8am: Fixed broken permalink. Yay, they broke a permalink...]

  • The Old New Thing

    What is the maximum number of timers a program can create?

    • 12 Comments

    As MSDN correctly notes, "Timers are a limited global resource." How limited are they? (We're talking about timers created by SetTimer.)

    Not as limited as they once were.

    Originally, there were eight timers total for the entire system. When there are only eight timers, you have to be very careful not to waste them and to destroy them when they aren't needed.

    Windows 3.0 increased this to 32.

    Windows 95 increased this to around 2500, although the debug version of Windows got mad at you if a single program created more than 32.

    Windows NT 3.1 would create timers until you exhausted the desktop heap. The maximum number of timers depends on what other window manager objects had been created.

    Starting with Windows NT 4, the window manager treats timers as User Objects for bookkeeping purposes, so all your timers, windows, menus, and so on fight for space in the per-process 10,000 object limit and the 32,000-ish object limit for a desktop.

    As you can see, the precise limit changes over time, so you couldn't count on any particular limit being in effect. Who knows, maybe the limit will change again in a future version of Windows.

    These limits are pretty high, but that doesn't mean you can be lazy. Jessica pointed out that the WinForms Timer component is easily leaked "because most people don't know that they have to call Dispose on it." Another thing to check for when you find that you can't create any more timers.

  • The Old New Thing

    The way to stop people from copying files to a folder is to use NTFS security, not to block drag/drop

    • 19 Comments

    A customer wanted to prevent users from copying files to certain locations, and they did it by hooking functions like SHFileOperation and failing the operation if the parameters were not to its liking. The customer found that the hooks stopped working in Windows Vista because Explorer in Windows Vista uses the new IFileOperation COM interface instead of using the old SHFileOperation function. The customer wanted assistance in getting their hook working again so they could prevent users from copying files to directories they wanted to block.

    Well, first of all, arbitrary function hooking is not supported by any version of Windows, so the customer was already in unsupported territory right off the bat. (There are some components which have an infrastructure for hooks, such as file system filter drivers or Winsock Layered Service Providers.)

    Second, attempting to hook SHFileOperation to prevent the user from copying files into specific directories is looking at the problem at the wrong level, similar to the people who want to block drag/drop when what they really want to block is accidental drag/drop. If you block copying files via drag/drop in Explorer, that won't stop the user from copying files by other means, or by doing the "poor man's copy" by opening the document from the source location and doing a Save As to create a duplicate in the destination.

    If you want to prevent the user from copying files to a directory, use the NTFS security model. Withhold Create files permission in the folder, and users will be blocked from copying files into the directory in Explorer, Notepad, or any other program.

    Related: Shell policy is not the same as security.

  • The Old New Thing

    In Ephesus, you juggle or die

    • 4 Comments

    In 1987, The Flying Karamazov Brothers performed their interpretation of Shakespeare's A Comedy of Errors. When I watched this show (part 1, part 2) when it first aired, it was my introduction both to the juggling team and to the play. It also reinforced my impression that Shakespeare was meant to be performed and not merely read. The jokes simply don't work as well when you merely read them.

    For some reason, I still remember the tiny juggling mishap in the final seconds of the show (part 2, time code 1:05:14): The actress at the far left edge of the screen (Luciana) drops a pin but covers up the mistake nicely.

  • The Old New Thing

    Meta-content: Suggestion Box 4 will open sometime next year

    • 22 Comments

    Yesterday, I finished composing the last entry taken from an item in Suggestion Box 3. My prediction that the backlog would clear in early 2010 was off by exactly one year: The last Suggestion Box 3 entry is scheduled to be posted on January 3, 2011.

    I figure I'll open Suggestion Box 4 sometimes next year. But I'll leave it open for only a little while, to avoid the problem with Suggestion Box 3 where I left it open for so long that it took six years to clear out.

    (Then again, maybe I should stick to a six-year cycle for emptying the Suggestion Box. That would certainly discourage people from putting "Please help me with my problem" type entries into it. Unless they're willing to wait six years for a response...)

  • The Old New Thing

    My phone just DoS'd my office network

    • 22 Comments

    The other day I was working in my office minding my own business when I suddenly lost network connectivity. I couldn't contact any machines other than the ones in my office.

    When this happens, I go through some basic troubleshooting steps. Is my neighbor's network okay? How about power-cycling the affected machines? Refreshing the TCP/IP security policies? None of that seemed to work, so I called the network helpdesk, on the assumption that my port was shut down because I somehow missed an e-mail message announcing a mandatory security patch that I had failed to keep up with.

    My office has an IP phone. It's hard to call the network helpdesk when your network is down and your office phone is network-based. I called them from my cell phone instead.

    After giving the helpdesk person the MAC addresses of all the computers in the office, the technician said, "Nope, none of these is on the list. If your network isn't working, it's not because of a port shutdown. Try plugging one of your computers directly into the wall rather than going through the hub."

    Bingo, network connectivity restored. The problem was somewhere inside my office. I thanked the technician and set to figuring out what was wrong with my office.

    Now, in order to plug the computer directly into the wall, I had to unplug my IP phone, since the office network topology is wall→phone→hub→other computers. The phone goes straight into the wall on the recommendation of the phone people because they argue that not all hubs know how to intermediate the QoS packets that the phone uses to ensure that call quality is acceptable. When I plugged the phone back into the wall and rebooted the phone, I got the message Please wait while updates are being installed. Once the phone finished booting, I found that the rest of the computers in the office had network connectivity.

    Basically, my phone downloaded an update and tried to auto-reboot itself, but got wedged, and it took my office network down with it. My phone just DoS'd my office network.

    Historical note: This entry was written over a year ago, and the model of IP phone in question has long since been replaced.

Page 1 of 4 (35 items) 1234