December, 2009

  • The Old New Thing

    What are those little overlay icons: Windows 7 edition


    Some time ago, I summarized the overlay icons that come with Windows. There have been some changes in Windows 7, so I figured it'd be worth coming up with a new list.

    • A small arrow. This is still the shortcut overlay.
    • A padlock. This means that you have a private item in a non-private directory. (See below.)
    • A downward-pointing blue arrow. This is still the "to be written to CD" overlay.
    • A pair of green swirly arrows. This means that the item is available offline. This used to be a pair of blue swirly arrows. Apparently, green is the new blue. (See below for more discussion.)
    • A gray X. This means that the file has been archived to tape and will take a very long time to access. (Formerly, a black clock.)

    A private item is an item where the only user account with access is you.¹ You create one of these, for example, by going to the sharing wizard and saying Share with: Nobody. To avoid clutter, the overlay is shown only when there is a transition from non-private to private. (Otherwise you'd have a lock overlay on everything in your Documents folder, for example.)

    No longer present as an overlay is the sharing hand. Why was the sharing hand removed in favor of the private overlay?

    Given the changes in how people use computers, sharing information is becoming more and more of the default state. When you set up a HomeGroup, pretty much everything is going to be shared. To remove the visual clutter, the information was moved to the Details pane. What's more, a single overlay cannot express the different ways an item can be shared, so in order to figure out what the deal is, you have to go to the Details pane anyway.

    A similar thing happened to the offline files swirly arrows. They used to be placed on every item that was available offline, but feedback from customers highlighted that this was unnecessarily noisy because it trumped other (more informative) overlays. Instead, the swirly arrows are shown only on the root of the folder that is pinned and not on everything contained within it. In other words, the swirly arrows are placed on the thing you clicked on to make the files available offline, and conversely, on the things you need to click on to stop making them available offline. Per-file overlay information is still displayed in the preview pane, but it's been taken out of the icon list.

    Generally speaking, overlays are not a good way of presenting information because there can be only one overlay per icon, and there is a limit of 15 overlays per ImageList. If there are two or more overlays which apply to an item, then one will win and the others will lose, at which point the value of the overlay as a way of determining what properties apply to an item diminishes since the only way to be sure that a property is missing is when you see no overlay at all. (If you see some other overlay, you can't tell whether it's because your property is missing or because that other overlay is showing instead of yours.)


    ¹Even though you are the only user account, there can still be access granted to groups and non-user accounts such as the Administrators group and the SYSTEM account.

  • The Old New Thing

    How do I determine the processor's cache line size?


    When doing high-performance computing, you need to worry about the CPU cache line size in order to avoid issues like false sharing. But how can you determine the processor's cache size?

    The GetLogicalProcessorInformation function will give you characteristics of the logical processors in use by the system. You can walk the SYSTEM_LOGICAL_PROCESSOR_INFORMATION returned by the function looking for entries of type RelationCache. Each such entry contains a ProcessorMask which tells you which processor(s) the entry applies to, and in the CACHE_DESCRIPTOR, it tells you what type of cache is being described and how big the cache line is for that cache.

    Windows 7 adds the function GetLogicalProcessorInformationEx which does the RelationCache filtering for you.

  • The Old New Thing

    How do I minimize a group of windows in Windows 7 from the taskbar?


    The Windows 7 taskbar automatically groups similar windows, and when you right-click on the grouped icon, you may get fancy stuff like a jump list or a task list, but you will also get a very small repertoire of window management options. In particular, the only option that operates on the group is Close all windows. What about the other group options?

    To get a list of more group window options, hold the shift key when you right-click on the grouped icon. Then you'll get more options like Cascade and Minimize all windows.

    Since the contents of the regular right-click pop-up window are dynamic, when you hit "C" for Close all windows, it still waits for you to confirm by hitting Enter. On the other hand, the shift+right-click menu auto-executes Close all windows when you hit the "C" hotkey. Doesn't save you any more keystrokes (trading an Enter for a shift key), but you do get predictability since the shift+right-click menu is pretty stable.

    Bonus tip: To get the System menu for a window, you can right-click on its pop-up thumbnail.

  • The Old New Thing

    Fake trend watch: Bridesmaid pre-nuptial agreements


    My wanderings through the online world of bridesmaid craziness began with the article Brides taking their bridesmaids for Botox treatments or maybe a boob job. I blame the wedding-industrial complex, which constantly pushes weddings as the bride's "perfect day", "the best day of your life", a "fairy tale come true" where you can be "a princess for a day." (Folk tales which end in big lavish weddings are told from the female point of view; there aren't many folk tales about the young boy who grows up to marry a beautiful princess.)

    And I love Elizabeth A.'s comment called out in the sidebar to the New York Times article.

    Back to that article: Is the Botox girl's night out a real trend or a fake trend? In Pre-nups for bridesmaids. Gain weight and you're out, the author claims that "one in five women actually ask their bridesmaids to sign a pre-nup." On that, I call fake trend.

    First of all, I could find only one actual documented case of a bride who made her bridesmaids sign contracts agreeing not to gain weight before the wedding. And it was a prank.

    Okay, so if it happened only once, where did this "one in five" come from? I followed the citation to the source article in The Daily Mail, which merely says that one in five would ask their bridesmaids to sign such an agreement, not that one in five actually did it.

    But wait, there's more. I followed the citation from that Daily Mail article to the the original survey from You & Your Wedding magazine, and found that it was even weaker than The Daily Mail described it: The actual result was that one in five would consider a bridesmaid contract in general. So we're double-counterfactual now. And the survey was not scientific; it was just an online survey.

    Okay, so let's tally up the numbers. The claim that one in five brides ask their bridesmaids to sign a pre-nuptial agreement which includes a clause regarding weight would be true if...

    • The online survey results were representative of brides as a whole (and the people who answered the survey were answering seriously), and
    • Everyone who would consider having a bridesmaid pre-nup actually did consider it, and
    • Everyone who considered it followed through and did it, and
    • Every one of those pre-nups contained a clause regarding weight.

    I call fake trend.

    Bonus link: Extreme wedding planning. Warning: Contains bad dancing.

  • The Old New Thing

    What is the effect of setting the /3GB switch on my 64-bit Windows machine?



  • The Old New Thing

    Only an idiot would have parameter validation, and only an idiot would not have it


    The great thing about parameter validation is that there are people who say that only idiots would have it, and other people who say that only idiots wouldn't.

    Back in the old days, Windows didn't do parameter validation. If you called a function with an invalid window handle, your application crashed. If you called a function with an invalid pointer, your application crashed. If you called a function with an invalid bitmap handle, your application crashed.

    There was a lot of crashing going on.

    These crashes manifested themselves in the infamous Unrecoverable Application Error dialog, commonly known as the UAE message.

    Windows 3.1 added parameter validation to all of the functions in KERNEL, USER, and GDI. If an application passed an invalid window handle, then instead of crashing, it just got an error back.

    This change was met with derision. "Oh, I'm so impressed. You finally got around to doing something you should have been doing all along. Not doing parameter validation was a totally idiotic decision."

    But nowadays, parameter validation is out of fashion again. If you detect an invalid parameter and return an error code, then all you're doing is masking a latent bug in the application. It should crash and burn with a big red fat'n'ugly blinking exception.

    In other words, we should go back to the way things were before we added parameter validation. (Well, except that the bit fat ugly exception wasn't red and it didn't blink.)

    Who's the idiot now?

  • The Old New Thing

    No, you can't lock icons to the user's desktop


    In another installment of I bet somebody got a really nice bonus for that feature, I submit this question for your consideration.

    My customer wants to know how to lock a specific icon to the upper left hand corner of the desktop.

    This company must be writing the most awesome program to end all programs, a program so amazingly awesome that it should appear as the very first thing on the desktop so you won't forget how awesome it is.

    I think their users may disagree with that assessment.

    And the answer is, no, there is no supported way to force a particular icon to appear at a particular desktop position.

  • The Old New Thing

    You are listening to Radio Free Bob, a pirate radio station broadcasting on the Microsoft corporate network


    Back in the late 1980's, when NETBIOS ruled the land at Microsoft, one of my colleagues ran a pirate radio station on the Microsoft corporate network. Let's call this colleague Bob, my generic name for a Microsoft employee.

    Bob had converted a bunch of songs to WAV format (mp3 not yet having been invented) and kept them on his machine to listen to while he worked. But he also travelled from room to room to investigate problems in various offices and labs. This was also the days before laptop computers and iPods. A portable computer was one of these puppies, affectionately known as a luggable because it was the size of (and weighed more than) a suitcase.

    Bob liked to listen to music while he worked, and since he couldn't take his music with him, he did what he thought was the next best thing: He had his music come to him.

    Bob wrote a program to stream his music collection over the Microsoft corporate network. Of course, Bob didn't want to have to pre-program the list of offices and labs he was going to visit during the day (in part of course because at the start of the day, he didn't know where he was going to be), so the program broadcasted his music collection to every computer at Microsoft. That way, no matter where he (or anybody else) was, he could listen to his music collection. He called this service Radio Free Bob.

    Radio Free Bob was not on the air for very long, however, before getting the heat from The Man. Pumping that much data to every computer at Microsoft, even the machines in overseas offices like Hong Kong and Berlin, doesn't sit well with corporate network administrators. I don't know the exact number, but it was consuming some huge percentage of the network bandwidth of the entire company. The IT department frantically triangulated the packets, identified the building that was the source of the network broadcasts, narrowed it down to a specific wing of the building, then began a room-by-room search for the offending computer, descending upon it like a SWAT team.

    Thus ended the short life of Radio Free Bob.

  • The Old New Thing

    What was the ShowCursor function intended to be used for?


    Back in the days when Windows was introduced, a mouse was a fancy newfangled gadget which not everybody had on their machine. Windows acknowledged this and supported systems without a mouse by having keyboard accelerators for everything (or at least that was the intent). But if the design stopped there, you'd have a dead cursor in the middle of your screen all the time, which you could move around if you had a mouse, which you didn't.

    Enter the ShowCursor function.

    The ShowCursor function takes a parameter that indicates whether you want to show or hide the cursor. (It would perhaps be more verbosely named ChangeCursorShowState.) If you call ShowCursor(TRUE) then the cursor show count is incremented by one; if you call ShowCursor(FALSE) then the cursor show count is decremented by one. A cursor is show on the screen if the cursor show count is greater than or equal to zero.

    When Windows starts up, it checks if you have a mouse. If so, then the cursor show count is initialized to zero; otherwise, it is initialized to negative one. That way, you don't get an annoying immovable cursor on the screen if you don't have a mouse.

    If a program entered a state where it wanted to show the cursor even on systems without a mouse, it would call ShowCursor(TRUE) when it entered the state, and ShowCursor(FALSE) when it left it. One such state might be when activating the keyboard interface for selecting a rectangular region in a document. Under these conditions, a program naturally is expected to move the cursor around in response to user actions, even if the user didn't move the physical mouse hardware.

    But the most common reason for forcing the cursor to be shown is in order to show an hourglass cursor because it's busy. That's right, back in the mouseless days, code to display an hourglass cursor went like this:

    HCURSOR hcurPrev = SetCursor(LoadCursor(NULL, IDC_WAIT));
    ShowCursor(TRUE); // force cursor shown on mouseless systems
    ... perform long operation ...
    ShowCursor(FALSE); // re-hide cursor on mouseless systems

    Conversely, if a program entered a state where it wanted to hide the cursor even on systems with a mouse, it would call ShowCursor(FALSE) when it entered the state, and ShowCursor(TRUE) when it left it. For example, you might do this when showing a slide show.

    Let's look at how this all worked out in practice. I use a table because people seem to like tables.

    Machine with mouse Machine without mouse
    Normal 0 (cursor shown) -1 (cursor hidden)
    Enter mode where cursor should be forced shown
    ShowCursor(TRUE) 1 (cursor shown) 0 (cursor shown)
    Exit mode where cursor should be forced shown
    ShowCursor(FALSE) 0 (cursor shown) -1 (cursor hidden)
    Enter mode where cursor should be forced hidden
    ShowCursor(FALSE) -1 (cursor hidden) -2 (cursor hidden)
    Exit mode where cursor should be forced hidden
    ShowCursor(TRUE) 0 (cursor shown) -1 (cursor hidden)

    Now that all systems come with a mouse as standard equipment, this historical information is not of much use, but there it is in case you were wondering. (And in a case of everything old is new again, the growing popularity of touch computing means that you once again have a class of computers with no mouse. So maybe this information is useful after all. Just a fluke, I assure you.)

    Back in the old 16-bit days, this counter was a global state, along with other window manager states like the focus window and the input queue. During the conversion to Win32, the cursor show counter became a thread-local state. (Naturally, multiple threads could merge their cursor show counters by attachment.) Consequently, when a thread calls ShowCursor it affects the cursor show state only for windows that belong to that thread.

  • The Old New Thing

    A shell extension is a guest in someone else's house; don't go changing the carpet


    A customer was running into this problem with a shell extension:

    I am writing a shell namespace extension. I need to get data from a COM server, which requires impersonation via CoInitializeSecurity with RPC_C_IMP_LEVEL_IMPERSONATE. As I am just writing an extension into explorer.exe, I am not able to call CoInitialize, CoInitializeSecurity anymore from my extension. Is there a way I can start explorer.exe by setting RPC_C_IMP_LEVEL_IMPERSONATE in its COM initialization? I was browsing through web, and explorer.exe seems to take some settings from registry, but couldn't find anything related to this one.

    First of all, who says that the host process is explorer.exe? If I open Notepad, then do a File.Open, and then navigate to your shell extension, boom, your shell extension is now loaded into Notepad, and I doubt you told Notepad that you wanted it to initialize COM in a special way, just for you. Same goes for Quicken, Lotus Notes, all those other programs that use the shell. Even if you solved the problem for Explorer, that doesn't solve your problem in general.

    Second, what if two shell extensions did this? Your shell extension requires RPC_C_IMP_LEVEL_IMPERSONATE, but another one requires RPC_C_IMP_LEVEL_DELEGATE. Who wins? Or are those shell extensions mutually incompatible? And what about the effect your decision has on the other shell extensions hosted by Explorer? Now they are running with RPC_C_IMP_LEVEL_IMPERSONATE even though they didn't ask for it. Will that introduce a security vulnerability? Will those other shell extensions stop working or even crash?

    A shell extension is a guest in the host process's house. You don't go and change the color of the carpet when you are invited over for dinner.

    This question is yet another example of using a global setting to solve a local problem. To solve your local problem (I need this specific COM interface to run with impersonation), use a local solution.

Page 1 of 4 (40 items) 1234