The IE3.0 solution for pluggable URL protocols

There are two mechanisms in IE3.0 for registering new URL protocol handlers. The first is implemented via ShellExecute(), and is enabled by defaultthis mechanism allows registering a new application to be launched on all attempts to navigate to a particular URL (for example registering applications to handle "mailto:" or "news:" URLs). The latter mechanism is implemented via URL Monikers, and it allows defining new protocols for retrieving data and linking into the IE3.0 web browser and all clients of URL Monikers. This latter mechanism is disabled by default in IE3.0, but it may be enabled via a registry setting. Neither of these solutions address the needs of all customers of pluggable URL protocols, but together we believe they address 80% of customer needs.

Registering a new ShellExecute verb as the handler for a particular protocol

It is very simple to register an application to be ShellExecute()ed on all attempts to navigate to a particular URL protocol (e.g. "mailto:", "news:", "foo:", etc.). This is best demonstrated by example. The following registry values must be added to register a new application (say "notepad.exe") to handle a new URL protocol (say "note:"):

[HKEY_CLASSES_ROOT]
    [note]
        (Default) = "URL:Note Protocol"
        URL Protocol = ""
        [DefaultIcon]
            (Default) = "notepad.exe"
        [shell]
            [open]
                [command]
                    (Default) = "c:\windows\notepad.exe %1"
By adding these settings to the registry, attempts to navigate to URLs such as "note:c:\foo.txt" would launch NOTEPAD to edit the file "note:c:\foo.txt". Furthermore, all of the commands supported under Shell\Open are supported, including DDEEXEC (in other words, "command" is not the only key you can put under the verb name).

Note: The example above doesn't work correctly because NOTEPAD cannot understand edit files with the prefix "note:".

Note: It is not possible to register handlers to override the "http:", "ftp:", "gopher:", or "file:" protocols.

Defining a new URL protocol for binding to data via URL Monikers

It is possible to define a new URL protocol for binding to data via URL Monikers. This allows hooking a new storage medium or transport protocol into all clients of URL Monikers (including IE3.0 and most Internet-aware ActiveX Controls) without requiring any code change from those clients. This opens up a world of possibilities for extending web browsers, e.g. enabling the browsing of HTML documents inside databases, either in a compressed format on a CD or on a local network, or enabling the browsing of web pages over new network protocols, etc.

Unfortunately, the current implementation of pluggable URL protocols has limitations that will hopefully be resolved in future releases of URL Monikers:

  1. All pluggable protocols must take the format "mk:@progid:random-display-name", where progid is the name of the new protocol, and random-display-name is a protocol-specific string interpreted by the protocol handler. In the future, URL Monikers should support pluggable protocols with the friendlier format "progid:random-display-name".
  2. Binding to pluggable protocols always happens synchronously, even if the underlying data source could support asynchronous downloads. Future plans include support for asynchronous pluggable protocols.
  3. The pluggable URL protocol mechanism is disabled in default installations of URL Monikers and Microsoft Internet Explorer 3.0. A registry setting is needed to enable the pluggable protocol behavior, although in the future this capability should be enabled by default.

Details

When interpreting URLs of the format "mk:@progid:display-name", the URL Moniker's pluggable protocol manager will look up the CLSID for the given progid and then call

    CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IParseDisplayName)
The resulting IParseDisplayName interface is used to parse the string "@progid:display-name" and to return a custom "protocol-handler" moniker that understands the new protocol. This custom moniker must support synchronous data binding via IMoniker::BindToStorage(…IID_IStream…), and it must also support IMoniker::ParseDisplayName. The pluggable protocol manager uses this custom moniker to bind to the data (via BindToStorage) and to return the data to the URL Moniker client. Note: The stream returned by the custom moniker should support IStream::Stat() (to get the stream size) and IStream::Seek(), to rewind the stream to offset 0.

It's important to note that the URL Moniker's pluggable protocol manager disguises all pluggable protocol handlers as URL Monikers. As far as a client of URL Monikers is concerned, all the new "mk:@progid:" protocols are still represented by URL Monikers and behave like other URL Monikers. In addition, the Windows Internet Functions for parsing URLs (e.g. InternetCanonicalizeURL) also parse URLs in the "mk:@progid:" format. The first portion of the URL (up to a forward slash) is assumed to be a "root", and the usual rules of parsing (including relative paths) apply.

How to enable the pluggable protocol support

The "mk:@progid:" pluggable protocol scheme only works when the registry key "HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer" contains the key "MkEnabled" = "Yes". This registry setting should be enabled at the same time as the custom protocol-handler moniker is registered in the system.