`
zhaohaolin
  • 浏览: 1016345 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

使你的ActiveX控件执行时不弹出安全性提示 (转载)

 
阅读更多
使你的ActiveX控件执行时不弹出安全性提示
2010-06-19 19:57

我们编写一个ActiveX控件在IE中运行,一般会弹出一个安全提示,如何避免这种情况?下面是我在参考前人的文章后,总结出“在浏览器中执行时不弹出警告的ActiveX控件”的两种编写方法,予以备忘。注意,这里不会弹出警告是说在执行时不会弹出 ,也就是说已经安装了这个ActiveX控件。如果要下载安装这个ActiveX控件时不会弹出安全警告,恐怕就得去买数字证书了。 不过即使有数字证书,还是得用户同意后才会下载安装。
以下两种方法在WINXP-SP2+VC6下通过。


方法1:修改注册表
可 能你在看完下面的过程后会发现,程序没有一个地方对注册表操作过。其实不然,这里所谓的修改注册表的方法就是使用组件类型管理器(Component Categories Manager)创建一个正确的入口到系统注册表。IE通过检测注册表判断一个控件是否可以安全地初始化和脚本操作。IE会通过调用 ICatInformation::IsClassOfCategories 方法确定控件是否支持给出的安全性分组。其中对注册表的操作都已经封装起来,隐藏在底层了,所以看不到。

必须包括两个头文件

#include <comcat.h>
#include <Objsafe.h>

const GUID CDECL CLSID_SafeItem =
{0xD321B11E, 0x8E79, 0x4829, 0xAB, 0x80, 0x9E, 0x59, 0x92, 0x06, 0xAB, 0xB7};//用你的控件类GUID替换
// 注册组件种类为安全
HRESULT AddCategorySafty(CATID catid, TCHAR* catDescription)
{
    ICatRegister* pcr = NULL ;
    HRESULT hr = S_OK ;

    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
   NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (FAILED(hr))
        return hr;

    CATEGORYINFO catinfo;
    catinfo.catid = catid;
    catinfo.lcid = 0x0409 ; // 英语语言

    // 最长只拷贝127个字符。
    int len = lstrlen(catDescription);
if (len > 127)
{
   len = 127;
}
    lstrcpyn((TCHAR*)(catinfo.szDescription), catDescription, len+1);

    hr = pcr->RegisterCategories(1, &catinfo);
pcr->Release();

    return hr;
}

//移除已经注册为安全的组件种类
HRESULT RemoveCategorySafty(CATID catid)
{
    ICatRegister* pcr = NULL ;
    HRESULT hr = S_OK ;

    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
   NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (FAILED(hr))
        return hr;

    hr = pcr->UnRegisterCategories(1, &catid);
pcr->Release();

    return hr;
}

// 把你的控件注册到已经注册为安全的组件种类
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
    ICatRegister* pcr = NULL ;
    HRESULT hr = S_OK ;
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
   NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (SUCCEEDED(hr))
    {
   CATID rgcatid[1] ;
   rgcatid[0] = catid;
   hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
    }
    if (pcr != NULL)
        pcr->Release();
    return hr;
}
// 把你的控件从安全组件种类移除
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
    ICatRegister* pcr = NULL ;
    HRESULT hr = S_OK ;

    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
   NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (SUCCEEDED(hr))
    {
   // Unregister this category as being "implemented" by the class.
   CATID rgcatid[1] ;
   rgcatid[0] = catid;
   hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);
    }

    if (pcr != NULL)
        pcr->Release();

    return hr;
}

//使你的控件不弹出警告地执行
HRESULT MakeActiveXSafty(REFCLSID clsid)
{
HRESULT hr;

    hr = AddCategorySafty(CATID_SafeForInitializing,
   _T("Controls safely initializable!"));
    if (FAILED(hr))
        return hr;
    hr = RegisterCLSIDInCategory(clsid, CATID_SafeForInitializing);
    if (FAILED(hr))
        return hr;

    hr = AddCategorySafty(CATID_SafeForScripting, _T("Controls safely scriptable!"));
    if (FAILED(hr))
        return hr;
    hr = RegisterCLSIDInCategory(clsid, CATID_SafeForScripting);

return hr;
}

//去除控件的安全执行性
HRESULT UnMakeActiveXSafty(REFCLSID clsid)
{
HRESULT hr;
    hr = UnRegisterCLSIDInCategory(clsid, CATID_SafeForInitializing);
    if (FAILED(hr))
        return hr;
    hr = UnRegisterCLSIDInCategory(clsid, CATID_SafeForScripting);
    if (FAILED(hr))
        return hr;

//下面的代码是把安全组件种类去掉。去掉的话,如果有其他的控件注册为这两个种类
//那么其他的控件执行时就会弹出警告。需不需要下面的代码就见仁见智,看实际情况了
    hr = RemoveCategorySafty(CATID_SafeForInitializing);
    if (FAILED(hr))
        return hr;
    hr = RemoveCategorySafty(CATID_SafeForScripting);

return hr;
}

然后在DllRegisterServer函数的“return NOERROR;”前添加如下代码:

HRESULT hr = MakeActiveXSafty(CLSID_SafeItem);
if (FAILED(hr))
        return hr;

在DllUnregisterServer函数的“AFX_MANAGE_STATE(_afxModuleAddrThis);”后添加如下代码:

HRESULT hr = UnMakeActiveXSafty(CLSID_SafeItem);
if (FAILED(hr))
        OutputDebugString(_T("去除控件的安全执行性时出错!"));

方法2:实现ObjectSafe接口

我创建了一个MFC ActiveX ControlWizard的工程,工程为TestAX,它的控件类是CTestAXCtrl,下面所有的代码和操作都是在这个类的头文件和实现文件中进行。红色的部分是为了实现ObjectSafe接口而增加的代码。

在头文件中:

#if !defined(AFX_TESTAXCTL_H__C2084528_F93E_42D8_A13D_7E38775A0481__INCLUDED_)
#define AFX_TESTAXCTL_H__C2084528_F93E_42D8_A13D_7E38775A0481__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// #include <ComCat.h>
#include <ObjSafe.h>//增加这个头文件

// TestAXCtl.h : Declaration of the CTestAXCtrl ActiveX Control class.

/////////////////////////////////////////////////////////////////////////////
// CTestAXCtrl : See TestAXCtl.cpp for implementation.

class CTestAXCtrl : public COleControl
{
DECLARE_DYNCREATE(CTestAXCtrl)

// Constructor
public:
CTestAXCtrl();

//增加如下代码:
DECLARE_INTERFACE_MAP()
  
BEGIN_INTERFACE_PART(MyObjSafe, IObjectSafety)
STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) (
   REFIID riid,
   DWORD __RPC_FAR *pdwSupportedOptions,
   DWORD __RPC_FAR *pdwEnabledOptions
   );

STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) (
   REFIID riid,
   DWORD dwOptionSetMask,
   DWORD dwEnabledOptions
   );
END_INTERFACE_PART(MyObjSafe);

。。。。。。

在实现文件中:

// TestAXCtl.cpp : Implementation of the CTestAXCtrl ActiveX Control class.

#include "stdafx.h"
#include "testAX.h"
#include "TestAXCtl.h"
#include "TestAXPpg.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


IMPLEMENT_DYNCREATE(CTestAXCtrl, COleControl)

//接口映射
BEGIN_INTERFACE_MAP(CTestAXCtrl, COleControl )
INTERFACE_PART(CTestAXCtrl, IID_IObjectSafety, MyObjSafe)
END_INTERFACE_MAP()

。。。。。。(其他代码省略)

//接口的函数实现
ULONG FAR EXPORT CTestAXCtrl::XMyObjSafe::AddRef()
{
METHOD_PROLOGUE(CTestAXCtrl, MyObjSafe)
return pThis->ExternalAddRef();
}

ULONG FAR EXPORT CTestAXCtrl::XMyObjSafe::Release()
{
METHOD_PROLOGUE(CTestAXCtrl, MyObjSafe)
return pThis->ExternalRelease();
}

HRESULT FAR EXPORT CTestAXCtrl::XMyObjSafe::QueryInterface(REFIID iid, void FAR* FAR* ppvObj)
{
METHOD_PROLOGUE(CTestAXCtrl, MyObjSafe)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}

//调用方法与数据是否可信任,设置这两个标志位就可以了
const DWORD g_dwSupportedBits = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
const DWORD g_dwNotSupportedBits = ~g_dwSupportedBits;

HRESULT FAR EXPORT CTestAXCtrl::XMyObjSafe::GetInterfaceSafetyOptions(REFIID riid,
                   DWORD __RPC_FAR *pdwSupportedOptions,
                   DWORD __RPC_FAR *pdwEnabledOptions)
{
METHOD_PROLOGUE(CTestAXCtrl, MyObjSafe)
*pdwSupportedOptions = *pdwEnabledOptions = g_dwSupportedBits;
return S_OK;
}

HRESULT FAR EXPORT CTestAXCtrl::XMyObjSafe::SetInterfaceSafetyOptions(REFIID riid,
                   DWORD dwOptionSetMask,
                   DWORD dwEnabledOptions)
{
METHOD_PROLOGUE(CTestAXCtrl, MyObjSafe)

//如果有任何一个不支持的设置位,则返回不支持错误。
if (dwOptionSetMask & g_dwNotSupportedBits)
{
   return CO_E_NOT_SUPPORTED;
}
//不需要做其他的事情
return S_OK;
}

详细的接口实现步骤请参考MSDN的《TN038: MFC/OLE IUnknown Implementation》。

分享到:
评论

相关推荐

    ActiveX控件执行时不弹出安全性提示

    本篇文章将深入探讨“ActiveX控件执行时不弹出安全性提示”这一主题,以及如何实现这一功能。 首先,ActiveX控件在执行时通常会弹出安全性提示,这是为了保护用户的系统免受恶意代码的侵害。当用户访问包含ActiveX...

    activex控件在IE中弹出安全警告的解决办法.txt

    在使用Internet Explorer(以下简称IE)浏览器时,用户可能会遇到ActiveX控件弹出的安全警告。这通常发生在试图加载或运行未被信任的ActiveX控件时。这种警告是IE为了保护用户的计算机安全而设置的一项功能。然而,...

    不弹出警告的ActiveX控件的源代码

    在描述中提到的"不弹出警告的ActiveX控件"是指一种特殊设计的控件,它可以在运行时避免向用户显示通常与安全相关的警告对话框。这种控件对于开发人员来说具有一定的价值,因为它可以提供更流畅的用户体验,同时...

    vb写的activex控件不再弹出警告提示

    标题“vb写的activex控件不再弹出警告提示”涉及到的是在Visual Basic(VB)环境中创建ActiveX控件时,如何避免或禁用程序运行时出现的警告提示。ActiveX控件是微软的一种技术,用于创建可重用的软件组件,它们可以...

    在浏览器中不会弹出警告的ActiveX

    通常,当浏览器遇到不熟悉的ActiveX控件时,会弹出警告提示,询问用户是否允许运行。这种做法是为了保护用户免受潜在有害控件的影响。如果一个ActiveX控件能够绕过这个警告机制,那么可能是通过优化签名或利用特定的...

    使用VS2008C#开发ActiveX控件

    5. **实现 IObjectSafety 接口**:为了提高安全性并确保 ActiveX 控件能够在不受信任的环境中运行,控件需要实现 `IObjectSafety` 接口。可以通过添加以下代码来实现: ```csharp [ComVisible(true)] [Guid("59...

    VS2005C#开发ActiveX控件

    在.NET开发环境中,特别是使用C#语言时,开发者可以利用Visual Studio 2005或Visual Studio 2008这样的集成开发环境来创建ActiveX控件。尽管通常ActiveX控件使用C++或VB开发,但本文将探讨如何在VS2008环境下使用C#...

    使用VS2008C_开发ActiveX控件

    为了增强ActiveX控件的安全性,使其能够获取客户端的信任,我们需要让控件实现“IObjectSafety”接口。这一步骤非常重要,因为没有正确的安全声明,控件可能无法在Internet Explorer等浏览器中正确运行。 创建...

    ActiveXforChrome.zip

    ActiveX for Chrome是一款专为谷歌浏览器(Chrome)设计的ActiveX控件,允许用户在Chrome浏览器上运行需要ActiveX技术的网页应用。ActiveX是一种由微软开发的技术,主要用于Internet Explorer,它提供了创建和使用...

    IE加载未签名的ActiveX控件

    1. **安全性考量**:虽然通过以上步骤可以解决未签名ActiveX控件的加载问题,但这也可能带来一定的安全风险。因此,在实际操作中需谨慎对待,尽量仅对可信来源的网站进行此类设置。 2. **版本兼容性**:不同版本的IE...

    OCX控件去除IE安全弹窗

    然而,由于安全考虑,当IE(Internet Explorer)浏览器加载这些控件时,通常会弹出安全警告对话框,询问用户是否允许执行该控件。这可能会对用户的浏览体验造成困扰,特别是对于已知安全且需要频繁使用的OCX控件。本...

    EXCEL表格保存时提示此文档包含宏、ActiveX控件不能保存怎么办.docx

    EXCEL表格保存时提示此文档包含宏、ActiveX控件不能保存怎么办 知识点1: EXCEL表格保存时提示"隐私问题警告" * 在EXCEL表格保存时,可能会弹出对话框,提示"隐私问题警告:此文档中包含宏、ActiveX控件、XML扩展包...

    ActiveX控件无法安装导致监控硬盘录像机不能通过Web方式访问件[归纳].pdf

    4. 在弹出的“安全设置”对话框中,滚动到“活动脚本”和“ActiveX控件和插件”部分。 5. 关于“下载未签名的ActiveX控件”,将其设置为“启用”或“提示”,然后点击“确定”。 6. 重新加载网页,按照提示安装监控...

    发布MFC ActiveX控件并实现自动更新

    ### 发布MFC ActiveX控件并实现自动更新 #### 一、引言 MFC(Microsoft Foundation ...通过以上步骤,可以有效地发布MFC ActiveX控件并实现自动更新,从而提高控件的可用性和安全性,为用户提供更好的服务体验。

    如何在IE浏览器中调用未签名ActiveX控件的设置方法?.docx

    ActiveX 控件在 IE 浏览器中的调用设置方法 在 IE 浏览器中调用未签名 ActiveX 控件是一件需要注意的任务。...调用未签名 ActiveX 控件在 IE 浏览器中需要按照一定的步骤进行,以确保浏览器的安全性和稳定性。

    win7修改浏览器activeX权限(ie内核)

    当尝试安装未签名或不受信任的ActiveX控件时,系统可能会阻止其运行,并弹出“硬盘访问被拒绝”等权限错误提示。解决这个问题的方法通常是通过修改浏览器的安全设置来提高ActiveX控件的权限。 首先,你需要打开...

    基于MFC的ActiveX控件开发(VS2005)

    - 打开VS2005,选择“文件” -&gt; “新建” -&gt; “项目”,在弹出的新建项目对话框中,选择左侧的“Visual C++” -&gt; “MFC”,然后选择右侧的“MFC ActiveX控件”。 - 在下一步中输入解决方案和项目名称,例如项目名...

    解决Win7系统中网页视频看不了提示web浏览器阻止activex控件的方法.docx

    在Windows 7系统中,用户可能会遇到在浏览网页时无法正常播放视频的情况,并收到“Web浏览器阻止ActiveX控件”的提示。这通常是由于浏览器(如Internet Explorer)的安全设置过于严格导致的。本篇文章将详细介绍如何...

    使用vc6创建activeX控件步骤 c++代码

    总的来说,创建一个ActiveX控件涉及多个步骤,包括选择适当的项目模板,添加对象和方法,编写实现代码,以及处理安全性问题。通过以上步骤,你已经掌握了在VC6中创建和使用ActiveX控件的基本流程。记住,为了确保...

Global site tag (gtag.js) - Google Analytics