History

  • The Old New Thing

    It's time we face reality, my friends: We're not rocket scientists

    • 12 Comments

    During the development of Windows 95, it was common for team members to pay visits to other teams to touch base and let them know what's been happening on the Windows 95 side of the project.

    It was during one of these informal visits that the one of my colleagues reported that he saw that one of the members of the partner team had a Gary Larson cartoon from The Far Side depicting a group of scientists studying a multi-stage rocket ship they just assembled, but the stages are connected all crooked. One of the scientists says, "It's time we face reality, my friends. … We're not exactly rocket scientists."

    The comic was "enhanced" a bit by the partner team. They added a sign on the wall of the laboratory that says Windows 95 Development, and the stages of the rocket are alternately labeled 16-bit and 32-bit. The graffiti were clearly poking fun at Windows 95's attempt to straddle the 16-bit and 32-bit worlds.

    The Windows 95 team knew how to take a joke, and for a time, they adopted "Hey, we're not rocket scientists" as a catch phrase.

    Following up on that article from 2010: Microsoft ran a free seminar on Windows 95 development for Macintosh programmers at the 1995 MacWorld Expo. Upon successful completion, participants received T-shirts with the slogan "Windows 95 sucks less."

  • The Old New Thing

    My friend and his buddy invented the online shopping cart back in 1994

    • 25 Comments

    Back in 1994 or so, my friend helped out his buddy who worked as the IT department for a local Seattle company known as Sub Pop Records. Here's what their Web site looked like back then. Oh, and in case you were wondering, when I said that his buddy worked as the IT department, I mean that the IT department consisted of one guy, namely him. And this wasn't even his real job. His main job was as their payroll guy; he just did their IT because he happened to know a little bit about computers. (If you asked him, he'd say that his main job was as a band member in Earth.)

    The mission was to make it possible for fans to buy records online. Nobody else was doing this at the time, so they had to invent it all by themselves. The natural metaphor for them was the shopping cart. You wandered through the virtual record store putting records in your basket, and then you went to check out.

    The trick here is how to keep track of the user as they wander through your store. This was 1994. Cookies hadn't been invented yet, or at least if they had been invented, support for them was very erratic, and you couldn't assume that every visitor to your site is using a browser that supported them.

    The solution was to encode the shopping cart state in the URL by making every link on the page include the session ID in the URL. It was crude but it got the job done.

    The site went online, and soon they were taking orders from excited fans around the world. The company loved it, because they probably got to charge full price for the records (rather than losing a cut to the distributor). And my friend told me the deep dark secret of his system: "We do okay if you ask for standard shipping, but the real money is when somebody is impatient and insists on overnight shipping. Overcharging for shipping is where the real money is."

    (Note: Statements about business models for a primitive online shopping site from 1994 are not necessarily accurate today.)

  • The Old New Thing

    Did the Windows 95 interface have a code name?

    • 17 Comments

    Commenter kinokijuf wonders whether the Windows 95 interface had a code name.

    Nope.

    We called it "the new shell" while it was under preliminary development, and when it got enabled in the builds, we just called it "the shell."

    (Explorer originally was named Cabinet, unrelated to the container file format of the same name. This original name lingers in the window class: CabinetWClass.)

  • The Old New Thing

    The alternate story of the time one of my colleagues debugged a line-of-business application for a package delivery service

    • 77 Comments

    Some people objected to the length, the structure, the metaphors, the speculation, and fabrication. So let's say they were my editors. Here's what the article might have looked like, had I taken their recommendations. (Some recommendations were to text that was also recommended cut. I applied the recommendations before cutting; the cuts are in gray.) You tell me whether you like the original or the edited version.

    Back in the days of Windows 95 development, one of my colleagues debugged a line-of-business application for a major delivery service. This was a program that the company gave to its top-tier high-volume customers, so that they could place and track their orders directly. And by directly, I mean that the program dialed the modem (since that was how computers communicated with each other back then) to contact the delivery service's mainframe (it was all mainframes back then) a computer at the delivery service and upload the new orders and download the status of existing orders.¹

    [Length. The "top tier customer" part of the story is irrelevant.]
    [Length. The mainframe part of the story is irrelevant.]
    [Speculation. No proof that the computer being dialed is a mainframe. For all you know, it was an Apple ][ on the other end of the modem.]

    Version 1.0 of the application had a notorious bug: Ninety days after you installed the program, it stopped working. They forgot to remove the beta expiration code. I guess that's why they have a version 1.01. It told you that the beta period has expired.

    [Length. Version 1.0 is irrelevant.]
    [Speculation. No proof that the beta expiration code was left by mistake. It could have been intentional, for whatever reason. Probably some nefarious reason.]

    Anyway, the bug that my colleague investigated was that If you entered a particular type of order with a particular set of options in a particular way, then the application crashed your system. Setting up a copy of the application in order to replicate the problem was itself a bit of an ordeal, but that's a whole different story.

    [Length. Retransition no longer necessary. The "setting up" story is irrelevant.]

    Okay, the program is set up, and yup, it crashes exactly as described when run on Windows 95. Actually, it also crashes exactly as described when run on Windows 3.1. This is just plain an application bug.

    [Length. Irrelevant.]

    The initial crash

    [Structure. Create heading (even though it gives away some of the story).]

    Here's why it crashed: After the program dials up the mainframe to submit the order the order system, it tries to refresh the list of orders that have yet to be delivered a list box control. The code that does this assumes that the list of undelivered orders the list box control is the control with focus. But if you ask for labels to be printed, then the printing code changes focus in order to display the "Please place the label on the package exactly like this" dialog, under the specific circumstances, the control is no longer focus; as I recall, it was because a dialog box had appeared and changed focus, and as a result, the refresh code can't find the undelivered order list list box and crashes on a null pointer. (I'm totally making this up, by the way. The details of the scenario aren't important to the story.)

    [Fabrication. All that is known is that there was a list box that lost focus to a dialog box.]

    Okay, well, that's no big deal. A null pointer fault should just put up the Unrecoverable Application Error dialog box and close the program. Why does this particular null pointer fault crash the entire system?

    [Embellishment.]

    Recovering from the crash

    [Structure. Create heading.]

    The developers of the program saw that their refresh code sometimes crashed on a null pointer, and instead of fixing it by actually fixing the code so it could find the list of undelivered orders even if it didn't have focus, or fixing it by adding a null pointer check, they fixed it by adding a null pointer exception handler. (I wish to commend myself for resisting the urge to put the word fixed in quotation marks in that last sentence.) The program installed a null pointer exception handler.

    [Speculation. No way of knowing that this was what the developers were thinking when they wrote the code.]

    Now, 16-bit Windows didn't have structured exception handling. The only type of exception handler was a global exception handler, and this wasn't just global to the process. This was global to the entire system. Your exception handler was called for every exception everywhere. If you screwed it up, you screwed up the entire system. (I think you can see where this is going.)

    [Embellishment.]

    The developers of the program converted their global exception handler to a local one by going to every function that had a "We seem to crash on a null pointer and I don't know why" bug and making these changes: A few functions in the program took the following form:

    extern jmp_buf caught;
    extern BOOL trapExceptions;
    
    void scaryFunction(...)
    {
     if (setjmp(&caught)) return;
     trapExceptions = TRUE;
     ... body of function ...
     trapExceptions = FALSE;
    }
    

    Their global exception handler checks the trapExceptions global variable, and if it is TRUE, they set it back to FALSE and do a longjmp which sends control back to the start of the function, which detects that something bad must have happened and just returns out of the function.

    [Speculation. No way of knowing that this was what the developers were thinking when they wrote the code. No proof that the code was first written without a global exception handler, and that the handler was added later. No proof that every such function set this variable. No proof that the reason for adding the setjmp was to protect against null pointer failures.]

    Yes, things are kind of messed up as a result of this. Yes, there is a memory leak. But at least their application didn't crash.

    [Embellishment.]

    On the other hand, if the global variable is FALSE, because their application crashed in some other function that didn't have this special protection, or because some other totally unrelated application crashed, the global exception handler decided to exit the application by running around freeing all the DLLs and memory associated with their application.

    Okay, so far so good, for certain values of good.

    [Embellishment.]

    Failed recovery

    [Structure. Add heading here.]

    These system-wide exception handlers had to be written in assembly code because they were dispatched with a very strange calling convention. But the developers of this application didn't write their system-wide exception handler in assembly language. Their application was written in MFC, so they just went to Visual C++ (as it was then known), clicked through some Add a Windows hook wizard, and got some generic HOOKPROC. (I don't know if Visual C++ actually had an Add a Windows hook wizard; they could just have copied the code from somewhere.) Nevermind that these system-wide exception handlers are not HOOKPROCs, so the function has the wrong prototype. What's more, the code they used marked the hook function as __loadds. This means that the function For whatever reason, the handler they installed saves the previous value of the DS register on entry, then changes the register to point to the application's data, and on exit, the function restores the previous value of DS.

    [Speculation. No proof that the program was written with MFC in the Microsoft Visual C++ IDE. It could have been written with Notepad in assembly language that just happens to look like the assembly language generated by the Microsoft Visual C++ compiler when it compiles code written in MFC.]

    The DS is a register on the x86 CPU that describes the data currently being operated upon. All that's important here is that the value in the DS register must always be valid, or the CPU will raise an exception.

    [Need to explain the DS register in case the reader cannot infer this from the description that comes later. We have established that neither the author nor the reader is allowed to draw inferences.]

    Okay, now we're about to enter the set piece at the end of the movie: Our hero's fear of spiders, his girlfriend's bad ankle from an old soccer injury, the executive toy on the villain's desk, and all the other tiny little clues dropped in the previous ninety minutes come together to form an enormous chain reaction.

    [Embellishment.]

    The application crashes on a null pointer. The system-wide custom exception handler is called. The crash is not one that is being protected by the global variable, so the custom exception handler frees the application from memory. The system-wide custom exception handler now returns, but wait, what is it returning to?

    The crash was in the application, which means that the DS register it saved on entry to the custom exception handler points to the application's data. The custom exception handler freed the application's data and then returned, declaring the exception handled. As the function exited, it tried to restore the original DS register, but the CPU said, "Nice try, but that is not a valid value for the DS register (because you freed it)." The CPU reported this error by (dramatic pause) raising an exception.

    [Embellishment.]

    That's right, The system-wide custom exception handler crashed with an exception.

    [Embellishment]

    The chain reaction

    [Structure. Add heading here.]

    Okay, things start snowballing. This is the part of the movie where the director uses quick cuts between different locations, maybe with a little slow motion thrown in.

    [Embellishment.]

    Since an exception was raised, the custom exception handler is called recursively. Each time through the recursion, the custom exception handler frees all the DLLs and memory associated with the application. But that's okay, right? Because the second and subsequent times, the memory was already freed, so the attempts to free them again will just fail with an invalid parameter error.

    But wait, their list of DLLs associated with the application included USER, GDI, and KERNEL. Now, Windows is perfectly capable of unloading dependent DLLs when you unload the main DLL, so when they unloaded their main program, the kernel already decremented the usage count on USER, GDI, and KERNEL automatically. But they apparently didn't trust Windows to do this, because after all, it was Windows that was causing their application to crash, so they took it upon themselves to free those DLLs manually. For whatever reason, the handler frees the DLLs anyway.

    [Speculation. No way of knowing that this was what the developers were thinking when they wrote the code.]

    Therefore, each time through the loop, the usage counts for USER, GDI, and KERNEL drop by one. Zoom in on the countdown clock on the ticking time bomb.

    Beep beep beep beep beep. The reference count finally drops to zero. The window manager, the graphics subsystem, and the kernel itself have all been unloaded from memory. There's nothing left to run the show!

    [Embellishment.]

    Boom, bluescreen. Hot flaming death.

    The punch line to all this is that whenever you call the company's product support line and describe a problem you encountered, their response is always, "Yeah, we're really sorry about that one."

    [Length. Irrelevant.]

    Bonus chatter: What is that whole different story mentioned near the top?

    [Length. Cut the entire bonus chatter. Irrelevant story.]

    Well, when the delivery service sent the latest version of the software to the Windows 95 team, they also provided an account number to use. My colleague used that account number to try to reproduce the problem, and since the problem occurred only after the order was submitted, she would have to submit delivery requests, say for a letter to be picked up from 221B Baker Street and delivered to 62 West Wallaby Street, or maybe for a 100-pound package of radioactive material to be picked up from 1600 Pennsylvania Avenue and delivered to 10 Downing Street. all of which were fictitious.

    [Fabrication. No proof that these were the addresses and orders used. All that is known is that fictitious orders were placed.]

    After about two weeks of this, my colleague got a phone call from people identifying themselves as Microsoft's shipping department. "What the heck are you doing?"

    [Speculation. No proof that the call truly came from the shipping department. Could have been a lucky prank call.]
    [Fabrication. No transcript of this call exists.]

    It turns out that the account number my colleague was given was Microsoft's own corporate account number. As in a real live account. She was inadvertently prank-calling the delivery company and sending actual trucks all over the country to pick up nonexistent letters and packages. The people who identified themselves as Microsoft's shipping department and people from the delivery service's headquarters claimed that they were frantic trying to trace where all the bogus orders were coming from.

    [Hearsay.]

    ¹ Mind you, this sort of thing is the stuff that average Joe customers can do while still in their pajamas, but back in those days, it was a feature that only top-tier customers had access to, because, y'know, mainframe.

  • The Old New Thing

    The time one of my colleagues debugged a line-of-business application for a package delivery service

    • 41 Comments

    Back in the days of Windows 95 development, one of my colleagues debugged a line-of-business application for a major delivery service. This was a program that the company gave to its top-tier high-volume customers, so that they could place and track their orders directly. And by directly, I mean that the program dialed the modem (since that was how computers communicated with each other back then) to contact the delivery service's mainframe (it was all mainframes back then) and upload the new orders and download the status of existing orders.¹

    Version 1.0 of the application had a notorious bug: Ninety days after you installed the program, it stopped working. They forgot to remove the beta expiration code. I guess that's why they have a version 1.01.

    Anyway, the bug that my colleague investigated was that if you entered a particular type of order with a particular set of options in a particular way, then the application crashed your system. Setting up a copy of the application in order to replicate the problem was itself a bit of an ordeal, but that's a whole different story.

    Okay, the program is set up, and yup, it crashes exactly as described when run on Windows 95. Actually, it also crashes exactly as described when run on Windows 3.1. This is just plain an application bug.

    Here's why it crashed: After the program dials up the mainframe to submit the order, it tries to refresh the list of orders that have yet to be delivered. The code that does this assumes that the list of undelivered orders is the control with focus. But if you ask for labels to be printed, then the printing code changes focus in order to display the "Please place the label on the package exactly like this" dialog, and as a result, the refresh code can't find the undelivered order list and crashes on a null pointer. (I'm totally making this up, by the way. The details of the scenario aren't important to the story.)

    Okay, well, that's no big deal. A null pointer fault should just put up the Unrecoverable Application Error dialog box and close the program. Why does this particular null pointer fault crash the entire system?

    The developers of the program saw that their refresh code sometimes crashed on a null pointer, and instead of fixing it by actually fixing the code so it could find the list of undelivered orders even if it didn't have focus, or fixing it by adding a null pointer check, they fixed it by adding a null pointer exception handler. (I wish to commend myself for resisting the urge to put the word fixed in quotation marks in that last sentence.)

    Now, 16-bit Windows didn't have structured exception handling. The only type of exception handler was a global exception handler, and this wasn't just global to the process. This was global to the entire system. Your exception handler was called for every exception everywhere. If you screwed it up, you screwed up the entire system. (I think you can see where this is going.)

    The developers of the program converted their global exception handler to a local one by going to every function that had a "We seem to crash on a null pointer and I don't know why" bug and making these changes:

    extern jmp_buf caught;
    extern BOOL trapExceptions;
    
    void scaryFunction(...)
    {
     if (setjmp(&caught)) return;
     trapExceptions = TRUE;
     ... body of function ...
     trapExceptions = FALSE;
    }
    

    Their global exception handler checks the trapExceptions global variable, and if it is TRUE, they set it back to FALSE and do a longjmp which sends control back to the start of the function, which detects that something bad must have happened and just returns out of the function.

    Yes, things are kind of messed up as a result of this. Yes, there is a memory leak. But at least their application didn't crash.

    On the other hand, if the global variable is FALSE, because their application crashed in some other function that didn't have this special protection, or because some other totally unrelated application crashed, the global exception handler decided to exit the application by running around freeing all the DLLs and memory associated with their application.

    Okay, so far so good, for certain values of good.

    These system-wide exception handlers had to be written in assembly code because they were dispatched with a very strange calling convention. But the developers of this application didn't write their system-wide exception handler in assembly language. Their application was written in MFC, so they just went to Visual C++ (as it was then known), clicked through some Add a Windows hook wizard, and got some generic HOOKPROC. (I don't know if Visual C++ actually had an Add a Windows hook wizard; they could just have copied the code from somewhere.) Nevermind that these system-wide exception handlers are not HOOKPROCs, so the function has the wrong prototype. What's more, the code they used marked the hook function as __loadds. This means that the function saves the previous value of the DS register on entry, then changes the register to point to the application's data, and on exit, the function restores the previous value of DS.

    Okay, now we're about to enter the set piece at the end of the movie: Our hero's fear of spiders, his girlfriend's bad ankle from an old soccer injury, the executive toy on the villain's desk, and all the other tiny little clues dropped in the previous ninety minutes come together to form an enormous chain reaction.

    The application crashes on a null pointer. The system-wide custom exception handler is called. The crash is not one that is being protected by the global variable, so the custom exception handler frees the application from memory. The system-wide custom exception handler now returns, but wait, what is it returning to?

    The crash was in the application, which means that the DS register it saved on entry to the custom exception handler points to the application's data. The custom exception handler freed the application's data and then returned, declaring the exception handled. As the function exited, it tried to restore the original DS register, but the CPU said, "Nice try, but that is not a valid value for the DS register (because you freed it)." The CPU reported this error by (dramatic pause) raising an exception.

    That's right, the system-wide custom exception handler crashed with an exception.

    Okay, things start snowballing. This is the part of the movie where the director uses quick cuts between different locations, maybe with a little slow motion thrown in.

    Since an exception was raised, the custom exception handler is called recursively. Each time through the recursion, the custom exception handler frees all the DLLs and memory associated with the application. But that's okay, right? Because the second and subsequent times, the memory was already freed, so the attempts to free them again will just fail with an invalid parameter error.

    But wait, their list of DLLs associated with the application included USER, GDI, and KERNEL. Now, Windows is perfectly capable of unloading dependent DLLs when you unload the main DLL, so when they unloaded their main program, the kernel already decremented the usage count on USER, GDI, and KERNEL automatically. But they apparently didn't trust Windows to do this, because after all, it was Windows that was causing their application to crash, so they took it upon themselves to free those DLLs manually.

    Therefore, each time through the loop, the usage counts for USER, GDI, and KERNEL drop by one. Zoom in on the countdown clock on the ticking time bomb.

    Beep beep beep beep beep. The reference count finally drops to zero. The window manager, the graphics subsystem, and the kernel itself have all been unloaded from memory. There's nothing left to run the show!

    Boom, bluescreen. Hot flaming death.

    The punch line to all this is that whenever you call the company's product support line and describe a problem you encountered, their response is always, "Yeah, we're really sorry about that one."

    Bonus chatter: What is that whole different story mentioned near the top?

    Well, when the delivery service sent the latest version of the software to the Windows 95 team, they also provided an account number to use. My colleague used that account number to try to reproduce the problem, and since the problem occurred only after the order was submitted, she would have to submit delivery requests, say for a letter to be picked up from 221B Baker Street and delivered to 62 West Wallaby Street, or maybe for a 100-pound package of radioactive material to be picked up from 1600 Pennsylvania Avenue and delivered to 10 Downing Street.

    After about two weeks of this, my colleague got a phone call from Microsoft's shipping department. "What the heck are you doing?"

    It turns out that the account number my colleague was given was Microsoft's own corporate account number. As in a real live account. She was inadvertently prank-calling the delivery company and sending actual trucks all over the country to pick up nonexistent letters and packages. Microsoft's shipping department and people from the delivery service's headquarters were frantic trying to trace where all the bogus orders were coming from.

    ¹ Mind you, this sort of thing is the stuff that average Joe customers can do while still in their pajamas, but back in those days, it was a feature that only top-tier customers had access to, because, y'know, mainframe.

  • 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

    For Honor, For Excellence, For Pizza

    • 18 Comments

    Hacker News member citizenlow recalls the time I went over after hours to help out the Money team debug a nasty kernel issue. They were running into mysterious crashes during their stress testing and asked for my help in debugging it.

    I helped out other teams quite a bit, like writing a new version of Dr. Watson for the Windows 98 team or writing a new version of the MSConfig tool based on a sketch on a bar napkin. And for a time, I followed the official policy for moonlighting to make sure everybody understood that I was doing work outside the boundaries of my official job duties.

    When the Money folks asked me for help, I told them that before I could help them, they would have to help me fill out some paperwork.

    • Who will you be working for? Microsoft Corporation.
    • Where will you be doing the work? Office XX/YYYY on Microsoft Redmond Campus.
    • When will the work begin and end? Begin on YYYY/MM/DD at 5pm, ending YYYY/MM/DD at 11pm.
    • How much will you be paid for this work?

    The Money folks were not sure how to answer that last question, since they didn't have any formal budget or procedures for hiring an outside consultant, much less any procedures for hiring one from inside the company.

    I told them, "Just write One slice of pizza."

    Nobody from the Personnel department seemed to notice the odd circumstances of this moonlighting request; they simply rubber-stamped it and put it in my file.

    The crash, it turns out, was in Windows itself. There was a bug in the special compiler the Languages team produced to help build certain components of Windows 95 which resulted in an incorrect address computation under a particularly convoluted boundary condition. The Money folks had merely stumbled across this bug as part of their regular testing. I notified the appropriate people, and the Windows team applied a workaround in their code to tickle the compiler into generating the correct code.

    As I recall, the pizza was just fine. It was just your average delivery pizza, nothing gourmet or anything. Not that it had to be, because I wasn't there for the pizza.

  • The Old New Thing

    What happened to the Shut Down menu in classic Task Manager?

    • 61 Comments
    The great thing about open comments is that anybody can use them to introduce their favorite gripe as long as it shares at least four letters of the alphabet in common with the putative topic of the base article.

    xpclient "asks" why the Shut Down menu was removed from Task Manager. I put the word "asks" in quotation marks, because it's really a complaint disguised as a question. As in "Why do you guys suck?"

    The first thing to understand is that classic Task Manager went into a state of sustained engineering since Windows 2000. In other words, the component is there, but there is no serious interest in improving it. (That's why it wasn't updated to call Enable­Theme­Dialog­Texture on its pages.) It's not like there's a Task Manager Team of five people permanently dedicated to making Task Manager as awesome as possible for every release of Windows. Rather, the responsibility for maintaining Task Manager is sort of tacked onto somebody whose primary responsibilities are for other parts of the system.

    There are a lot of Windows components in this state of "internal sustained engineering." The infamous "Install font" dialog, for example. The responsibility for maintaining these legacy components is spread out among the product team so that on average, teams are responsible both for cool, exciting things and some not-so-cool, legacy things.

    (On the other hand, according to xpclient, an app must be serving its users really well if it hasn't changed much, so I guess that Install font dialog is the best dialog box in all of Windows at serving its users, seeing as it hasn't changed since 1995.)

    The engineering budget for these components in internal sustained engineering is kept to a minimum, both because there is no intention of adding new features, and also because the components are so old that there is unlikely to be any significant work necessary in the future.

    Every so often, some work becomes necessary, and given that the engineering interest and budget are both very low, the simplest way out when faced with a complicated problem in a rarely-used feature is simply to remove the rarely-used feature.

    And that's what happened to the Shut Down menu. (Note that it's two words "Shut down" since it is being used as a verb, not a noun.) Given the changes to power management in Windows Vista, the algorithm used by Task Manager was no longer accurate. And instead of keeping Task Manager updated with every change, the Shutdown user interface design team agreed to give the Task Manager engineering team a break and say, "Y'know, the Shut Down menu on Task Manager is rarely-used, so we'll let you guys off the hook on this one, so you don't keep getting weekly requests from us to change the way Shut Down works."

    I remember, back in the days of Windows XP, seeing the giant spreadsheet used by the person responsible for overall design of the Shutdown user interface. It tracked the gazillion group policies, user settings, and system configurations which all affect how shutting down is presented to the user. Removing the column for Task Manager from the spreadsheet probably was met with a huge sigh of relief, not just from the Task Manager engineering team, but also from the person responsible for the spreadsheet.

    Remember, engineering is about trade-offs. If you decide to spend more effort making Task Manager awesome, you lose the ability to expend that effort on something else. (And given that you are expending effort in a code base that is relatively old and not fresh in the minds of the people who would be making those changes, you also increase the likelihood that you're going to introduce a bug along the way.)

  • The Old New Thing

    10 is the new 6

    • 35 Comments

    While it may no longer be true that everything at Microsoft is built using various flavors of Visual C++ 5.0, 6.0, and 7.0, there is still a kernel of truth in it: A lot of customers are still using Visual C++ 6.0.

    That's why the unofficial slogan for Visual C++ 2010 was 10 is the new 6. Everybody on the team got a T-shirt with the slogan (because you don't have a product until you have a T-shirt).

  • The Old New Thing

    Who would ever write a multi-threaded GUI program?

    • 37 Comments

    During the development of Windows 95, the user interface team discovered that a component provided by another team didn't work well under multi-threaded conditions. It was documented that the Initialize function had to be the first call made by a thread into the component.

    The user interface team discovered that if one thread called Initialize, and then used the component, then everything worked great. But if a second thread called Initialize, the component crashed whenever the second thread tried to use it.

    The user interface team reported this bug back to the team that provided the component, and some time later, an updated version of the component was delivered.

    Technically, the bug was fixed. When the second thread called Initialize, the function now failed with ERROR_NOT_SUPPORTED.

    The user interface team went back to the team that provided the component. "It's nice that your component detects that it is being used by a multi-threaded client and fails the second thread's attempt to initialize it. But given that design, how can a multi-threaded client use your component?"

    The other team's reply was, "It doesn't matter. Nobody writes multi-threaded GUI programs."

    The user interface team had to politely reply, "Um, we are. The next version of Windows will be built on a multi-threaded shell."

    The other team said, "Oh, um, we weren't really expecting that. Hang on, we'll get back to you."

    The idea that somebody might write a multi-threaded program that used their component caught them by surprise, and they had to come up with a new design of their component that supported multiple threads in a clean way. It was a lot of work, but they came through, and Windows 95 could continue with its multi-threaded shell.

Page 1 of 49 (485 items) 12345»