Web Site Blocker

AID: 1906
  • Status: Published

2210 points

  • Bymilindsm
  • TypeGeneral
  • Posted on2009-11-04 at 21:04:29
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, i.e. for every instance of Internet Explorer. BHOs run in Internet Explorer's address space and can perform any operations on available objects (windows, modules etc.). BHO instantiates and gets destructed with browser's instance as it is tied to a browser's main window.

If your system has got active desktop enabled the BHO gets instantiated along with the 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;
                                    
1:
2:
3:
4:
5:

Select allOpen in new window



BHO's COM Server must implement IObjectWithSite that will help our object to hook on browser's events. Internet Explorer will pass a pointer to its IUnknown interface by the means of IObjectWithSite. Only 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 for receiving event notifications
  return Connect();
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:

Select allOpen in new window



Here connect function would look like,

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; 
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:

Select allOpen in new window



By calling Advise method we tell the browser that BHO would be eager to receive notifications about events. By this, what we mean is, BHO will provide the browser with the pointer to IDispatch (this is due to Component's event handling). Browser then calls IDispatch's Invoke method and passes it the ID of an event as an argument. So our BHO must implement 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/%22,(const%20char%20*)psz">http://www.xyz.com/",(const%20char%20*)psz) == 0) 

  // Here you can also use strstr instead of stricmp
  // which will help to allow all domain 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/%22,psz">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;
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:

Select allOpen in new window




You also need to change .rgs file of your project. Add following code snippet to it,
HKLM
{
   SOFTWARE
   {
      Microsoft
      {
         Windows
         {
            CurrentVersion
            {
               Explorer
               {
                  'Browser Helper Objects'
                  {
                     ForceRemove {0CB66BA8-5E1F-4963-93D1-E1D6B78FE9A2}
                  }
               }
            }
         }
      }
   }
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:

Select allOpen in new window



Using the code

Once you are done with the compilation, register your component using regsvr32. Whenever you want to disable the BHO, simply use regsvr32 with /u option. One can also 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.
Asked On
2009-11-04 at 21:04:29ID1906
Tags

Browser Helper Objects

,

BHO

,

ATL COM

Topic

Web Browsers

Views
1134

Comments

Add your Comment

Please Sign up or Log in to comment on this article.

Join Experts Exchange Today

Gain Access to all our Tech Resources

Get personalized answers

Ask unlimited questions

Access Proven Solutions

Search 3.2 million solutions

Read In-Depth How-To Guides

1000+ articles, demos, & tips

Watch Step by Step Tutorials

Learn direct from top tech pros

And Much More!

Your complete tech resource

See Plans and Pricing

30-day free trial. Register in 60 seconds.

Loading Advertisement...

Top Web Browsers Experts

  1. COBOLdinosaur

    88,759

    Master

    200 points yesterday

    Profile
    Rank: Genius
  2. DaveBaldwin

    84,683

    Master

    0 points yesterday

    Profile
    Rank: Genius
  3. jcimarron

    78,286

    Master

    2,800 points yesterday

    Profile
    Rank: Genius
  4. ve3ofa

    73,227

    Master

    0 points yesterday

    Profile
    Rank: Genius
  5. mplungjan

    38,840

    0 points yesterday

    Profile
    Rank: Savant
  6. thinkpads_user

    36,528

    0 points yesterday

    Profile
    Rank: Genius
  7. Run5k

    34,604

    0 points yesterday

    Profile
    Rank: Genius
  8. SSharma

    21,658

    1,500 points yesterday

    Profile
    Rank: Genius
  9. BillDL

    19,718

    0 points yesterday

    Profile
    Rank: Genius
  10. motnahp00

    16,968

    0 points yesterday

    Profile
    Rank: Sage
  11. ahoffmann

    14,725

    0 points yesterday

    Profile
    Rank: Genius
  12. Netty

    14,668

    0 points yesterday

    Profile
    Rank: Guru
  13. Ray_Paseur

    14,225

    0 points yesterday

    Profile
    Rank: Savant
  14. Anuroopsundd

    13,538

    0 points yesterday

    Profile
    Rank: Sage
  15. LZ1

    13,024

    0 points yesterday

    Profile
    Rank: Genius
  16. flubbster

    12,680

    0 points yesterday

    Profile
    Rank: Genius
  17. Tymetwister

    12,308

    0 points yesterday

    Profile
    Rank: Master
  18. jason1178

    11,668

    0 points yesterday

    Profile
    Rank: Genius
  19. xmediaman

    11,500

    0 points yesterday

    Profile
    Rank: Guru
  20. dgofman

    9,250

    0 points yesterday

    Profile
    Rank: Genius
  21. esskayb2d

    9,000

    1,500 points yesterday

    Profile
    Rank: Master
  22. giltjr

    8,784

    0 points yesterday

    Profile
    Rank: Genius
  23. d4durvesh

    8,670

    10 points yesterday

    Profile
    Rank: Master
  24. ged325

    8,500

    0 points yesterday

    Profile
    Rank: Genius
  25. DavisMcCarn

    8,064

    0 points yesterday

    Profile
    Rank: Genius

Hall Of Fame