[转]ActiveX控件安全初始化之一:实现ISafeObject接口

时间:2022-06-12 21:01:29

【转】自http://www.cnblogs.com/carekee/articles/1772201.html 
ActiveX控件安全初始化之一:实现ISafeObject接口

ActiveX控件打包成cab后,在脚本中调用中时,要保证控件的安全性才能在你的网页上安全运行,有两种方法来实现这一保证:实现一个名称为IObjectSafe的接口到你的控件。如果IE发现你的控件支持IObjectSafety,它调用 IObjectSafety::SetInterfaceSafetyOptions 方法然后才载入你的控件。另外一种方法需要修改注册表,我将会在另外一篇文章中详细介绍。

1。创建了一个叫做“tryISafeObject.ocx”的MFC ActiveX控件。

2。在tryISafeObjectCtrl.h中定义ISafeObject接口:

#include <objsafe.h> // for IObjectSafety; in ActiveX SDK

class CtryISafeObjectCtrl : public COleControl
{

 DECLARE_DYNCREATE(CtryISafeObjectCtrl)
//........................................................................
//ISafeObject
 DECLARE_INTERFACE_MAP()

 BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)
  STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) ( 
            /* [in] */ REFIID riid,
            /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
            /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions
  );
        
        STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) ( 
            /* [in] */ REFIID riid,
            /* [in] */ DWORD dwOptionSetMask,
            /* [in] */ DWORD dwEnabledOptions
  );
 END_INTERFACE_PART(ObjSafe);

//ISafeObject
//........................................................................

。。。。。

};

在objsafe.h头文件中有ISafeObject接口的相关定义

3。在tryISafeObjectCtrl.cpp中ISafeObject接口的相关实现:

//.............................................................................
// Interface map for IObjectSafety

BEGIN_INTERFACE_MAP( CtryISafeObjectCtrl, COleControl )
 INTERFACE_PART(CtryISafeObjectCtrl, IID_IObjectSafety, ObjSafe)
END_INTERFACE_MAP()

//.............................................................................
// IObjectSafety member functions

// Delegate AddRef, Release, QueryInterface

ULONG FAR EXPORT CtryISafeObjectCtrl::XObjSafe::AddRef()
{
    METHOD_PROLOGUE(CtryISafeObjectCtrl, ObjSafe)
    return pThis->ExternalAddRef();
}

ULONG FAR EXPORT CtryISafeObjectCtrl::XObjSafe::Release()
{
    METHOD_PROLOGUE(CtryISafeObjectCtrl, ObjSafe)
    return pThis->ExternalRelease();
}

HRESULT FAR EXPORT CtryISafeObjectCtrl::XObjSafe::QueryInterface(
    REFIID iid, void FAR* FAR* ppvObj)
{
    METHOD_PROLOGUE(CtryISafeObjectCtrl, ObjSafe)
    return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}

const DWORD dwSupportedBits = 
  INTERFACESAFE_FOR_UNTRUSTED_CALLER |
  INTERFACESAFE_FOR_UNTRUSTED_DATA;
const DWORD dwNotSupportedBits = ~ dwSupportedBits;

//.............................................................................
// CStopLiteCtrl::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 
 CtryISafeObjectCtrl::XObjSafe::GetInterfaceSafetyOptions( 
  /* [in] */ REFIID riid,
        /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
        /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
{
 METHOD_PROLOGUE(CtryISafeObjectCtrl, 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 
 CtryISafeObjectCtrl::XObjSafe::SetInterfaceSafetyOptions( 
        /* [in] */ REFIID riid,
        /* [in] */ DWORD dwOptionSetMask,
        /* [in] */ DWORD dwEnabledOptions)
{
    METHOD_PROLOGUE(CtryISafeObjectCtrl, 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);
}