April, 2008

  • The Old New Thing

    We can't cut that; it's our last feature


    Many years ago, I was asked to help a customer with a problem they were having. I don't remember the details, and they aren't important to the story anyway, but as I was investigating one of their crashes, I started to wonder why they were even doing it.

    I expressed my concerns to the customer liaison. "Why are they writing this code in the first place? The performance will be terrible, and it'll never work exactly the way they want it to."

    The customer liaison confided, "Yeah, I thought the same thing. But this is a feature they're adding to the next version of their product. The product is so far behind schedule, they've been cutting features like mad to get back on track. But they can't cut this feature. It's the last one left!"

  • The Old New Thing

    User interface code + multi-threaded apartment = death


    There are single-threaded apartments and multi-threaded apartments. Well, first there were only single-threaded apartments. No wait, let's try that again.

    First, applications had only one thread. Remember, 16-bit Windows didn't have threads. Each process had one of what we today call a thread, end of story. Compatibility with this ancient model still exists today, thanks to the dreaded "main" threading model. The less said about that threading model the better.

    OLE was developed back in the 16-bit days, so it used window messages to pass information between processes, there being no other inter-process communication mechanism available. When you initialized OLE, it created a secret OleMainThreadWnd window, and those secret windows were used to communicate between processes (and in Win32, threads). As we learned some time ago, window handles have thread affinity, which means that these communication windows have thread affinity, which means that OLE has thread affinity. When you made a call to an object that belonged to another apartment, OLE posted a message to the owner thread's secret OleMainThreadWnd window to tell it what needs to be done, and then it went into a private message loop waiting for the owner thread to do the work and post the results back.

    Meanwhile, the OLE team realized that there were really two parts to what they were doing. There was the low-level object and interface management stuff (IUnknown, CoMarshalInterThreadInterfaceInStream) and the high-level "object linking and embedding" stuff (IOleWindow, IOleDocument) that was the impetus for the OLE effort in the first place. The low-level stuff got broken out into a functional layer known as COM; the high-level stuff kept the name OLE.

    Breaking the low-level and high-level stuff apart allowed the low-level stuff to be used by non-GUI programs, which for quite some time were eyeing that object management functionality with some jealousy. As a result, COM grew two personalities, one focused on the GUI customers and another focused on the non-GUI customers. For the non-GUI customers, additional functionality such as multi-threaded apartments were added, and since the customers didn't do GUI stuff, multi-threaded apartments weren't burdened by the GUI rules. They didn't post messages to communicate with each other; they used kernel objects and WaitForSingleObject. Everybody wins, right?

    Well, yes, everybody wins, but you have to know what side your bread is buttered on. If you initialize a GUI thread as a multi-threaded apartment, you have violated the assumptions under which multi-threaded apartments were invented! Multi-threaded apartments assume that they are not running on GUI threads since they don't pump messages; they just use WaitForSingleObject. This not only clogs up broadcasts, but it can also deadlock your program. The thread that owns the object might try to send a message to your thread, but your thread can't receive the message since it isn't pumping messages.

    That's why COM objects involved with user interface programming nearly always require a single-threaded apartment and why OleInitialize initializes a single-threaded apartment. Because multi-threaded apartments were designed on the assumption that there was no user interface. Once you're doing user interface work, you have to use a single-threaded apartment.

  • The Old New Thing

    One-line batch script to delete empty directories


    You don't need a whole 260KB program to do it. This batch file does the trick just fine:

    for /f "usebackq" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"

    I call it rdempty.cmd.

    This is the long-forgotten follow-up to Performing an operation in each subdirectory of a directory tree from batch. We're using the same technique as in that article, but pumping the result through "| sort /R" to reverse the order of the enumeration so we enumerate the directories bottom-up rather than top-down. This is important for deleting empty directories because you have to remove the subdirectories before you remove the parent.

    Disclaimer: I doubt anybody actually enjoys working with batch files, but that doesn't mean that tips on using it more effectively aren't valid. If you would rather gouge your eyes out than use the confusing command prompt batch language, then you are more than welcome to use the scripting language of your choice instead. At no point in this article am I saying that this is the only way or the best way to do it. But it's definitely smaller than a 260KB program.

  • The Old New Thing

    Why doesn't Explorer let you create a file whose name begins with a dot?


    Rolf Viehmann asks why Explorer doesn't let you create a file whose name begins with a dot.

    Such files are considered to have an extension but no name. If the extension is known and the user has chosen to hide known extensions, the resulting file would have no name at all!

    If you really want to create a file with a leading dot in its name, you are free to do so. You can do it from the command line or use your favorite file management tool. And then you can watch the file show up with no name and then observe the confusion that ensues. Maybe you're lucky and don't run any programs that freak out when a file has no name. If so, then more power to you.

    If it really bugs you that you can't do it from Explorer, you are free to write your own shell extension to do "Rename this file, and if I'm going to shoot myself in the foot, then let me."

  • The Old New Thing

    The double-click time tells the window manager how good your reflexes are


    The double-click time is sort of the dialog unit of time. It's used as the basis for many user interface time values that don't have their own custom setting. Here are just a few examples, along with the values you get if you leave the double-click time at its default of 500ms:

    • The default tooltip timeouts are based on the double-click time. (Initial: 0.5s, autopop: 5s, reshow: 0.1s.)
    • Incremental searching in list boxes resets after 4 times the double click time (2s).
    • When you click and hold over a scroll bar arrow, autorepeat begins after 4/5 of the double-click time has elapsed (.4s), and autorepeat occurs at one tenth of the double-click time (0.05s = 20 repeats per second).
    • The menu speed used to be 4/5 of the double click speed (0.4s), but now it has its own setting (SPI_SETMENUSHOWDELAY).

    If you go into the mouse control panel and speed up your double-click speed, then you'll find that other user interface operations tend to speed up as well. The double-click time is a sort of barometer for how good the user's reaction time is. If you set it too low, you may find that things just happen too fast.

  • The Old New Thing

    Racking up the frequent shopper points at the register office


    In Scotland, a 24-year-old woman got married for the fourth time. The first three ended under unusual circumstances. Let's see, for starters, marriage number one ended when her husband ran off to marry her mom, and the woman even served as a bridesmaid at her mother's wedding. Oh, and a musical thong was also involved.

    When I read this article, I thought, "Certainly the UK has a counterpart to The Jerry Springer Show, doesn't it?" It appears that I am not disappointed.

  • The Old New Thing

    Pranksters breathe a sigh of relief: There will never be a Building 7


    It is a longstanding prank at Microsoft's main Redmond campus to send an unsuspecting new employee to building 7 under the pretense of having a meeting or needing to pick up something. There is no such building on the main Microsoft campus. This nonexistent building has also been used as a sort of inside joke. For example, if somebody invites you to a meeting in Building 7, they're probably inviting you off campus to take a break from work.

    A few years ago, there was a vacancy in a small business park a very short walk from the main Microsoft campus. (You don't even have to cross the street to get there.) I thought it would be great if somebody leased the space and opened a bar called Building 7. It could have a back room decorated like a Microsoft meeting room, complete with WiFi and a large monitor. Then somebody could legitimately invite you to a meeting in Building 7, and people could use it as a cover story: "Sorry, I'm going to be working late tonight. Team meeting in Building 7."

    The announcement in February 2006 of a major expansion of the main Redmond campus came with a little map, and people with way too much time on their hands pored over the unreadably tiny print on the map and noticed a little 7 printed on the orange building in the upper right corner. They quietly fretted that a piece of Microsoft history was vanishing and that they'll have to come up with a new prank to play on the new-hires.

    In June 2007, pranksters (and people with a nostalgic streak) breathed a sigh of relief. The real estate department announced that the new building tentatively labelled 7 on the map will now be known as Building 37. In deference to Microsoft tradition, the name Building 7 has been officially retired. There will never be a Building 7.

  • The Old New Thing

    Raymond's reading list: The Mythical Man-Month, The Design of Everyday Things, and Systemantics


    The first two of these books are probably on everybody else's reading list, but I'm going to mention them anyway since I consider them required reading for managers and designers.

    The Mythical Man-Month is over 30 years old, but the lessons contained therein are as true now as they were back in 1975, such as what is now known as Brooks' law: Adding manpower to a late software product makes it later.

    I much preferred the original title for The Design of Everyday Things, namely, The Psychology of Everyday Things, but I'm told that booksellers ended up mistakenly filing the book in the psychology section. Once you've read this book, you will never look at a door the same way again. And you'll understand the inside joke when I say, "I bet it won an award."

    The third book is the less well-known Systemantics: How Systems Work and Especially How They Fail. The book was originally published in 1978, then reissued under the slightly less catchy title, Systemantics: The Underground Text of Systems Lore, and re-reissued under the completely soul-sucking title The Systems Bible. I reject all the retitling and continue to refer to the book as Systemantics.

    Systemantics is very much like The Mythical Man-Month, but with a lot more attitude. The most important lessons I learned are a reinterpretation of Le Chatelier's Principle for complex systems ("Every complex system resists its proper functioning") and the Fundamental Failure-Mode Theorem ("Every complex system is operating in an error mode").

    You've all experienced the Fundamental Failure-Mode Theorem: You're investigating a problem and along the way you find some function that never worked. A cache has a bug that results in cache misses when there should be hits. A request for an object that should be there somehow always fails. And yet the system still worked in spite of these errors. Eventually you trace the problem to a recent change that exposed all of the other bugs. Those bugs were always there, but the system kept on working because there was enough redundancy that one component was able to compensate for the failure of another component. Sometimes this chain of errors and compensation continues for several cycles, until finally the last protective layer fails and the underlying errors are exposed.

    That's why I'm skeptical of people who look at some catastrophic failure of a complex system and say, "Wow, the odds of this happening are astronomical. Five different safety systems had to fail simultaneously!" What they don't realize is that one or two of those systems are failing all the time, and it's up to the other three systems to prevent the failure from turning into a disaster. You never see a news story that says "A gas refinery did not explode today because simultaneous failures in the first, second, fourth, and fifth safety systems did not lead to a disaster thanks to a correctly-functioning third system." The role of the failure and the savior may change over time, until eventually all of the systems choose to have a bad day all on the same day, and something goes boom.

  • The Old New Thing

    What happened to winipcfg and netmon?


    Commenter Michael Moulton asks:

    Back in the Win95 & 98 days, we had winipcfg to manage DHCP leases on the client. Additionally, we had an app (I think it was netmon) to let you view people currently accessing your shares.

    Now, we have ipconfig on the command line and nothing like netmon.

    I'd be interested in hearing why those tools weren't retained.

    Let's start with winipcfg. On the Windows NT side, the tool for managing IP addresses has always been ipconfig, and it hasn't gone away. It's still there in Windows Vista. The winipcfg program was created for Windows 3.1 as a workaround because Windows 3.1 didn't have a console subsystem. The program was retained in Windows 95 because Windows 95 was based on Windows 3.1. The workaround wasn't ported to Windows NT because Windows NT already had the functionality, as a console program, which is probably how it should have been done in the first place.

    Oh wait, that is how it was done in the first place.

    In other words, the question isn't why winipcfg changed to ipconfig but rather why ipconfig changed to winipcfg. The change was a workaround, and now the workaround is no longer needed.

    Meanwhile, the functionality provided by netmon exists in the Windows NT series as an MMC snap-in. The quickest way to get to it is to right-click the My Computer icon and select Manage, then go to the Shared Folders node.

    (This question really wasn't in my area, since I never worked on networking. I'm just answering the question based having used Windows for a while and not being afraid to look around.)

  • The Old New Thing

    How do I force the ECHO command to echo?


    The ECHO built-in command, how much simpler could it get? It takes whatever you put on the command line and prints it. And yet it's not that simple.

    For example, the ECHO must be careful not to compress whitespace, because people will write

    ECHO Some text
    ECHO    Indented text
    ECHO             ----     underlined

    and when you execute this, the result had better be

    Some text
       Indented text
                ----     underlined

    and not

    Some text
    Indented text
    ---- underlined

    But what if you want to echo a blank line or the word "ON" or "OFF" or a slash and a question mark?

    C:\> ECHO ON
    C:\> ECHO
    ECHO is on.
    C:\> ECHO /?
    Displays messages, or turns command-echoing on or off.

    To force the ECHO command not to interpret its arguments, put a dot immediately after the word "echo":

    C:\> ECHO.    ON
    C:\> ECHO.
    C:\> ECHO./?

    This is what happens when a language develops not by design but by evolution. It becomes filled with all sorts of strange quirks in order to accommodate new behavior while remaining compatible with old behavior. Nobody actually likes the batch language; they just are used to it.

Page 1 of 5 (41 items) 12345