October, 2012

  • The Old New Thing

    An unexpected application of negative numbers to gift-giving

    • 7 Comments

    A college classmate of mine informed me that one of his colleagues had planned his wedding so far in advance that on his negative-first anniversary (i.e., precisely one year before his anticipated wedding date), he gave paper to all of his friends.

    Said my classmate, "It's too bad that neither of us had been born on his −50th anniversary. That would have been more lucrative."

  • The Old New Thing

    Why does RegOpenKey sometimes (but not always) fail if I use two backslashes instead of one?

    • 11 Comments

    A customer reported that on Windows XP, they observed that their program would very rarely get the error ERROR_INVALID_ARGUMENT when they passed two backslashes instead of one to the Reg­Open­Key­Ex function:

    RegOpenKeyEx(hk, L"Blah\\\\Oops", ...);
    

    After removing C++ escapes, the resulting string passed to Reg­Open­Key­Ex is

    Blah\\Oops
    

    The failure was very sporadic and not reproducible under controlled conditions.

    Well, first of all, doubled backslashes are not legal in registry key paths in the first place, so the first recommendation is stop doubling the backslashes. Once you fix that, the problem will go away.

    But the next question is why the error was detected sometimes but not always.

    When an application tries to open a registry key, the registry code first consults a cache of recently-opened keys, since registry accesses exhibit very high locality of reference. If a match is found in the cache, then the cached result is used. Otherwise, it's a cache miss, and the registry tree is searched in the old-fashioned way. The registry tree search rejects the double-backslash since it interprets the path Blah\\Oops as "Look for a subkey called "Blah", then a subkey called "", then a subkey called "Oops"." The "subkey called """ step fails because key cannot have an empty string as their name.

    On the other hand, the code that checks the cache has a different search algorithm which happens to have the effect of collapsing consecutive backslashes, so the path Blah\\Oops is interpreted as "Look for a subkey called "Blah", then a subkey called "Oops"." (Note: "has the effect of". There is no explicit "collapse backslashes" step; it just turns out that the way the path is parsed, consecutive backslashes end up being treated as if they were single backslashes.)

    In the customer's case, therefore, the key in question is in the cache most of the time, which is why the doubled backslash is silently corrected to a single backslash. But every so often, the key is not in the cache, and the old-fashioned search is performed. And the old-fashioned search rejects the double-backslash as an invalid path.

    The discrepancy in the two parsing algorithms was resolved in Windows Vista, so you'll see this issue only on Windows XP and earlier.

    But this historical tidbit does highlight one of the hidden gotchas of optimization: If your optimized version differs from the unoptimized version in cases that are theoretically anyway illegal, you may find yourself chasing elusive bugs when somebody accidentally stumbles into those cases and managed to get away with it... until now.

  • The Old New Thing

    How do I suppress the default animation that occurs when I hide or show a window?

    • 18 Comments

    A customer wanted to know how they can disable the default fade-in/fade-out animation that occurs when a window is hidden or shown. "I don't want to use WS_EX_TOOL­WINDOW because that causes my window to disappear from the taskbar. I tried Dwm­Enable­Composition but that affects the entire desktop and is too jarring. We want to suppress the effect because our program replaces one window with another, and we want the operation to be invisible to the user."

    Whoa, heading straight for Dwm­Enable­Composition? That's using a global solution to a local problem.

    To disable the animations on a specific window, use something like this:

    HRESULT DisableDwmAnimations(HWND hwnd)
    {
        BOOL fDisable = TRUE;
        return DwmSetWindowAttribute(hwnd,
                    DWMWA_TRANSITIONS_FORCEDISABLED,
                    &fDisable,
                    sizeof(fDisable));
    }
    

    Re-enabling the animations is left as an exercise for the reader.

  • The Old New Thing

    Microspeak: Granular

    • 13 Comments

    Today's Microspeak word is granular. Here are some citations.

    Please bring your cost estimates at the granularity of 3, 5 or 10 days.
    The archive function archives all data older than the date specified. Is there a way to get the archive to be more granular than just a date? Our database covers multiple accounts, and we'd like to choose a different date for each account.
    There are about 2000 warnings to be investigated. I've assigned them at component granularity.

    Granularity is roughly equivalent to level of detail or unit of separation.

    In the first example, the cost estimates should be broken down into units that are 3, 5, or 10 days. In the second example, the request is for the archive function to determine which data to archive based on more than just the item date. In in the third example, the 2000 warnings were group by component and all warnings in a particular component were assigned to a single person.

    The term granular is used plenty outside Microsoft, too, especially in the phrase granular control, which you will be relieved to know is also wildly popular at Microsoft. (Remember, Microspeak is not only about words and phrases unique to Microsoft. It also covers words and phrases used inside Microsoft at a rate significantly higher than their usage outside Microsoft.)

    There is also a more jargony use of granular when used in conjunction with the verb to get. To get granular means to study in greater detail. And in a peculiar mix of metaphor, the way to get granular is to drill down.

  • The Old New Thing

    What's the difference between F5 and F8 at the boot screen?

    • 34 Comments

    Ian B wondered what the difference is between pressing F5 and F8 while Windows is booting.

    I have no idea either. My strategy was to just mash on the function keys, space bar, DEL key, anything else I can think of. Keep pressing them all through the boot process, and maybe a boot menu will show up.

    The F5 hotkey was introduced in Windows 95, where the boot sequence hotkeys were as follows:

    • ESC - Boot in text mode.
    • F5 - Boot in Safe Mode.
    • Shift+F5 - Boot to Safe Mode MS-DOS.
    • Ctrl+F5 - Boot to Safe Mode MS-DOS with drive compression disabled.
    • Alt+F5 - Boot with LOADTOP=0 for Japanese systems.
    • F6 - Boot in Safe Mode with networking.
    • F4 - Boot to previous version of MS-DOS.
    • Ctrl+F4 - Boot to previous version of MS-DOS with drive compression disabled.
    • F8 - Boot to menu.
    • Shift+F8 - Boot with step-by-step confirmation.
    • Ctrl+F8 - Boot with step-by-step confirmation with drive compression disabled.

    Man, that's an insane number of boot options all buried behind obscure function keys. Boy am I glad we got rid of them. This frees up room in my brain for things like Beanie Baby trivia.

    Bonus chatter: The next generation of computers boots so fast that there's no time to hit any of these hotkeys!

Page 3 of 3 (25 items) 123