Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

How To Tie ActiveX Controls to a Specific Domain


View products that this article applies to.

This article was previously published under Q196061

↑ Back to the top


Summary

When you create an ActiveX control for use under Internet Explorer, you might want to have your controls only function when they are being hosted on a Web page in a specific domain. For instance, you might want to protect your control from being reused without your permission.

This article provides Visual C++ sample code to demonstrate how to determine the domain that your control is running under.

↑ Back to the top


More information

To determine if the URL of the current Web page is on your domain, follow these steps:
1.Insert the body of the following ATL class declaration into your Visual C++ project. The following code is an Internet Explorer control that was created by the Visual C++ New ATL Object wizard.

Sample Code

   #include <ExDisp.h>
      #include <shlguid.h>
      #include <WinInet.h>

      #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))

      class ATL_NO_VTABLE CYourControl :
         public CComObjectRootEx<CComSingleThreadModel>,
         public CComCoClass<CTstDomain, &CLSID_TstDomain>,
         public IObjectWithSiteImpl<CTstDomain>,
         public IDispatchImpl<ITstDomain, &IID_ITstDomain,
                             &LIBID_TSTCTRLLib>
      {
      public:
         CYourControl() {}

      DECLARE_PROTECT_FINAL_CONSTRUCT()

      BEGIN_COM_MAP(CTstDomain)
         COM_INTERFACE_ENTRY(ITstDomain)
         COM_INTERFACE_ENTRY(IDispatch)
         COM_INTERFACE_ENTRY(IObjectWithSite)
      END_COM_MAP()

         // IObjectWithSite Methods.
         STDMETHODIMP SetSite(IUnknown* pUnkSite)
         {
            _spUnkSite = pUnkSite;

            ATLTRACE("Approved Domain: %s", InApprovedDomain()
                                            ? "Yes" : "No");

            return S_OK;
         };

         STDMETHODIMP GetSite(REFIID riid, LPVOID* ppvSite)
         {
            return _spUnkSite->QueryInterface(riid, ppvSite);
         }

         bool InApprovedDomain()
         {
            char ourUrl[INTERNET_MAX_URL_LENGTH];
            if (!GetOurUrl(ourUrl, sizeof ourUrl))
               return false;

            return IsApprovedDomain(ourUrl);
         }

         bool GetOurUrl(char* pszURL, int cbBuf)
         {
            HRESULT hr;
            CComPtr<IServiceProvider> spSrvProv;
            CComPtr<IWebBrowser2> spWebBrowser;

            hr = GetSite(IID_IServiceProvider, (void**)&spSrvProv);
            if (FAILED(hr))
               return false;

            hr = spSrvProv->QueryService(SID_SWebBrowserApp,
                                         IID_IWebBrowser2,
                                         (void**)&spWebBrowser);
            if (FAILED(hr))
               return false;

            CComBSTR bstrURL;
            if (FAILED(spWebBrowser->get_LocationURL(&bstrURL)))
               return false;

            WideCharToMultiByte(CP_ACP, 0, bstrURL, -1, pszURL, cbURL,
                                NULL, NULL);

            return true;
         }

         bool IsApprovedDomain(char* ourUrl)
         {
            // Only allow http access.
            // You can change this to allow file:// access.
            // 
            if (GetScheme(ourUrl) != INTERNET_SCHEME_HTTP)
               return false;

            char ourDomain[256];
            if (!GetDomain(ourUrl, ourDomain, sizeof(ourDomain)))
               return false;

            for (int i = 0; i < ARRAYSIZE(_approvedDomains); i++)
            {
               if (MatchDomains(const_cast<char*>(_approvedDomains[i]),
                                ourDomain))
               {
                  return true;
               }
            }

            return false;
         }

         INTERNET_SCHEME GetScheme(char* url)
         {
            char buf[32];
            URL_COMPONENTS uc;
            ZeroMemory(&uc, sizeof uc);

            uc.dwStructSize = sizeof uc;
            uc.lpszScheme = buf;
            uc.dwSchemeLength = sizeof buf;

            if (InternetCrackUrl(url, lstrlen(url), ICU_DECODE, &uc))
               return uc.nScheme;
            else
               return INTERNET_SCHEME_UNKNOWN;
         }

         bool GetDomain(char* url, char* buf, int cbBuf)
         {
            URL_COMPONENTS uc;
            ZeroMemory(&uc, sizeof uc);

            uc.dwStructSize = sizeof uc;
            uc.lpszHostName = buf;
            uc.dwHostNameLength = cbBuf;

            return (InternetCrackUrl(url, lstrlen(url), ICU_DECODE, &uc)
                    != FALSE);
         }

         // Return if ourDomain is within approvedDomain.
         // approvedDomain must either match ourDomain
         // or be a suffix preceded by a dot.
         // 
         bool MatchDomains(char* approvedDomain, char* ourDomain)
         {
            int apDomLen  = lstrlen(approvedDomain);
            int ourDomLen = lstrlen(ourDomain);

            if (apDomLen > ourDomLen)
               return false;

            if (lstrcmpi(ourDomain+ourDomLen-apDomLen, approvedDomain)
                != 0)
               return false;

            if (apDomLen == ourDomLen)
               return true;

            if (ourDomain[ourDomLen - apDomLen - 1] == '.')
               return true;

            return false;
         }

         private:
            static char* _approvedDomains[2];
      };
	
					
2.Change the approvedDomains variable to include your domain names.
3.Call InApprovedDomain(). Make sure that the container site has been set through a call to IOleObjectWithSite::SetSite. Otherwise, this function will fail.
4.Add WinInet.lib to the list of libraries to link into your control. To set this option, go to the Project menu, click Settings, and click the Link tab. If the current web page is in one of the domains specified by ourDomains, InApprovedDomain will return TRUE.
5.Initialize the _approvedDomains array in your implementation (.cpp) file as follows:
    char* CYourControl::_approvedDomains[] = { "approvedDomain1",
                                                 "approvedDomain2 };
					

↑ Back to the top


References

For an alternate approach that is compatible with Internet Explorer 3.x, please see the following article in the Microsoft Knowledge Base:
181678 How To Retrieve the URL of a Web Page from an ActiveX Control
Component Development in the MSDN Online Web Workshop (c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Scott Roberts, Microsoft Corporation.

↑ Back to the top


Keywords: KB196061, kbcode, kbctrl, kbhowto

↑ Back to the top

Article Info
Article ID : 196061
Revision : 4
Created on : 7/13/2004
Published on : 7/13/2004
Exists online : False
Views : 528