December, 2008

  • The Old New Thing

    Crazy or cell phone?

    • 53 Comments

    You've seen it, I'm sure. People walking down the street talking to themselves. Crazy or cellphone?

    What really gets me are the people who wear the headsets even when they aren't talking on the telephone, but rather in anticipation of receiving a telephone call. To those people, I have this to say to you:

    You're not that important. Get over yourself.

    I remember a few years ago, I was in Los Angeles attending a little party and got a ride home from somebody who was heading my way. We got in the car, and she put on her headset before putting the car in gear. It was a half-hour drive. No telephone call.

  • The Old New Thing

    A file can go by multiple names, but two files can't have the same name

    • 48 Comments

    Thanks to short file names and hard links, a single file can go by multiple names. (And for the purpose of today's discussion, I'm treating the full path as the name instead of just the part after the last backslash. Don't make me bring back the nitpicker's corner.) For example, C:\PROGRA~1 and C:\Program Files are two possible names for the same directory thanks to short names. [Typo fixed 7:15am.] If you've created hard links, then you can give a single file two entirely unrelated names, and those names need not even be in the same directory.

    On the other hand, you can't have two files with the same name. What would that even mean? Which one would you get if you issue an Open call? How would you open the other one? Heck, even before we get to this point: How do you even create two files with the same name? If you call CreateFile to create the "second" file, it'll just open the existing one!

    That's why I am baffled by this question that asks:

    I've seen a few cases where people write their own version of GetLongPathName (usually because they need to support NT4) using FindFirstFile. Are there situations where that approach would return an incorrect path? Is it safe in practice because FindFirstFile("foo.bar") always will return the exact match first before returning "foo.barbaz"?

    This question assumes that it's possible to have two files in a directory with the same name: One is the file "foo.bar"; the other is the file that goes by the long name "foo.barbaz" and the short name "foo.bar".

    I'm not sure what the sequence of events would be that could result in two files with the same name. Here's one scenario:

    1. Create file "foo.barbaz". It gets assigned the short name "foo.bar".
    2. Create file "foo.bar". This creates a new file called "foo.bar" which conflicts with the short name of the existing file "foo.barbaz".

    Except that's not what'll happen. When you perform step 2, the attempt to create the file "foo.bar" merely overwrites the existing file which has "foo.bar" as one of its names. Result: A single file with long name "foo.barbaz" and short name "foo.bar".

    Another scenario might go like this:

    1. Create file "foo.bar".
    2. Create file "foo.barbaz". The file system auto-assigns the short name "foo.bar".

    Except that's not what happens either. At the second step, the file system generates a short name like "foo~1.bar" specifically to avoid the name collision.

    You can run these experiments yourself from the command line to confirm. The "dir /x" command will come in handy.

  • The Old New Thing

    On 64-bit Windows, 32-bit programs run in an emulation layer, and if you don't like that, then don't use the emulator

    • 43 Comments

    On 64-bit Windows, 32-bit programs run in an emulation layer. This emulation layer simulates the x86 architecture, virtualizing the CPU, the file system, the registry, the environment variables, the system information functions, all that stuff. If a 32-bit program tries to look at the system, it will see a 32-bit system. For example, if the program calls the GetSystemInfo function to see what processor is running, it will be told that it's running on a 32-bit processor, with a 32-bit address space, in a world with a 32-bit sky and 32-bit birds in the 32-bit trees.

    And that's the point of the emulation: To keep the 32-bit program happy by simulating a 32-bit execution environment.

    Commenter Koro is writing an installer in the form of a 32-bit program that detects that it's running on a 64-bit system and wants to copy files (and presumably set registry entries and do other installery things) into the 64-bit directories, but the emulation layer redirects the operations into the 32-bit locations. The question is "What is the way of finding the x64 Program Files directory from a 32-bit application?"

    The answer is "It is better to work with the system than against it." If you're a 32-bit program, then you're going to be fighting against the emulator each time you try to interact with the outside world. Instead, just recompile your installer as a 64-bit program. Have the 32-bit installer detect that it's running on a 64-bit system and launch the 64-bit installer instead. The 64-bit installer will not run in the 32-bit emulation layer, so when it tries to copy a file or update a registry key, it will see the real 64-bit file system and the real 64-bit registry.

  • The Old New Thing

    Why isn't there a SendThreadMessage function?

    • 42 Comments

    Here's an interesting customer question:

    Windows has PostMessage and SendMessage. It also has PostThreadMessage but no SendThreadMessage. Why isn't there a SendThreadMessage function? Am I forced to simulate it with an event?

    What would this imaginary SendThreadMessage function do? Recall that SendMessage delivers the message directly to the window procedure; the message pump never sees it. The imaginary SendThreadMessage function would have to deliver the message directly to.... what? There is no "thread window procedure" to deliver it to.

    Okay, maybe you still intend to process the thread message in your message pump, but you want the caller of the imaginary SendThreadMessage function to wait until you've finished processing the message. But how does it know when you're finished? It can't wait for DispatchMessage to return, since DispatchMessage can't dispatch thread messages. (Where would it dispatch them to?) The processing of the thread message is completely under the control of the message pump. The window manager gives it a thread message, and as far as the window manager is concerned, that's the end of the story.

    You might say that the processing of the thread message is complete when somebody next calls GetMessage or PeekMessage, but there's no guarantee that the next call to a message-retrieval function will come from the message pump. Handling the thread message may result in a call to MessageBox, and as a modal function, it will have its own message loop, which will call GetMessage, resulting in your imaginary SendThreadMessage function deciding that message processing is complete when in fact it's still going on.

    What should you do instead? Just create a window and send it a message. The scenarios where you would want to use the PostThreadMessage function are very limited and specialized. Under normal circumstances, you should just send a regular window message.

  • The Old New Thing

    Why does the Explorer address bar reset itself while you're typing into it?

    • 37 Comments

    When you ask Explorer to navigate to a new location, the steps go roughly like this (vastly oversimplified):

    1. User initiates a navigation.
    2. Explorer puts up the "busy" animation and starts looking for the location you navigated to.
    3. When the location is found, the contents of the folder are switched to the new location and the address bar is updated to reflect that new location.

    Pretty straightforward, right? Well, commenter dhiren asks:

    Any idea why the address bar in Explorer randomly decides to reset itself while you're typing in it?

    It's not like Explorer is saying, "Ha, ha! Sucker!" Explorer is just doing its thing, following its happy little checklist, and when it finally locates the navigation target, it moves on to step three and switches the view and synchronizes the address bar to match the view.

    If you've messed with the address bar in the meantime, the synchronization of the address bar with the folder contents overwrites the changes you were in the process of making. This isn't an intentional "let's make the user's life miserable"; it's just a consequence of the simple checklist.

    Now, yes, it is an annoyance, and yes, it's a bug, but it's not a bug in the sense that somebody wrote code that failed to implement the specification; rather the bug is due to an oversight in the specification itself. This is another example of how things can get extremely complicated even though the basic idea is very simple: Once you have the simple idea working, everybody finds random special cases that force you to take your simple idea and make it more and more complicated.

  • The Old New Thing

    A bar on Microsoft main campus? What should we call it?

    • 37 Comments

    When my colleagues discovered that Seattle bar Spitfire is opening a bar on the main Microsoft campus, a quick game of Name that bar sprung up. (Todd Bishop has his suggestions.)

    Here are some names we came up with:

    Though I suspect they'll just call it Spitfire.

    Sidebar: Although alcohol is available at many company-sponsored social events, there is no pressure to drink an alcoholic beverage, and people don't even notice one way or the other. (Just like nobody notices that you had the vegetarian appetizers and avoided the meat ones.)

  • The Old New Thing

    Don't use global state to manage a local problem

    • 36 Comments

    We've seen a few instances where people have used a global setting to solve a local problem. For example, people who use the LockWindowUpdate function to prevent a window from redrawing, toggle a global setting to see what its value is, or who change the system time zone as part of an internal calculation. To this, I'll add as an example a program which figures that if you don't want the program's feature, you don't want that feature in any competing products either.

    The first service pack of Windows XP introduced the Set Program Access and Defaults control panel. Among other things, media players can register here to allow users to choose them as the default media player, to enable access to the media player, or to remove access. The guidelines for the use of this control panel recommend that in response to the Remove access command, media players should remove their user interface entry points (such as shortcuts on the Start menu and notification icons), disable their autoplay feature, and generally act as if they weren't there.

    One media player decided that if the user instructed it to remove its access points and disable its autoplay, it would dutifully remove its user interface entry points, and it would also go into the configuration manager and disable media insertion detection on the CD drive. "If you don't want me to autoplay your CDs, then fine, and I'll make sure nobody else can autoplay your CDs either." They also disabled autorun, a related but separate feature.

    This program addresses a local problem (disable autoplay for Program X) by applying a global solution (disable all media insertion detection). Whether media insertion detection is enabled or disabled, and which programs should be notified when it occurs, is the decision of the computer user. Programs should not be altering hardware configuration unless the user specifically requested it. The correct thing for Program X to do is to remove its autoplay registration, leaving intact the behavior of other programs.

    It turns out that Program X was not disabling media insertion detection out of spite. The people responsible for Program X simply followed the description literally without understanding the big picture. "The documentation says that we should disable our autoplay feature. Well, I guess if we disable media insertion detection, that'll disable our autoplay feature."

    I wonder if their uninstaller reformats the hard drive.

    Moral of the story: Don't use global state to manage a local problem.

  • The Old New Thing

    The Fargo campus responds to Redmond's December 2008 storm conditions

    • 34 Comments

    The main Microsoft campus has been blanketed in snow the past few days. Microsoft Real Estate and Facilities has been sending out emergency alerts regarding the state of the campus, what services are available, what services are reduced, that sort of thing. Our friends over in the Fargo campus are generally unimpressed by all this hubbub and have written up their own adverse weather notification to make fun of us wusses in Redmond. (Reprinted below with some editing.)

    Fargo Campus Open with No Interruptions

    Due to normal cold weather and heavy snowfall the Microsoft Facilities in Fargo, including satellite areas (ABC, DEF, and GHI) will have NO SERVICES INTERUPTED due to Snow/Ice conditions in the local area.

    Forecast:

    Current conditions: Light snow and windy
    Temperature: −8°F
    Feels like −40°F
    UV Index: 0 Low
    Wind: From N at 40mph
    gusting to 48 mph
    Humidity: Low
    Pressure: 29.81 in. ↑
    Dew Point: −12°F
    Visibility: 0.8 miles
    Updated: Dec 14 10:25 am CT

    Effective For: Thursday, December 18, 2008 through the end of April

    Please exercise normal caution driving and walking on campus as you are more likely to be attacked by a bunny than slip and fall on the ice.


    Campus Services

    Reception: Building lobbies will be open. If your building reception is closed then they will be fired.

    Shuttle: Campus shuttles will not be operating because there is no such thing as a campus shuttle in Fargo.

    Mailing Services: Mailing Services will be operating under full service.

    Food Service: There will full menu service available in all buildings.

    Facilities Maintenance Response: A full maintenance staff is at work on campus today.

    Building Services: All services such as heat, lighting and network connectivity will be operational.

    Other Advisory Notes:

    Security: Corporate Security advises its services will remain available to the campus. If you need assistance, stop by the office and wake them up.

    Parking: Park as usual, the snow plow drivers will just plow around you. You're all capable of driving on snow/ice so plowing will be limited.

    Connectivity: You shouldn't have any connectivity issues because you're expected to be at work. We only had 10" of snow and 40mph wind.

    Microsoft Company Store: The Company store will not be open today because the Fargo Campus doesn't have a company store.

    Area Roads: In light of the continuing snowfall and icy road conditions, most local roads are snow-covered and slippery and will remain that way until March. For information on current road conditions, please look out the window.

    Weather Updates: For information on how the weather is impacting Microsoft services and accessibility, please visit http://www.youtube.com regularly throughout the day or tune into your local news stations for updates when you are in the office as conditions on campus could quickly change but they probably won't since cold, snow, and ice is the normal conditions this time of year.

    Thank you for your understanding and cooperation.

    Microsoft Real Estate & Facilities

  • The Old New Thing

    How do I obtain the computer manufacturer's name?

    • 33 Comments

    One customer wanted a way to determine the name of the computer manufacturer. For example, they wanted to make some function call and get back "IBM" or "Compaq" or "Dell". I don't know why they wanted this information, and for the moment, I don't care.

    And of course, when you're looking for information, you don't search MSDN; that's for crazy people. No, let's just fire up regedit and hit Ctrl+F. (I can't imagine how many application compatibility bugs were created by that "helpful" Ctrl+F dialog in regedit.)

    The customer found the registry keys that are used to customize the System control panel, as well as the OEMINFO.INI file that also takes part. But then the question of reliability arose. After all, since it's just a registry key and an INI file, the user could just edit it and make it say anything they want. If the customer wiped their hard drive and reinstalled Windows from scratch, then this information would be lost, too. This customer wanted some degree of assurance that if the computer claimed to be a Dell, then it really was a Dell.

    Enter WMI. The Scripting Guys are all over WMI. If you search for the phrase "from Win32_ComputerSystem" you will find hit after hit from the Hey, Scripting Guy! column.

    And it so happens that WMI exposes the computer manufacturer info as well. If you look at the scripts that the Scripting Guys put out, probably two thirds of them fall into this pattern:

    strComputer = "."
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery("Select * from something")
    For Each objItem in colItems
         Wscript.Echo objItem.something
    Next
    

    All we have to do is fill in the "something".

    strComputer = "."
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery("Select * from Win32_ComputerSystem")
    For Each objItem in colItems
         Wscript.Echo "System Name: " & objItem.Name
         Wscript.Echo "Manufacturer: " & objItem.Manufacturer
         Wscript.Echo "Model: " & objItem.Model
         Wscript.Echo
    Next
    

    Okay, so great, we can use WMI to get this information. But how reliable is it?

    Well, the WMI folks tell me that they get the information by querying the SMBIOS directly, so it's as reliable as your BIOS. Major manufacturers will put their names into the BIOS¹, but if you're running on a home-built machine, the values are whatever came with your motherboard. The BIOS manufacturers typically put placeholder strings into their SMBIOS, setting the manufacturer to a generic string like "Manufacturer", for example. When the motherboard manufacturer installs the BIOS, they're supposed to replace the placeholder strings with something more meaningful, but most of them don't bother. The result is that a machine you put together from parts you bought at the local computer shop will most likely just say "Manufacturer" for the manufacturer.

    In summary, if you query WMI for the computer manufacturer and it comes back "Dell", then you can be pretty sure you have a Dell. (Either that or somebody with way too much time on their hands burned a custom BIOS that says "Dell".) On the other hand, if it comes back as "Manufacturer" then you're still in the dark. All you know is you've got some sort of generic computer.

    ¹Even though major manufacturers will put their name into the BIOS, I'm told that if you send your computer back to the manufacturer and they replace the motherboard, they will sometimes forget to burn their name into the BIOS of the replacement motherboard. As a result, even on a name-brand computer, you might see "Manufacturer".

  • The Old New Thing

    The struggle against those annoying plastic packages gains a few allies

    • 33 Comments

    Some companies are switching to easy-to-open packaging. Not a moment too soon, in my opinion.

Page 1 of 4 (38 items) 1234