HOWTO: Tie ActiveX Controls to a Specific Domain
ID: Q196061
|
The information in this article applies to:
-
Microsoft Internet Explorer (Programming) versions 4.0, 4.01, 4.01 SP1, 5.0, 5.0dp1
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 <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];
};
- Change the approvedDomains variable to include your domain names.
- Call InApprovedDomain(). Make sure that the container site has been set through a call to IOleObjectWithSite::SetSite. Otherwise, this function will fail.
- 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.
- Initialize the _approvedDomains array in your implementation (.cpp)
file as follows:
char* CYourControl::_approvedDomains[] = { "approvedDomain1",
"approvedDomain2 };
REFERENCES
For an alternate approach that is compatible with Internet Explorer 3.x,
please see the following article in the Microsoft Knowledge Base:
Q181678 HOWTO: Retrieve the URL of a Web Page from an ActiveX Control
Component Development in the MSDN Online Web Workshop
http://www.msdn.microsoft.com/workshop/c-frame.htm#/workshop/components/default.asp (c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Scott Roberts, Microsoft Corporation.
Additional query words:
Keywords : kbcode kbActiveX kbCtrl kbIE400 kbIE401 kbIE401sp1 kbIE500dp1 kbIE500 kbDSupport
Version : WINDOWS:4.0,4.01,4.01 SP1,5.0,5.0dp1
Platform : WINDOWS
Issue type : kbhowto
|