关闭

添加IObjectSafety接口使MFC写的OCX可信

标签: mfc安全控件OCX
521人阅读 评论(0) 收藏 举报
分类:

感谢此篇博客。找了很久没有找到IObjectSafety需要添加哪些代码,这篇代码很详细。
MFC OCX控件实现安全初始化和脚本安全的方法

原文有两个方法,我更推荐用IObjectSafety,原博客的代码不太好看,我这里整理一下。
我的环境是VS2013,用模板生成的项目包含的文件基本相同,不构成影响。一般如下结构:
模板

假定我们用模板生成的项目名叫[TestOCX],所以马赛克部分应该都是TestOCX。相应的,本文涉及的两个文件分别为TestOCXCtrl.h和TestOCXCtrl.cpp。 如果需要,则请将代码中的TestOCXCtrl替换成各位自己的名字。

  1. TestOCXCtrl.h中添加如下代码
#include <objsafe.h> // for IObjectSafety; in ActiveX SDK

这个代码是实现IObjectSafety的前提。

  1. 依然是在TestOCXCtrl.h中,一般在类的构造函数前有一行
DECLARE_DYNCREATE(CTestOCXCtrl)

在这行代码前添加如下代码:


#pragma region objsafe
//*******************************************************add begin
    //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
//*******************************************************add end

#pragma endregion

加上#pragma region objsafe只是因为方便折叠…

  1. TestOCXCtrl.cpp中,注意替换下述代码中所有CTestOCXCtrl为自己控件的名称。需要添加的有几个位置
    (1)消息映射内添加如下代码
BEGIN_MESSAGE_MAP(CTestOCXCtrl, COleControl)
    //下面是要添加的
    //{{AFX_MSG_MAP(CTestOCXCtrl)
    // NOTE - ClassWizard will add and remove message map entries
    //    DO NOT EDIT what you see in these blocks of generated code !
    //}}AFX_MSG_MAP
    ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
    //添加结束
END_MESSAGE_MAP()

(2)紧跟其后如果没有接口映射的话,下述代码完整添加;否则添加到接口映射内即可

//*******************************************************add begin
BEGIN_INTERFACE_MAP(CTestOCXCtrl, COleControl)
    INTERFACE_PART(CTestOCXCtrl, IID_IObjectSafety, ObjSafe)
END_INTERFACE_MAP()
//*******************************************************add end

(3)在文件末尾完整复制粘贴如下代码

增加IObjectSafety接口实现方法
////***************************************************************add begin

// IObjectSafety member functions

// Delegate AddRef, Release, QueryInterface

ULONG FAR EXPORT CTestOCXCtrl::XObjSafe::AddRef()

{

    METHOD_PROLOGUE(CTestOCXCtrl, ObjSafe)

    return pThis->ExternalAddRef();

}

ULONG FAR EXPORT CTestOCXCtrl::XObjSafe::Release()

{

    METHOD_PROLOGUE(CTestOCXCtrl, ObjSafe)

    return pThis->ExternalRelease();

}

HRESULT FAR EXPORT CTestOCXCtrl::XObjSafe::QueryInterface(REFIID iid, void FAR* FAR* ppvObj)

{

    METHOD_PROLOGUE(CTestOCXCtrl, 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 

CTestOCXCtrl::XObjSafe::GetInterfaceSafetyOptions( 

 /* [in] */ REFIID riid,

 /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,

 /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)

{

    METHOD_PROLOGUE(CTestOCXCtrl, 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 
CTestOCXCtrl::XObjSafe::SetInterfaceSafetyOptions(

 /* [in] */ REFIID riid,

 /* [in] */ DWORD dwOptionSetMask,

 /* [in] */ DWORD dwEnabledOptions)

{

    METHOD_PROLOGUE(CTestOCXCtrl, 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);
}

//***************************************************************add end

完成上述步骤之后,编译,在HTML中添加

<!-- saved from url=(0017)http://localhost/ -->

应该就不会弹出安全警告了。

0
0
查看评论

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

转自:http://www.cnblogs.com/carekee/articles/1772201.html ActiveX控件打包成cab后,在脚本中调用中时,要保证控件的安全性才能在你的网页上安全运行,有两种方法来实现这一保证:实现一个名称为IObjectSafe的接口到你的控件...
  • rankun1
  • rankun1
  • 2016-06-22 17:29
  • 1437

再谈IObjectSafety

都说ActiveX危险,那么为什么XmlHttpRequest以及MediaPlayer都是用ActiveX的方式创建的,却没有问题?原来,这是因为这些ActiveX组件都声明自己是脚本安全的,而IE的中级安全设置上,是允许脚本安全的ActiveX创建,并且不予警告的。IE怎么知道一个插件是脚本安全...
  • optman
  • optman
  • 2007-07-18 22:39
  • 18035

ATL 实现IObjectSafety 接口

如果com组件要在IE中进行调用,则必须实现IObjectSafety接口,不然在ie中必须调整activex选项才可以正常运行,如下是实现IObjectSafety的例子:#include //////////////////////////////
  • sstower
  • sstower
  • 2011-07-05 21:39
  • 3427

ActiveX ocx控件有时在网页中无法显示需要实现IObjectSafety接口

ActiveX ocx控件有时在网页中无法显示需要实现IObjectSafety接口 通过自己调试,可能导致的原因是:          如果没有实现IobjectSafety接口浏览器交互不安全...
  • caijun12358098
  • caijun12358098
  • 2012-03-06 08:53
  • 2683

ActiveX学习笔记二 ActiveX在IE中安全级别问题-实现IObjectSafety接口

使用MFC开发ActiveX控件,在IE中会提示安全问题,这个可以通过实现IObjectSafety接口来解决问题1.首先要包含头文件#include 2.然后在你的ActiveX头文件中添加DECLARE_INTERFACE_MAP()BEGIN_INTERFACE_PART(ObjSafe, I...
  • freedomqx
  • freedomqx
  • 2009-12-07 11:38
  • 3249

MFC 对话框中动态加载OCX控件

以前在MFC中创建OCX控件后,再到对话框中加载用的都是看似简单但实际上最麻烦的办法:  那是就是在对话框上右键->insert ActiveX control...,然后给插入的控件绑定一个变量,这时候MFC会自动生成一个对应的类,然后调用方法,相应事件都很简单。 但是如果这个...
  • yumulinxiang
  • yumulinxiang
  • 2017-10-29 15:42
  • 273

vs2010开发activex(MFC)控件/ie插件(三),js调用ocx控件的接口函数

vs2010开发activex(MFC)控件/ie插件(三),js调用ocx控件的接口函数      js调用ocx控件的接口函数,先看demo效果:      简单测试过程:两个数相加。      测试插件加...
  • yhhyhhyhhyhh
  • yhhyhhyhhyhh
  • 2016-03-04 14:30
  • 4867

创建添加对话框的Activex

1.ActiveX的基本概念          ActiveX控件可以看作是一个极小的服务器应用程序,它不能独立运行,必须嵌入到某个容器程序中,与该容器一起运行。这个容器包括WEB网页,应用程序窗体等。。。 ...
  • wangzhiyang925
  • wangzhiyang925
  • 2014-08-20 23:10
  • 2265

ActiveX(MFC)控件——添加接口及WEB调用

上一节实现了控件在页面中的加载及界面显示,这一节开始在上一节的基础上添加接口供WEB调用。 手动在CMainDlg.h中添加一方法: public:          LONG SetParam(LPCT...
  • z526882183
  • z526882183
  • 2016-04-14 19:29
  • 1225

Ocx 控件添加函数接口,注册控件

MFC Ocx 控件添加函数接口 注册控件 注销控件
  • Acheld
  • Acheld
  • 2016-03-21 22:56
  • 861
    个人资料
    • 访问:46283次
    • 积分:517
    • 等级:
    • 排名:千里之外
    • 原创:17篇
    • 转载:1篇
    • 译文:0篇
    • 评论:2条
    文章分类
    最新评论