January, 2006

  • The Old New Thing

    Understanding what things mean in context: Dispatch interfaces

    • 23 Comments

    Remember that you have to understand what things mean in context. For example, the IActiveMovie3 interface has a method called get_MediaPlayer. If you come into this method without any context, you might expect it to return a pointer to an IMediaPlayer interface, yet the header file says that it returns a pointer to an IDispatch interface instead. If you look at the bigger picture, you'll see why this makes sense.

    IActiveMovie3 is an IDispatch interface. As you well know, the IDispatch interface's target audience is scripting languages, primarily classic Visual Basic (and to a lesser degree, JScript). Classic Visual Basic is a dynamically-typed language, wherein nearly all variables are merely "objects", the precise type of which is not known until run-time. A statically-typed language will complain at compile time that you are invoking a method on an object that doesn't support that method or that you are passing the wrong number or type of operands to a method. A dynamically-typed language, on the other hand, doesn't check until the line of code is actually executed whether the method exists, and if it does, whether you called it correctly.

    When working with IDispatch and dynamically-typed languages, therefore, the natural unit of currency for objects is the IDispatch. All objects take the form of IDispatch. Objects that produce other objects will produce IDispatch interfaces, because that's what the scripting engine is expecting.

    That's why the get_MediaPlayer method returns an IDispatch. Because that's what the scripting engine expects. And, if you are familiar with the context, it's also what you should expect.

    A tell-tale sign of this context comes from the name "get_MediaPlayer". This name does not follow the COM function naming convention but rather is a constructed name for the C/C++ binding of the "get" property. C/C++ bindings are the assembly language of OLE automation: You're operating with the nuts and bolts of OLE automation, and if you want to play at this level, you're going to have to know how to use a screwdriver.

  • The Old New Thing

    France, she is, how you say, on sale!

    • 46 Comments

    Marketplace reports on the start of the winter sale season in France. By law, retailers are permitted sales only twice a year, so the onset of sale season generates quite a bit of shopping madness. There is also a proposal to allow more sale periods, but opponents argue that doing so would harm smaller businesses. Coming from the land of sale fatigue (we just emerged from the after-Christmas sale season and are entering the Winter White Sale season, after which comes the President's Day season...), I find a certain appeal to the idea of limiting how often things can "go on sale". Who can forget the oriental rug stores that are perpetually going out of business? It's become such a joke that The New York Times flatly refuses to run "Going Out of Business" sales for oriental rug stores.

  • The Old New Thing

    Why do words beginning with "home" get treated as URLs?

    • 21 Comments

    Vitaly from the Suggestion Box asked (with grammatical editing),

    Could you explain why Windows starts the web browser if the file name passed to ShellExecute starts with "home".

    First thing to note is that this URL-ization happens only after the ShellExecuteEx function has tried all the other possible interpretations. If a file named "homestar" is found in the current directory or on the PATH or in the App Paths, then that file will be chosen, as you would expect. Only when the ShellExecuteEx function is about to give up does it try to "do what you mean".

    What you're seeing is autocorrection kicking in yet again. If you go to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\URL\Prefixes, you can see the various autocorrection rules that ShellExecute consults when it can't figure out what you are trying to do. For example, if the thing you typed begins with "www", it will stick "http://" in front and try again. This is why you can just type "www.microsoft.com" into the Run dialog instead of having to type the cumbersome "http://www.microsoft.com".

    Most of the autocorrection rules are pretty self-evident. Something beginning with "ftp" is probably an FTP site. Something beginning with "www" is probably a web site. But why are strings beginning with "home" also treated as web sites?

    For one thing, several web sites have domains whose names begin with "home". Furthermore, some internet service providers set up their DNS so that non-fully-qualified domain names go to servers that the ISP set up specifically to provide customer services. For example, "mail" would send you to a web-based mail system, and "home" would send you to the ISP's home page.

    The use of "home" has fallen out of fashion of late, so the auto-correction rule isn't all that useful any more, but the rule stays around because it doesn't really hurt anybody, and compatibility concerns advise against removing a feature if it isn't hurting anyone and you aren't absolutely certain that nobody is still using it. (Heck, if you look at the key, you can see an entry for "gopher". Like anybody uses gopher any more.)

  • The Old New Thing

    When web sites rely on security holes

    • 44 Comments

    Perhaps the biggest risk when making a change in the name of security is all the things that may have been relying on the previously-lax security settings. After all, disabling an insecure feature is easy. The hard part is disabling it while retaining compatibility with people who were relying on that feature. In the security investigations I've been involved with, perhaps the largest chunk of my time is spent trying to find a way to mitigate the security hole without breaking existing customers. (And it's the Line of Business scenario that is the biggest question mark.)

    Here's a real-life example: Consider a sports web site which sells a service to subscribers wherein the site creates a pop-up window whenever a game's score has changed or some other significant event has occurred. That way, you can leave your browser minimized and go about your day, but when something happens in the game, it will pop up an alert.

    The round of security changes in Windows XP SP2 broke this site because the rules on positioning of pop-up windows were tightened so that pop-up windows could not appear outside the browser itself. This prevents pop-up windows from being used to cover important browser elements (such as the status bar, the address bar, or a security dialog) and makes it harder for pop-ups to masquerade as system dialogs. But it also broke this company's business model.

    And of course, if Microsoft does something that cause you to lose money, you sue.

    There were probably corporations that had internal web sites that relied on the ability to position pop-ups without restriction. Those corporations no doubt also complained about this change in the name of security.

    As with most security changes that have compatibility consequences, a "safety valve" was added to return to the old insecure behavior for those customers who were relying on it. In this case, you can put the affected sites in the Trusted Sites zone and enable the "Allow script-initiated windows without size or position constraints" setting. But this is just a stop-gap, re-opening the security hole to let this site continue to operate the way it does. The real fix is not to rely on the security hole.

  • The Old New Thing

    The decoy visual style

    • 79 Comments

    During the development of Windows XP, the visual design team were very cloak-and-dagger about what the final visual look was going to be. They had done a lot of research and put a lot of work into their designs and wanted to make sure that they made a big splash at the E3 conference when Luna was unveiled. Nobody outside the visual styles team, not even me, knew what Luna was going to look like.

    On the other hand, the programmers who were setting up the infrastructure for visual styles needed to have something to test their code against. And something had to go out in the betas.

    The visual styles team came up with two styles. In secret, they worked on Luna. In public, they worked on a "decoy" visual style called "Mallard". (For non-English speakers: A mallard is a type of duck commonly used as the model for decoys.) The ruse was so successful that people were busy copying the decoy and porting it to their own systems. (So much for copyright protection.)

  • The Old New Thing

    The decoy display control panel

    • 25 Comments

    Last time, we saw one example of a "decoy" used in the service of application compatibility with respect to the Printers Control Panel. Today we'll look at another decoy, this time for the Display Control Panel.

    When support for multiple monitors was being developed, a major obstacle was that a large number of display drivers hacked the Display Control Panel directly instead of using the documented extension mechanism. For example, instead of adding a separate page to the Display Control Panel's property sheet for, say, virtual desktops, they would just hack into the "Settings" page and add their button there. Some drivers were so adventuresome as to do what seemed like a total rewrite of the "Settings" page. They would take all the controls, move them around, resize them, hide some, show others, add new buttons of their own, and generally speaking treat the page as a lump of clay waiting to be molded into their own image. (Here's a handy rule of thumb: If your technique works only if the user speaks English, you probably should consider the possibility that what you're doing is relying on an implementation detail rather than something that will be officially supported going forward.)

    In order to support multiple monitors, the Settings page on the Display Control Panel underwent a major overhaul. But when you tried to open the Display Control Panel on a system that had one of these aggressive drivers installed, it would crash because the driver ran around rearranging things like it always did, even though the things it was manipulating weren't what the developers of the driver intended!

    The solution was to create a "decoy" Settings page that looked exactly like the classic Windows 95 Settings page. The decoy page's purpose in life was to act as bait for these aggressive display drivers and allow itself to be abused mercilessly, letting the driver have its way. Meanwhile, the real Settings page (which is the one that was shown to the user), by virtue of having been overlooked, remained safe and unharmed.

    There was no attempt to make this decoy Settings page do anything interesting at all. Its sole job was to soak up mistreatment without complaining. As a result, those drivers lost whatever nifty features their shenanigans were trying to accomplish, but at least the Display Control Panel stayed alive and allowed the user to do what they were trying to do in the first place: Adjust their display settings.

  • The Old New Thing

    Beware the MSJ subscription scam

    • 7 Comments

    Stephen Toub from MSDN Magazine alerts us to the MSJ subscription scam. Somebody has been sending out (via paper mail) a fake subscription offer for Microsoft Systems Journal, a magazine that ceased publication back in 2000. Read Stephen's article for more details as well as a copy of the scam letter itself. (The address for the "publisher" is a rented mailbox at a what appears to be a UPS Store in the Beaumont Centre mall.) Under no circumstances send these people any money!

  • The Old New Thing

    When programs assume that the system will never change, episode 3

    • 37 Comments

    One of the stranger application compatibility puzzles was solved by a colleague of mine who was trying to figure out why a particular program couldn't open the Printers Control Panel. Upon closer investigation, the reason became clear. The program launched the Control Panel, used FindWindow to locate the window, then accessed that window's "File" menu and extracted the strings from that menu looking for an item that contained the word "Printer". It then posted a WM_COMMAND message to the Control Panel window with the menu identifier it found, thereby simulating the user clicking on the "Printers" menu option.

    With Windows 95's Control Panel, this method fell apart pretty badly. There is no "Printers" option on the Control Panel's File menu. It never occurred to the authors of the program that this was a possibility. (Mind you, it was a possibility even in Windows 3.1: If you were running a non-English version of Windows, the name of the Printers option will be something like "Skrivare" or "Drucker". Not that it mattered, because the "File" menu will be called something like "Arkiv" or "Datei"! The developers of this program simply assumed that everyone in the world speaks English.)

    The code never checked for errors; it plowed ahead on the assumption that everything was going according to plan. The code eventually completed its rounds and sent a garbage WM_COMMAND message to the Control Panel window, which was of course ignored since it didn't match any of the valid commands on that window's menu.

    The punch line is that the mechanism for opening the Printers Control Panel was rather clearly spelled out on the very first page of the "Control Panel" chapter of the Windows 3.1 SDK:

    The following example shows how an application can start Control Panel and the Printers application from the command line by using the WinExec function:

        WinExec("control.exe printers", SW_SHOWNORMAL);
    

    In other words, they didn't even read past the first page.

    The solution: Create a "decoy" Control Panel window with the same class name as Windows 3.1, so that this program would find it. The purpose of these "decoys" is to draw the attention of the offending program, taking the brunt of the mistreatment and doing what they can to mimic the original behavior enough to keep that program happy. In this case, it waited patiently for the garbage WM_COMMAND message to arrive and dutifully launched the Printers Control Panel.

    Nowadays, this sort of problem would probably have been solved with the use of a shim. But this was back in Windows 95, where application compatibility technology was still comparatively immature. All that was available at the time were application compatibility flags and hot-patching of binaries, wherein the values are modified as they are loaded into memory. Using hot-patching technology was reserved for only the most extreme compatibility cases, because getting permission from the vendor to patch their program was a comparatively lengthy legal process. Patching was considered a "last resort" compatibility mechanism not only for the legal machinery necessary to permit it, but also because patching a program fixes only the versions of the program the patch was developed to address. If the vendor shipped ten versions of a program, ten different patches would have to be developed. And if the vendor shipped another version after Windows 95 was delivered to duplication, that version would be broken when Windows 95 hit the shelves.

    It is important to understand the distinction between what is a documented and supported feature and what is an implementation detail. Documented and supported features are contracts between Windows and your program. Windows will uphold its end of the contract for as long as that feature exists. Implementation details, on the other hand, are ephemeral; they can change at any time, be it at the next major operating system release, at the next service pack, even with the next security hotfix. If your program relies on implementation details, you're contributing to the compatibility cruft that Windows carries around from release to release.

    Over the next few days, I'll talk about other decoys that have been used in Windows.

    [Somebody caught my misspelling of "Drucker" while I was fixing it! - 7:45am]

  • The Old New Thing

    Where do call signs come from?

    • 18 Comments

    In celebration of the impending return of Battlestar Galactica to the airwaves, I refer to you the blog of Major John M. Bell, one of our brave Marines stationed in Iraq. His entry from 26 Oct 2005 gives some real-world examples of military call signs and how they were chosen.

  • The Old New Thing

    Why do image lists and tool bars use horizontal strips if vertical is so much better?

    • 12 Comments

    Two people pointed out that the ImageList_Add function and toolbars use horizontal strips even though we learned that vertical strips are much more efficient. While it's true that the images are passed to the ImageList_Add and CreateToolbarEx functions in horizontal strips, the image list and toolbar code copy them to a vertical strip.

    In other words, the horizontal strip is merely an interchange format. Internally, the image list and toolbar use the more efficient vertical arrangement.

Page 3 of 4 (36 items) 1234