November, 2005

  • The Old New Thing

    The Airline Screening Playset

    • 6 Comments

    Here I am sitting in the airport waiting for my flight to begin boarding. What better time to break out the Airline Screening Playset. I love the fact that the gun fits into the suitcase.

  • The Old New Thing

    Sometimes the fault is not in our stars but in ourselves

    • 14 Comments

    An earlier name for Windows Server 2003 was Microsoft Windows .NET Server, and in the final weeks leading up the the product's release, we received the following bug from a beta tester:

    When I call the GetVersionEx function on build 3773, the OS name is still reported as "Microsoft Windows .NET Enterprise Server". I have attached a sample program illustrating the bug.

    I found this kind of confusing, because the GetVersionEx function doesn't return a human-readable product name. Intriguged, I took a look at the sample program and it wasn't too hard to see where the bug was. The program contained the lines

    if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
       lstrcpyn(szOS, L"Microsoft Windows .NET", MAX_PATH);
    

    In other words, the program had the incorrect string hard-coded into it.

    I reported my findings back to the person who submitted the bug, and the response was "Oops, sorry about that."

  • The Old New Thing

    The craft of UI design: flow|state

    • 41 Comments

    You can tell right away that Jan Miksovsky's flow|state is about user interface design. I've had the pleasure of working with Jan when he was at Microsoft. Whereas I focus on the mechanics of making a user interface happen, Jan looks at the bigger problems of design and interface architecture. For example, in this entry he considers the issue of asking the user unnecessary questions and highlights some ways you can avoid hassling the user with a barrage of questions while still giving the user the ability to answer the question if they choose to. Good stuff.

  • The Old New Thing

    Taxes: Geopolitics

    • 23 Comments

    One frequently-overlooked software "tax" is geopolitics. We've alread seen that the time zone and regional settings dialogs created international unrest. It appears that Google Maps failed to recognize the extremely sensitive issue of naming the body of water that lies between Korea and Japan, as well as stirring up international tensions with the way it labelled the island of Taiwan. Like many issues regarding naming, these subjects are tied up in history with strong feelings on both sides. (And Google's efforts to placate the Taiwanese government only served to anger the Chinese government. Welcome to the big time.) As we saw in the time zone example, deferring to United Nations-approved boundaries or terminology is not always sufficient to calm the parties involved in a dispute.

    This is why you tend to see the word "region" used in Microsoft products instead of "country". There are still many parts of the world where sovereignty is a highly contentious issue. If you call something a "country", you have effectively "taken sides" in a dispute you probably would be better off staying out of.

    Geopolitics wasn't so much of an issue in the past, where you could control where in the world your program was running by virtue of controlling where your distributors are. But with the Internet, everything you post instantly becomes available to an international audience.

    Unfortunately, I don't have any good advice on this particular tax. My personal rule is "Stay far, far away from maps."

  • The Old New Thing

    Where does an IT guy from a major hotel chain stay at the PDC?

    • 9 Comments

    I believe it was Marc Miller who related this story to me at the PDC. He was chatting with someone whose name badge identified him as an employee from a major high-end hotel chain. Marc joked, "Well, I think it's obvious which hotel you're staying at."

    "Oh no," the gentleman replied. "They won't let me stay there. Too expensive."

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    Taxes: Hierarchical Storage Management

    • 11 Comments

    One of the taxes I alluded to some time ago when I broached the issues of software development "taxes" is Hierarchical Storage Management. The short description of Hierarchical Storage Management is that it is a way of archiving data transparently. When a file is due for archival, it is transferred to a slower (but less expensive) storage medium, such as magnetic tape, leaving a stub behind.

    The stub retains some of the file's original metadata, such as last-modified time and file size, but none of the original file's contents are recorded by the stub. If a program tries to open the stub, the original file is "recalled" from tape backup, a process which can take minutes.

    Programmatically, you can detect that you stumbled across one of these stubs by checking for the FILE_ATTRIBUTE_OFFLINE file attribute. (Note that this is not the same as Offline Files.) We already saw that Explorer indicates such files with a black clock. The command prompt indicates such files by putting the file size in parentheses. If your program encounters a file with this attribute, it should not open the file unless the user explicitly asked it to do so. Examples of operations that should be suppressed for an offline file in the absence of explicit user indications to the contrary:

    • Auto-preview.
    • Content indexing.
    • Searching.
    • Scanning for viruses.
    • Sniffing file content.

    For example, a context menu handler should not open an offline file just to see which context menu options to offer. Right-clicking a file is not a strong enough reason to recall it from tape.

    Failing to respect the FILE_ATTRIBUTE_OFFLINE file attribute when performing a search would result in all files accessed during the search being recalled from tape. If left unchecked, this will eventually recall every single file on the system, completely negating the act of archiving the files to tape in the first place!

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    How to get Raymond to stop being interested in talking with you

    • 46 Comments

    I was at a party in New York City earlier this year, and a conversation went like this:

    Person: What do you do?
    Me: I'm a computer programmer at Microsoft.
    Person: <viciously> I hate you.

    If Miss Manners didn't say so explicitly, I suspect she would nevertheless agree that snarling "I hate you" to somebody on first introduction is not exactly getting off on the right foot.

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    This video universally gets one of two reactions

    • 27 Comments

    When I show someone this web site and the videos they put together on how Microsoft main campus could be serviced by a system of self-driving overhead personal vehicles, I get one of two reactions.

    1. "That's so cool!"
    2. "That's so stupid!" (Or words to that effect. Use your imagination.)

    Yet another of their web sites writes

    The small PRT tracks are only three feet across, and compliment modern office architecture.

    Psst, the word you want is "complement" with an "e". If you "compliment" (with an "i") something, you praise it. If you "complement" (with an "e") something, then you complete it. (In the realm of aesthetics, things that complement each other mutually enhance each other.) Mnemonic: "complement" = "complete".

    The comma is incorrect as well. This is a conjunction of predicates, not of clauses, and therefore demands no comma.

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    What causes a program to be marked as "new" on the Start menu?

    • 50 Comments

    One of the features new in the Windows XP Start menu is that "newly-installed" programs are highlighted. Before discussing the rules, a quick backgrounder on why the feature exists at all.

    Research revealed that one of the tasks people had trouble with was installing a new program and running it. The step that the "new programs" feature tries to assist with is the "running it" part. In our tests, we found that people who managed to muddle through a program's setup got stuck at the "Okay, why don't you play the game now that you've installed it?" step because they couldn't figure out how to get to that program. That's why there's a balloon that pops up saying "Psst. That program you just installed? It's over here." And then there's a "yellow brick road" leading you through the Start menu to the program launch point itself.

    What are the rules that control whether a program counts as "newly-installed"? The basic idea is simple: The Start menu looks for shortcuts that were recently created and point to files that were recently created. If there are multiple shortcuts to the same program, only one of them is chosen. (No point highlighting two shortcuts to the same thing.) Once you've run a program, it is no longer marked as "new".

    But then there are a bunch of rules, based on feedback from our research, that "tweak" the results by removing candidates from the list:

    • Things that aren't even programs. Example: A shortcut to a text file.
    • Shortcuts in the Startup group, since they are already run for you automatically.
    • Shortcuts more than a week old. Clearly you aren't interested in those any more.
    • Shortcuts that should be ignored because they aren't really programs. Some people felt that they had to run every single highlighted program "because the computer told me to", so we had to un-highlight the ones that either aren't really all that important or are downright dangerous.
      • Online help disguised as programs. Examples: "XYZ Read Me", "XYZ Documentation", "What's New in XYZ 2.0".
      • Product support disguised as programs. Example: "XYZ Support Center".
      • Application management disguised as programs. Examples: "Uninstall XYZ", "XYZ Feature Setup", "INSTALL.EXE".
      You can imagine the excitement that reigned when "Uninstall XYZ" was highlighted on the Start menu and one of those "the computer told me to" people was sitting at the computer.
    • Shortcuts to programs which are being used as file viewers rather than as programs in their own right. Examples: "explorer.exe", "rundll32.exe", "quikview.exe".
    • Shortcuts to programs which were already installed before you installed Windows. These programs are obviously not new, even though you may never have run them. Before this rule was put into effect, upgrading a computer resulted in every single old program being highlighted because the Windows XP Start menu said, "Well, I've never seen you run any of these programs; they all must be new."
    • Shortcuts to programs which were installed within one hour of installing Windows. Although these programs are "new" in the strict sense of the word, they were clearly installed by whoever set up the computer and not by the end user. Therefore, there is no need for a "yellow brick road" to find them. Before this rule was put into effect, a person who bought a computer with a dozen programs preinstalled would turn on their computer Christmas morning and be greeted with a wall of yellow programs.

    Wow, that's a lot of tweaks. But each one was to address a real-world scenario that was found during research and testing.

    A typographical note: The correct capitalization is "Start menu" with a capital S and a small m. (I got it wrong for the first several years as well until somebody corrected me.) Not that anybody pays any attention to what I say about how things should be called.

    [Raymond is currently away; this message was pre-recorded.]

  • The Old New Thing

    Semaphores don't have owners

    • 16 Comments

    Unlike mutexes and critical sections, semaphores don't have owners. They merely have counts.

    The ReleaseSemaphore function increases the count associated with a semaphore by the specified amount. (This increase might release waiting threads.) But the thread releasing the semaphore need not be the same one that claimed it originally. This is different from mutexes and critical sections, which require that the claiming thread also be the releasing one.

    Some people use semaphores in a mutex-like manner: They create a semaphore with initial count 1 and use it like this:

    WaitForSingleObject(hSemaphore, INFINITE);
    ... do stuff ..
    ReleaseSemaphore(hSemaphore, 1, NULL);
    

    If the thread exits (or crashes) before it manages to release the semaphore, the semaphore counter is not automatically restored. Compare mutexes, where the mutex is released if the owner thread terminates while holding it. For this pattern of usage, a mutex is therefore preferable.

    A semaphore is useful if the conceptual ownership of a resource can cross threads.

    WaitForSingleObject(hSemaphore, INFINITE);
    ... do some work ..
    ... continue on a background thread ...
    HANDLE hThread = CreateThread(NULL, 0, KeepWorking, ...);
    if (!hThread) {
      ... abandon work ...
      ReleaseSemaphore(hSemaphore, 1, NULL); // release resources
    }
    
    DWORD CALLBACK KeepWorking(void* lpParameter)
    {
      ... finish working ...
      ReleaseSemaphore(hSemaphore, 1, NULL);
      return 0;
    }
    

    This trick doesn't work with a mutex or critical section because mutexes and critical sections have owners, and only the owner can release the mutex or critical section.

    Note that if the KeepWorking function exits and forgets to release the semaphore, then the counter is not automatically restored. The operating system doesn't know that the semaphore "belongs to" that work item.

    Another common usage pattern for a semaphore is the opposite of the resource-protection pattern: It's the resource-generation pattern. In this model the semaphore count normally is zero, but is incremented when there is work to be done.

    ... produce some work and add it to a work list ...
    ReleaseSemaphore(hSemaphore, 1, NULL);
    
    // There can be more than one worker thread.
    // Each time a work item is signalled, one thread will
    // be chosen to process it.
    DWORD CALLBACK ProcessWork(void* lpParameter)
    {
      for (;;) {
        // wait for work to show up
        WaitForSingleObject(hSemaphore, INFINITE);
        ... retrieve a work item from the work list ...
        ... perform the work ...
      }
      // NOTREACHED
    }
    

    Notice that in this case, there is not even a conceptual "owner" of the semaphore, unless you count the work item itself (sitting on a work list data structure somewhere) as the owner. If the ProcessWork thread exits, you do not want the semaphore to be released automatically; that would mess up the accounting. A semaphore is an appropriate object in this case.

    (A higher performance version of the producer/consumer semaphore is the I/O completion port.)

    Armed with this information, see if you can answer this person's question.

    [Raymond is currently away; this message was pre-recorded.]

Page 1 of 4 (40 items) 1234