使你的ActiveX控件执行时不弹出安全性提示(转载)
我们编写一个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 > )
{
len = ;
}
lstrcpyn((TCHAR*)(catinfo.szDescription), catDescription, len+); hr = pcr->RegisterCategories(, &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(, &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[] ;
rgcatid[] = catid;
hr = pcr->RegisterClassImplCategories(clsid, , 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[] ;
rgcatid[] = catid;
hr = pcr->UnRegisterClassImplCategories(clsid, , 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控件卸载时出现"DllUnregisterServer函数出错,错误代码:0x80070002"问题解决
已安全化的ActiveX控件卸载时出现"DllUnregisterServer函数出错,错误代码:0x80070002"问题解决 情况一:当该控件未注册或者已经卸载时,你尝试卸 ...
- 配置Info.plist (设置状态栏样式、自定义定位时系统弹出的提示语、配置3DTouch应用快捷菜单)
一.概述 iOS中很多功能需要配置Info.plist才能实现,如设置后台运行.支持打开的文件类型.自定义访问隐私内容时弹出的提示等.了解Info.plist中各字段及其含义,可以访问苹果开发网站相关 ...
- android中RecyclerView控件实现长按弹出PopupMenu菜单功能
之前写过一篇文章:android中实现简单的聊天功能 现在是在之前功能的基础上,添加一个长按聊天记录,删除对应聊天记录的功能 RecyclerView控件,没有对应的长按事件,我们需要自己手工添加,修 ...
- 自己写个activex控件,如何知道他的classid(转载)
在网页里用的时候需要知道他的classid我在代码中看到有 const GUID CDECL BASED_CODE _tlid = { 0x89201950, 0x2CAC, 0x4CF7, { 0x ...
- VC6.0 MFC中WebBrowser控件禁止新窗口弹出的解决办法
http://blog.csdn.net/gnorth/article/details/7258293 分类: WebBrowser MFC 禁止新窗口2012-02-14 15:25 1787人阅读 ...
- VB动态添加WebBrowser控件,并拦截弹出窗口(不用引用任何组件)
新建空白窗体,然后粘帖下面代码: Option ExplicitPublic WithEvents br As VBControlExtender Private Sub br_ObjectEvent ...
- jqgrid 获取远端数据失败时,弹出错误提示
有时,我们给jqgrid绑定的远端数据获取失败,此时,需要把错误信息反馈给用户展示,如何实现? 可通过jqgrid的 loadError 来处理错误数据的返回.详细如下: $("#jqGri ...
- Xcode调试项目时取消弹出框提示授权
问题2: instruments wants permission to analyze other processes.'DTServiceHub'需要控制另外一个进程,以便继续调试,键入密码以允许 ...
- 解决IE打开时,弹出的提示调用active的问题,阻止js运行。
在html和head中间加上: <!-- saved from url=(0014)about:internet -->
随机推荐
- Java并发编程:深入剖析ThreadLocal (总结)
ThreadLocal好处 Java并发编程的艺术解释好处是:get和set方法的调用可以不用在同一个方法或者同一个类中. 问答形式总结: 1. ThreadLocal类的作用 ThreadLocal ...
- CAP理论-解析
分布式系统的CAP理论:理论首先把分布式系统中的三个特性进行了如下归纳:● 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值.(等同于所有节点访问同一份最新的数据副本) ...
- 软件项目技术点(9)——如何将gif动态图拆分绘制
AxeSlide软件项目梳理 canvas绘图系列知识点整理 背景介绍 我们的软件支持插入gif图片,并且展示在软件里是动态的,例如插入下面这张gif图. 在软件里显示的同样是这样的动态效果: 那 ...
- spring org.springframework.web.bind.annotation 常用注解
开发中常用的注解记录,查缺补漏 Request注解 @RequestBody @RequestHeader @RequestMapping @RequestParam @RequestPart @Co ...
- Git连接GitLab远程仓库
1.简介 远程仓库是指托管在网络上的项目仓库,现在互联网上有很多项目托管平台,比如github.gitlab等.为了不公开自己项目代码,可以在自己的服务器上搭建自己的项目仓库,最常见的是搭建GitLa ...
- Re-thinking Deep Residual Networks
本文是对ImageNet 2015的冠军ResNet(Deep Residual Networks)以及目前围绕ResNet这个工作研究者后续所发论文的总结,主要涉及到下面5篇论文. 1. Link: ...
- IDEA maven 多项目 出现 java 程序包找不到
使用idea 多项目引入的时候,出现报错信息:Error java程序包找不到 解决办法: 我在引入多个项目的时候,他们是在一个目录里面的.我把整个目录引入了进去.结果报依赖包找不到. 把引入的全部项 ...
- Hadoop学习---Hadoop的深入学习
Hadoop生态圈 存储数据HDFS(Hadoop Distributed File System),运行在通用硬件上的分布式文件系统.具有高度容错性.高吞吐量的的特点. 处理数据MapReduce, ...
- CVE-2014-0321漏洞成因分析
1. 简介 最近在补之前落下的想学的东西,古河之前已经在微薄里面公布了此漏洞的poc及利用思路,不过在看古河的文章前我先独立分析一下其漏洞成因,记录下自己的分析流程. 2. 实验环境 操作系统:Win ...
- 对EJB的认识
对EJB的认识 接触EJB以来有一段时间了,走马观花一样把它所涉及到的东西看了一遍,随着深入了解越来越感觉到ejb的很强大,用了java后觉的java好用.学历SSH觉的比java好用.学了ejb觉的 ...