May, 2010

  • The Old New Thing

    We've traced the call and it's coming from inside the house: Operating system names


    As the Windows Server 2003 project wound down, somebody reported a serious bug that went something like this:

    Subject: Windows Server 2003 still refers to itself as Windows .NET Server

    Previous versions of Windows report the product name correctly, but Windows Server 2003 still calls itself "Windows .NET Server" instead of Windows Server 2003.

    // on Windows XP
    C:\> osver
    Windows XP
    // on Windows 2000
    C:\> osver
    Windows 2000 Professional
    // on Windows 2000 Server
    C:\> osver
    Windows 2000 Server
    // on Windows NT 4 SP3
    C:\> osver
    Windows NT 4 SP3 Workstation
    // but on Windows Server 2003
    C:\> osver
    Windows .NET Server

    I've attached a copy of the osver program you can use to reproduce the problem.

    Indeed, if you run the osver program attached to the bug report, it does report Windows .NET Server when run on Windows Server 2003. Now to find out where osver gets the product name from, so we can find and fix it.

    The customer was kind enough to include the source code to the osver program, and we found some code in that program that gave away the root of the problem:

    if (osv.dwMajorVersion == 5 &&
        osv.dwMinorVersion == 2) {
     printf("Windows .NET Server\n");

    When we pointed this out to the bug submitter, we received a simple but gracious reply:

    "Oops. Sorry about that."

  • The Old New Thing

    If you can detect the difference between an emulator and the real thing, then the emulator has failed


    Recall that a corrupted program sometimes results in a "Program too big to fit in memory" error. In response, Dog complained that while that may have been a reasonable response back in the 1980's, in today's world, there's plenty of memory around for the MS-DOS emulator to add that extra check and return a better error code.

    Well yeah, but if you change the externally visible behavior, then you've failed as an emulator. The whole point of an emulator is to mimic another world, and any deviations from that other world can come back to bite you.

    MS-DOS is perhaps one of the strongest examples of requiring absolute unyielding backward compatibility. Hundreds if not thousands of programs scanned memory looking for specific byte sequences inside MS-DOS so it could patch them or hunted around inside MS-DOS's internal state variables so it could modify them. If you move one thing out of place, those programs stop working.

    MS-DOS contains chunks of "junk DNA", code fragments which do nothing but waste space, but which exist so that programs which go scanning through memory looking for specific byte sequences will find them. (This principle is not dead; there's even some junk DNA in Explorer.)

    Given the extreme compatibility required for MS-DOS emulation, I'm not surprised that the original error behavior was preserved. There is certainly some program out there that stops working if attempting to execute a COM-style image larger than 64KB returns any error other than 8. (Besides, if you wanted it to return some other error code, you had precious few to choose from.)

  • The Old New Thing

    No good deed goes unpunished, part 2, redux


    I noted some time ago that I have taken to "blaming" Exchange when someone assumes that my reply to a thread on a distribution list implies that I have taken responsibility for resolving their problem. One of my colleagues in another group is in a similar situation with respect to a different product, and he has taken to using the same basic formulation when sending issues back to the distribution list.

    One variation he used a while back gave me a chuckle:

    We need a new Exchange server. This one keeps stripping the mailing list.
  • The Old New Thing

    An insight into the balance between forgiveness and permission


    One of my colleagues shared this valuable insight into the balance between forgiveness and permission, which he in turn learned from a high-level manager in his organization:

    The statement that it is better to ask for forgiveness than to obtain permission is true 90% of the time. The key to success is knowing where the other 10% is.
  • The Old New Thing

    If Windows 3.11 required a 32-bit processor, why was it called a 16-bit operating system?


    Commenter Really16 asks via the Suggestion Box how 32-bit Win32s was, and why Windows 3.11 was called 16-bit Windows when it required a 32-bit CPU and ran in 32-bit protected mode.

    First, let's look at how Windows worked in so-called Standard mode. Actually, it was quite simple: In Standard mode, Windows consisted of a 16-bit protected-mode kernel which ran applications in 16-bit protected mode. I suspect there would be no controversy over calling this a 16-bit operating system.

    With the introduction of Enhanced mode, things got more complicated. With Enhanced mode, there were actually three operating systems running at the same time. The operating system in charge of the show was the 32-bit virtual machine manager which ran in 32-bit protected mode. As you might suspect from its name, the virtual machine manager created virtual machines. Inside the first virtual machine ran... a copy of Standard mode Windows. (This is not actually true, but the differences are not important here. Don't make me bring back the Nitpicker's Corner.)

    The other virtual machines each ran a copy of MS-DOS and were responsible for your MS-DOS sessions. Recall that Enhanced mode Windows allowed you to run multiple MS-DOS prompts that were pre-emptively multi-tasked. These other virtual machines ran in a variety of modes, but spent most of their time in virtual-86 mode. MS-DOS applications could use the DPMI interface to switch into 16-bit protected mode, or even 32-bit protected mode if they wanted to. (And that's how Standard mode Windows ran inside the first virtual machine: It used the DPMI interface to switch to 16-bit protected mode.)

    It's kind of stunning to realize that Enhanced mode Windows was really a completely new operating system with multiple virtual machines, pre-emptively multi-tasked with virtual memory. In principle, it could have created a virtual machine and hosted yet another random operating system inside it, but in practice the only two operating systems it bothered to host were Standard mode Windows and MS-DOS.

    Enhanced mode Windows was called a 16-bit operating system because it ran 16-bit Windows applications (inside a "Windows box", you might say). The supervisor operating system was a 32-bit operating system, but since applications didn't run in supervisor mode, that really didn't mean much. For all anybody cared, the supervisor operating system could have been written in 6502 assembly language. As long as it does its supervisory job, it doesn't matter what it's written in. What people care about is the applications that you could run, and since Enhanced mode Windows ran 16-bit Windows applications, and since it ran a copy of 16-bit Standard mode Windows to do all the things that people considered Windows-y, it was the number 16 that was important.

    Besides, you can imagine the uproar from the Slashdot crowd (if Slashdot had existed back then) that an operating system whose purpose is to run 16-bit applications in a 16-bit GUI environment would dare call itself a 32-bit operating system.

    How 32-bit was Win32s? Pretty darned 32-bit. A Win32s application ran in the same virtual machine as the rest of Standard mode Windows, but when it ran, the CPU really was in 32-bit protected mode. Naturally, it did all its work under the supervision of the virtual machine manager, and it had to coordinate its work with the Standard mode Windows kernel that it was sharing the virtual machine with. But when your 32-bit application was running, you were bought in: Your registers were 32-bit, your pointers were 32-bit, you accessed data in a 32-bit data segment, and you executed 32-bit instructions out of a 32-bit code segment.

    [The blog server is undergoing a long-overdue upgrade which will take a week to complete. During that time, comments will be disabled.]

  • The Old New Thing

    Maxing out the upsell-o-meter


    Many grocery stores in the United States have a printer next to the cash register which prints out coupons customized to your purchases. If you buy the house brand of spaghetti, it might print out a coupon for a slightly more expensive brand of spaghetti. The goal with these coupons is to get you to try a fancier (and therefore more profitable) version of the product in the hopes that you will like it and switch.

    For reasons not important to the story, one of my colleagues needed to buy baby formula for his newborn son. He and his wife carefully researched the options and decided that the best brand to get was XYZ brand. They went to the grocery store to buy some, and as expected, they got a cash register coupon.

    But upon closer inspection, it wasn't a coupon after all.

    Thank you for buying XYZ brand baby formula.

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

  • The Old New Thing

    How do I prevent users from dragging and dropping files in Explorer?


    More than once, I've had a customer ask, "How do I prevent users from dragging and dropping files in Explorer?" Actually, three of them in the past year phrased it in an even more provocative way: "I want to write a program that hooks Explorer and displays a prompt before every drag/drop operation."

    This is one of those cases where you have to figure out what the customer really wants. They've solved half of their problem and are asking you for help with the other half.

    In my experience so far, when customers ask this question, their real problem is always one of the following:

    First, they just want to prevent the user from moving files into or out of directories that the users shouldn't be modifying. In other words, the question isn't "How do I prevent users from dragging and dropping files in Explorer?" but rather "How do I prevent users from moving files I don't want them to move, and to prevent them from moving files into directories I don't want them to modify?"

    The answer to the customer's real question is not to try to block the user interface operation (because, even if you block it there, they can still move the file around by other means, like say, the command prompt) but rather to apply ACLs to the underlying files and directories so that the users don't have permission to perform the operation you want to block.

    Another common response to "Please explain why you think you need to do this" is "Well, I find that my users will accidentally move files around when they didn't mean to. They might be clicking on a file, but accidentally drag the mouse while clicking, resulting in the file being dropped into a folder by mistake." In other words, the real question is "How do I prevent users from performing accidental drag and drop operations?"

    The answer to this customer's real question is to increase the mouse drag sensitivity (via System­Parameters­Info(SPI_SETDRAGWIDTH) and SPI_SETDRAGHEIGHT) to require uses to drag the mouse a "definitely not accidental" distance before the system considers a drag operation to be in progress. Depending on your users, you might crank this up to 10, 30, or even 60 pixels.

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

  • The Old New Thing

    Things the locals know: How to have lunch at El Brillante


    One of my colleagues moved to Granada last year, and he kindly provided me some recommendations for places to eat in Madrid. We found El Brillante easily, positioned across the street from the Atoche train station, with its back door and terrace facing the Museo Nacional Centro de Arte Reina Sofia (which mercifully goes by the nickname Museo Reina Sofia). But once you step inside to order your lunch, you enter a crowded, cacophanous world with people yelling back and forth and nothing even resembling a line.

    Here is how to have lunch at El Brillante:

    • When you step inside, you will find the restaurant in the shape of a long, wide hallway, with a path down the center and a set of counters along each wall. Go to the side with the bar. The bar is the crowded place with the beer tap, as opposed to the cook who is the busy but lonely guy with the cases of food in front of him.
    • Work your way to the bar, which may be very crowded. We found that if you wander towards the side facing the museum, the bar is much less crowded.
    • The counter staff will come to you when it's your turn. I don't know whether there is an invisible queue or whether you have to get the attention of a staff person. When I was there, I was the only one waiting to order, so even if there were a queue, I was the only person in it.
    • Place your order. Do it in Spanish because nobody speaks English here. Fortunately, each item on the menu is numbered, so if you've learned your numbers, you can at least order your food. For beverages, you're on your own.
    • The counter staff will shout your order to the cook on the other side of the hall.
    • Enjoy your beverage while you wait for your food. Soak up the atmosphere as the counter staff shout more orders to the cook, the waiters from the terrace come in and shout five or six orders to the cook in rapid succession, the cook shouts completed orders to the wait staff, waiters deliver the food to the counter and shout the order to the counter staff... You may have noticed that there's a lot of shouting. That's just the way they do it here. Don't fight it. Revel in it.
    • Eat your food. Watch the counter staff juggle multiple tasks: Shouting orders, pouring drinks, making coffee, washing dishes, settling bills. Note that this arrangement would be a major health code violation in the United States, because the United States is safety-obsessed.
    • Napkin dispensers are on the counter, and you're going to run through a lot of napkins. But where's the trash? At your feet. The kickplate is a trough for soiled napkins.
    • When you're finished, get your server's attention (I asked for la cuenta—the check). But there is no actual check. The server merely calculates your bill in his head and tells you the total. Of course, if your knowledge of Spanish is limited to counting to twenty (learned from watching Sesame Street as a child), you may not understand what he says. If you have a pen, you can ask the counter staff to write the total on a napkin for you.
    • Pay, leave a 5% tip, and head out on your way.

    As you can see, it's a well-choreographed zoo.

    Oh, and the food is good, too. That's why the place is so crowded. During our brief stay, we saw calamari sandwiches whipping past one after another; they are apparently famous for them.

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

  • The Old New Thing

    Why can I type a lowercase s with caron with the numeric keypad, but not a lowercase r with caron?


    For concreteness, let's assume that you are using 437 as your OEM code page (which as we all know is not actually provided by the OEM) and 1252 as your ANSI code page (which as we all known is not actually the product of the American National Standards Institute).

    You can use Alt+0154 to type a Latin small letter s with caron because position 154 in code page 1252 is the Latin small letter s with caron. On the other hand, lowercase r with caron does not exist in code page 1252, nor does it exist in code page 437, so if you want to type that character, you're out of luck. The Alt+nnn sequence lets you type characters from the OEM code page, and Alt+0nnn lets you type characters from the ANSI code page, but if the character you want is in neither of them, then those sequences aren't going to help you.

    (As an experiment, I didn't write any motivating discussion. It's actually easier for me because coming up with a narrative to accompany a dry technical article is hard work. If I don't have to do it, so much the better for me.)

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

  • The Old New Thing

    The problem with setting up a story is that people focus on the set-up and miss the point of the story


    In writing, one of the steps you need to perform is motivating the discussion. Now, technically, you don't have to do that, but if you just dive into the guts of a topic right off the bat, people are going to say, "What the heck is going on and why should I care?"

    Consider, for example, an article I wrote a while back on how to use WMI to obtain computer configuration information. To motivate the discussion, I considered a customer who wanted to collect computer manufacturer information programmatically (presumably for asset inventory purposes). But really, the reason wasn't important. It was just something for the script to do. If it weren't printing the computer manufacturer, it could have been getting the number of processors, or querying, I dunno, the thermal state of the motherboard.

    Actually, the computer manufacturer was what I was after because of the bonus commentary regarding how computer manufacturer information is one of the things computer manufacturers often skimp on providing when they manufacture their computers.

    Often it's not even the set-up but the placeholder itself that people fixate on. Consider, for example, my complaint about repeated pony-begging. Most people understood that the question itself was just a placeholder (and some people even joined in), but you can always count on someone complaining about the placeholder.

    Another common problem is people who take an analysis of a specific case and extrapolate it to all cases. There are places where you want to use bitfields, and places where you don't. It so happens that the example I chose was one of the ones where it wasn't. Some people interpreted this to mean that there were no cases where you would want to use bitfields. Remember, good advice comes with a rationale so you can tell when it becomes bad advice. These people skipped the rationale and just applied the advice blindly.

    As an experiment, I've deleted the motivating preliminary discussion from tomorrow's article. It would have involved a little game of one-upsmanship between two Czech colleagues. (Update: Who, according to one commenter, have no self-respect.)

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

Page 2 of 4 (32 items) 1234