• The Old New Thing

    Windows is not an MFC delivery channel


    Depending on what version of Windows you're running, there may be a variety of support DLLs for things that aren't formal product components, but which are merely along for the ride. For example, Windows 95 came with MFC30.DLL because the Fax Viewer was written with the help of MFC 3.0. But if you look at Windows 98, MFC30.DLL is gone.

    What happened?

    What happened is that Windows 98 didn't have a fax viewer that used MFC 3.0. The fact that some MFC 3.0 DLLs wound up on the machine with Windows 95 was merely a side effect of the implementation and not a part of the product specification. And in fact, if you chose not to install the Fax Viewer during Windows 95 setup, you wouldn't have gotten MFC30.DLL at all either, because MFC30.DLL wouldn't have been needed.

    We had a category of Windows 98 compatibility bugs from programs that assumed that MFC30.DLL was a contractual part of Windows. If the tester did a minimal install of Windows 95 and then installed the application, the application wouldn't run there either. The application vendor simply assumed that MFC was part of Windows, even though it wasn't. In other words, the program didn't work even on Windows 95. Is it a bug in Windows 98 if the program didn't work on Windows 95?

    This problem persists today. People go scrounging around the binaries that come with Windows looking for something they can remora. And then they're surprised when those binaries change or vanish entirely. For example, one customer had reverse-engineered the Kodak image viewer in Windows 2000 and wanted to keep using it in Windows XP. But those components are not included in Windows XP; the Kodak image viewer was merely a stopgap solution until the Windows XP fax and image viewer came along. (The linked Knowledge Base article has more information on that product.) I mention this because that customer, a Fortune 500 company, was trying to copy the files from Windows 2000 and install them onto a Windows XP machine and actually came to us asking for help in what may very well have been a violation of the Windows license agreement! (And certainly a violation of Microsoft's agreement with Kodak.)

    (I now predict that everybody will comment on the last two sentences and completely ignore the point of this article.)

  • The Old New Thing

    When programs assume that the system will never change, episode 1


    An example, all too frequent, of ways programs assume that the user interface will never change is reaching into system binaries and sucking out undocumented resources. In the shell, we have fallen into the reluctant position of carrying "dead" icons around for the benefit of programs that assumed that they would always be available. However, we often make these "orphaned" icons blank so that these programs don't crash, but they don't necessarily look all that wonderful either.

    Recently, I learned of a new type of resource stealing: Stealing animations. For Windows Vista, there have been many changes to the way the system internally organizes its resources in order to support the Multilingual User Interface feature. One of the things we found was a handful of programs that reach directly into Shell32.dll in order to obtain the file copy animation. Too bad (1) the animation isn't kept there any more, and even if we moved the animation back to its original location, (2) the animation uses a new compression scheme that older programs can't handle.

    Remember, resources in system DLLs should be treated as implementation details, unless explicitly documented otherwise.

    I'm not sure what we're going to do about the animation resource problem. Suggestions anyone? Should we declare these programs broken and make the people who bought them go back to their vendors for upgrades? (What if there is no vendor?) Should we develop a shim and hope that those four are the only programs that need it? Should we carry the original animation in shell32.dll as junk? If I told you that one of the programs that did this won "Game of the Year" recently, would that change your answer? What if another turned out to be a top-rated anti-spyware program?

  • The Old New Thing

    Raymond makes a psychic prediction for 2006


    I have gazed into my crystal ball and emerged with a prediction for 2006. Revealing my prediction now may influence the event itself, so I will post only the hash for the prediction. I will post the actual prediction at the end of the year.

    using System.Security.Cryptography;
    using System;
    class Prediction {
     static void DoHash(byte[] bytes, string name, HashAlgorithm hash)
      byte[] result = hash.Hash;
      for (int i = 0; i < result.Length; i++) {
       Console.Write("{0:X2}", result[i]);
       if (i % 32 == 31) Console.WriteLine();
      if (result.Length % 32 != 0) Console.WriteLine();
     static void Main()
      string msg = "prediction goes here";
      Console.WriteLine("length {0}", msg.Length);
      byte[] bytes = (new System.Text.ASCIIEncoding()).GetBytes(msg);
      DoHash(bytes, "MD5", MD5.Create());
      DoHash(bytes, "SHA1", SHA1.Create());
      DoHash(bytes, "SHA256", SHA256.Create());
      DoHash(bytes, "SHA384", SHA384.Create());
      DoHash(bytes, "SHA512", SHA512.Create());

    The output of this program (after you replace "prediction goes here" with the actual prediction, of course) is as follows:

    length 45
  • The Old New Thing

    It's not surprising at all that people search for Yahoo


    Earlier this year, one columnist was baffled as to why "Yahoo" was the most searched-for term on Google. I wasn't baffled at all. Back in 2001, Alexa published the top ten most searched-for terms on their service, and four of the top ten were URLs: yahoo.com, hotmail.com, aol.com, and ebay.com.

    A lot of people simply don't care to learn the difference between the search box and the address bar. "If I type what I want into this box here, I sometimes get a strange error message. But if I type it into that box there, then I get what I want. Therefore, I'll use that box there for everything." And you know what? It doesn't bother me that they don't care. In fact, I think it's good that they don't care. Computers should adapt to people, not the other way around.

    You can try to explain to these people, "You see, this is a URL, so you type it into the address box. But that is a search phrase, so you type it into the search box."

    "You-are-what? Look, I don't care about your fancy propeller-beanie acronyms. You computer types are always talking about how computers are so easy to use, and then you make up these arbitrary rules about where I'm supposed to type things. If I want something, I type into this box and click 'Search'. And it finds it. Watch. I want Yahoo, so I type 'yahoo' into the box, and boom, there it is. I have a system that works. Why are you trying to make my life more confusing?"

    I remember attending a presentation by the MSN Explorer team on what they learned about how people use a web browser. They found many situations where people failed to accomplish their desired task because they typed the right thing into the wrong box. But instead of trying to teach people which box to type it in, they just expanded the definition of "right". You typed your query into the wrong box? No problem, we'll just pretend you typed it into the correct box. In fact, let's just get rid of all these special-purposes boxes. Whatever you want, just type it into this box, and we'll get it for you.

    I wish the phone company would learn this. Sometimes I'll dial a telephone number and I'll get an automated recording that says, "I'm sorry. You must dial a '1' before the number. Please hang up and try again." Or "I'm sorry. You must not dial a '1' before the number. Please hang up and try again." That's because in the state of Washington, there are complicated rules about when you have to dial a "1" in front of the number and when you don't. (Fortunately, the rule on when you have to dial the area code is easier to remember: If the area code you are calling is the same as the area code you are dialing from, then you can omit the area code.) For example, suppose your home number is 425-882-xxxx. Here's how you have to dial the following numbers:

    To call this numberyou dial

    If you get it wrong, the voice comes on the line to tell you. Hey, since you know what I did wrong and you know what I meant to do, why not just fix it? If I dial a number and forget the "1", just insert the 1 and connect the call. If I dial a number and include the "1" when I didn't need to, just delete the 1 and connect the call. Don't make me have to look up in the book whether I need a 1 or not. (In the front of the phone book are tables showing which numbers need a "1" and which don't. I hate those tables.)

    (Yes, I know there are weird technical/legal reasons for why I have to dial the phone in four different ways depending on whom I want to call. But it's still wrong that these technical/legal reasons mean that the rules for dialing a telephone are impossibly complicated.)

  • The Old New Thing

    ZOMG! This program is using 100% CPU!1! Think of the puppies!!11!!1!1!eleven


    For some reason, people treat a program consuming 100% CPU as if it were unrepentantly running around kicking defenseless (and cute) puppies. Calm down already. I get the impression that people view the CPU usage column in Task Manager not as a diagnostic tool but as a way of counting how many puppies a program kicks per second.

    While a program that consumes 100% CPU continuously (even when putatively idle) might legitimately be viewed as an unrepentant puppy-kicker, a program that consumes 100% CPU in pursuit of actually accomplishing something is hardly scorn-worthy; indeed it should be commended for efficiency!

    Think of it this way: Imagine if your CPU usage never exceed 50%. You just overpaid for your computer; you're only using half of it. A task which could have been done in five minutes now takes ten. Your media player drops some frames out of your DVD playback, but that's okay, because your precious CPU meter never went all the way to the top. (Notice that the CPU meter does not turn red when CPU usage exceeds 80%. There is no "danger zone" here.)

    Consider this comment where somebody described that they want their program to use less CPU but get the job done reasonably quickly. Why do you want it to use less CPU? The statement makes the implicit assumption that using less CPU is more important than getting work done as fast as possible.

    You have a crowd of people at the bank and only ten tellers. If you let all the people into the lobby at once, well, then all the tellers will be busy—you will have 100% teller utilization. These people seem to think it would be better to keep all the customers waiting outside the bank and only let them into the lobby five at a time in order to keep teller utilization at 50%.

    If it were done when 'tis done, then 'twere well / It were done quickly.

    Rip off the band-aid.

    Piss or get off the pot.

    Just do it.

    If you're going to go to the trouble of taking the CPU out of a low-power state, you may as well make full use of it. Otherwise, you're the person who buys a bottle of water, drinks half of it, then throws away the other half "because I'm thinking of the environment and reducing my water consumption." You're making the battery drain for double the usual length of time, halving the laptop's run time because you're trying to "conserve CPU."

    If the task you are interested in is a low priority one, then set your thread priority to below-normal so it only consumes CPU time when there are no foreground tasks demanding CPU.

    If you want your task to complete even when there are other foreground tasks active, then leave your task's priority at the normal level. Yes, this means that it will compete with other foreground tasks for CPU, but you just said that's what you want. If you want it to compete "but not too hard", you can sprinkle some Sleep(0) calls into your code to release your time slice before it naturally expires. If there are other foreground tasks, then you will let them run; if there aren't, then the Sleep will return immediately and your task will continue to run at full speed.

    And cheerfully watch that CPU usage go all the way to 100% while your task is running. Just make sure it drops back to zero when your task is complete. You don't want to be a task which consumes 100% CPU even when there's nothing going on. That'd just be kicking puppies.

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

    Clarification: Many people appear to be missing the point. So let's put it more simply: Suppose you have an algorithm that takes 5 CPU-seconds to complete. Should you use 100% CPU for 5 seconds or 50% CPU for 10 seconds? (Obviously, if you can refine your algorithm so it requires only 2 CPU-seconds, that's even better, but that's unrelated to the issue here.)

  • The Old New Thing

    Why does Outlook map Ctrl+F to Forward instead of Find, like all right-thinking programs?


    It's a widespread convention that the Ctrl+F keyboard shortcut initiates a Find operation. Word does it, Excel does it, Wordpad does it, Notepad does it, Internet Explorer does it. But Outlook doesn't. Why doesn't Outlook get with the program?

    Rewind to 1995.

    The mail team was hard at work on their mail client, known as Exchange (code name Capone, in keeping with all the Chicago-related code names from that era). Back in those days, the Ctrl+F keyboard shortcut did indeed call up the Find dialog, in accordance with convention.

    And then a bug report came in from a beta tester who wanted Ctrl+F to forward rather than find, because he had become accustomed to that keyboard shortcut from the email program he used before Exchange.

    That beta tester was Bill Gates.

  • The Old New Thing

    Why is the Program Files directory called Program Files instead of just Programs?


    Some people suggest that one thing Microsoft Research could do with that time machine they're working on is to go back in time and change the name of the Program Files directory to simply Programs.

    No, it really should be Program Files.

    Program Files are not the same as Programs. Programs are things like Calc, Notepad, Excel, Photoshop. They are things you run.

    Program Files are things like ACRORD32.DLL and TWCUTCHR.DLL. They are files that make programs run.

    If the directory were named Programs, then people who wanted to run a program would start digging into that directory and seeing a page full of weird DLL names and wonder "What the heck kind of programs are these?" And eventually they might figure out that if they want to run PowerPoint, they need to double-click on the icon named POWERPNT. "Computers are so hard to use."


    If you want to find your programs, go to the Start menu. The Program Files directory is like the pantry of a restaurant. You aren't expected to go in there and nibble on things that look interesting. You're expected to order things from the menu.

  • The Old New Thing

    Okay, I changed my mind, I wrote a book after all


    Back in 2003, I wrote that I'm doing this instead of writing a book. That was true then, but last year I decided to give this book thing another go, only to find that publishers generally aren't interested in this stuff any more.

    "Does the world really need another book on Win32? Nobody buys Win32 books any more, that dinosaur!"

    "A conversational style book? People want books with step-by-step how-to's and comprehensive treatments, not water cooler anecdotes!"

    "Just 200 pages? There isn't enough of an audience for a book that small!"

    Luckily, I found a sympathetic ear from the folks at Addison-Wesley Professional who were willing to take a chance on my unorthodox proposal. But I caved on the length, bringing it up to 500 pages. Actually, I came up with more like 700 pages of stuff, and they cut it back to 500, because 700 pages would take the book into the next price tier, and "There isn't enough of an audience for a book that big!"

    Eighteen months later, we have The Old New Thing: Practical Development Throughout the Evolution of Windows, following in what appears to be the current fad of giving your book a title of the form Catchy Phrase: Longer Explanation of What the Catchy Phrase Means.

    It's a selection of entries from this blog, loosely organized, and with new material sprinkled in. There are also new chapters that go in depth into parts of Win32 you use every day but may not fully understand (the dialog manager, window messages), plus a chapter dedicated to Taxes. (For some reason, the Table of Contents on the book web site is incomplete.)

    Oh, and those 200 pages that got cut? They'll be made available for download as "bonus chapters". (The bonus chapters aren't up yet, so don't all rush over there looking for them.)

    The nominal release date for the book is January 2007, which is roughly in agreement with the book web site which proclaims availability on December 29th. Just in time for Christmas your favorite geek, if your favorite geek can't read a calendar.

    Now I get to see how many people were lying when they said, "If you wrote a book based on this blog, I'd buy it."

    (Update: The bonus chapters are now available.)

    (Update: Now available in Japanese! ISBN 978-4756150004.)

    (Update: Now available in Chinese! ISBN 7111219194.)

  • The Old New Thing

    The wisdom of seventh graders: What to do with a time machine (part 1)


    All the students at a local school were asked to composed an in-class essay on the following topic: "Your science teacher has invented a time machine. You have been selected to take the first trip. Explain in a multi-paragraph letter to your teacher where you will go and why." (Students were given two hours, plus one additional hour upon request. In practice, many students were finished early and almost nobody requested the third hour.)

    (Aside: Sometimes I think my readers believe in time machines. For example, one of them wondered why OLE/COM uses HRESULTs instead of Win32 error codes. Um, when OLE was invented, Win32 didn't exist.)

    The students really enjoyed this topic. Too much so, however, for more than a few of them turned their essays into a narrative rather than sticking to the assignment. One student was so excited that the essay consisted of a single five-page paragraph. Well, technically it was two paragraphs, thereby meeting the letter (if not the spirit) of the "multi-paragraph" requirement. About halfway down page three was this sentence: "The essay continues in the next paragraph."

    Roughly two thirds of the students opted to go into the past; one third chose to go into the future. One student didn't travel in time at all (!), choosing instead to visit Europe in the present day "to see castles and ruins". Psst, you've got a time machine. Why not go and see the ruins before they are ruined? (Actually, some friends pointed out to me that travelling to the present day is still handy. You can use your time machine as a teleporter. And you can even set the time machine to zip you backward, say, eight hours. That way, when you travel from Seattle to Europe, you arrive without any jet lag!)

    Boys were more likely to want to travel back in time to get rich, although their plans for doing so were not necessarily fully thought-out.

    • Go back in time, steal an invention, and then bring it back to the present.
    • Go back in time thirty years and invest all your money in Google, Amazon, and Microsoft.
    • Go back to the time of Jesus and sell a bag of candy to the king in exchange for gold and gemstones.
    • Go to the 1970's buy up land in California, and then return to the present and you'll be filthy rich.
    • Go back in time, bury some everyday objects, then return to the present and dig them up. Bingo, instant antiques! (This one had a chance of working.)

    (Good luck getting anybody in the past to accept today's money.)

    Girls were more likely to travel in time to meet themselves or close ancestors.

    • Go back in time to meet your grandparents who died when you were very young.
    • Go forward in time to see how you did. (These people were very susceptible to lapsing into speculative fiction.)

    A few students confused a time machine with regressive therapy, choosing to go back in time to re-live a cherished moment from a year or two ago. Psst, if you use a time machine to go into the past to visit yourself on that awesome vacation to Hawaii, you won't re-live the vacation. You'll be watching the other copy of yourself enjoy the vacation. (And that's assuming that the other copy of yourself doesn't see you and freak out.)

    Several students wanted to change world history.

    • Go back to Los Alamos and convince the scientists not to detonate the first atomic bomb.
    • Go back to New York City on September 11, 2001.
      • One student has a clever plan: Run into the World Trade Center buildings and pull the fire alarms eleven minutes before the planes collided with the buildings. By the student's calculations, that's enough time to get everybody out of the building but not so much time that the firemen will have arrived.
      • Another student wanted to prevent the planes from crashing into the Empire State Building. (I think he succeeded!)
    • Go back to Phuket in December, 2004 and warn everybody about the coming tsunami. (The student acknowledges that he will likely fail but he wants to try anyway.)

    Many students wanted to go back in time to observe and experience a historical period. One student wanted to ask Jesus to teach him how to walk on water. (Step one: Be the son of God.)

    Coming up in Part 2, selected sentences from student essays.

    Where would you go if you could take one trip in a time machine?

  • The Old New Thing

    A new scripting language doesn't solve everything


    Yes, there are plenty of scripting languages that are much better than boring old batch. Batch files were definitely a huge improvement over SUBMIT back in 1981, but they've been showing their age for quite some time. The advanced age of boring old batch, on the other hand, means that you have millions of batch files out there that you had better not break if you know what's good for you. (Sure, in retrospect, you might decide to call the batch language a design mistake, but remember that it had to run in 64KB of memory on a 4.77MHz machine while still remaining compatible in spirit with CP/M.)

    Shipping a new command shell doesn't solve everything either. For one thing, you have to decide if you are going to support classic batch files or not. Maybe you decide that you won't and prefer to force people to rewrite all their batch files into your new language. Good luck on that.

    On the other hand, if you decide that you will support batch files after all, then presumably your new command shell will not execute old batch files natively, but rather will defer to CMD.EXE. And there's your problem: You see, batch files have the ability to modify environment variables and have the changes persist beyond the end of the batch file. Try it:

    C> copy con marco.cmd
    @set MARCO=polo
            1 file(s) copied.
    C> echo %MARCO%
    C> marco
    C> echo %MARCO%

    If your new command shell defers to CMD.EXE, these environment changes won't propagate back to your command shell since the batch file modifies the environment variables of CMD.EXE, not your shell. Many organizations have a system of batch files that rely on the ability to pass parameters between scripts by stashing them into environment variables. The DDK's own razzle does this, for example, in order to establish a consistent build environment and pass information to build.exe about what kind of build you're making. And I bet you have a batch file or two that sets your PROMPT or PATH environment variable or changes your current directory.

    So good luck with your replacement command shell. I hope you figure out how to run batch files.

Page 4 of 453 (4,525 items) «23456»