December, 2008

  • 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

    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

    What is the mysterious fourth message box button?

    • 25 Comments

    When you call the MessageBox function, you pass flags specifying which of a fixed set of button patterns you want (for example, Yes/No and OK/Cancel) and which button you want to be the default (MB_DEFBUTTON1 through MB_DEFBUTTON4.)

    Wait a second. What's with this MB_DEFBUTTON4? None of the button patterns are four-button patterns. The highest number of buttons you can specify is three: Abort/Retry/Ignore. How can you set a nonexistent button to be the default?

    Let's do some header file spelunking. The flag for this magical fourth button is defined here:

    #define MB_DEFBUTTON1               0x00000000L
    #define MB_DEFBUTTON2               0x00000100L
    #define MB_DEFBUTTON3               0x00000200L
    #if(WINVER >= 0x0400)
    #define MB_DEFBUTTON4               0x00000300L
    #endif /* WINVER >= 0x0400 */
    

    Aha, the magic fourth button was added in WINVER 4.0. Therefore, whatever the fourth button is, it was introduced when WINVER == 0x0400. Let's see what other message box flags were introduced then:

    #define MB_OK                       0x00000000L
    #define MB_OKCANCEL                 0x00000001L
    #define MB_ABORTRETRYIGNORE         0x00000002L
    #define MB_YESNOCANCEL              0x00000003L
    #define MB_YESNO                    0x00000004L
    #define MB_RETRYCANCEL              0x00000005L
    #if(WINVER >= 0x0500)
    #define MB_CANCELTRYCONTINUE        0x00000006L
    #endif /* WINVER >= 0x0500 */
    
    
    #define MB_ICONHAND                 0x00000010L
    #define MB_ICONQUESTION             0x00000020L
    #define MB_ICONEXCLAMATION          0x00000030L
    #define MB_ICONASTERISK             0x00000040L
    
    #if(WINVER >= 0x0400)
    #define MB_USERICON                 0x00000080L
    #define MB_ICONWARNING              MB_ICONEXCLAMATION
    #define MB_ICONERROR                MB_ICONHAND
    #endif /* WINVER >= 0x0400 */
    
    #define MB_ICONINFORMATION          MB_ICONASTERISK
    #define MB_ICONSTOP                 MB_ICONHAND
    
    #define MB_DEFBUTTON1               0x00000000L
    #define MB_DEFBUTTON2               0x00000100L
    #define MB_DEFBUTTON3               0x00000200L
    #if(WINVER >= 0x0400)
    #define MB_DEFBUTTON4               0x00000300L
    #endif /* WINVER >= 0x0400 */
    
    #define MB_APPLMODAL                0x00000000L
    #define MB_SYSTEMMODAL              0x00001000L
    #define MB_TASKMODAL                0x00002000L
    #if(WINVER >= 0x0400)
    #define MB_HELP                     0x00004000L // Help Button
    #endif /* WINVER >= 0x0400 */
    
    #define MB_NOFOCUS                  0x00008000L
    #define MB_SETFOREGROUND            0x00010000L
    #define MB_DEFAULT_DESKTOP_ONLY     0x00020000L
    
    #if(WINVER >= 0x0400)
    #define MB_TOPMOST                  0x00040000L
    #define MB_RIGHT                    0x00080000L
    #define MB_RTLREADING               0x00100000L
    #endif /* WINVER >= 0x0400 */
    
    #ifdef _WIN32_WINNT
    #if (_WIN32_WINNT >= 0x0400)
    #define MB_SERVICE_NOTIFICATION          0x00200000L
    #else
    #define MB_SERVICE_NOTIFICATION          0x00040000L
    #endif
    #define MB_SERVICE_NOTIFICATION_NT3X     0x00040000L
    #endif
    

    We can discount the flags like MB_ICONWARNING which are just alternate names for existing flags, as well as MB_SERVICE_NOTIFICATION which already existed but with a different value. This leaves the following:

    #define MB_USERICON                 0x00000080L
    #define MB_HELP                     0x00004000L // Help Button
    #define MB_TOPMOST                  0x00040000L
    #define MB_RIGHT                    0x00080000L
    #define MB_RTLREADING               0x00100000L
    

    Of these flags, MB_USERICON affects the icon, and MB_TOPMOST, MB_RIGHT and MB_RTLREADING affect the dialog box's position and layout; none of them affect the buttons. But wait, there's MB_HELP. Ah, that flag "adds a Help button to the message box." That's our magical fourth button! Let's celebrate by showing a four-button message box with the default set to the fourth button:

    #include <windows.h>
    
    int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev,
                       LPSTR lpCmdLine, int nShowCmd)
    {
      return MessageBox(NULL, TEXT("Four buttons!"), TEXT("Title"),
                MB_ABORTRETRYIGNORE | MB_HELP | MB_DEFBUTTON4);
    }
    
  • 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

    How to create a Zune podcast from an audiobook or other files you already have

    • 21 Comments

    Here's a trick one of my friends taught me.

    The Zune has two styles of audio playback, one for music, and another for podcasts. For music, clicking right and left move you by song, and when you switch to another album, then come back to the first album, it starts you over at the beginning of the album. On the other hand, for podcasts, clicking right and left seeks through the episode, and when you return to a podcast, it resumes from where you left off. This is nice, because podcast episodes tend to be long, and the sequence is usually important.

    But what if you want the podcast behavior for songs? For example, you might have a book on tape CD or a lecture series that you downloaded to your Zune. When you stop a chapter in the middle, you want to resume where you left off, not from the start of the chapter—and certainly not from the start of the book!

    Here's the secret: Before adding the content to your Zune collection, use Windows Explorer or Windows Media Player or some other metadata-editing tool to do two, possible four, things:

    • Change the Genre to Podcast,
    • Set the album title on all the episodes to the title of the book (or lecture series, or whatever),
    • Confirm that the file creation times are sequential: Episode 1 should have the earliest creation time, and so on.
    • Optionally, set the title of each episode to "Chapter N" or something similarly meaningful.

    Once you have the metadata set correctly, you can import the files into your collection. The Zune will see the Podcast genre and create a new podcast named after the album. It will show up in the Podcast section, not in the Music section. The tracks of the album will be treated as podcast episodes, and the file creation time is used to determine the chronology of the episodes. Set the podcast properties to "Oldest episodes first" and you now have your book on Zune ready for listening.

    What if you already added the files to your collection? Well, you can move them to a temporary directory outside your collection (thereby removing them from the collection), do your metadata editing, then move them back (re-adding them).

    As a shortcut, you can avoid the remove/edit/re-add cycle by editing the metadata while the files are still in your collection, then opening an Explorer window and dragging/dropping the files from Explorer into your Zune music collection (even though they're already there). This sometimes is enough of a nudge to tell the Zune client, "Hey, go look at these files again, I changed something." Remember, even though you dropped the files into your music collection, they will show up in the Podcast section. It will look like they disappeared, but really they just moved.

    I've had mixed success with the drag/drop approach, so I've gotten into the habit of playing it safe and doing the remove/edit/re-add thing.

  • The Old New Thing

    The worms go in, the worms go out

    • 12 Comments

    Neuroscientist Daniel Levitin, author of This Is Your Brain on Music: The Science of a Human Obsession (another book in the Catchy title: Long boring subtitle category), explains why ABBA songs get stuck in your head. Meanwhile, the Earworm Research Institute has some tips on how to get them out.

  • The Old New Thing

    Microspeak: Suited and booted

    • 14 Comments

    At Microsoft's consulting divisions, customer visits are a part of the job. A shorthand has developed to describe how formally dressed you should be at the meeting with the customer.

    • Suited and booted: Business suit including necktie.
    • Business casual: Collared shirt and trousers (no jeans).
    • Microsoft casual: Jeans and a t-shirt.

    (I leave it as an exercise to develop the comparable attire for women.)

    Note: This Microspeak entry was submitted by a colleague from the UK, so it may be peculiar to the UK dialect of Microspeak.

  • The Old New Thing

    Today, we use a GPS to locate Baby Jesus

    • 12 Comments

    When Baby Jesus disappears from a Nativity scene, he might be wearing a tracking device:

    For two consecutive years, thieves made off with the baby Jesus figurine in Wellington, a town of 60,000 in Palm Beach County, Fla. The ceramic original, donated by a local merchant, was made in Italy and worth about $1,800...

    Last year, officials took a GPS unit normally used to track the application of mosquito spray and implanted it in the latest replacement figurine. After that one disappeared, sheriff's deputies quickly tracked it down.

    It's sad that the world has come to this, but nice to know that technology is helping to make the world a slightly better place.

  • 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

    PDC 2008 notes: The aftermath

    • 4 Comments

    The Web page associated with my PDC 2008 talk has been updated to include the source code that I used for all of the demos.

    Other remarks:

Page 2 of 4 (38 items) 1234