October 22nd, 2008, 07:15 AM
#1
ActiveX and IObjectSafetySiteLock,IObjectWithSite
hello,
i am trying to create a simple MFC activeX control through wizard.
it has nothing fancy. just a method to display message box
however, i want to add sitelock to this control. for that i downloaded the
Sitelock ATL template. form microsoft.
http://www.microsoft.com/downloads/d...displaylang=en
i added the sitelock.h file.to the mfc control.
now if it was a ATL project them i just need to derive from the "IObjectSafetySiteLockImpl" and things works.
but how do i accomplish it in MFC control.
for this i read some article at MSDN.
http://msdn.microsoft.com/en-us/library/ms974305.aspx
for this i code like this
in the .h file
Code:
BEGIN_INTERFACE_PART(ObjSafe, IObjectSafetySiteLock)
STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid,DWORD dwOptionSetMask, DWORD dwEnabledOptions);
STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid,DWORD __RPC_FAR *pdwSupportedOptions,DWORD __RPC_FAR *pdwEnabledOptions);
STDMETHOD(GetCapabilities)(DWORD * pdwCapability);
STDMETHOD(GetApprovedSites)(const SiteList ** pSiteList, DWORD * cSites);
STDMETHOD(GetExpiryDate)(DWORD * pdwLifespan, FILETIME * pExpiryDate);
END_INTERFACE_PART(ObjSafe);
BEGIN_INTERFACE_PART(ObjWithSite, IObjectWithSite)
STDMETHOD(SetSite)(IUnknown *pUnkSite);
STDMETHOD(GetSite)(REFIID riid, void **ppvSite);
STDMETHOD(SetChildSite)(IUnknown* punkChild);
STDMETHOD(SetChildSite)(IUnknown* punkChild, IUnknown* punkParent);
END_INTERFACE_PART(ObjWithSite);
in the .cpp file
Code:
const DWORD dwSupportedBits = INTERFACESAFE_FOR_UNTRUSTED_CALLER |INTERFACESAFE_FOR_UNTRUSTED_DATA;
const DWORD dwNotSupportedBits = ~ dwSupportedBits;
/////////////////////////////////////////////////////////////////////////////
// CSWEnforceActiveXCtrl::XObjSafe::GetInterfaceSafetyOptions
// Allows container to query what interfaces are safe for what. We're
// optimizing significantly by ignoring which interface the caller is
// asking for.
HRESULT STDMETHODCALLTYPE
CMFCSiteCtrl::XObjSafe::GetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
/* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
{
METHOD_PROLOGUE(CMFCSiteCtrl, ObjSafe)
HRESULT retval = ResultFromScode(S_OK);
// does interface exist?
IUnknown FAR* punkInterface;
retval = pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface);
if (retval != E_NOINTERFACE)
{ // interface exists
punkInterface->Release(); // release it--just checking!
}
// we support both kinds of safety and have always both set,
// regardless of interface
*pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits;
return retval; // E_NOINTERFACE if QI failed
}
/////////////////////////////////////////////////////////////////////////////
// CStopLiteCtrl::XObjSafe::SetInterfaceSafetyOptions
// Since we're always safe, this is a no-brainer--but we do check to make
// sure the interface requested exists and that the options we're asked to
// set exist and are set on (we don't support unsafe mode).
HRESULT STDMETHODCALLTYPE
CMFCSiteCtrl::XObjSafe::SetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [in] */ DWORD dwOptionSetMask,
/* [in] */ DWORD dwEnabledOptions)
{
METHOD_PROLOGUE(CMFCSiteCtrl, ObjSafe)
// does interface exist?
IUnknown FAR* punkInterface;
pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface);
if (punkInterface)
{ // interface exists
punkInterface->Release(); // release it--just checking!
}
else
{ // interface doesn't exist
return ResultFromScode(E_NOINTERFACE);
}
// can't set bits we don't support
if (dwOptionSetMask & dwNotSupportedBits)
{
return ResultFromScode(E_FAIL);
}
// can't set bits we do support to zero
dwEnabledOptions &= dwSupportedBits;
// (we already know there are no extra bits in mask )
if ((dwOptionSetMask & dwEnabledOptions) !=dwOptionSetMask)
{
return ResultFromScode(E_FAIL);
}
// don't need to change anything since we're always safe
return ResultFromScode(S_OK);
}
HRESULT STDMETHODCALLTYPE
CMFCSiteCtrl::XObjSafe::GetCapabilities(DWORD * pdwCapability)
{
// Data validation
if (!pdwCapability)
return E_POINTER;
// Return the version if 0 is passed in
if (0 == *pdwCapability)
{
*pdwCapability = SITELOCK_VERSION;
return S_OK;
}
// Return the options if 1 is passed in
if (1 == *pdwCapability)
{
*pdwCapability =
#ifdef SITELOCK_USE_IOLEOBJECT
Capability::UsesIOleObject |
#endif
#ifndef SITELOCK_NO_EXPIRY
Capability::HasExpiry |
#endif
0;
return S_OK;
}
// Return not implemented otherwise
*pdwCapability = 0;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE
CMFCSiteCtrl::XObjSafe::GetApprovedSites(const SiteList ** pSiteList, DWORD * pcEntries)
{
// Data validation
if (!pSiteList || !pcEntries)
return E_POINTER;
// Return specified site lock entries
#ifdef SITELOCK_USE_MAP
// Use the site lock map
*pSiteList = T::GetSiteLockMapAndCount(*pcEntries);
#else
// Use the static member
*pSiteList = T::rgslTrustedSites;
*pcEntries = cElements(T::rgslTrustedSites);
#endif
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CMFCSiteCtrl::XObjSafe::GetExpiryDate(DWORD * pdwLifespan, FILETIME * pExpiryDate)
{
if (!pdwLifespan || !pExpiryDate)
return E_POINTER;
#ifdef SITELOCK_NO_EXPIRY
*pdwLifespan = 0;
::ZeroMemory((void*)pExpiryDate, sizeof(FILETIME));
return E_NOTIMPL;
#else
*pdwLifespan = T::dwControlLifespan;
// Calculate expiry date from life span
time_t ttExpire = ImageNtHeaders(&__ImageBase)->FileHeader.TimeDateStamp;
ttExpire += T::dwControlLifespan*86400; // seconds per day
_UNIXTimeToFILETIME(ttExpire, pExpiryDate);
return S_OK;
#endif
}
HRESULT STDMETHODCALLTYPE
CMFCSiteCtrl::XObjWithSite::SetSite(IUnknown *pUnkSite)
{
ATLTRACE(atlTraceCOM, 2, _T("IObjectWithSiteImpl::SetSite\n"));
CMFCSiteCtrl* pT = static_cast<CMFCSiteCtrl*>(this);
pT->m_spUnkSite = pUnkSite;
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CMFCSiteCtrl::XObjWithSite::GetSite(REFIID riid, void **ppvSite)
{
ATLTRACE(atlTraceCOM, 2, _T("IObjectWithSiteImpl::GetSite\n"));
CMFCSiteCtrl* pT = static_cast<CMFCSiteCtrl*>(this);
ATLASSERT(ppvSite);
HRESULT hRes = E_POINTER;
if (ppvSite != NULL)
{
if (pT->m_spUnkSite)
hRes = pT->m_spUnkSite->QueryInterface(riid, ppvSite);
else
{
*ppvSite = NULL;
hRes = E_FAIL;
}
}
return hRes;
}
HRESULT STDMETHODCALLTYPE
CMFCSiteCtrl::XObjWithSite::SetChildSite(IUnknown* punkChild)
{
if (punkChild == NULL)
return E_POINTER;
HRESULT hr;
CComPtr<IObjectWithSite> spChildSite;
hr = punkChild->QueryInterface(__uuidof(IObjectWithSite), (void**)&spChildSite);
if (SUCCEEDED(hr))
hr = spChildSite->SetSite((IUnknown*)this);
return hr;
}
HRESULT STDMETHODCALLTYPE
CMFCSiteCtrl::XObjWithSite::SetChildSite(IUnknown* punkChild, IUnknown* punkParent)
{
return AtlSetChildSite(punkChild, punkParent);
}
some of the code i took from ATL template class
as they are template class for i tried to repalce the "T" with "CMFCSiteCtrl"
somewhere they works
but here is my problem
the sitelock declare some variable of type that a "CMFCSiteCtrl" must declare
they are as follows
static const SiteList rgslTrustedSites[6];
enum { dwControlLifespan =365 };
as you could see this is "SiteList" Structure which is defined in the "Sitelock.h" i get undeclare identifier for it. how do i make it accesible??
i mean how do it get this structure defined in the "Interface" in my MFCCtrl Class??
Any help would be greatly Appreciated
regards
Dingo
October 22nd, 2008, 07:19 AM
#2
Re: ActiveX and IObjectSafetySiteLock,IObjectWithSite
Last edited by dingo_kasper; August 7th, 2009 at 03:38 AM .
November 10th, 2008, 12:58 AM
#3
Re: ActiveX and IObjectSafetySiteLock,IObjectWithSite
hello,
i solved this problem
just to help others if they ever encounter this. i am posting the solution
there were couple of problems in the code.
(1) as i was using the MFC ActiveX control so the activeX control class gets inherited from the COleControl. now this is what MSDN says about it that you have to use IOleObject and IObjectWithSite exclusively. means you could not use the both interfaces so the call to "STDMETHOD(SetSite)(IUnknown *pUnkSite);" will not happen. as we have already used IOleObject.
now how did i resolve this problem is i extracted all related functions from the sitelock template class the wrap them in a diffrent Class. and then referenced this class at what places it was required. the only thing i want to get was the URL of the control and the Zone setting. which was presented in the "Sitelock.h" template class. i added this code to my class with correctly passing the interface pointers. and all done!!
codeguru is the one of best place to spend time with, thanks you All!!
thanks
Dingo
February 17th, 2009, 09:37 PM
#4
Re: ActiveX and IObjectSafetySiteLock,IObjectWithSite
Hi,
Since I found dingo_kasper's help very, very useful - but it didn't detail the complete necessary steps, I decided to add my little guide.
So, what you need is the following:
Modified sitelock.h (attached)
Additions to your Ctrl.h file:
Code:
#include <ObjSafe.h>
#define SITELOCK_USE_IOLEOBJECT
#include <atlbase.h>
#include "sitelock.h"
.....
class CYourCtrl : public COleControl
{
.....
BEGIN_INTERFACE_PART(ObjSafe, IObjectSafetySiteLock)
STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid,DWORD dwOptionSetMask, DWORD dwEnabledOptions);
STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid,DWORD __RPC_FAR *pdwSupportedOptions,DWORD __RPC_FAR *pdwEnabledOptions);
STDMETHOD(GetCapabilities)(DWORD * pdwCapability);
STDMETHOD(GetApprovedSites)(const SiteList ** pSiteList, DWORD * cSites);
STDMETHOD(GetExpiryDate)(DWORD * pdwLifespan, FILETIME * pExpiryDate);
private:
static const IObjectSafetySiteLock::SiteList rgslTrustedSites[6];
// Number of days before expiration of control
static const DWORD dwControlLifespan;
// Used internally in said functions
bool ControlExpired(DWORD dwExpiresDays = dwControlLifespan);
bool InApprovedDomain(const SiteList* rgslTrustedSites = rgslTrustedSites,
int cTrustedSites = _countof(rgslTrustedSites));
// Retrieves the activation URL
bool GetOurUrl(CComBSTR &bstrURL, DWORD &dwZone);
// Checks if an activation URL is in an allowed domain / zone
bool FApprovedDomain(const OLECHAR* wzUrl, DWORD dwZone,
const SiteList* rgslTrustedSites,
int cTrustedSites);
// Normalizes an international domain name
HRESULT NormalizeDomain(OLECHAR* wzDomain, int cchDomain);
// Extracts a normalized domain and scheme from an activation URL
HRESULT GetDomainAndScheme(const OLECHAR * wzUrl,
OLECHAR * wzScheme,
DWORD cchScheme,
OLECHAR* wzDomain,
DWORD cchDomain);
// Attempts to match an activation URL with a domain name
bool MatchDomains(const OLECHAR * wzTrustedDomain,
const OLECHAR * wzOurDomain);
static DWORD m_dwCurrentSafety;
END_INTERFACE_PART(ObjSafe);
......
};
......
Attached Files
February 17th, 2009, 09:38 PM
#5
Re: ActiveX and IObjectSafetySiteLock,IObjectWithSite
and additions to your Ctrl.cpp file:
Code:
// Trusted sites, to allow this control to run on
const IObjectSafetySiteLock::SiteList CYourCtrl::XObjSafe::rgslTrustedSites[6] =
{
{ IObjectSafetySiteLock::SiteList::Allow, L"http", L"microsoft.com" },
{ IObjectSafetySiteLock::SiteList::Allow, L"http", SITELOCK_INTRANET_ZONE },
{ IObjectSafetySiteLock::SiteList::Allow, L"https", L"micrososft.com" },
{ IObjectSafetySiteLock::SiteList::Allow, L"https", SITELOCK_INTRANET_ZONE },
{ IObjectSafetySiteLock::SiteList::Allow, L"http", L"192.168.2.130" },
{ IObjectSafetySiteLock::SiteList::Allow, L"https", L"192.168.2.130" },
};
// Control lifespan, in days
const DWORD CYourCtrl::XObjSafe::dwControlLifespan = 30;
DWORD CYourCtrl::XObjSafe::m_dwCurrentSafety = 0;
......
BEGIN_INTERFACE_MAP(CYourCtrl, COleControl)
INTERFACE_PART(CYourCtrl, IID_IObjectSafety, ObjSafe)
INTERFACE_PART(CYourCtrl, IID_IObjectSafetySiteLock, ObjSafe)
END_INTERFACE_MAP()
......
const DWORD dwSupportedSafety =
INTERFACESAFE_FOR_UNTRUSTED_CALLER |
INTERFACESAFE_FOR_UNTRUSTED_DATA;
const DWORD dwNotSupportedSafety = ~dwSupportedSafety;
#ifndef SITELOCK_NO_EXPIRY
// Helper functions for expiry
#if defined(_WIN64) && defined(_M_IA64)
#pragma section(".base", long, read, write)
extern "C" __declspec(allocate(".base")) extern IMAGE_DOS_HEADER __ImageBase;
#else
extern "C" IMAGE_DOS_HEADER __ImageBase;
#endif
#define ImageNtHeaders(pBase) ((PIMAGE_NT_HEADERS)((PCHAR)(pBase) + ((PIMAGE_DOS_HEADER)(pBase))->e_lfanew))
#define LODWORD(_qw) ((DWORD)(_qw))
#define HIDWORD(_qw) ((DWORD)(((_qw) >> 32) & 0xffffffff))
inline void UNIXTimeToFILETIME(time_t t, LPFILETIME ft)
{
// The time_t is a 32-bit value for the number of seconds since January 1, 1970.
// A FILETIME is a 64-bit for the number of 100-nanosecond periods since January 1, 1601.
// Convert by multiplying the time_t value by 1e+7 to get to the same base granularity,
// then add the numeric equivalent of January 1, 1970 as FILETIME.
ULONGLONG qw = ((ULONGLONG)t * 10000000ui64) + 116444736000000000ui64;
ft->dwHighDateTime = HIDWORD(qw);
ft->dwLowDateTime = LODWORD(qw);
}
inline time_t FILETIMEToUNIXTime(LPFILETIME ft)
{
ULONGLONG qw = (((ULONGLONG)ft->dwHighDateTime)<<32) + ft->dwLowDateTime;
return (time_t)((qw - 116444736000000000ui64) / 10000000ui64);
}
#endif // SITELOCK_NO_EXPIRY
// Allows container to query what interfaces are safe for what. We're
// optimizing significantly by ignoring which interface the caller is
// asking for.
HRESULT STDMETHODCALLTYPE
CYourCtrl::XObjSafe::GetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
/* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
{
METHOD_PROLOGUE(CYourCtrl, ObjSafe)
// Data validation
if (!pdwSupportedOptions || !pdwEnabledOptions)
return E_POINTER;
// Declarations
HRESULT hr = S_OK;
IUnknown * pUnk = NULL;
// Check if the requested COM interface is supported
hr = pThis->ExternalQueryInterface(&riid, (void**)&pUnk);
if (FAILED(hr))
{
*pdwSupportedOptions = 0;
*pdwEnabledOptions = 0;
return hr;
}
// Release the interface
pUnk->Release();
// Check expiry and if the activation URL is allowed
if (!ControlExpired() && InApprovedDomain())
{
*pdwSupportedOptions = dwSupportedSafety;
*pdwEnabledOptions = m_dwCurrentSafety;
}
else
{
*pdwSupportedOptions = dwSupportedSafety;
*pdwEnabledOptions = 0;
}
return S_OK;
}
// Since we're always safe, this is a no-brainer—but we do check to make
// sure the interface requested exists and that the options we're asked to
// set exist and are set on (we don't support unsafe mode).
HRESULT STDMETHODCALLTYPE
CYourCtrl::XObjSafe::SetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [in] */ DWORD dwOptionSetMask,
/* [in] */ DWORD dwEnabledOptions)
{
METHOD_PROLOGUE(CYourCtrl, ObjSafe)
// Declarations
HRESULT hr = S_OK;
IUnknown * pUnk = NULL;
// Check if we support the interface and return E_NOINTERFACE if we don't
// Check if the requested COM interface is supported
hr = pThis->ExternalQueryInterface(&riid, (void**)&pUnk);
if (FAILED(hr))
return hr;
// Release the interface
pUnk->Release();
// Reject unsupported requests
if (dwOptionSetMask & ~dwSupportedSafety)
return E_FAIL;
// Calculate safety options
DWORD dwNewSafety = (m_dwCurrentSafety & ~dwOptionSetMask) | (dwOptionSetMask & dwEnabledOptions);
if (m_dwCurrentSafety != dwNewSafety)
{
// Check expiry and if the activation URL is allowed
if (ControlExpired() || !InApprovedDomain())
return E_FAIL;
// Set safety options
m_dwCurrentSafety = dwNewSafety;
}
return S_OK;
}
// Delegate AddRef, Release, QueryInterface
ULONG FAR EXPORT CYourCtrl::XObjSafe::AddRef()
{
METHOD_PROLOGUE(CYourCtrl, ObjSafe)
return pThis->ExternalAddRef();
}
ULONG FAR EXPORT CYourCtrl::XObjSafe::Release()
{
METHOD_PROLOGUE(CYourCtrl, ObjSafe)
return pThis->ExternalRelease();
}
HRESULT FAR EXPORT CYourCtrl::XObjSafe::QueryInterface(
REFIID iid, void FAR* FAR* ppvObj)
{
METHOD_PROLOGUE(CYourCtrl, ObjSafe)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
HRESULT STDMETHODCALLTYPE
CYourCtrl::XObjSafe::GetCapabilities(DWORD * pdwCapability)
{
// Data validation
if (!pdwCapability)
return E_POINTER;
// Return the version if 0 is passed in
if (0 == *pdwCapability)
{
*pdwCapability = SITELOCK_VERSION;
return S_OK;
}
// Return the options if 1 is passed in
if (1 == *pdwCapability)
{
*pdwCapability =
#ifndef SITELOCK_NO_EXPIRY
IObjectSafetySiteLock::UsesIOleObject |
#endif
0;
return S_OK;
}
// Return not implemented otherwise
*pdwCapability = 0;
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE
CYourCtrl::XObjSafe::GetApprovedSites(const SiteList ** pSiteList, DWORD * pcEntries)
{
// Data validation
if (!pSiteList || !pcEntries)
return E_POINTER;
// Return specified site lock entries
#ifdef SITELOCK_USE_MAP
// Use the site lock map
*pSiteList = /*T::*/ GetSiteLockMapAndCount(*pcEntries);
#else
// Use the static member
*pSiteList = /*T::*/ rgslTrustedSites;
*pcEntries = _countof(/*T::*/ rgslTrustedSites);
#endif
return S_OK;
}
HRESULT STDMETHODCALLTYPE
CYourCtrl::XObjSafe::GetExpiryDate(DWORD * pdwLifespan, FILETIME * pExpiryDate)
{
if (!pdwLifespan || !pExpiryDate)
return E_POINTER;
#ifdef SITELOCK_NO_EXPIRY
*pdwLifespan = 0;
::ZeroMemory((void*)pExpiryDate, sizeof(FILETIME));
return E_NOTIMPL;
#else
*pdwLifespan = /*T::*/ dwControlLifespan;
// Calculate expiry date from life span
time_t ttExpire = ImageNtHeaders(&__ImageBase)->FileHeader.TimeDateStamp;
ttExpire += /*T::*/ dwControlLifespan*86400; // seconds per day
UNIXTimeToFILETIME(ttExpire, pExpiryDate);
return S_OK;
#endif
}
bool CYourCtrl::XObjSafe::ControlExpired(DWORD dwExpiresDays /*= dwControlLifespan*/)
{
SYSTEMTIME st = {0};
FILETIME ft = {0};
GetSystemTime(&st);
if (!SystemTimeToFileTime(&st, &ft))
return true;
time_t ttTime = FILETIMEToUNIXTime(&ft);
time_t ttExpire = ImageNtHeaders(&__ImageBase)->FileHeader.TimeDateStamp;
ttExpire += dwExpiresDays*86400;
return (ttTime > ttExpire);
}
bool CYourCtrl::XObjSafe::InApprovedDomain(const IObjectSafetySiteLock::SiteList* rgslTrustedSites /*= rgslTrustedSites*/, int cTrustedSites /*= _countof(rgslTrustedSites)*/)
{
// Retrieve the activation URL
CComBSTR bstrUrl;
DWORD dwZone = URLZONE_UNTRUSTED;
if (!GetOurUrl(bstrUrl, dwZone))
return false;
// Check if the activation URL is in an allowed domain / zone
return FApprovedDomain(bstrUrl, dwZone, rgslTrustedSites, cTrustedSites);
}
bool CYourCtrl::XObjSafe::GetOurUrl(CComBSTR &bstrURL, DWORD &dwZone)
{
METHOD_PROLOGUE(CYourCtrl, ObjSafe)
// Declarations
HRESULT hr = S_OK;
CComPtr<IServiceProvider> spSrvProv;
CComPtr<IInternetSecurityManager> spInetSecMgr;
CComPtr<IWebBrowser2> spWebBrowser;
// Retrieve the activation site
CComPtr<IOleClientSite> spClientSite = pThis->GetClientSite();
if ((FAILED(hr)) || (spClientSite == NULL))
return false;
hr = spClientSite->QueryInterface(IID_IServiceProvider, (void **)&spSrvProv);
if (FAILED(hr))
return false;
// Query the site for a web browser object
hr = spSrvProv->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, (void **)&spWebBrowser);
if (FAILED(hr))
{
// Local declarations
CComPtr<IHTMLDocument2> spDoc;
CComPtr<IOleContainer> spContainer;
// Reinitialize
spSrvProv = NULL;
spClientSite = NULL;
// Get the client site, container, and provider, etc.
spClientSite = pThis->GetClientSite();
if (FAILED(hr) || spClientSite == NULL)
return false;
hr = spClientSite->GetContainer(&spContainer);
if (FAILED(hr))
return false;
hr = spContainer->QueryInterface(IID_IHTMLDocument2, (void **)&spDoc);
if (FAILED(hr))
return false;
if (FAILED(spDoc->get_URL(&bstrURL)))
return false;
hr = spClientSite->QueryInterface(IID_IServiceProvider, (void **)&spSrvProv);
if (FAILED(hr))
return false;
}
else
{
// Query the web browser object for the activation URL
hr = spWebBrowser->get_LocationURL(&bstrURL);
if (FAILED(hr))
return false;
}
// Query the site for its associated security manager
hr = spSrvProv->QueryService(SID_SInternetSecurityManager, IID_IInternetSecurityManager, (void **)&spInetSecMgr);
if (FAILED(hr))
return false;
// Query the security manager for the zone the activation URL belongs to
hr = spInetSecMgr->MapUrlToZone(bstrURL, &dwZone, 0);
if (FAILED(hr))
return false;
return true;
}
bool CYourCtrl::XObjSafe::FApprovedDomain(const OLECHAR * wzUrl, DWORD dwZone, const IObjectSafetySiteLock::SiteList * rgslTrustedSites, int cTrustedSites)
{
// Declarations
HRESULT hr = S_OK;
OLECHAR wzDomain[INTERNET_MAX_HOST_NAME_LENGTH + 1] = {0};
OLECHAR wzScheme[INTERNET_MAX_SCHEME_LENGTH + 1] = {0};
// Retrieve the normalized domain and scheme
hr = GetDomainAndScheme(wzUrl, wzScheme, _countof(wzScheme), wzDomain, _countof(wzDomain));
if (FAILED(hr))
return false;
// Try to match the activation URL with each entry in order
DWORD cbScheme = (::lstrlenW(wzScheme) + 1) * sizeof(OLECHAR);
for (int i=0; i < cTrustedSites; i++)
{
// Try to match by scheme
DWORD cbSiteScheme = (::lstrlenW(rgslTrustedSites[i].szScheme) + 1) * sizeof(OLECHAR);
if (cbScheme != cbSiteScheme)
continue;
if (0 != ::memcmp(wzScheme, rgslTrustedSites[i].szScheme, cbScheme))
continue;
// Try to match by zone
if (rgslTrustedSites[i].szDomain == SITELOCK_INTRANET_ZONE)
{
if ((dwZone == URLZONE_INTRANET) || (dwZone == URLZONE_TRUSTED))
return rgslTrustedSites[i].iAllowType == IObjectSafetySiteLock::SiteList:: Allow;
}
else if (rgslTrustedSites[i].szDomain == SITELOCK_MYCOMPUTER_ZONE)
{
if (dwZone == URLZONE_LOCAL_MACHINE)
return rgslTrustedSites[i].iAllowType == IObjectSafetySiteLock::SiteList:: Allow;
}
else if (rgslTrustedSites[i].szDomain == SITELOCK_TRUSTED_ZONE)
{
if (dwZone == URLZONE_TRUSTED)
return rgslTrustedSites[i].iAllowType == IObjectSafetySiteLock::SiteList:: Allow;
}
// Try to match by domain name
else if (MatchDomains(rgslTrustedSites[i].szDomain, wzDomain))
{
return rgslTrustedSites[i].iAllowType == IObjectSafetySiteLock::SiteList:: Allow;
}
}
return false;
}
HRESULT CYourCtrl::XObjSafe::NormalizeDomain(OLECHAR * wzDomain, int cchDomain)
{
// Data validation
if (!wzDomain)
return E_POINTER;
// If the domain is only 7-bit ASCII, normalization is not required
bool fFoundUnicode = false;
for (const OLECHAR * wz = wzDomain; *wz != 0; wz++)
{
if (0x80 <= *wz)
{
fFoundUnicode = true;
break;
}
}
if (!fFoundUnicode)
return S_OK;
// Construct a fully qualified path to the Windows system directory
static const WCHAR wzNormaliz[] = L"normaliz.dll";
static const int cchNormaliz = _countof(wzNormaliz);
WCHAR wzDllPath[MAX_PATH + 1] = {0};
UINT cchDllPath = ::GetSystemDirectoryW(wzDllPath, _countof(wzDllPath) - cchNormaliz - 1);
if (cchDllPath == 0 || cchDllPath > _countof(wzDllPath) - cchNormaliz - 1)
return E_FAIL;
if (wzDllPath[cchDllPath-1] != L'\\')
wzDllPath[cchDllPath++] = L'\\';
::CopyMemory(wzDllPath + cchDllPath, wzNormaliz, cchNormaliz * sizeof(WCHAR));
// Load the DLL used for domain normalization
HMODULE hNormaliz = ::LoadLibraryExW(wzDllPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (!hNormaliz)
return E_FAIL;
HRESULT hr = E_FAIL;
// Locate the entry point used for domain normalization
PFN_IdnToAscii pfnIdnToAscii = (PFN_IdnToAscii)::GetProcAddress(hNormaliz, "IdnToAscii");
if (!pfnIdnToAscii)
goto cleanup;
// Normalize the domain name
WCHAR wzEncoded[INTERNET_MAX_HOST_NAME_LENGTH + 1] = {0};
int cchEncode = pfnIdnToAscii(IDN_USE_STD3_ASCII_RULES, wzDomain, ::lstrlenW(wzDomain), wzEncoded, _countof(wzEncoded));
if (cchEncode <= 0 || cchEncode >= _countof(wzEncoded))
{
hr = HRESULT_FROM_WIN32(::GetLastError());
goto cleanup;
}
// Copy results to the input buffer
if (cchEncode >= cchDomain)
{
hr = E_OUTOFMEMORY;
goto cleanup;
}
::CopyMemory(wzDomain, wzEncoded, cchEncode * sizeof(WCHAR));
hr = S_OK;
cleanup:
if (hNormaliz)
::CloseHandle(hNormaliz);
return hr;
}
HRESULT CYourCtrl::XObjSafe::GetDomainAndScheme(const OLECHAR * wzUrl, OLECHAR * wzScheme, DWORD cchScheme, OLECHAR* wzDomain, DWORD cchDomain)
{
// Data validation
if (!wzDomain || !wzScheme)
return E_POINTER;
// Extract the scheme
HRESULT hr = ::UrlGetPartW(wzUrl, wzScheme, &cchScheme, URL_PART_SCHEME, 0);
if (FAILED(hr))
return E_FAIL;
// Extract the host name
DWORD cchDomain2 = cchDomain;
hr = ::UrlGetPartW(wzUrl, wzDomain, &cchDomain2, URL_PART_HOSTNAME, 0);
if (FAILED(hr))
*wzDomain = 0;
// Exclude any URL specifying a user name or password
if ((0 == ::_wcsicmp(wzScheme, L"http")) || (0 == ::_wcsicmp(wzScheme, L"https")))
{
DWORD cch = 1;
WCHAR wzTemp[1] = {0};
::UrlGetPartW(wzUrl, wzTemp, &cch, URL_PART_USERNAME, 0);
if (1 < cch)
return E_FAIL;
::UrlGetPartW(wzUrl, wzTemp, &cch, URL_PART_PASSWORD, 0);
if (1 < cch)
return E_FAIL;
}
// Normalize the domain name
return NormalizeDomain(wzDomain, cchDomain);
}
bool CYourCtrl::XObjSafe::MatchDomains(const OLECHAR * wzTrustedDomain, const OLECHAR * wzOurDomain)
{
// Data validation
if (!wzTrustedDomain)
return (0 == *wzOurDomain); // match only if empty
// Declarations
int cchTrusted = ::lstrlenW(wzTrustedDomain);
int cchOur = ::lstrlenW(wzOurDomain);
bool fForcePrefix = false;
bool fDenyPrefix = false;
// Check if all activation URLs should be matched
if (0 == ::wcscmp(wzTrustedDomain, L"*"))
return true;
// Check if the entry is like *. and setup the comparison range
if ((2 < cchTrusted) && (L'*' == wzTrustedDomain[0]) && (L'.' == wzTrustedDomain[1]))
{
fForcePrefix = true;
wzTrustedDomain += 2;
cchTrusted -= 2;
}
// Check if the entry is like = and setup the comparison range
else if ((1 < cchTrusted) && (L'=' == wzTrustedDomain[0]))
{
fDenyPrefix = true;
wzTrustedDomain++;
cchTrusted--;
};
// Check if there is a count mismatch
if (cchTrusted > cchOur)
return false;
// Compare URLs on the desired character range
if (0 != ::memcmp(wzOurDomain + cchOur - cchTrusted, wzTrustedDomain, cchTrusted * sizeof(OLECHAR)))
return false;
// Compare URLs without allowing child domains
if (!fForcePrefix && (cchTrusted == cchOur))
return true;
// Compare URLs requiring child domains
if (!fDenyPrefix && (wzOurDomain[cchOur - cchTrusted - 1] == L'.'))
return true;
return false;
}
Finally, so Google finds this:
sitelock with MFC
IObjectSafetySiteLock with MFC
February 17th, 2010, 03:06 AM
#6
Re: ActiveX and IObjectSafetySiteLock,IObjectWithSite
Thanks guys, I thought I'd chip in too. I had some trouble with the above directions. What I basically did was I followed this codeproject article: http://www.codeproject.com/KB/COM/CompleteActiveX.aspx on creating a simple MFC ActiveX control. I then wanted to use the SiteLock template on that example but had a thrilling time banging my head on the wall for a couple of days. This post really helped. I took your modifed sitelock.h and replaced the one I had and added the code you posted to my h and cpp files.
I found that I needed to add DECLARE_INTERFACE_MAP() (after all the other DECLAREs) to my CYourctrl.h file.
I also changed the following in GetInterfaceSafetyOptions:
// Check expiry and if the activation URL is allowed
if (!ControlExpired() && InApprovedDomain())
{
*pdwSupportedOptions = dwSupportedSafety;
*pdwEnabledOptions = m_dwCurrentSafety;
}
else
{
*pdwSupportedOptions = 0; // Changed from dwSupportedSafety
*pdwEnabledOptions = 0;
}
This way if the site doesn't belong to the approved list, safety will not be supported ( before I did that safety settings were working for both approved and unapproved sites) not sure what the logic with the m_dwCurrentSafety option is.
I've attached the example project I was working on in case somebody else is having as much trouble dealing with this. As I understood from this post, the OleObject route is your only choice when you are working with MFC and the SiteLock template.
Thanks for the effort guys
Attached Files
Posting Permissions
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Rules
Click Here to Expand Forum to Full Width