URL Open Stream Functions

"...pass in a URL, get a stream..."

Disclaimer THIS DOCUMENT IS AN EARLY RELEASE OF THE FINAL SPECIFICATION. IT IS MEANT TO SPECIFY AND ACCOMPANY SOFTWARE THAT IS STILL IN DEVELOPMENT. SOME OF THE INFORMATION IN THIS DOCUMENTATION MAY BE INACCURATE OR MAY NOT BE AN ACCURATE REPRESENTATION OF THE FUNCTIONALITY OF THE FINAL SPECIFICATION OR SOFTWARE. MICROSOFT ASSUMES NO RESPONSIBILITY FOR ANY DAMAGES THAT MIGHT OCCUR EITHER DIRECTLY OR INDIRECTLY FROM THESE INACCURACIES. MICROSOFT MAY HAVE TRADEMARKS, COPYRIGHTS, PATENTS OR PENDING PATENT APPLICATIONS, OR OTHER INTELLECTUAL PROPERTY RIGHTS COVERING SUBJECT MATTER IN THIS DOCUMENT. THE FURNISHING OF THIS DOCUMENT DOES NOT GIVE YOU A LICENSE TO THESE TRADEMARKS, COPYRIGHTS, PATENTS, OR OTHER INTELLECTUAL PROPERTY RIGHTS.

Overview

Without a doubt the easiest, most efficient and most powerful way to download data from the Internet is using the new URL Open Stream (UOS) functions. Before jumping into the specifications, let's cover a few of the high-level features and the philosophy behind the creation of these functions. The UOS functions are the newest addition to the ActiveX™ extensions to the Win32 API. They combine the familiarity of C-style programming with the power of COM. These functions work equally well inside an ActiveX framework (for example, a component, a document or frame window, a subcomponent, or a scriptable object) or completely standalone.

Unlike other more complex interface negotiations, using these functions requires knowledge of no more than two COM interfaces, IStream and IBindStatusCallback.

Because these functions use services from URL monikers and WinInet, all the caching and thread synchronization features of those components are in use whenever you call these functions. In addition, the UOS functions handle all the host binding operations if your code is in an ActiveX container: the UOS functions automatically do the right thing to manage the download in the ActiveX client framework.

Every UOS function works in the same basic way: the caller implements an IBindStatusCallback interface (optional in some cases), then calls the function. The URLOpenStream and URLOpenPullStream functions require the caller to be on a thread that has a message loop (GetMessage/DispatchMessage). In the case of an ActiveX component, a message loop is a given if this function is called from the main thread. For a standalone application without a user interface, a message loop is still necessary for these functions.

With the URL Open Stream functions, you can:

IBindStatusCallback

Callbacks are issued on an IBindStatusCallback interface that is implemented on the caller. This is a simple callback interface to implement, because most of the methods on the interface are optional (for example, OnStartBinding, GetPriority, OnStopBinding) and can simply return S_OK or E_NOTIMPL. Although clients may choose to implement many of the IBindStatusCallback methods, the only callback required to do anything for the UOS functions to work correctly is OnDataAvailable for the URLOpenStream and URLOpenPullStream functions. In fact, for some UOS functions (URLDownloadToFile and URLDownloadToCacheFile. URLOpenBlockingStream), OnDataAvailable is never called because it is unnecessary. Furthermore, GetBindInfo is neverinvoked for UOS clients, because the bind information is determined according to which UOS function is being called. The UOS programming model is straightforward because there are no special flags to pass to the functions.

The URL Open Stream functions are described below:

HRESULT URLDownloadToCacheFile(

LPUNKNOWN pCaller,
LPCWSTR szURL,
DWORD dwResv,
LPBINDSTATUSCALLBACK lpfnCB);

URLDownloadToCacheFile downloads data into the Internet cache and returns the filename of the cache location for retrieving the bits. The client can optionally be notified of progress via a notification callback.

This function will always return a filename if the download operation succeeds. If the given URL is a "file:" URL, URLDownloadToCacheFile will directly return the filename for the "file:" URL rather than making a copy to the cache. If the given URL is an Internet URL ("http:", "ftp:"), URLDownloadToCacheFile will download this file and return the local filename of the cached copy. Using this function ensures that a filename is returned without unnecessary copying of data.

LPUNKNOWNpCaller
Pointer to the controlling IUnknown of the calling ActiveX component (if the caller is an ActiveX component). If the caller is not an ActiveX component, this value may be set to NULL. Otherwise, the caller is a COM object that is contained in another component (such as an ActiveX Control in the context of an HTML page). The parameter represents the outermost IUnknown of the calling component. The function will attempt the download in the context of the ActiveX client framework and allow the caller's container to receive callbacks on the progress of the download.
LPCWSTRszURL
The URL to be downloaded. Cannot be NULL.
DWORDdwBufLen
Reserved for future use; must be zero.
DWORDdwResv
Reserved for future use; must be zero.
LPBINDSTATUSCALLBACKlpfnCB
Pointer to caller's IBindStatusCallback interface pointer on the caller. URLDownloadToCacheFile calls this interface's OnProgress method on some connection activity, including the arrival of data. OnDataAvailable is never called. Implementing OnProgress allows a caller to implement some user interface or other progress monitoring functionality. It also allows the download operation to be completely canceled by returning E_ABORT from the OnProgress call. Can be NULL.

URLDownloadToFile(


LPUNKNOWN pCaller,
LPCWSTR szURL,
LPCTSTR szFileName,
DWORD dwResv,

URLDownloadToFile downloads bits from the Internet and saves them to a file. The client can optionally be notified of progress via a notification callback.

LPUNKNOWNpCaller
Pointer to the controlling IUnknown of the calling ActiveX component (if the caller is an ActiveX component). If the caller is not an ActiveX component, this value may be set to NULL. Otherwise, the caller is a COM object that is contained in another component (such as an ActiveX Control in the context of an HTML page). The parameter represents the outermost IUnknown of the calling component. The function will attempt the download in the context of the ActiveX client framework and allow the caller's container to receive callbacks on the progress of the download.
LPCWSTRszURL
The URL to be downloaded. Cannot be NULL.
LPCTSTRszFileName
Name of the file to create with bits that come from the download.
DWORDdwResv
Reserved for future use; must be zero.
LPBINDSTATUSCALLBACKlpfnCB
Pointer to the IBindStatusCallback interface pointer on the caller. URLDownloadToFile calls this interface's OnProgress method on some connection activity, including the arrival of data. OnDataAvailable is never called. Implementing OnProgress allows a caller to implement some user interface or other progress monitoring functionality. It also allows the download operation to be completely canceled by returning E_ABORT from the OnProgress call. Can be NULL.

URLOpenStream(

LPUNKNOWN pCaller,
LPCWSTR szURL, 
DWORD dwResv,
LPBINDSTATUSCALLBACK lpfnCB);

URLOpenStream creates a push-type stream object from a URL. The data is downloaded from the Internet as fast as possible. Every time data is available, it is "pushed" at the client through a notification callback.

LPUNKNOWNpCaller
Pointer to the controlling IUnknown of the calling ActiveX component (if the caller is an ActiveX component). If the caller is not an ActiveX component, this value may be set to NULL. Otherwise, the caller is a COM object that is contained in another component (such as an ActiveX Control in the context of an HTML page). The parameter represents the outermost IUnknown of the calling component. The function will attempt the download in the context of the ActiveX client framework and allow the caller's container to receive callbacks on the progress of the download.
LPCWSTRszURL
The URL to be converted to a stream object. Cannot be NULL.
DWORDdwResv
Reserved for future use; must be zero.
LPBINDSTATUSCALLBACKlpfnCB
Pointer to caller's IBindStatusCallback interface, on which URLOpenStream calls OnDataAvailable every time data arrives from the Internet. OnDataAvailable can return E_ABORT to abort the download. When the callback is invoked and the pstm member of the STGMEDIUM structure is not NULL, the caller can read from the stream the amount of data specified in the dwSize argument passed with the OnDataAvailable call (delta anything that has been read on previous calls to OnDataAvailable). If the caller does not read the full amount or does not call pstm Read at all, OnDataAvailable will still be called the next time data arrives, as long the grfBSCF flags do not indicate BINDF_LASTDATANOTIFICATION. In that case, no more data will be downloaded. Any data that is not read at any given time will still be available the next time OnDataAvailable is called.

The logic in the following code fragment is a typical implementation of OnDataAvailable as it is used by the URLOpenStream function:


HRESULT MyBindStatusCallback::OnDataAvailable
(
	DWORD grfBSCF, DWORD dwSize, ..., STGMEDIUM * pstgmed
)
{

	if( dwSize &lt  sizeof(BITMAPINFOHEADER) )
		return(NOERROR);	// not enough has been read yet, just return

	if( !g_bGotInfoHeader )	// did we get info before?
	{
		// No, go ahead, read now...

		DWORD dwRead;
		HRESULT hr = pstgmed->pstm->Read( &bmih, sizeof(bmih), &dwRead);
		if( SUCCEEDED(hr) )
		{
			// now we got it... we can return
			g_bGotInfoHeader = TRUE;
			return(hr);
		}

}
}

URLOpenBlockingStream(


LPUNKNOWN pCaller,
LPCWSTR szURL,
LPSTREAM *ppStream,
DWORD dwResv,
LPBINDSTATUSCALLBACK lpfnCB);

URLOpenBlockingStream creates a blocking-type stream object from a URL. The data is downloaded from the Internet on demand by a call to IStream::Read. The Read call will block until enough data has arrived.

LPUNKNOWNpCaller
Pointer to the controlling IUnknown of the calling ActiveX component (if the caller is an ActiveX component). If the caller is not an ActiveX component, this value may be set to NULL. Otherwise, the caller is a COM object that is contained in another component (such as an ActiveX Control in the context of an HTML page). The parameter represents the outermost IUnknown of the calling component. The function will attempt the download in the context of the ActiveX client framework and allow the caller's container to receive callbacks on the progress of the download.
LPCWSTRszURL
The URL to be converted to a stream object. Cannot be NULL.
LPSTREAM *ppStream
Pointer to the IStream interface pointer on the stream object created by this function. The caller can read from the stream as soon as it has this pointer. If the data requested has not yet been downloaded, the Read method will block until enough data has been downloaded. The following is a code fragment that logically does this:
DWORDdwResv
Reserved for future use; must be zero.
LPBINDSTATUSCALLBACKlpfnCB
Pointer to the IBindStatusCallback interface pointer on the caller. URLOpenBlockingStream calls this interface's OnProgress method on some connection activity, including the arrival of data. OnDataAvailable is never called. Implementing OnProgress allows a caller to implement some user interface or other progress monitoring functionality. It also allows the download operation to be completely canceled by returning E_ABORT from the OnProgress call. Can be NULL.

URLOpenPullStream(

LPUNKNOWN pCaller,
LPCWSTR szURL,
DWORD dwResv,
LPBINDSTATUSCALLBACK lpfnCB);

URLOpenPullStream creates a pull-type stream object from a URL. The data is downloaded from the Internet on demand. If not enough data is available locally to satisfy the requests, the IStream::Read call will not block until enough data has arrived. Instead, Read will immediately return E_PENDING, and URLOpenPullStream will request the next packet of data from the Internet server.

LPUNKNOWNpCaller
Pointer to the controlling IUnknown of the calling ActiveX component (if the caller is an ActiveX component). If the caller is not an ActiveX component, this value may be set to NULL. Otherwise, the caller is a COM object that is contained in another component (such as an ActiveX Control in the context of an HTML page). The parameter represents the outermost IUnknown of the calling component. The function will attempt the download in the context of the ActiveX client framework and allow the caller's container to receive callbacks on the progress of the download.
LPCWSTRszURL
The URL to be converted to a stream object. Cannot be NULL.
DWORDdwResv
Reserved for future use; must be zero.
LPBINDSTATUSCALLBACKlpfnCB
Pointer to caller's IBindStatusCallback interface, on which URLOpenPullStream calls OnDataAvailable every time data arrives from the Internet. OnDataAvailable can return E_ABORT to abort the download. When the callback is invoked and the pstm member of the STGMEDIUM structure is not NULL, the caller can read from the stream the amount of data specified in the dwSize argument passed with the OnDataAvailable call (delta anything that has been read on previous calls to OnDataAvailable). If the caller does not read the full amount or does not call pstmRead at all, OnDataAvailable will not be called again until this happens and Read returns E_PENDING.

The pull model is slightly more cumbersome than the push model, but it gives total control to the client over the amount of Internet access for the download.

The logic in the following code fragment is a typical implementation of OnDataAvailable as it is used by the URLOpenStream function:

© 1996 Microsoft Corporation