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 |
The diagram below shows the implementation architecture for the Internet Component Download mechanism and its relation to other system services:
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.
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:
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 | Major 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 | Minor 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 (beta) 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.
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.
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.
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. |
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. |
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). |