Web Site Blocker that Uses Browser Helper Objects (BHO) | CodeGuru

Web Site Blocker that Uses Browser Helper Objects (BHO)

Introduction This article describes how a BHO (Browser Helper Object) could be used to block a particular Web site. Background BHO is a simple ATL COM object that Internet Explorer will load each time it runs; in other words, for every instance of Internet Explorer. BHOs run in Internet Explorer’s address space and can perform […]

Written By
CodeGuru Staff
CodeGuru Staff
Mar 28, 2006
2 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Introduction

This article describes how a BHO (Browser Helper Object) could be used to block a particular Web site.

Background

BHO is a simple ATL COM object that Internet Explorer will load each time it runs; in other words, for every instance of Internet Explorer. BHOs run in Internet Explorer’s address space and can perform any operations on available objects (windows, modules, and so forth). BHOs instantiate and get destructed with a browser’s instance because it is tied to a browser’s main window.

If your system has an active desktop enabled, the BHO gets instantiated along with Windows Explorer as well. To disable the BHO for Windows Explorer, you can add following code snippet to DllMain:

TCHAR strLoader[MAX_PATH];

::GetModuleFileName (NULL, strLoader, MAX_PATH);
if(stricmp("explorer.exe", strLoader) == 0)
   return FALSE;

BHO’s COM Server must implement IObjectWithSite to help your object hook on the browser’s events. Internet Explorer will pass a pointer to its IUnknown interface by the means of IObjectWithSite. Only the SetSite method of IObjectWithSite will need to be implemented, as follows:

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;
}

By calling the Advise method, you tell the browser that BHO would be eager to receive notifications about events. This means that BHO will provide the browser with the pointer to IDispatch (this is due to Component’s event handling). The browser then calls IDispatch’s Invoke method and passes it the ID of an event as an argument. So, your BHO must implement the Invoke method to handle the events.

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;
}
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.