June, 2005

  • The Old New Thing

    Beware of roaming user profiles

    • 38 Comments

    One of the less-known features of Windows is the roaming user profile. I know that this is not well-known because I often see suggestions that fail to take the roaming user profile scenario into account. Indeed, if your program behaves badly enough, you can cause data loss. (More on this later.)

    What is a roaming user profile?

    Well, your user profile is the collection of things that reside under your %USERPROFILE% directory. (This is not quite true, but it's a good enough approximation for the purpose of this discussion. An important exception will be noted next time.) Your per-user registry is kept in %USERPROFILE%\ntuser.dat, so your per-user registry is part of your user profile.

    In highly managed environments (corporations), system administrators can set up user profiles on a centralized server, so that users log onto any machine and have available their files and settings. This is accomplished by copying the user profile from the server when the user logs on and copying it back to the server when the user logs off. (Of course, there is also caching involved to save time if the user logs back onto the same machine.)

    What does this mean for you, the programmer?

    For one thing, it means that the path to the user's profile can change from one logon session to the next. If the user runs your program from Computer A, their user profile directory might be C:\Documents and Settings\Fred, but when they log off from Computer A and log on to Computer B, the directory to their user profile might change to C:\WINNT\Profiles\Fred. In particular, that file that used to be at C:\Documents and Settings\Fred\My Documents\Proposal.txt has moved to C:\WINNT\Profiles\Fred\My Documents\Proposal.txt. If your program has a feature where it offers a list of recently-used files (or auto-opens the most recently used file), you may find that the file no longer exists at its old location. The solution is to use profile-relative paths, or even better, shell virtual folder-relative paths (e.g., recording the path relative to CSIDL_MYDOCUMENTS), so that when the profile roams to a machine with a different user profile path, your program can still find its files.

    For another thing, you cannot just cruise through the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList registry key expecting to find all the user profiles and possibly even modify them, because the copy of the user profile on the local computer might not be the authoritative one. If the profile is a cached roaming profile, then any changes you make will either (1) be lost when the user roams back to the computer after using another computer, or (2) cause the local profile to be considered newer than the master copy on the server, causing the changes the user made to the copy on the server to be lost! (Which of the two bad scenarios you find yourself in depends on the time you change the cached profile and the time the target user logs off that other computer.)

    Another consequence of roaming user profiles is that your program can effectively see itself changing versions constantly. If Computer A has version 1.0 of your program and Computer B has version 2.0, then as the profile roams between the two computers, both versions 1.0 and 2.0 will be operating on the user profile in turn. If versions 1.0 and 2.0 use the same registry keys to record their settings, then your registry formats had better be both upward- and downward-compatible. This is a particularly painful requirement for operating system components, which consequently need to maintain bidirectional registry format compatibility with systems as old as Windows NT 4. (Windows NT 3.51 had a different model for roaming user profiles.)

    Yet another consequence of roaming user profiles applies to services. Prior to Windows XP, if a service holds a registry key open after the user logged off, then the registry hive cannot be unloaded and consequently (1) consumes memory for that profile even though the user is no longer logged on, and (2) prevents the user's local registry changes from being copied back to the server. This "hive leakage" problem was so rampant that in Windows XP, the profile unload code takes a more aggressive stance against services that hold keys open too long. You can read more about the changes to registry hive roaming in the Resource Kit article linked at the top of this entry.

  • The Old New Thing

    What if two programs did this?

    • 54 Comments

    The thought experiment "Imagine if this were possible" is helpful in thinking through whether Windows lets you do something or other. (A special case of this is "When people ask for security holes as features.") If the possibility leads to an obvious contradiction or the violation of generally-accepted rules of metaphysics, then you can be pretty sure that Windows doesn't support it. (Of course, the absence of such a contradiction doesn't prove that Windows does support it. But you can use it to rule out obvious bad ideas.)

    The question "What if two programs did this?" is also helpful in evaluating a feature or a design request. Combining this with "Imagine if this were possible" leads to an impressive one-two punch. Here are a few examples:

    "How do I create a window that is never covered by any other windows, not even other topmost windows?"

    Imagine if this were possible and imagine if two programs did this. Program A creates a window that is "super-topmost" and so does Program B. Now the user drags the two windows so that they overlap. What happens? You've created yourself a logical impossibility. One of those two windows must be above the other, contradicting the imaginary "super-topmost" feature.

    "How do I mark my process so that it always the first/last to receive the system shutdown notification? I want to do something before/after all other programs have shut down."

    Imagine if this were possible and imagine if two programs did this. You now have two programs both of which want to be first/last. But you can't have two first or two last things. One of them must lose. (This of course generalizes to other things people might want to be first or last.)

    "How do I make sure that my program is always the one that runs when the user double-clicks an .XYZ file?"

    Imagine if this were possible and imagine if two programs did this. Now the user double-clicks an .XYZ file. Which program runs?

    In this case, the solution is to leave the user in charge of their file associations; if they decide that they want your competitor's program to be used for .XYZ files, then that's their decision and you should respect it.

    My colleague Zeke [link fixed 11am], who is responsible, among other things, for the way file associations work in Explorer, provides a few alternatives:

    Here is the entry point in MSDN to the documentation on file associations in Explorer.

    For many of these "I want to be the X-est"-type questions, you can often come up with some sort of hack, where you run a timer that periodically checks whether you are still X, and if not, pushes you back into the X-position. And then you stop and think, "What if two programs did this?" and realize that it's a bad idea. At least I hope you do.

    Even with this explanation, some people still don't get it. I'll ask them to consider, "What if two programs did this? They'll be fighting back and forth," and the answer I get back is, "Then I can have the second program check if the first program is already running." They don't understand that they didn't write the second program.

    When two programs "duke it out" like this, you can't predict which one will win, but you can predict with 100% certainty who will lose: The user.

    I remember well when one of my colleagues called me into his office to show me two very popular commercial programs that both wanted to guarantee that they were the program that ran when the user double-clicked an .XYZ document. Since there is no such guarantee, they faked it with the timer hack.

    You installed the first program, it set itself as the .XYZ file handler, and everything seemed normal. You then installed the second program, it set itself as the new .XYZ file handler, and the first program noticed and said, "Uh-uh, I'm the program that runs .XYZ files", and changed things back. Then the second program said, "No way, I'm the program that runs .XYZ files" and set itself back.

    This childish game of "Nuh-uh/Yuh-huh!" went on while the user sat there dumbfounded and helpless, watching the icon for their .XYZ files flicker back and forth between the two programs, both of whom egotistically believed they were doing the user a "favor" by insisting on being the program that runs .XYZ files.

  • The Old New Thing

    Using /LARGEADDRESSAWARE on 64-bit Windows for 32-bit programs

    • 11 Comments

    Probably the biggest advantage of 64-bit Windows is not the larger registers but rather the expansive 64-bit address space. Recall that even when the /3GB switch is set, 32-bit programs receive only 2GB of address space unless they indicate their willingness to cope with addresses above 2GB by passing the /LARGEADDRESSAWARE flag.

    This flag means the same thing on 64-bit Windows. But since 64-bit Windows has a much larger address space available to it, it can afford to give the 32-bit Windows program the entire 4GB of address space to use. This is mentioned almost incidentally in Knowledge Base article Q889654 in the table "Comparison of memory and CPU limits in the 32-bit and 64-bit versions of Windows".

    In other words, certain categories of 32-bit programs (namely, those tight on address space) benefit from running on 64-bit Windows machine, even though they aren't explicitly taking advantage of any 64-bit features.

  • The Old New Thing

    The Date/Time control panel is not a calendar

    • 85 Comments

    Although many people use the Date/Time control panel to flip through a calendar, that's not what it is for. In fact, if you use it that way, you can create all sorts of havoc!

    In its original incarnation in Windows 95, the Date/Time control panel changed your date and time. If you clicked through the calendar to see next month, you actually changed your system clock to next month. If you changed your mind and clicked "Cancel", the Date/Time control panel undid its changes and restored the date to the original date.

    In other words, here's what happened, step by step:

    • On April 1, you open the Date/Time control panel.
    • You change the month to May. The Date/Time control panel changes your system date to May 1. If you are running an appointment calendar program, all appointments from the month of April will fire. (For example, your April 15th alarm to remind you to file your income taxes.) You are annoyed by all these alerts and you cancel them.
    • You decide you didn't want to change the month to May after all and click Cancel.
    • The Date/Time control panel changes the date back to April 1.
    • On April 15th, your income tax alarm fails to fire because you cancelled it, remember?

    In other words, the Date/Time control panel was not designed for letting you flip through a calendar. It was designed for changing the system date and time.

    Unaware of its design, people have been using the Date/Time control panel as if it were a calendar, not realizing that it was doing all sorts of scary things behind the scenes. It's like using a cash register as an adding machine. Sure, it does a great job of adding numbers together, but you're also messing up the accounting back at the main office!

    For Windows 2000, in reluctant recognition of the way people had been mis-using the Date/Time control panel, it was rewritten so that it doesn't change the system time until you hit the Apply button.

    Aaron Margosis shows you how to grant a user permission to change the system date and time without having to make them a full administrator.

  • The Old New Thing

    Google is the cute two-year-old girl with curly blond hair that gets all the attention

    • 85 Comments

    Let's see, Google Maps adds the world outside the United States, Canada and the UK, and people go ga-ga. Nevermind that Google's new "maps" have nothing beyond country boundaries. "Aww, look at Google, she's so cute and adorable!"

    I'm sure the people at the existing online map services like MapQuest and MSN MapPoint are sitting there like older siblings, wondering when exactly they turned into chopped liver. MSN MapPoint has actual maps of most of Europe, and MapQuest's library of maps is larger still. (Kathmandu anyone?) Both sites provide documentation on how to link directly to them. Yet they don't get drooled over.

    Somebody at MapQuest should take out a full page ad that goes something like this:

    Dear Google Maps,

    Welcome to the rest of the world! If you ever need driving directions, don't hesitate to ask.

    Love ever,
    MapQuest

  • The Old New Thing

    Why does Windows XP SP2 sometimes forget my CD autoplay settings?

    • 34 Comments

    It didn't forget them; it's just double-checking with you.

    The developer responsible for CD autoplay in Windows XP SP2 explained it to me. There were two problems with the way Windows XP handled CD autoplay.

    First, when you installed a new program that included CD autoplay capability, many users didn't know where in the UI to go to select that new program as their default CD autoplay program. If they had previously selected a program and ticked "Always perform this action", there was no easily-discoverable way to undo the "always" flag to make the dialog reappeared and allow the user to select the new program instead.

    Second, many programs, upon installation, secretly hacked the undocumented CD autoplay settings in order to set themselves as the default CD autoplay handler, gleefully overriding the user's previously-stated preference. Because these programs egotistically believed themselves to be the coolest most amazing program ever written in the history of mankind.

    In other words, the two problems were, "I just installed this program and I want it to be the CD autoplay program" and its converse "I just installed this program and I don't want it to be the CD autoplay program".

    Windows XP SP2 introduced new behavior related to CD autoplay in an attempt to address these problems: When it sees that a new CD autoplay handler is available, it shows you the CD autoplay dialog one more time. This gives you a chance to (a) pick that new program you just installed, or (b) un-pick that program you just installed (if it was presumptuously rude enough to set itself as your default).

    The first time you insert a CD into your computer after upgrading to Windows XP SP2, you will also get the CD autoplay dialog. This is a "better late than never" dialog to cover for any handlers that were installed before you upgraded to Windows XP SP2.

    What's the moral of the story? Whereas in the old days, you only had to worry about helping other programmers interface with your feature, in the new software landscape, you also have to worry about stopping programmers who are trying to abuse your interface.

  • The Old New Thing

    Why do Microsoft code samples tend to use ZeroMemory instead of { 0 }?

    • 24 Comments

    If you go browsing around MSDN, you'll find that code samples tend to call ZeroMemory explicitly rather than using "= { 0 }" notation. Why is that?

    To make it clearer for people who are used to other programming languages.

    Like it or not, a significant percentage of people who write programs for Windows do it in languages other than C and C++. Although those developers may have a basic understanding of C and C++, they don't have all the language subtleties memorized.

    Compare the situation of speaking in English to a group of people where not everyone speaks the language fluently. If you're considerate of your audience, you're going to avoid the more esoteric grammatical constructions, the rare words, and the obscure idioms. Instead of saying, "Were it to rain, we will see that umbrellas be available," you would use the simpler "If it rains, then we will make sure that umbrellas are available," thereby avoiding the grammatical complexity of the implied conditional by inversion ("if"), the subjunctive of condition ("were"), the implied conclusion ("then"), and the subjunction of intention ("be").

    Heck, even people who claim to know C and C++ don't have all the language subtleties memorized. Some of them have false impressions of what " = { 0 }" does. And who among us really has C/C++'s bizarre operator precedence rules committed to memory?

    Consequently, MSDN samples tend to use ZeroMemory to make it blindingly obvious what is being set to zero. One of the things we've learned over the years is that many people just copy/paste sample code without understanding it. If there are little things like ZeroMemory that can be done to make the intent of sample code clearer and reduce translation errors, then that's a good thing.

    If you prefer " = { 0 }", then go ahead and use it, secure in the knowledge that thousands of programmers aren't going to read your code and try to translate it into Visual Basic because that's the only language they know. But MSDN doesn't have that luxury.

  • The Old New Thing

    What is the difference between "Unpin from Start menu" and "Remove from this list"?

    • 34 Comments

    The list of programs on the left hand side of the Start menu is really two lists. (You can see the separator line between them.) The top list is the so-called "pin list". This is the list of programs you picked to be "locked" to the top of the Start menu. You can "pin" a program by right-clicking it and selecting "Pin to Start menu", or you can just drag it directly into the pin area.

    The bottom list on the left hand side of the Start menu is the "most frequently used" section of the Start menu, which selects the programs you have used the most in the past month or so.

    If you right-click an item that happens to be in the Start menu's pin list (either by right-clicking it from the pin list itself, or by right-clicking the original), one of the options is "Unpin from Start menu". If you select this option, then the item is removed from the Pin list.

    If you right-click an item on the "most frequently used" section of the Start menu, one of the options is "Remove from this list". If you select this option, then the item is removed from the "most frequently used" section of the Start menu. As far as the Start menu is concerned, you never ran that program. Of course, as you start running the program subsequently, it works its way up the popularity chain and might break into your "most frequently used" list based on your usage after you removed it originally.

    The difference, then, between the two, is that each removes the item you clicked from a different list. One removes it from the pin list, and the other removes it from the "most frequently used programs" list. There is a line separating the two lists, but most people don't realize that the line is there for a reason. It's not just a pretty face.

    To make things less (or perhaps more) confusing, if you select "Remove from this list" for an item from the pin list, it also removes it from the pin list as well as removing it from the "most frequently used programs" list.

  • The Old New Thing

    Why does Explorer eject the CD after you finish burning it?

    • 44 Comments

    Partly as a convenience, but partly to work around buggy hardware. The developer responsible for CD burning explained it to me.

    Most CD drives cache information about the disc in their internal memory to improve performance. However, some drives have a bug where they fail to update the cache after the CD has been written to. As a result, you can write some data to a CD, then ask the CD drive for the data you just wrote, and it won't be there! The drive is returning the old cached data instead of the new data. For most drives, ejecting and reinserting the CD is enough to force the drive to update its internal cache.

    "But wait, it gets worse!" I'm told.

    Some drives are "smart" and realize you've reinserted the same media, and then don't update. These drives require that you put in another type of media (or pressed CD-ROM media) to force them to update. These drives were manufactured around 2002, and new drives don't have it this bad, but still have the above problem requiring an eject/insertion cycle.

    So there's your tip for the day. If you are burning data to a CD and you find the data isn't there, try ejecting the disc and reinserting it. If your drive is particularly buggy, you'll have to eject the disc, insert a different type of disc, then eject that second disc and reinsert the first one.

  • The Old New Thing

    Why don't control panel programs and property sheets show up in the taskbar?

    • 50 Comments

    Control panel programs and property sheets don't show up in the taskbar. Why not?

    As I recall, the explanation was that control panel programs and property sheets aren't applications. They are auxiliary helper windows that assist you with a task, but they aren't a program in their own right. Therefore, they don't get a taskbar button.

    I've always been kind of suspicious of that explanation, but there it is, make of it what you will. (I don't mind the behavior—putting them in the taskbar just creates clutter—but the explanation I found kind of wanting.)

Page 1 of 4 (35 items) 1234