DOWNLOAD.CPP

// =========================================================================== 
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright 1996 Microsoft Corporation. All Rights Reserved.
// ===========================================================================
#include <urlmon.h>
#include <wininet.h>
// #include <datapath.h>
#include "range.h"
#include "callback.hpp"

//==============================================================================
HRESULT GetAnInterface
(
IUnknown * punk,
const IID & riid,
void ** pout,
BOOL bCheckServiceProvider,
const IID & siid,
const IID & siid_riid,
void ** sout
)
{
IOleObject * oleObj = 0;
IOleClientSite * oleSite = 0;
IOleContainer * container = 0;
IUnknown * service = 0;

HRESULT hr = E_FAIL;

// Initialize passed in interface pointers: calling code assumes NULL for failure
if(pout)
*pout = NULL;
if(sout)
*sout = NULL;

if(punk)
hr = punk->QueryInterface( IID_IOleObject, (void **)&oleObj );

while( SUCCEEDED(hr) && oleObj )
{
if( oleSite )
{
//oleSite->Release();
oleSite = 0;
}

hr = oleObj->GetClientSite(&oleSite);

if( FAILED(hr) )
break;

if( bCheckServiceProvider )
{
IServiceProvider * servProv;

hr = oleSite->QueryInterface( IID_IServiceProvider, (void**)&servProv);

if( SUCCEEDED(hr) )
{
hr = servProv->QueryService
(siid, siid_riid, (void **) &service);
servProv->Release();
}

if( SUCCEEDED(hr) )
{
bCheckServiceProvider = FALSE;

hr = service->QueryInterface( riid, pout );
}

if( SUCCEEDED(hr) )
break;

}

if( container )
{
container->Release();
container = 0;
}

hr = oleSite->GetContainer( &container );

if( FAILED(hr) )
break;

hr = container->QueryInterface( riid, pout );

if( SUCCEEDED(hr) )
break;

oleObj->Release();
oleObj = 0;

hr = container->QueryInterface( IID_IOleObject, (void**)&oleObj );

}

if( oleSite )
{
//oleSite->Release();
}

if( oleObj )
oleObj->Release();

if( container )
container->Release();

if( service )
*sout = service;

return( hr );

}

//==============================================================================
BOOL HttpReadFromServer (PHTTP_REQUEST_PARAM pParam)
{
IMoniker* m_pmk = NULL;
IBindStatusCallback* m_pbsc = NULL;
HRESULT hr = S_OK;

IBindHost *pBindHost = NULL;

// Create a callback object.
m_pbsc = new CUrlmonCallback (pParam);
if (m_pbsc == NULL)
{
hr = E_OUTOFMEMORY;
goto err;
}

// Look for a bind host.
if (pParam->punkOuter)
{
hr = GetAnInterface
(
(IUnknown *) pParam->punkOuter,
IID_IBindHost, // const IID & riid,
(void **) &pBindHost, // void ** pout,
TRUE, // BOOL bCheckServiceProvider,
IID_IBindHost, // const IID & siid,
IID_IBindHost, // const IID & siid_riid,
(void **) &pBindHost // void ** sout
);
}

// Convert ANSI URL to Unicode.
WCHAR wszUrl[INTERNET_MAX_URL_LENGTH];
MultiByteToWideChar(CP_ACP, 0, pParam->pszUrl, -1, wszUrl, sizeof(wszUrl));

// Initialize bind context, stream.
IBindCtx *pbc;
IStream *pstm;
pbc = NULL;
pstm = NULL;

// Call the appropriate BindToStorage.
if (pBindHost)
{
pBindHost->CreateMoniker (wszUrl, NULL, &m_pmk, 0);
pBindHost->MonikerBindToStorage
(m_pmk, NULL, m_pbsc, IID_IStream, (void **) &pstm);
}
else
{
CreateURLMoniker(NULL, wszUrl, &m_pmk);
CreateAsyncBindCtx(0, m_pbsc, NULL, &pbc);
m_pmk->BindToStorage(pbc, NULL, IID_IStream, (void **) &pstm);
}

// Clean up bind context, stream.
if (pbc)
pbc->Release();
if (pstm)
pstm->Release();

return SUCCEEDED(hr);

err:
delete m_pbsc;

if (m_pmk != NULL)
{
m_pmk->Release();
m_pmk = NULL;
}
return FALSE;

}