# URLOpenPullStream

Creates a pull-type stream object from a URL.

HRESULT URLOpenPullStream(

LPUNKNOWN pCaller, | // Caller’s controlling IUnknown
LPCWSTR szURL, | // URL to be converted to stream
DWORD dwResv, | // Reserved for future use
LPBINDSTATUSCALLBACK lpfnCB | // Caller’s IBindStatusCallback
); |

Parameters

pCaller
  [] Pointer to the caller’s controlling IUnknown. If the caller is not an ActiveX component, this value may be set to NULL
szURL
  [out] The URL to be converted to a stream object. Cannot be NULL.
dwResv
  [in] Reserved for future use. Must be zero.
lpfnCB
  [in] Pointer to caller's IBindStatusCallback interface

Return Values

This function returns the same values as IBindHost::MonikerBindToStorage.

Remarks

If pCaller is non-NULL, the caller is a COM object that is contained in another component, such as an ActiveX Control in the context of an HTML page.In this case, the function attempts the download in the context of the ActiveX client framework and allows the caller's container to receive callbacks on the progress of the download.

URLOpenPullStream calls IBindStatusCallback::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. If the caller does not read the full amount or does not call IStream::Read 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 the client gives total control over the download operation.

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

    HRESULT CMyBindStatusCallback::OnDataAvailable( ...)
    {
        HRESULT hr = NOERROR;
        DWORD dwAmountToRead = dwSize - g_readSoFar;
        BYTE * buffer = new BYTE[ dwAmountToRead ];
        while( TRUE )
        {
            DWORD dwRead;
            hr = pstgmed->pstrm->Read( buffer, dwAmountToRead, &dwRead );
            if( hr == E_PENDING )
            {
                // we'll get notified again when more data comes
                return(NOERROR);
            }
            if( SUCCEEDED(hr) )
            {
                // ok, process bits ....
                // keep looping
            }
            else
            {
                // we have an error...
                return(hr);
            }
        }
    }

See Also

IBindStatusCallback, IBindStatusCallback::OnDataAvailable, IStream, IStream::Read