TCHAR strLoader[MAX_PATH];
::GetModuleFileName (NULL, strLoader, MAX_PATH);
if(stricmp("explorer.exe", strLoader) == 0)
return FALSE;
STDMETHODIMP CBhoApp::SetSite(IUnknown *pUnkSite)
{
// Retrieve and store the IWebBrowser2 pointer
m_spWebBrowser2 = pUnkSite;
if (m_spWebBrowser2 == NULL)
return E_INVALIDARG;
// Retrieve and store the IConnectionPointerContainer pointer
m_spCPC = m_spWebBrowser2;
if (m_spCPC == NULL)
return E_POINTER;
// Connect to the container to receive event notifications
return Connect();
}
Here, the connect function would look like the following:
HRESULT CBhoApp::Connect()
{
HRESULT hr;
CComPtr<IConnectionPoint> spCP;
// Receives the connection point for WebBrowser events
hr = m_spCPC->FindConnectionPoint(DIID_DWebBrowserEvents2, &spCP);
if (FAILED(hr))
return hr;
// Pass our event handlers to the container. Each time an event
// occurs the container will invoke the functions of the
// IDispatch interface we implemented.
hr = spCP->Advise(reinterpret_cast<IDispatch*>(this),&m_dwCookie);
return hr;
}
STDMETHODIMP CBhoApp::Invoke(DISPID dispidMember,REFIID riid,
LCID lcid,WORD wFlags,
DISPPARAMS *pDispParams,VARIANT
*pvarResult, EXCEPINFO *pExcepInfo,
UINT *puArgErr)
{
USES_CONVERSION; // This macro should be called when using
// ATL string conversion macros to avoid
// compile time errors (here we are using OLE2T)
if(dispidMember == DISPID_BEFORENAVIGATE2)
{
BSTR bstrUrlName;
HRESULT hr = m_spWebBrowser2->get_LocationURL(&bstrUrlName);
if(FAILED(hr))
return hr;
LPTSTR psz = new TCHAR[SysStringLen(bstrUrlName)];
lstrcpy(psz, OLE2T(bstrUrlName));
// Here, I am directly comparing with xyz.com. You can
// maintain a list of all sites to be blocked and then compare.
// Or, you can also keep this data in a database, but I guess
// that might affect the performance.
// (Experts! please comment on this.)
if (stricmp("http://www.xyz.com/",psz) == 0)
// Here, you also can use strstr instead of stricmp;
// this will help allow all domains originating from xyz.
{
VARIANT vFlags = {0},vTargetFrameName = {0};
// Instead of "about:blank", you can redirect user to some
// page saying site has been blocked. :-)
m_spWebBrowser2->Navigate(SysAllocString(L"about:blank"),
&vFlags,&vTargetFrameName,
NULL,NULL);
m_spWebBrowser2->put_Visible(VARIANT_TRUE);
return S_FALSE;
}
return S_OK;
}
else if(dispidMember == DISPID_NAVIGATECOMPLETE2)
// This checking is done to avoid post-navigation loading of a page.
{
BSTR bstrUrlName;
HRESULT hr = m_spWebBrowser2->get_LocationURL(&bstrUrlName);
if(FAILED(hr))
return hr;
// Convert the text from Unicode to ANSI
LPTSTR psz = new TCHAR[SysStringLen(bstrUrlName)];
lstrcpy(psz, OLE2T(bstrUrlName));
::OutputDebugString("In Navigate Complete");
::OutputDebugString(psz);
if (stricmp("http://www.xyz.com/",psz) == 0)
{
VARIANT vFlags = {0},vTargetFrameName = {0};
m_spWebBrowser2->Navigate(SysAllocString(L"about:blank"),
&vFlags,&vTargetFrameName,
NULL,NULL);
m_spWebBrowser2->put_Visible(VARIANT_TRUE);
}
return S_OK;
}
return S_FALSE;
}You also need to change the .rgs file of your project. Add the following code snippet to it:
HKLM
{
SOFTWARE
{
Microsoft
{
Windows
{
CurrentVersion
{
Explorer
{
'Browser Helper Objects'
{
ForceRemove {0CB66BA8-5E1F-4963-93D1-E1D6B78FE9A2}
}
}
}
}
}
}
}
Using the Code
Once
you are done with the compilation, use regsvr32 to register your
component. Whenever you want to disable the BHO, simply use regsvr32
with the /u option. One also can provide a simple UI to do this.
Improvements
A UI element could be added to add a URL to the list of "sites to be blocked."
References
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwebgen/html/bho.asp.
Downloads
- BhoNew_src.zip - Source Code