September, 2007

  • The Old New Thing

    2007 Q3 link clearance: Microsoft blogger edition


    A few random links that I've collected from other Microsoft bloggers.

  • The Old New Thing

    How do I put a different wallpaper on each monitor?


    When you set a wallpaper on a multi-monitor system, that wallpaper goes onto each monitor. For example, if your wallpaper is a picture of a flower, each monitor shows that same flower. Commenter David Phillips wonders whether there is a way to set a different wallpaper on each monitor, or whether it is some sort of trick.

    It's some sort of trick.

    And it's a trick because it's not something that the window manager folks intended to happen; rather, it's just an artifact of how wallpapers work.

    The trick is to set your wallpaper to "tile" rather than "center" or "stretch". When the window manager draws a tiled bitmap, it places the tiles so that the upper left corner of the primary monitor exactly coincides with the top left corner of a tile. The remaining tiles are then arranged around that anchor tile.

    You're not listening. I said that I wanted a different picture on each monitor, not the same picture tiled across all of my monitors.

    Yes, I know. Here comes the trick: Create a "monster tile". For example, suppose you have two 800×600 monitors arranged side by side (primary on the left), and you want a tropical island on the primary monitor and a country road sunset on the second, like this:

    Create a single bitmap that consists of the two images side by side. In our case, it would be a single 1600×600 bitmap.

    When this bitmap is tiled, the "virtual infinite screen" looks like this:

    And the upper left corner of the primary monitor lines up against the upper left corner of a tile, like so:

    If your monitors aren't the same size, you can still use this trick; you just need to add some dummy space to get the tiles to line up the way you want. For example, suppose your secondary monitor is smaller than your primary, positioned so that its top edge lines up with the top edge of the primary. Your "monster bitmap" would place the country road sunset in the corresponding position next to the bitmap you want to use for your primary monitor.

    When this bitmap is tiled and the upper left corner of the tile is placed at the upper left corner of the primary monitor, you get the desired effect:

    Ah, but what if you have a monitor above or to the left of your primary monitor? Since the bitmap is tiled, you just "wrap around" from the left of the "monster bitmap" to the extreme right. For example, if your monitors are arranged side by side but you have the secondary monitor on the left, then you still put the image for the secondary monitor on the right; that way, when the origin of your monitor system is placed against a tile, the image from the tile to the left is the one that shows up on your secondary monitor.

    Given these examples, I leave you to develop the general algorithm.

  • The Old New Thing

    Does creating a thread from DllMain deadlock or doesn't it?


    Let me get this out of the way up front: Creating a thread from DllMain is not recommended. The discussion here has to do with explaining the behavior you may observe if you violate this advice.

    Commenter Pete points out that "according to Usenet" creating a thread in DllMain is supposed to deadlock, but that's not what he saw. All he saw was that the thread entry procedure was not called.

    I'm going to set aside what "according to Usenet" means.

    Recall how a thread starts up. When you call CreateThread, a kernel thread object is created and scheduled. Once the thread gets a chance to run, the kernel calls all the DllMain functions with the DLL_THREAD_ATTACH code. Once that's done, the thread's entry point is called.

    The issue with deadlocks is that all DllMain functions are serialized. At most one DllMain can be running at a time. Suppose a DllMain function is running and it creates a thread. As we noted above, a kernel thread object is created and scheduled, and the first thing the thread does is notify all the DLLs with DLL_THREAD_ATTACH. Since DllMain functions are serialized, the attempt to send out the DLL_THREAD_ATTACH notifications must wait until the current DllMain function returns.

    That's why you observe that the new thread's entry point doesn't get called until after you return from DllMain. The new thread hasn't even made it that far; it's still working on the DLL_THREAD_ATTACH notifications. On the other hand, there is no actual deadlock here. The new thread will get itself off the ground once everybody else has finished doing their DllMain work.

    So what is this deadlock that Usenet talks about? If you've been following along, you should spot it easily enough.

    If your DllMain function creates a thread and then waits for the thread to do something (e.g., waits for the thread to signal an event that says that it has finished initializing, then you've created a deadlock. The DLL_PROCESS_ATTACH notification handler inside DllMain is waiting for the new thread to run, but the new thread can't run until the DllMain function returns so that it can send a new DLL_THREAD_ATTACH notification.

    This deadlock is much more commonly seen in DLL_PROCESS_DETACH, where a DLL wants to shut down its worker threads and wait for them to clean up before it unloads itself. You can't wait for a thread inside DLL_PROCESS_DETACH because that thread needs to send out the DLL_THREAD_DETACH notifications before it exits, which it can't do until your DLL_PROCESS_DETACH handler returns.

    (It is for this thread cleanup case that the function FreeLibraryAndExitThread was created.)

  • The Old New Thing

    Why isn't QuickEdit on by default in console windows?


    In the properties of console windows, you can turn on QuickEdit mode, which allows the mouse to be used to select text without having to go explicitly into Mark mode. (In a sense, the console window is permanently in Mark mode.) Why isn't this on by default? It's so useful!

    Somebody thought the same thing and changed the default in one of the earlier versions of Windows (my dim recollection was that it was Windows 2000) without telling anyone, especially not the manager responsible for the feature itself.

    The change was slipped in late in the game and made it into the released product.

    And then all the complaints came streaming in.

    Since the change wasn't part of any of the betas or release candidates, customers never got a chance to register their objections before the product hit the streets.

    Why did customers object anyway? Because it breaks console programs that want to use the mouse. A console program that calls ReadConsoleInput can receive input records related to mouse activity. A full-screen character mode editor like, say, emacs or vi or something more Windows-centric like the M editor that came with the Programmer's Workbench will use the mouse to select text within the editor itself. Or they might hook up a context menu to right-clicks. At any rate, turning QuickEdit on by default means that the mouse stops working in all of these programs.

    A hotfix had to be issued to change the QuickEdit default back to "off". If it means that much to you, you can turn it on yourself.

  • The Old New Thing

    The first day at Microsoft: A fender-bender


    This is the first of what might be a series of stories on the subject, So what happened on your first day at Microsoft? Some facts may have been altered to preserve the anonymity of the subject, but the essense is true. Our first storyteller is "Employee X":

    At the end of my first day, I back out of my parking space and accidentally hit a Lexus parked behind me. Oh great, my first day at work, and I dent somebody's fancy car. I leave a note of apology on the windshield, with my name, email address, phone number, and a promise to pay for whatever repairs are necessary.

    The next day, I come to work, and I have a new email message.

    From Bill Gates.

    Oh my God, I dented Bill Gates' car.

    Fortunately, he said not to worry about it.

    Bonus: Russell Ball shares a voicemail message left by a new employee on his second day.

  • The Old New Thing

    Microspeak: Going forward


    The jargon phrase going forward has largely replaced the more mundane equivalent from now on. It appears that I'm not the only person who is bothered by this phrase. Sample usages:

    • We discussed the membership and timeframe for support team meetings going forward.
    • There will be change to the status reports going forward.
    • Going forward we will be doing this for every milestone.

    Notice that the phrase going forward usually adds little to the sentence. You can delete it from all of the sentences above and nobody would notice a difference.

  • The Old New Thing

    It rather involved being on the other side of this airtight hatchway: Elevation to administrator


    Surprisingly, it is not a security vulnerability that administrators can add other users to the Administrators group. But that doesn't stop people from claiming that it is.

    For example, it's not uncommon for a vulnerability report to come in with the following steps:

    1. (a) Install this rogue service/driver, or (b) copy this rogue program to your machine and change this registry key in HKEY_LOCAL_MACHINE to point to it, or (c) replace this file in the system directory with a rogue program.
    2. Log on as an unprivileged user.
    3. Perform magical operation X.
    4. Boom! User is now an administrator!

    Wow, this looks bad. An unprivileged user can elevate to administrator and... wait a second, what's that in step 1?

    To perform step 1, you need to have administrative privileges already. Only administrators can install services and drivers, only administrators can change registry keys in HKEY_LOCAL_MACHINE, and only administrators have write permission in the system directory. Therefore, this "vulnerability" basically says "If you can gain administrator privileges, then you can add anybody to the Administrators group." Well, sure, but you really chose the complicated way of doing it. Once you get administrator privileges, just do a NET LOCALGROUP Administrators Fred /ADD and you're done.

    After all, why write a service or a driver when a batch file does the trick just as easily?

    An alternative step 4 is "Boom! User is pwnz0red!" Well, yeah, an administrator can install software that commandeers user accounts. This is hardly a surprise, is it?

    In a sense, this is "security vulnerability by obscurity": By making your alleged exploit unnecessarily complicated, you can fool people into thinking that you're actually onto something.

  • The Old New Thing

    What do I do with per-user data when I uninstall?


    If the user chooses to uninstall your program, what do you do with the data your program kept in HKEY_CURRENT_USER, and other parts of the user profile? Should you enumerate all the profiles on the machine and clean them up?

    No. Let the data go.

    First, messing with the profiles of users that aren't logged on can result in data corruption, as we saw when we looked at roaming user profiles. Users don't like it when their data get corrupted.

    Second, the users might want to keep that local data, especially if they are uninstalling your program only temporarily. For example, maybe your program's installation got corrupted and the user is doing an uninstall/reinstall in an attempt to repair it. Or the user might be uninstalling your program only because they're going to be reinstalling a newer version of your program. If you deleted all the users' saved games, say, they are going to be kind of miffed that they won't be able to finish off the big boss that they've been working weeks to defeat.

    Now, if you want, you can clean up the per-user data for the current user (after asking for permission), but you definitely should not be messing with the profiles of other users.

    (Remember, this is my personal recommendation, not an official recommendation of Microsoft Corporation. I know that had I not included this explicit disclaimer, somebody would have written an article somewhere saying that "Microsoft says to...")

  • The Old New Thing

    Whenever there is a coordination problem, somebody says, "Hey, let's create a process!"


    Whenever there is a coordination problem, somebody says, "Hey, let's create a process." Now you have two coordination problems.

    I see this over and over, and paradoxically the people who create a process for managing a coordinating problem come off looking like proactive problem-solvers who get ahead of the problem. They're the go-getters, the people who look at each problem as an opportunity for continuous improvement. All that great management buzzword stuff.

    It doesn't matter whether or not the process actually works, because failure is an orphan, and besides, nobody follows up a year later to see whether your process actually improved things or whether it was abandoned six weeks after roll-out. You get the credit for proposing the process in the first place.

    Consider this problem at a hypothetical toy company: Some rumors have started that one of their toy cars is dangerous because of a wiring flaw that can result in excessive heat and possible fire. (It doesn't matter what the crisis is. I just made up something vaguely plausible.) Employees all over the company are getting email from their relatives asking about the toys, but the employees don't know what the story is either. Presumably, the safety department is investigating the problem and providing guidance to the PR and marketing departments so they can prepare a public response, and if there really is a problem, they're working with the product recall team to organize how the recall will be carried out, and they're working with the product engineering team to figure out what changes need to be made to the product to avoid the problem. In other words, the safety department is up to their ears in crisis.

    A employee from the dolls department, whose brother asked him about this toy car problem, can't find any information on the status of this issue and sends email to the "Employee Issues" alias, and a dozen people chime in with "Yes, please, we would like this information, I want to know what I can tell my brother and everybody else who is asking me about it. I might even post it on my blog so I can try to counteract some of the out-of-control rumors that are out there."

    A half hour later, somebody from the safety department responds, "Yes, we know about this, we're working on it. Please don't say anything publicly since we're still investigating."

    Somebody watching the saga unfold proposes a process by which employees can be kept up to date on the status of these types of emergent crises.

    • Create an internal web site that contains a list of all current emergencies at the company, their status, what information is speculation and what information is solid, which pieces of that information can be revealed to the public, and recommended phrasing for the information when it is revealed.
    • Whenever there is an emergency, the people responsible for responding to the emergency update the web site with the status of the investigation and the other information listed above.

    This is the wrong solution to the problem.

    The reason why this is the wrong solution is that it suffers from the classic "Create work for somebody else" problem. The people who benefit from this site are not the same people who would make the site useful. This doesn't give the people who make the site useful much incentive to do so. They're busy dealing with the emergency. They don't want to waste the time of one of their valuable investigators to do "internal PR".

    This scenario repeats itself on a less dramatic scale with various types of inter-group coordination problems. One group wants to be kept advised of the progress of another group for whatever reason. But if the second group doesn't need the first group for anything, they have no incentive to keep the first group informed.

    For example, suppose the first team provides an interface that the second team uses, and the first team decides that they need to redesign the interface for whatever reason. During the transition, the first team provides both interfaces so that the second team can transition from the old to the new, with the request that the second team let them know when they have finished transitioning to the new interface so they can remove support for the old one.

    Unless the first team keeps on top of things, the second team will probably forget to tell the first team when they have completed the transition, or they may even forget to transition to the new interface at all! After all, the old interface still works.

    In this case, the traditional way of making the second team care is to file a bug against them saying, "Stop using the old interface." That way, it shows up in their bug statistics as a reminder, and when they actually do the work, they can resolve the bug back to the first team. But you can imagine a scenario where the information the first team wants is more of a continuous nature rather than a single event. (Since bugs track single events.)

  • The Old New Thing

    Why did the shortcut template change in Windows Vista?


    Since Windows 95, when you right-dragged an item and selected "Create Shortcut", you got "Shortcut to X". But in Windows Vista, the name is now "X - Shortcut". Why is that?

    Two reasons.

    The first reason is globalization. The template "Shortcut to X" made X the object of a preposition. In some languages, this may require changes to X (for case) or to the word "to" (based on grammatical properties of X). Constructing sentences from phrases is a dangerous endeavor due to language issues like this, and the new formulation sidesteps the issue by not trying to make a phrase out of the result.

    The second reason is sorting. With the new format, the shortcut sorts next to the original object, making it easier to find. (This is particularly helpful when you're in an auto-sort view. "Hey, where's that shortcut I just created? Oh well, I'll just make another one.")

Page 1 of 4 (36 items) 1234