Microsoft KB Archive/196061

= How To Tie ActiveX Controls to a Specific Domain =

Article ID: 196061

Article Last Modified on 7/13/2004

-

APPLIES TO


 * Microsoft Internet Explorer 4.0 128-Bit Edition
 * Microsoft Internet Explorer 4.01 Service Pack 2
 * Microsoft Internet Explorer 4.01 Service Pack 1
 * Microsoft Internet Explorer 5.0
 * Microsoft Internet Explorer 5.5

-



This article was previously published under Q196061



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.



MORE INFORMATION
To determine if the URL of the current Web page is on your domain, follow these steps:   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      #include       #include 

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

class ATL_NO_VTABLE CYourControl : public CComObjectRootEx, public CComCoClass, public IObjectWithSiteImpl, public IDispatchImpl {     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 spSrvProv; CComPtr 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(_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]; };                    Change the approvedDomains variable to include your domain names.</li> Call InApprovedDomain. Make sure that the container site has been set through a call to IOleObjectWithSite::SetSite. Otherwise, this function will fail.</li> 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.</li>  Initialize the _approvedDomains array in your implementation (.cpp) file as follows: char* CYourControl::_approvedDomains[] = { "approvedDomain1", "approvedDomain2 };                   </li></ol>

<div class="references_section">