January, 2009

  • The Old New Thing

    You cannot pre-emptively reserve a file extension


    The following question came in from a customer:

    If our program isn't installed and users double-click our document, they get sent to a Web site that presents a list of programs, but we want to send the user directly to our download site. How do we claim a file extension for our application?

    Um, you don't.

    You cannot pre-emptively reserve a file extension. If your program uses the extension .ABC and somebody off in another country working out of a garage also uses the extension .ABC, then that's fine. Of course, things get exciting when a user installs both your program and the garage program, but that's a conflict for the user to resolve. It is not your position to declare unilaterally that you are more important than that person in a garage.

    What you can do is list your program among the ones that support the .ABC extension, so that when the user double-clicks an .ABC document and no program is installed to handle it, the user is sent to a Web page that includes your program as one which can open that file. But this doesn't grant you exclusivity. You'll just show up on the list with everybody else who wants to claim that file extension.

  • The Old New Thing

    Why isn't the screen resolution a per-user setting?


    Via the suggestion box, Dominic Self asks why screen resolution is a global setting rather than a per-user setting. Well, first of all, it's not even a global setting. It's a session setting.

    That it's not a global setting is not readily apparent most of the time since only Windows Terminal Server is set up to support multiple simultaneous interactive sessions. On Windows Terminal Server, you specify the properties of the virtual monitor you wish to connect with, including resolution, and the server accommodates your wishes. Well, up to a point. I mean if you ask for a 1,000,000×1,000,000 pixel screen, the server is probably going to say "As if!" (The Remote Desktop Connection feature found in, for example, Windows Vista Ultimate is basically the same thing, but on a smaller scale.)

    You can have ten different people logged on, each using a different video configuration. Some users might be running at lowly 640×480, others at 800×600 and still others at 1024×768. Some of them are running in 16-color mode, others 8-bit color, and some really adventuresome people with a lot of network bandwidth running at 24-bit color. You can even have the same user logged on more than once, with each session running at a different screen resolution.

    If the resolution settings really were per-user, you'd have some conflict resolution to deal with. If a user logs on and specifies a resolution different from the one stored in the user profile, does the new resolution overwrite the existing one? Or is the new resolution just a temporary resolution and the original one should stay? If a user tries to log on a second time with a conflicting resolution, is the second resolution ignored? Does the second resolution force the first session to change its resolution? Do you just get two sessions running with different resolutions? Which one gets saved as the user's preferred resolution?

    You also have to come up with a way to customize the resolution of the screen when nobody is logged on, a way to reconcile the effect of roaming profiles, what happens if you do a Run As on a user whose screen resolution conflicts with the user who opened the session.

    I'm not saying that these problems can't be solved. They probably can, given enough thought, but not all of the solutions will please everybody all the time, because no matter what you do, somebody will tell you that you're an idiot. And think of all the time and effort necessary to design how the feature should work, nail all the boundary conditions ("What happens if your per-user setting conflicts with an administrative policy?"), then code it up, write automated tests for it, run it through usability exercises ("Does the behavior match what users intuitively expect?" The answers may surprise you.) write up the documentation and help text, and continue maintaining the code, tests, and documentation for the feature's anticipated lifetime (which in this case is probably forever). Could all those resources have been spent on something that would have a greater total benefit to the customer base? (The answer to that is always "Yes"—everybody and her sister-in-law can find a way to finish the sentence, "I can't believe they wasted all that time on this stupid feature instead of fixing...")

    Remember, every feature starts with minus 100 points.

  • The Old New Thing

    Why doesn't Windows 95 format floppy disks smoothly?


    Welcome, Slashdot readers. Remember, this Web site is for entertainment purposes only.

    Who spends all day formatting floppy disks? From the reaction of geekdom, it appears that there are lots of geeks who sit around formatting disks all day. (Psst, you can buy them pre-formatted.) But why did Windows 95 get all sluggish when you formatted a floppy disk?

    It's that pesky MS-DOS compatibility again.

    As we saw a while ago, MS-DOS acted as the 16-bit legacy device driver layer for Windows 95. Even though the operation was handled by the 32-bit file system, all I/O calls were routed through 16-bit code (if only briefly) so that 16-bit drivers, TSR, and the like would see what appeared to be "normal 16-bit behavior" and continue operating in the manner to which they had become accustomed.

    In the old 16-bit days, disk formatting was done via software interrupt 13h, and many programs took advantage of this by hooking the interrupt so they would know whenever a floppy disk was being formatted. Some TSRs did this, as did backup programs (including backup programs designed for Windows 3.0 which included 32-bit Windows 3.x drivers—VxDs they were called—to monitor the floppy drive). But that doesn't explain everything. After all, Windows 95 sent all disk I/O through the 16-bit vectors, not just floppy disk formatting. Why does floppy disk formatting take such a toll on the system?

    As I noted in the linked article, the 32-bit file system did a lot of fakery to make 16-bit code believe that MS-DOS was in charge, even though it wasn't. Anybody who's done TSR programming (wow, the phrase anybody who's done TSR programming used to cover a lot of people but nowadays describes a few dozen geezers, most of whom are trying very hard to forget those days) knows all about the INDOS flag. This was a flag that MS-DOS set when an MS-DOS I/O call was active. Since MS-DOS was not re-entrant, TSRs had to pay close attention to that flag to know whether it was safe to issue MS-DOS calls or not. This INDOS flag was the 16-bit manifestation of what the 32-bit kernel called simply The Critical Section, with the definite article, because the 32-bit kernel kept the two critical sections (the 32-bit one and the 16-bit one) in sync so that MS-DOS drivers and TSRs wouldn't themselves get re-entered. If one virtual machine claimed the critical section, another virtual machine that tried to claim it would wait until the first one released it. In that manner, the driver or TSR would not get re-entered.

    As I already noted, back in the 16-bit days, the actual work of formatting was done by the ROM BIOS, and for compatibility reasons, floppy disk formatting was still sent through software interrupt 13h on the 16-bit side so any TSRs or drivers could see what was going on. There are a lot of crazy ROM BIOSes out there, and when a floppy disk format request was issued, the 32-bit kernel would do a bunch of extra work to ensure that the ROM BIOS got the execution environment it wanted. For example, the hardware timer ports were temporarily unvirtualized so as not to mess up the sensitive timing loops that ROM BIOSes used for floppy disk formatting.

    Okay, let's add up the damage. When a floppy disk is formatting, the timer is unvirtualized so that the ROM BIOS timing loops will run accurately. Only the virtual machine that is formatting the floppy drive receives timer ticks; the others have to wait. No timer ticks means the scheduler doesn't get told when it's time to let another thread run. What's more, the critical section is held across this operation, which means that no other thread can issue I/O operations either. And on top of that, the floppy disk is a slow medium, so any operations that wait on the floppy disk will have to sit and wait for several seconds.

    Well, at least floppy disks are formatted a track at a time, so the system doesn't get locked out for the entire duration of the format operation. The ROM BIOS would be told to format a track, and when it was done, the timers would be returned to normal (allowing the scheduler to do a little bit of scheduling), the critical section would be released (so that any pent-up I/O gets a chance to run), but then the FORMAT.COM program would turn around and format the next track, and the system would go back into hang on, let's not disturb the ROM BIOS while it does its thing mode for another track.

    Now, as with the 32-bit file system, there was a 32-bit floppy driver that tried to catch the format operations on the back end, and if successful, it would take over the job of formatting one track from the ROM BIOS. It was a valiant effort, but it doesn't matter how high-performance your driver is; the speed of formatting a track is pretty much constrained by the mechanics of the floppy disk drive itself. (The person responsible for Windows 95's 32-bit floppy driver was no slouch. I'll try to remember to tell some more stories later.)

    Sure, if Windows 95 didn't have to be compatible with 16-bit device drivers, TSRs, and squirly ROM BIOSes, it could have gone straight to the 32-bit floppy driver to do the formatting without having to do all this timer and critical section nonsense. But it turns out we already had a product that said good-bye to compatibility with 16-bit device drivers, TSRs, 16-bit Windows programs that talked to custom 32-bit Windows 3.x drivers, and squirly ROM BIOSes. It was called Windows NT.

    If you want Windows NT you know where to find it.

  • The Old New Thing

    Where does shell.windows.com get information about file extensions, and how do I get in on that action?


    If you double-click a file for which there is no registered handler, Windows will offer to visit the Web service on shell.windows.com to locate a program that can open it. But where does this information come from, and how can you add your program to the database?

    Knowledge Base article Q929149, titled Windows File Association System On-Boarding Process, provides step-by-step instructions on how you can add your file extension.

    If you look at the existing entries on shell.windows.com, most of them have relatively straightforward and neutral descriptions. "This document is a PowerPoint presentation." "This document is a sound file." But there is at least one company that decided to use the file association service for a bit of grandstanding. "Invented by XYZ company and perfected over 15 years, ABC file format lets you capture information from any application, on any computer, and share it with anyone around the world."

    By the way, if the file association Web service offends you, you can disable it.

  • The Old New Thing

    If you're at a Thai restaurant with a Thai person who's ordering food in Thai, and she asks you if you like your food spicy, think twice before answering


    I think you see where this is going.

    I'm at a Thai restaurant with my sister-in-law, who is Thai. She's talking with the waitress in Thai, and she discovers that the restaurant's cook is someone she knows. And since she's from Thailand, she assumes the task of ordering the food, since she knows what's good and what isn't.

    During their conversation (entirely in Thai, so I don't understand a word of it), she turns to me and asks, "So, is spicy food okay?"

    I say, "Yeah, I like spicy food."

    Classic rookie mistake.

    I think that by the end of the meal, I had just started to regain the ability to taste the food.

    Happy birthday, P—! And you'll be relieved to know that I can taste food again.

  • The Old New Thing

    The day shell.windows.com went down


    When the file association Web service was first being developed, the programmer responsible for implementing the feature just scrounged around and found an old unused computer and set it up as a simple Web server under his desk, so there would be something to test the code against. That server happily churned away serving out file extension information, and when people asked for their program to be added, he would manually add it to the server. The server worked just fine, and like most things which work just fine, it was forgotten.

    And then remembered once things no longer worked just fine.

    I think it was during one of the beta cycles, or maybe it was RC1, when the quiet neglected computer went offline. I forget why, so let's pretend that the programmer unplugged it as part of an office redecoration project. Suddenly, the shell.windows.com service went down.

    What? The file association Web service went down?

    Everybody had forgotten that shell.windows.com was still running on a computer under that programmer's desk. It had done such a good job up until now that nobody gave it a second though.

    He plugged the computer back in and watched the server bang out requests like nobody's business.

    Wheels were quickly set into motion to transfer the file association Web service to a machine with a little bit more professional attention and maintenance.

  • The Old New Thing

    The problem with The Month Where Everyone Focuses on Improving Documentation is that most people are terrible technical writers


    Why not have a month where everybody focuses on improving documentation like that month a few years ago where everybody focused on security?

    Well, part of it is that most people suck at technical writing. The technical part, maybe, but the writing almost definitely not. Writing is hard (as I've learned firsthand), and technical writing is a special genre of writing that requires a comparatively rare skill set, combining technical background with strong writing skills. Because it doesn't matter how much technical information you know if you are unable to convey this information to anyone else clearly.

    Also, there are lots of tools available for identifying potential security problems. PREfast, for example, can alert you to potential buffer overruns, and other scripts can hunt down uses of deprecated functions and similar potential security problems. On the other hand, how do you write a script that locates bad documentation?

    Pre-emptive snarky comment: "Just write a script that jumps to a random MSDN page!"

    What's more, technical people tend to write documentation for other technical people, on the assumption that the reader is already familiar with the material. Even knowing how to recognize that something "obvious" may not be obvious to everyone is a skill that takes time to develop. And as I have learned over and over again, it's a skill that I myself do not possess. Consider, for example, my posting that merely restates what I thought was obvious from the documentation.

    There's another problem with taking everybody on the team off their normal tasks and focusing them on documentation: How do you explain the one month delay in the product? Even the one-month delay for the so-called security push had its skeptics. Imagine if you told everybody that the product was late because we pulled the development team off of fixing bugs and told them to write documentation.

  • The Old New Thing

    The programmers don't design skins; they just make skins possible


    Not all skill sets are interchangeable. That's why we have concepts like division of labor and specialization. But it appears that not everybody understands this.

    I was reminded of this topic when I read the reactions to the Microsoft Exchange Team announcing that they had added Xbox and Zune themes to OWA. Many people were shocked, such as Loren, who was furious that "development time" was wasted on something frivolous like new themes when there are so many bugs that need to be fixed. Loren appears to believe that the people who do graphic design and the people who are up to their elbows in the code base fixing bugs and adding features are one and the same, that any time spent building a new visual style is time not spent fixing bugs.

    Generally speaking, programmers don't do the visual design. I mean, these are people who are lucky if they are wearing matching socks when they come to work, if they even remember to wear socks at all. And you want them to design a color scheme? Visual design is done by people trained in the visual arts, people who know about color wheels and lighting effects, people who can argue for days about whether the spacing between two visual elements should be one point or two, about whether a serif or sans-serif font should be used for a particular screen element. What the programmers do is create the infrastructure for skins and themes, but the actual building of the skin or theme is left to the designers. Once the infrastructure is built, the programmers' work is pretty much done, and they can go back to fixing bugs and adding other features, stuff that keeps Loren happy. Of course, the infrastructure for themes and skins needs to be maintained, but the amount of work spent on maintenance is largely independent of how many themes the designers have come up with.

    (Similarly, the office disco party happened to have been the handiwork of the infrared communication team, not the Windows 95 setup team, so any time they wasted on the party had no effect on Windows 95 setup.)

    Mind you, the new skins do create additional work for the testers, who need to write tests to verify that that the new skins don't have bugs like "In the Zune skin, you can't read the subject lines." But presumably they already have a template for testing skins—after all, they have to test all the other skins—so plugging the new skin's parameters into the template is a comparatively low incremental cost.

    So go ahead and enjoy those new themes, comforted in knowing that the effort spent in making those new themes was not at the cost of bug fixing.

    Next time, a story about what happens when a tester needs to test the skinning infrastructure when there are no skins.

  • The Old New Thing

    It's surprising how suddenly those new skins started pouring in


    A friend of mine told me a story of a project from over ten years ago. Part of the product design was that it would include a bunch of skins (visual styles). The development team had written up the skinning infrastructure, but the company which was hired to create the actual skins hadn't delivered anything. My friend's assignment was to test the skin-switching interface, but since there were no skins, there was nothing to test.

    My friend was responsible for testing a bunch of other product features, so it's not like the days were spent thumb-twiddling. But eventually, it got to the point where the automated testing for most of the other features was nearly complete, and at the weekly status meetings, my friend would ask the representative from the company that was hired to deliver the skins when they might send over the first two or three. "I don't need all twenty skins, just two or three so I can test the skin-switcher."

    At the meetings, the company representative always answered, "Yes, we know you're waiting for it, but designing these skins is really complicated stuff, and it's pretty slow going."

    My friend wondered, "How hard is this, really?" A visit to the development team quickly produced the same tools and documents that the skin design company was given, and in a few hours on a Saturday, my friend produced a brand new skin. Since my friend was a big Star Trek fan at the time, the homegrown skin was naturally based on the science fiction series, created by surfing the Internet and downloading pictures and sound effects. There was obviously no way the company could include this skin with their product, but at least it was something to test with. The skin-switcher finally had something to switch between: You could have the standard look or the Star Trek skin.

    At the next meeting, my friend once again asked the representative from the design company when they might deliver a skin or two and received the same runaround as usual. "It's a lot harder than we anticipated, but we're getting close, so who knows, you might have something in a few weeks."

    Except this time, my friend had a response for them. "Oh, maybe I can help you guys out. I threw together this skin in just a few hours. Here, let me show you." And then followed a demonstration of the Star Trek theme. It had a lot of rough edges (for example, the sound volumes weren't leveled), but it certainly did the job as a demo.

    As if by magic, just a few days later, the company that had been contracted to produce the skins managed to overcome all the obstacles that had been plaguing them up until now, and a steady stream of new skins started arriving.

  • The Old New Thing

    If you didn't like the answer, asking the same question again is unlikely to help


    I find it surprising how often this happens. A customer liaison will send a question to a mailing list like this:

    From: X
    To: Gizmo Discussion

    Hi, everybody.

    My customer is using the Gizmo Toolkit and wants to frob a gizmo without first registering as a frobber. They created the gizmo with CreateGizmo, passing all the default flags, and then they call AttachGizmo to attach the gizmo to a sprocket. When the sprocket detects that its host is decycling, it tries to frob the gizmo by calling FrobGizmo, but the call fails. They can't register the sprocket as a frobber because the sprocket doesn't have the right frob context. They tried setting the DefaultFrobContext registry key to Any but that didn't help. How can they frob the gizmo?

    Somebody from the Gizmo team will reply, "Sorry, but you have to register as a frobber before you can frob a gizmo. The DefaultFrobContext registry key doesn't help you here; it's for cogs, not sprockets. There is no analogous registry key for sprockets, sorry."

    That seems to be the end of it; there is no further response. Then about two weeks later, some other person will ask a suspiciously similar question.

    From: Y
    To: Gizmo Discussion

    Hello. I hope somebody can help us with this.

    My customer is using the Gizmo Toolkit and wants to frob a gizmo without first registering as a frobber. They created the gizmo with CreateGizmo, passing all the default flags, and then they call AttachGizmo to attach the gizmo to a sprocket. When the sprocket detects that its host is decycling, it tries to frob the gizmo by calling FrobGizmo, but the call fails. They can't register the sprocket as a frobber because the sprocket doesn't have the right frob context. They tried setting the DefaultFrobContext registry key to Any but that didn't help. How can they frob the gizmo?

    Hm, that question looks awfully familiar, let me look in the archives and... hey, it's a word-for-word copy of the same question somebody else asked two weeks ago!

    In situations like this, I tend to respond by attaching the original reply with the text, "I refer the honourable gentleman to the answer given some moments ago."

    Okay, maybe the customer was not happy with the answer and instead of elaborating on their situation (so somebody might be able to spot an alternate design that avoided this problem), they just reopened the case and got a different liaison the second time. Maybe person Y was simply duped into asking the same question.

    And then this happens.

    From: Y
    To: Windows Programming Discussion


    My customer is using the Gizmo Toolkit and wants to frob a gizmo without first registering as a frobber. They created the gizmo with CreateGizmo, passing all the default flags, and then they call AttachGizmo to attach the gizmo to a sprocket. When the sprocket detects that its host is decycling, it tries to frob the gizmo by calling FrobGizmo, but the call fails. They can't register the sprocket as a frobber because the sprocket doesn't have the right frob context. They tried setting the DefaultFrobContext registry key to Any but that didn't help. How can they frob the gizmo?

    Okay, so much for the theory that person Y was a victim. Person Y is clearly fishing around, hoping that if you ask the right person, you'll get an answer you like. It's sort of like the teenager who asks his father, "Can I borrow your car?" When Dad says, "No," the teenager goes to his mother and asks, "Can I borrow Dad's car?" in the hopes that maybe Mom will give a more favorable answer than Dad.

    But if you're asking a question about the Gizmo Toolkit, it's going to get routed to the Gizmo team one way or another. And if you ask the same, identical question, you're going to get the same, identical answer, just with a greater degree of exasperation each time you ask it again.

    "Can I have a pony?"
    — No
    "Can I have a pony?"
    — No.
    "Can I have a pony?"
    — No.

    Let me draw you a picture.

Page 1 of 4 (34 items) 1234