// URLCallback.h : Declaration of the cURLCallback

#ifndef __URLCALLBACK_H_
#define __URLCALLBACK_H_

#include "resource.h"       // main symbols
#include "DownloadDlg.h"

/////////////////////////////////////////////////////////////////////////////
// cURLCallback
class ATL_NO_VTABLE cURLCallback : 
	public CComObjectRootEx<CComSingleThreadModel>,
   public IBindStatusCallback,
   public IServiceProvider,
   public IInternetSecurityManager,
   public IInternetHostSecurityManager,
   public ICodeInstall
{
public:
	cURLCallback()
	{
	}
	~cURLCallback()
	{
	}

BEGIN_COM_MAP(cURLCallback)
   COM_INTERFACE_ENTRY(IBindStatusCallback)
   COM_INTERFACE_ENTRY(IServiceProvider)
   COM_INTERFACE_ENTRY(IInternetSecurityManager)
   COM_INTERFACE_ENTRY(IInternetHostSecurityManager)
   COM_INTERFACE_ENTRY(ICodeInstall)
   COM_INTERFACE_ENTRY(IWindowForBindingUI)
END_COM_MAP()

   CComPtr< IBinding > m_pBinding;
   CComPtr< IInternetZoneManager > m_pZone;
   DWORD m_dwOldPolicy;
   cDownloadDlg *m_pDlg;

   // Helper functions for setting up a transfer
   void start( REFCLSID clsid, LPCWSTR szURL, DWORD dwMajor, DWORD dwMinor );
   void stop();

   void resetZone();

public:
   // IBindStatusCallback

   STDMETHOD(GetBindInfo)( DWORD *pgrfBINDF, BINDINFO *pbindinfo );
   STDMETHOD(GetPriority)( LONG *pnPriority )
   {
      *pnPriority = THREAD_PRIORITY_NORMAL;
      return S_OK;
   }

   STDMETHOD(OnDataAvailable)( DWORD, DWORD, FORMATETC *, STGMEDIUM * )
   {
      return E_NOTIMPL;
   }

   STDMETHOD(OnLowResource)(DWORD)
   {
      return E_NOTIMPL;
   }

   STDMETHOD(OnObjectAvailable)( REFIID iid, IUnknown *pUnk );
   STDMETHOD(OnProgress)( ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText );
   STDMETHOD(OnStartBinding)( DWORD dwReserved, IBinding *pBinding );
   STDMETHOD(OnStopBinding)( HRESULT hr, LPCWSTR szStatusText );

   // IServiceProvider
   STDMETHOD(QueryService)(REFGUID sid,REFIID iid,void **ppvItf)
   {
      return static_cast< IServiceProvider * >( this )->QueryInterface( iid, ppvItf );
   }

   // IInternetSecurityManager
   CComPtr< IInternetSecurityMgrSite > m_pSecuritySite;

	STDMETHOD(SetSecuritySite)(IInternetSecurityMgrSite*pSite)
   {
      m_pSecuritySite = pSite;

      return S_OK;
   }

	STDMETHOD(GetSecuritySite)(IInternetSecurityMgrSite **ppSite)
   {
      return m_pSecuritySite->QueryInterface( ppSite );
   }

	STDMETHOD(MapUrlToZone)(LPCWSTR,DWORD*pdwZone,DWORD)
   {
      // All URLs are on the local machine - most trusted
      *pdwZone = URLZONE_LOCAL_MACHINE;
      return S_OK;
   }

	STDMETHOD(GetSecurityId)(LPCWSTR,BYTE*,DWORD*,DWORD)
   {
   	return INET_E_DEFAULT_ACTION;
   }

	STDMETHOD(ProcessUrlAction)(
         /* [in] */ LPCWSTR pwszUrl,
         /* [in] */ DWORD dwAction,
         /* [size_is][out] */ BYTE *pPolicy,
         /* [in] */ DWORD cbPolicy,
         /* [in] */ BYTE *pContext,
         /* [in] */ DWORD cbContext,
         /* [in] */ DWORD dwFlags,
         /* [in] */ DWORD dwReserved = 0)
   {
      if( cbPolicy == sizeof( DWORD ) )
      {
         // Set everything to allow
         *reinterpret_cast< DWORD * >( pPolicy ) = URLPOLICY_ALLOW;
         return S_OK;
      }

		return INET_E_DEFAULT_ACTION;
   }

	STDMETHOD(QueryCustomPolicy)(LPCWSTR,REFGUID,BYTE**,DWORD*,BYTE*,DWORD,DWORD)
   {
	   return INET_E_DEFAULT_ACTION;
   }

	STDMETHOD(SetZoneMapping)(DWORD,LPCWSTR,DWORD)
   {
   	return INET_E_DEFAULT_ACTION;
   }

	STDMETHOD(GetZoneMappings)(DWORD,IEnumString**,DWORD)
   {
   	return INET_E_DEFAULT_ACTION;
   }

   // IInternetHostSecurityManager
   STDMETHOD(GetSecurityId)( BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
   {
      static LPCTSTR strSecurity = _T( "None:localhost+My Computer" );
      ::strcpy( reinterpret_cast< char * >( pbSecurityId ), strSecurity );
      *pcbSecurityId = ::_tcslen( strSecurity );

      return S_OK;
   }
        
   STDMETHOD(ProcessUrlAction)( 
      /* [in] */ DWORD dwAction,
      /* [size_is][out] */ BYTE __RPC_FAR *pPolicy,
      /* [in] */ DWORD cbPolicy,
      /* [in] */ BYTE __RPC_FAR *pContext,
      /* [in] */ DWORD cbContext,
      /* [in] */ DWORD dwFlags,
      /* [in] */ DWORD dwReserved)
   {
      switch( dwAction )
      {
      case URLACTION_DOWNLOAD_UNSIGNED_ACTIVEX:
         *reinterpret_cast< DWORD * >( pPolicy ) = URLPOLICY_QUERY;
         return S_OK;
      }

      if( cbPolicy == sizeof( DWORD ) )
      {
         // Set everything to allow
         *reinterpret_cast< DWORD * >( pPolicy ) = URLPOLICY_ALLOW;
         return S_OK;
      }

		return INET_E_DEFAULT_ACTION;
   }
        
        virtual HRESULT STDMETHODCALLTYPE QueryCustomPolicy( 
            /* [in] */ REFGUID guidKey,
            /* [size_is][size_is][out] */ BYTE __RPC_FAR *__RPC_FAR *ppPolicy,
            /* [out] */ DWORD __RPC_FAR *pcbPolicy,
            /* [in] */ BYTE __RPC_FAR *pContext,
            /* [in] */ DWORD cbContext,
            /* [in] */ DWORD dwReserved)
   {
   	return INET_E_DEFAULT_ACTION;
   }

   // ICodeInstall
   virtual HRESULT STDMETHODCALLTYPE OnCodeInstallProblem( 
      /* [in] */ ULONG ulStatusCode,
      /* [unique][in] */ LPCWSTR szDestination,
      /* [unique][in] */ LPCWSTR szSource,
      /* [in] */ DWORD dwReserved)
   {
      return S_OK;
   }

   // IWindowForBindingUI
   virtual HRESULT STDMETHODCALLTYPE GetWindow( 
      /* [in] */ REFGUID rguidReason,
      /* [out] */ HWND __RPC_FAR *phwnd);
};

#endif //__URLCALLBACK_H_
