• The Old New Thing

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

    • 100 Comments

    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

    • 99 Comments

    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)
     {
      Console.WriteLine(name);
      hash.ComputeHash(bytes);
      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
    MD5
    6D915EC203DF0C918D13B63C4FF7C1EE
    SHA1
    49A2E2B22D27D450890E30D0A34EBA53B454925E
    SHA256
    2C928DC82E133B0FAD5DAA64BC373BE400C700B124749072816B7053EECC9A82
    SHA384
    080BDBB804B8F9B28731E6E17F872C6BE6F8F08B6670CA3424726295DE58A8DE
    2FE9EA43D724B7AA2ED3366CA9A80631
    SHA512
    D0A84D8B1B330F101D115044C9C7146605C951199BC2F036EE677C690D5151A9
    3F78FDFD8E6FF147EE2DB517A96642B24ED17D2306A772B953281CB4C0BEEDF1
    
  • The Old New Thing

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

    • 99 Comments

    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
    425-202-xxxx202-xxxx
    425-203-xxxx1-203-xxxx
    206-346-xxxx206-346-xxxx
    206-347-xxxx1-206-347-xxxx

    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

    • 98 Comments

    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?

    • 97 Comments

    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?

    • 97 Comments

    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."

    WLCM2DOS

    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

    • 97 Comments

    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)

    • 96 Comments

    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

    • 96 Comments

    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
    ^Z
            1 file(s) copied.
    
    C> echo %MARCO%
    %MARCO%
    
    C> marco
    
    C> echo %MARCO%
    polo
    

    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.

  • The Old New Thing

    Tales from the interview: Can you rotate this two-dimensional array?

    • 94 Comments

    My colleague jeffdav told me about one job interview with a graduating college senior that didn't go well because the candidate simply gave up.

    He offered a simple programming task: Write a function that takes a 4×4 two-dimensional array and rotates it clockwise by 90 degrees. For example, the entry in the upper left corner of the array goes to the upper right corner.

    The interview candidate simply gave up without even writing so much as a function prototype. "I can't do it."

    — Okay, well, let's take it a step at a time. Maybe take a specific example and see what we can learn from it.

    "It's some sort of matrix multiplication."

    — All right, well how would you start working that out?

    "I don't know. I can't do it."

    That's really not a good way to demonstrate your problem-solving skills: By responding to a problem with a simple "I can't do it." All of us are faced with things we can't do. The important thing is that we are willing to learn what we need in order to be able to do them.

    I wonder if this particular person thought that attitude would fly at a real job. If your boss gives you a difficult job, would you just say, "I can't do it"? Heck, how do you even graduate from college with that attitude? Your professor gives you an assignment, and you just say, "I can't do it"?

    (The punch line for people who actually know matrix algebra: Matrix multiplication doesn't solve the problem anyway.)

    Bonus commentary: I reprint JeffDav's comment which he posted below, since it is after all his story.

    This was a question reserved for intern candidates and fresh out of college hires. I was usually the first one on the loop and used this as a warm-up question. Once they got it, we'd move on to something more interesting. This one guy just refused to believe it was even possible.

    Also, I would phrase it as "rotate an N x N matrix where N >= 1, and you are given N along with the matrix A." This makes it super easy. If you allow an N x M matrix (i.e. non-square) the question gets much harder.

    I don't ask this question as often anymore. I get bored with asking the same questions over and over. Furthermore, I think after about the 100th time you ask a question you have lost perspective on it. Once you can write the answer on the whiteboard by heart without even thinking, you get annoyed by anyone who takes more than a few seconds thinking about it. It may not be a conscious annoyance but it's there if you think about it, and I think it gives you a bit of a negative bias at times. At least it does for me. It's good to find new questions so you have to solve them yourself and you have that feeling of approaching the problem for the first time fresh in your memory.

Page 4 of 436 (4,360 items) «23456»