ActiveX控件实现安全的初始化和脚本


要想创建一个能够在IE中成功加载而没有“不安全”的警告或者错误提示信息的ActiveX控件,我们必须实现安 全的初始化和脚本。基本上,所有要做的工作都是在DllRegisterServer 和DllUnregisterServer这两个函数中完成 的。下面,我们就来一步步地将我们的ActiveX控件变成一个“安全的”控件。

       1. 编辑XXX(此处为控件的工程名).cpp并添加如下的代码。其中,CLSID_SafeItem的值应该跟XXXCtrl.cpp中的IMPLEMENT_OLECREATE_EX一致,这就等同于你的ActiveX控件。同样,它也应该跟你的HTML页面中的OBJECTID标签中的CLSID一致。

       以下是我工程中为实现安全的初始化和脚本添加的代码,可以与原先IDE自动生成的部分做对比查看那些部分是新增的,哪些部分是在创建ActiveX控件时自动生成的代码:

// test.cpp : CtestApp 和 DLL 注册的实现。

#include "stdafx.h"
#include "test.h"
#include "Cathelp.h"

#include <strsafe.h>
#include <ObjSafe.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


CtestApp theApp;

// const GUID CDECL _tlid = { 0x5F4E5259, 0x6B7A, 0x403B, { 0x9E, 0xA4, 0x68, 0xE1, 0x9F, 0x36, 0x5, 0x88 } };
const GUID CDECL BASED_CODE _tlid =
{ 0x5F4E5259, 0x6B7A, 0x403B, { 0x9E, 0xA4, 0x68, 0xE1, 0x9F, 0x36, 0x5, 0x88 } };
const GUID CDECL CLSID_SafeItem =
{ 0xcc5a3762, 0xac6e, 0x406e, {0x97, 0xd8, 0xd2, 0x52, 0xd6, 0xd4, 0x23, 0x35 }};


const WORD _wVerMajor = 1;
const WORD _wVerMinor = 0;






//在CLSID中创建与Component Categories中初始化安全和脚本安全项中相对应的implemented Categories项
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;

}

//注销与CLSID中的相应implemented Categories项,一般用不到,因为其它程序可能也会用到这此项
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))
	{
		CATID rgcatid[1] ;
		rgcatid[0] = catid;
		hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);
	}

	if (pcr != NULL)
		pcr->Release();
	return hr;
}


//创建Component Categories中的初始化安全和脚本安全项
HRESULT CreateComponentCategory(CATID catid, WCHAR* 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;

	// 确认HKCR\Component Categories\{..catid...}键值被注册
	CATEGORYINFO catinfo;
	catinfo.catid = catid;
	catinfo.lcid = 0x0409; // english
	//size_t len;
	// 确认描述不是太长。
	// 只复制开始的127个字符。
	// StringCchLength的第二个参数表示被读入catDescription的最大字符数。
	// 第三个参数表示字符串的长度
	//hr = StringCchLength(catDescription, STRSAFE_MAX_CCH, &len);
	int len = wcslen(catDescription);
	if (SUCCEEDED(hr))
	{
		if (len>127)
		{
			len = 127;
		}
	}   
	else
	{
		// TODO: Write an error handler;
	}

	wcsncpy(catinfo.szDescription, catDescription, len);
	//hr = StringCchCopy(catinfo.szDescription, len + 1, catDescription);
	// 添加字符串结束符.
	//catinfo.szDescription[len + 1] = '\0';
	catinfo.szDescription[len] = '/0';

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

// CtestApp::InitInstance - DLL 初始化

BOOL CtestApp::InitInstance()
{
	BOOL bInit = COleControlModule::InitInstance();

	if (bInit)
	{
		// TODO: 在此添加您自己的模块初始化代码。
	}

	return bInit;
}



// CtestApp::ExitInstance - DLL 终止

int CtestApp::ExitInstance()
{
	// TODO: 在此添加您自己的模块终止代码。

	return COleControlModule::ExitInstance();
}



// DllRegisterServer - 将项添加到系统注册表

STDAPI DllRegisterServer(void)
{
	AFX_MANAGE_STATE(_afxModuleAddrThis);

	if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
		return ResultFromScode(SELFREG_E_TYPELIB);

	if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
		return ResultFromScode(SELFREG_E_CLASS);



	//创建脚本安全“补充”项,非CLSID中
	HRESULT hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!");
	if (FAILED(hr))
		return hr;

	//创建初始化安全“补充”项,非CLSID中
	hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data!");
	if (FAILED(hr))
		return hr;

	//设置控件CLSID中补充项的脚本安全项,与“补充”项中的脚本安全项对应
	hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
	if (FAILED(hr))
		return hr;

	//设置控件CLSID中补充项的初始化安全项,与“补充”项中的初始化安全项对应
	hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
	if (FAILED(hr))
		return hr;

	return NOERROR;

}



// DllUnregisterServer - 将项从系统注册表中移除

STDAPI DllUnregisterServer(void)
{
	AFX_MANAGE_STATE(_afxModuleAddrThis);

	// 删除控件初始化安全入口.
	HRESULT hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
	if (FAILED(hr))
		return hr;

	// 删除控件脚本安全入口
	hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);
	if (FAILED(hr))
		return hr;



	if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
		return ResultFromScode(SELFREG_E_TYPELIB);

	if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
		return ResultFromScode(SELFREG_E_CLASS);




	return NOERROR;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值