Geoff Chappell - Software Analyst
As a large program, Internet Explorer has numerous options for its behaviour. This article is concerned with a relative handful of registry values that MSHTML treats specially. First, they have common handling, which alone might make it useful to document them as a group. Second, part of the detail to this common handling is that MSHTML is uniquely interested in always working from the most up-to-date settings of these registry values. Finally, there is a very real sense in which these particular registry values are the essence of what’s configurable about the HTML services that Internet Explorer provides to other programs: these are the Internet Explorer settings that MSHTML allows to be different for different programs.
A technical description of this article’s scope is: the options that are handled by MSHTML in its internal class COptionSettings (called OPTIONSETTINGS before version 7.00), specifically through tables of REGKEYINFORMATION structures. These names are known from Microsoft’s symbol files. Analysis is primarily of MSHTML.DLL as distributed with Windows XP SP1 and Windows Vista. Earlier versions have been looked at for these notes, but only cursorily.
The MSHTML options fall into two sets according to their location in different parts of the registry:
These are here referred to as the Internet Explorer options and the Windows options, respectively. That they are on different paths in the registry is not the reason for distinguishing them. Indeed, to say that the options are on those paths is not quite true. Those are merely the ordinary locations. Almost all the MSHTML options can be at multiple locations in the registry. Two mechanisms are involved, but the Windows options are subject to only one of them.
For the chronologically first mechanism, consider that potentially very many programs, for an unknowable generality of reasons, may be interested in using MSHTML as a service provider for presenting HTML pages. A user might not like it if all these programs are constrained to the same presentation. Neither might the writers of each program care to have their presentation exposed to whimsical reconfigurations of Internet Explorer. The more that MSHTML provides a service for multiple, unrelated programs, the more that it’s not enough for MSHTML to maintain separate options just for each user. It becomes desirable that options can apply per user per program.
The way that MSHTML supports this is that any program that hosts an HTML document may specify either or both of two other paths for MSHTML options. The document host does this by implementing the IDocHostUIHandler2 interface, particularly for the GetOptionKeyPath and GetOverrideKeyPath methods. (The older IDocHostUIHandler suffices if an override path is not wanted.) Whenever MSHTML reads its option settings, it calls these methods to learn the paths. As an aside, note that where the relevant Microsoft documentation talks of “the WebBrowser Control” in this context, it must mean MSHTML. Microsoft’s documentation states elsewhere that “Shdocvw.dll… is commonly referred to as the WebBrowser control”, but it is MSHTML that makes the calls and acts on whatever paths are returned.
These paths apply only to the Internet Explorer options, not the Windows options. The option key replaces the ordinary key for Internet Explorer options. The override key is extra to the ordinary key.
Let ordinary stand for Software\Microsoft\Internet Explorer, and let option and override stand for a document host’s option and override paths. Suppose that a particular option would ordinarily be some registry value in the key HKEY_CURRENT_USER\ordinary\subkey. If an option key is given, then MSHTML looks instead for the value with the same name but in the key HKEY_CURRENT_USER\option\subkey. The value in the ordinary location becomes irrelevant. If an override key is given, then MSHTML looks first at whichever is applicable of HKEY_CURRENT_USER\ordinary\subkey and HKEY_CURRENT_USER\option\subkey, and then looks for the same value in HKEY_CURRENT_USER\override\subkey, giving precedence to the latter.
An option path therefore allows a document host to provide a complete collection of Internet Explorer options. Anything omitted from this collection is defaulted. The settings for Internet Explorer become irrelevant. An override path allows a document host to provide a selection of options to build on a base collection. Anything omitted from the selection is instead taken from the base collection. In particular, when there is just an override path but no option path, anything omitted from the override selection is instead taken from the settings for Internet Explorer.
Now, Microsoft typically does not extend functionality unless Microsoft needs it, or at least imagines it, for Microsoft’s purposes or for those of someone close to Microsoft. So, it should not surprise that there are ready examples in the Windows package. The registry keys
in Windows Vista are respectively an option key and an override key. Other examples are found easily enough in other Microsoft products.
There presumably do exist document hosts that are not written by Microsoft but which implement an option key or override key for Internet Explorer options. However, some cynicism seems warranted. Consider the following from Microsoft’s page WebBrowser Customization:
Telling the WebBrowser Control where to look for your registry settings is the first step—actually, it’s the second step as far as program execution is concerned. Your program must set the keys at the location specified by IDocHostUIHandler::GetOptionKeyPath so the WebBrowser Control can read them. There are a variety of ways to do this. One way would be with a registry script that runs when the application is installed. Another way might be to do it programmatically when the application starts. Here’s a function that sets keys to change the default font, size, and color.
This may seem all well and good, at first sight. Microsoft has not only designed the functionality but is thorough enough to point out that programmers who use it must “set the keys” themselves. But where does Microsoft document those “keys” so that non-Microsoft programmers of non-Microsoft document hosts can know what “keys” can meaningfully be set?
On this matter, consider a product that Microsoft sells separately from Windows and in competition with products made by others. The programming suite Microsoft Visual Studio has long included an HTML Editor in its Integrated Development Environment (IDE). In Visual Studio .NET 2002, also known as Visual Studio 7, the actual rendering and editing is done by MSHTML, i.e., by Internet Explorer. This makes Visual Studio as good an example as any of a program that uses Internet Explorer as “middleware”, which is a term that many first (and perhaps have only ever) encountered in legal documents arising from a prominent anti-trust case against Microsoft.
Seen from the operating system looking out beyond the shell, Internet Explorer is an application, like any other end-user of operating-systerm functionality. It happens to be distributed in competition with other applications, collectively known as web browsers, made by hands other than Microsoft’s. Because these products that compete with one another all depend on the operating system and Microsoft has monopoly control in the market for operating systems (at least on a particular set of target machines), legislation applies with some sort of intention of keeping the competition fair in the market for web browsers. Among the ways that Microsoft has been accused of being unfair in this competition is that Internet Explorer is built with operating-system knowledge that is unavailable to Internet Explorer’s competitors.
However, Internet Explorer is not entirely an end-user of operating-system functionality. Though it is an application, some of its modules are more like those of an operating system. You can look outwards from Internet Explorer and see Visual Studio as a higher-level application. Visual Studio happens also to be distributed in competition with other applications which may do all or (more likely) some of the same things that Visual Studio uses Internet Explorer for. Indeed, these competing products may also use Internet Explorer for the same HTML functionality. Again, because Microsoft has monopoly control in the market for web browsers, the competition among products that use Internet Explorer for its shared functionality is supposed to be fair. Among the ways that Microsoft has been accused of being unfair in this competition is that some Microsoft applications are built with Internet-Explorer knowledge that is unavailable to those applications’ competitors.
In Visual Studio 7, the relevant components are an HTML Editor (HTMED.DLL) and a design component (TRIDSN.DLL). HMTED asks TRIDSN to create an instance of the TriDesignDocument class. The class is registered not under HKEY_CLASSES_ROOT\CLSID as a class that any COM program might find, but as one of Visual Studio’s own under HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0\CLSID. HTMED does not care where TRIDSN gets its HTML functionality to support a TriDesignDocument, only that TRIDSN provide HTML interfaces such as Microsoft documents for Hosting and Reusing.
That much is internal to Visual Studio, but then TRIDSN gets its HTML functionality by hosting and reusing MSHTML. It asks that someone create an instance of the HTMLDocument class. This class is registered as a COM class under HKEY_CLASSES_ROOT\CLSID, with MSHTML as the handler. TRIDSN thus becomes a document host, acting as a client for HTMED. The TriDesignDocument has an IOleObject interface. HTMED calls this interface’s SetClientSite method to tell TRIDSN of, among other things, an IDocHostUIHandler interface. TRIDSN wraps this into its own IDocHostUIHandler interface and tells MSHTML through the SetUIHandler method of the HTMLDocument object’s ICustomDoc interface. The connection is then complete. MSHTML sees TRIDSN as the document host, but the user-interface functionality comes from both TRIDSN and HTMED. For the GetOptionKeyPath method in particular, the TRIDSN implementation is just a wrapper, passing to HTMED. Thus does HTMED supply MSHTML with an option key: HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.0\HTML Editor\Internet Explorer.
HTMED also sets the value RtfConverterFlags in that key. Whatever may be the benefit, and there may in fact be none, it’s not something that Microsoft extends to Visual Studio’s competitors, e.g., by documenting it as something that any document host might set in an option key. Yes, it’s only one registry value, but the cumulative effect of little undocumented things is possibly significant.
In Visual Studio 2005, also known as Visual Studio 8, the corresponding registry key, with 7.0 changed to 8.0, is again an option key but not for MSHTML. The sketch of interactions, as given above, remains true except on two counts. One is trivial: HTMED has been renamed HTMLED. The other is that instead of asking the general COM machinery to create an instance of the HTMLDocument class, TRIDSN now asks within Visual Studio for an internal class named VSHTMLDocument. This is satisfied by a new DLL, named VSWEBDESIGN, which reproduces large tracts of the MSHTML code.
The duplication of MSHTML into VSWEBDESIGN looks to have been done at source level, not by linking from a shared library. At several places in the code, MSHTML is changed to VSHTML. In effect, Microsoft’s programmers for Visual Studio, or more likely their superiors who decide matters of strategy and law, have said something like “if we use MSHTML, we have to be on the same terms with our competitors in our use of it; if we make our own VSHTML from the MSHTML source code, then although we’ll still be using the MSHTML code, we are no longer competing as callers of MSHTML and those notions of fair competition don’t apply to us.” I trust that someone was paid well for coming up with that.
For the other mechanism by which MSHTML options may be sought elsewhere in the registry, the merit is that the ordinary location is readily accessible to users for configuring their own experience, but the other locations are restricted in some way, typically so that administrative privilege is needed for changing them (or even to see them). By giving precedence to the administrative location, MSHTML gives administrators the means to remove an option from a user’s control and configure it for the user as a matter of policy.
The general scheme allows for separate per-user and machine-wide policies. Consider an option that is ordinarily in some registry value in the key HKEY_CURRENT_USER\ordinary\subkey, where ordinary is:
Then this option’s instance as a policy is the value with the same name, but in either or both of HKEY_CURRENT_USER\policy\subkey or HKEY_LOCAL_MACHINE\policy\subkey, where policy is:
Some options are not supported as policies, either way. Some are subject to the per-user policy only. Some are subject to both the per-user and machine-wide policies. For these, the machine-wide policy has precedence, and the per-user policy isn’t even looked for if the following evaluates as true:
|Data||boolean (see below)|
Support for MSHTML Option Settings as policies is recent. A quick look at the MSHTML symbol files for intermediate Windows versions, specifically to see if a relevant function has an extra argument to name a policy key, suggests that the addition dates from Windows Server 2003 SP1.
In summary, each MSHTML option is represented by a registry value and a subkey, but the value may be in as many as four locations obtained by applying the subkey to the following paths in decreasing order of precedence:
Remember however that not all these possibilities are supported for all options.
An update of MSHTML options is triggered whenever MSHTML’s global window, which has the window class name “Internet Explorer_Hidden”, receives any of the following messages:
Most of these are well-known to Windows programmers and are in no way specific to Internet Explorer. They are typically posted, indeed broadcast, across the windowing system as notice of just about anyone’s reconfiguration of anything that might interest just about anyone else.
The last of the messages is a communication to Internet Explorer specifically. Instances are known from INETCPL.CPL, which implements the Internet Options for the Control Panel, but also from MSOE.DLL which is the heart of Windows Mail (previously called Outlook Express). Indeed, Microsoft’s symbol files confirm the private design by showing that relevant routines have names such as MSHTMLNotifyAllRefresh and SendTridentOptionsChanged (Trident apparently having been a codename for MSHTML). INETCPL posts the message to each window that has the class name “Internet Explorer_Hidden”, only ever after user activity that at least had some potential to have changed an MSHTML option. Such occasions are numerous, and can be trivial. For instance, it’s enough just to click OK on any of the dialogs for Colors, Language, Fonts or Accessibility, without having made any change.
That MSOE knows to post this message, including to know the hard-coded class name, is especially curious since there exist competing email products which one might think are supposed to be on equal footing with Microsoft’s in terms of their interactions with MSHTML. Will there ever be an end to these games that Microsoft plays with leveraging its monopoly products?
The particular registry values that are currently supported as MSHTML options make for quite a long list, given separately for Internet Explorer options and Windows options. For all these registry values, the registry data has a shared interpretation.
For those settings that the lists describe as “boolean”, the interpretation of the registry data is especially liberal. For data of type REG_DWORD and when treating ≤ 4 bytes of REG_BINARY data as a dword (see below), non-zero is true and zero is false. Data of any other type is interpreted as a case-insensitive string: any of yes, true and 1 count as true; no, false and 0 count as false; and anything else is an error.
Data of type REG_BINARY is acceptable to MSHTML wherever a dword is sought. For settings described as “boolean” or “dword”, the coding allows data of type REG_BINARY even if there are fewer than 4 bytes of data. In particular, though a single non-zero byte must be interpreted as true, it seems that a single null byte might not be interpreted as false.
A few options must be given as a dword of REG_BINARY data. Again, though the coding clearly expects 4 bytes, it does not check that there actually are as many.
For some options, REG_BINARY data is accepted just for its first byte and REG_DWORD data is accepted just for its low 16 bits.
Where a string is expected, only data of type REG_SZ is accepted. In most cases, strings that are not recognised explicitly are treated to a default interpretation, which is not necessarily the default for the option’s absence.
A setting that is described as taking an “RGB string” accepts only a string that conforms to a pattern for representing a colour. The form is of three integers, representing in turn the intensities for red, green and blue. Each integer is an optional positive or negative sign and then any number of consecutive decimal digits, with truncation if overflowing 32 bits. The colour values are just the low 8 bits of each integer. Separation of the integers is not strictly specified: the first two integers may each be followed by pretty much any one character and then by any amount of white space, including none; the last integer may be followed by nearly anything.