## The Internet Component Download interface

The Internet Component Download service is exposed via a single function, CoGetClassObjectFromURL(). This system function is called by an application that wishes to download, verify, and install code for an OLE component. The function is used in the implementation of Microsoft® Internet Explorer. The implementation uses URL Moniker to asynchronously download code, and it uses the WinVerifyTrust service to verify validity of the code.

Related Documents | Filename
URL Moniker specification | urlmon.doc
Asynchronous Moniker specification | asyncmon.doc
WinVerifyTrust specification | wintrust.doc

### Architecture

The diagram below shows the implementation architecture for the Internet Component Download mechanism and its relation to other system services:

### Technical Details

This section describes technical details of the Internet Component Download API used by applications (e.g. web browsers) to download and install COM Object code.

#### CoGetClassObjectFromURL

    STDAPI CoGetClassObjectFromURL ( [in] REFCLSID rclsid, [in] LPCWSTR szCodeURL, [in] DWORD dwFileVersionMS,
    			[in] DWORD dwFileVersionLS, [in] LPCWSTR szContentTYPE, [in] LPBINDCTX pBindCtx,
    			[in] DWORD dwClsContext, [in] LPVOID pvReserved, [in] REFIID riid, [out] VOID **ppv );

This function will return a factory object for a given rclsid. If no CLSID is specified (CLSID_NULL), this function will choose the appropriate CLSID for interpreting the Internet MIME type specified in szContentType. If the desired object is installed on the system, it is instantiated. Otherwise, the necessary code is downloaded and installed from the location specified in szCodeURL or from an Object Store on the Internet Search Path (see below).

This "download and install" process involves the following steps:

1. Downloading the necessary file(s) (.CAB, .INF, or executable) using URL Moniker(s).
2. Call WinVerifyTrust to ensure that all downloaded files are safe to install.
3. Complete self-registration of all COM components(8)
4. Add registry entries to keep track of downloaded code (see Appendix on Registry Details)
5. Call CoGetClassObject for the desired rclsid.

CoGetClassObjectFromURL accepts the following arguments:

REFCLSIDrclsid | CLSID of the COM object that needs to be installed. If value is CLSID_NULL, then szContentType is used to determine the CLSID.
LPCWSTRszCodeURL | URL pointing to the code for the COM object. This may point to an executable, to an .INF file, or to a .CAB file (see below for details). If this value is NULL, then Internet Component Download will still attempt to download the desired code from an Object Store on the Internet Search Path.
DWORDdwFileVersionMS | Most significant bits of the version number for the object that needs to be installed. If this value and the next are both 0xFFFFFFFF, then it is assumed that the latest version of the code is always desired, which means that Internet Component Download will always attempt to download new code.
DWORDdwFileVersionLS | Least significant bits of the version number for the object that needs to be installed. If this value and the previous one are both 0xFFFFFFFF, then it is assumed that the latest version of the code is always desired, which means that Internet Component Download will always attempt to download new code.
LPCWSTRszContentType | MIME type that needs to be understood by the installed COM object. If rclsid is CLSID_NULL, this string is used to determine the CLSID of the object that must be installed. Note: this parameter is only useful when trying to download a viewer for a particular media type, if the MIME type of the media is known but the CLSID is not.
LPBINDCTXpBindCtx | A bind context to use for downloading/installing component code. The client should register its IBindStatusCallback in this bind context to receive callbacks during the download and installation process. (See Asynchronous Monikers specification for details)
DWORDdwClsContext | Values taken from the CLSCTX enumeration specifying the execution context for the class object.
LPVOIDpvReserved | Reserved value, must be set to NULL.
REFIIDriid | The interface to obtain on the factory object (typically IClassFactory).
VOID **ppv | Pointer in which to store the interface pointer upon return if the call is synchronous.

S_OK | Success. ppv contains the requested interface pointer.
MK_S_ASYNCHRONOUS | Component code will be downloaded and installed asynchronously. The client will receive notifications through the IBIndStatusCallback interface it has registered on pBindCtx..
E_NOINTERFACE | The desired interface pointer is not available. Other CoGetClassObject error return values are also possible here..

In the common web-browser scenario, the values for parameters passed to this function are read directly from an HTML OBJECT tag. For example, the szCodeURL, dwFileVersionMS, and dwFileVersionLS are specified inside an <OBJECT> tag as "CODEBASE=http://www.foo.com/bar.ocx#Version=a,b,c,d", where szCodeURL is "http://www.foo.com/bar.ocx", dwFileVersionMS is MAKELONG(b, a), and dwFileVersionLS is MAKELONG(d, c).

Because the downloading and installation of code occurs asynchronously, CoGetClassObjectFromURL will often return immediately with a return value of E_PENDING. At this point, the IBindStatusCallBack mechanism is used to communicate the status of the download operation to the client(9). To participate in this communication, the client must implement IBindStatusCallback and register this interface in the pBindCtx passed into CoGetClassObjectFromURL using RegisterBindStatusCallback. The client can expect to be called with callback notifications for OnStartBinding (providing an IBinding for controlling the download), OnProgress (reporting progress), OnObjectAvailable (which returns the desired object interface pointer), and OnStopBinding (which returns error codes in case of an error). For further negotiations, the client must also implement ICodeInstall as described below.

Note The initial implementation of CoGetClassObjectFromURL will not handle system-wide simultaneous downloads of the same code. Similarly, it will not handle cases where different simultaneous downloads refer to the same piece of dependent code.

#### IBindStatusCallback::OnProgress

The client of CoGetClassObjectFromURL will receive notification about the download / install process via the provided IBindStatusCallback interface. During the download process , the following additional values (from the BINDSTATUS enumeration) may be passed back as the ulStatusCode parameter for IBindStatusCallback::OnProgress.

BINDSTATUS_BEGINDOWNLOADCOMPONENTS
  The download operation has begun downloading code for COM components that will be installed before the object may be instantiated. The szStatusText accompanying IBindStatusCallback::OnProgress() provides the display name of the component being downloaded.
BINDSTATUS_INSTALLINGCOMPONENTS
  The download operation has downloaded code and is installing it. The szStatusText accompanying IBindStatusCallback::OnProgress() provides the display name of the component being installed.
BINDSTATUS_ENDDOWNLOADCOMPONENTS
  The download operation has finished downloading and installing all necessary code. The szStatusText accompanying OnProgress() provides the display name of the newly installed component.

#### ICodeInstall

    interface ICodeInstallIParseDisplayNameInterfaces : IUnknown{
    	HRESULT	GetWindow( [out] HWND* phwnd);
    	HRESULT 	OnCodeInstallProblem( [in] ULONG ulStatusCode, [in] LPCWSTRszDestination,
    			[in] LPCWSTR szSource, [in] DWORD dwReserved);
    	};

A code install operation requires additional services from the client in order to complete the negotiation necessary for a download operation. Such services are requested using IBindStatusCallback::QueryInterface. The specific interface requested in IBindStatusCallback::QueryInterface is ICodeInstall. This interface must be implemented by a client of Internet Component Download.

#### ICodeInstall::GetWindow

This function is called when Component Download needs to display user interface for verification of downloaded code(10). When a client is called with this function, it has the opportunity to clear the message queue of it's parent window before allowing UI to be displayed. If the client does not wish to display UI, code verification may continue, but components may fail to be installed.

Note ICodeInstall actually inherits from the IWindow interface (see documentation for URL Monikers), which consists of the single member function GetWindow. However, as far as any client code is concerned, the interface definition in this specification is still accurate.

- S_OK | Success.
  S_FALSE | No window is available.
  E_INVALIDARG | The argument is invalid.

HWND *phwnd
  Client-provided HWND of the parent window for displaying code verification UI. If this parameter is NULL, the desktop window is used. If the value is INVALID_HANDLE_VALUE, or if the return value is S_FALSE, then no code verification UI will be displayed, and certain necessary components may not be installed.

#### ICodeInstall::OnCodeInstallProblem

This function is called when there is a problem with code installation. This notification gives the client a chance to resolve the problem, often by displaying UI, or by aborting the code installation process.

Note If the client does not understand the problem, it should return E_ABORT by default to abort the code installation process, because returning S_OK would imply retrying the operation.

- S_OK | Continue the installation process. If there was an "access denied" or disk-full problem, retry the installation. If there was an existing file (newer or older version), overwrite it.
  S_FALSE | Skip this particular file, but continue with the rest of the code installation process. Note: this is the typical response for the CIP_NEWER_VERSION_EXISTS case.
  E_ABORT | Abort the code installation process.
  E_INVALIDARG | The given arguments are invalid.

ULONGulStatusCode
  Status code describing what problem occurred. A member of CIP_STATUS.
LPCWSTRszDestination
  The name of the existing file that was causing a problem. This may be the name of an existing file that needs to be overwritten, the name of a directory causing access problems, or the name of a drive that is full.
LPCWSTRszSource
  Name of the new file to replace the existing file (if applicable).
DWORDdwReserved
  Reserved for future use.

The ulStatusCode parameter above is one of the following values:

    	typedef enum {
    		CIP_DISK_FULL,
    		CIP_ACCESS_DENIED,
    		CIP_OLDER_VERSION_EXISTS,
    		CIP_NEWER_VERSION_EXISTS,
    		CIP_NAME_CONFLICT,
    		CIP_TRUST_VERIFICATION_COMPONENT_MISSING
    	} CIP_STATUS;

CIP_DRIVE_FULL | The drive specified in szDestination is full..
CIP_ACCESS_DENIED | Access to the file specified in szDestination is denied.
CIP_OLDER_VERSION_EXISTS | An existing file (older version) specified in szDestination needs to be overwritten by the file specified in szSource.
CIP_NEWER_VERSION_EXISTS | A file exists (specified in szDestination) that is a newer version of a file to be installed (specified in szSource)
CIP_NAME_CONFLICT | A file exists (specified in szDestination) that has a naming conflict with a file to be installed (specified in szSource). The existing file is neither a newer nor an older version of the new filethey are mismatched but have the same file name.
CIP_TRUST_VERIFICATION_COMPONENT_MISSING | The code installation process cannot find the necessary component (WinVerifyTrust) for verifying trust in downloaded code. szSource specifies the name of the file that cannot be certified. The client should display UI asking the user whether or not to install the untrusted code, and should then return E_ABORT to abort the download, S_OK to continue anyway, or S_FALSE to skip this file but continue (usually dangerous).

© 1996 Microsoft Corporation