如何将 MFC ActiveX 控件标记为安全,脚本和初始化

默认情况下,MFC ActiveX 控件未标记为对脚本编写是安全的和对初始化是安全的。该控件运行在 Internet Explorer 中使用的安全级别设置为中或高时,这一点很明显。在上述这些模式中,控件的数据是不安全或不可能可安全执行脚本以使用该控件,可能会显示警告。
有两个控件可用于消除这些错误的方法。第一个涉及实现 IObjectSafety 接口的控件,可用于来更改它们的行为变得"安全"如果在 Internet 浏览器的上下文中运行的控件。第二步是修改控件的 DllRegisterServer 函数,可在注册表中标记该控件的"安全"。这篇文章讲述这些方法中的第二个。第一种方法,实现 IObjectSafety 接口,Internet 客户端 SDK 中介绍。
请记住控件应仅标记为安全,如果是,事实上,安全。请参考此说明的 Internet 客户端 SDK 文档。请参阅"安全初始化和脚本的 ActiveX 控件"部分下面的组件开发。

注意:本文不介绍如何将控件标记为可安全执行下载。有关代码下载和代码签名的详细信息,请参阅 Internet 客户端 SDK。


请按照以下步骤将 MFC ActiveX 控件标记为已对脚本编写是安全的和对初始化是安全的:
向项目中添加下面的 cathelp.h 和 cathelp.cpp 文件来实现 CreateComponentCategory 和 RegisterCLSIDInCategory 的 helper 函数。
Cathelp.h


#include "comcat.h"


// Helper function to create a component category and associated
// description
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);


// Helper function to register a CLSID as belonging to a component
// category
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);



Cathelp.cpp


#include "comcat.h"


// Helper function to create a component category and associated
// description
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;


    // Make sure the HKCR\Component Categories\{..catid...}
// key is registered
CATEGORYINFO catinfo;
catinfo.catid = catid;
catinfo.lcid = 0x0409 ; // english


// Make sure the provided description is not too long.
// Only copy the first 127 characters if it is
int len = wcslen(catDescription);
if (len>127)
len = 127;
wcsncpy(catinfo.szDescription, catDescription, len);
// Make sure the description is null terminated
catinfo.szDescription[len] = '\0';


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


return hr;
}


// Helper function to register a CLSID as belonging to a component
// category
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
// Register your component categories information.
ICatRegister* pcr = NULL ;
HRESULT hr = S_OK ;
hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
    NULL,
  CLSCTX_INPROC_SERVER,
  IID_ICatRegister,
  (void**)&pcr);
if (SUCCEEDED(hr))
{
// Register this category as being "implemented" by
// the class.
CATID rgcatid[1] ;
rgcatid[0] = catid;
hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
}


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


return hr;
}

修改 DllRegisterServer 标记为安全的控件。在.cpp 文件在项目中找到 DllRegisterServer 的实现。您将需要此.cpp 文件中添加几个方面。包括实现 CreateComponentCategory 和 RegisterCLSIDInCategory 文件:
#include "CatHelp.h"

定义与安全组件类别关联的 GUID:
const CATID CATID_SafeForScripting     =
{0x7dd95801,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};
const CATID CATID_SafeForInitializing  =
{0x7dd95802,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};

定义与您的控件关联的 GUID。为简单起见,您可以贷款从控件的主.cpp 文件中的IMPLEMENT_OLECREATE_EX宏的 GUID。稍微调整格式,以使其类似于以下:
const GUID CDECL BASED_CODE _ctlid =
{ 0x43bd9e45, 0x328f, 0x11d0,
{ 0xa6, 0xb9, 0x0, 0xaa, 0x0, 0xa7, 0xf, 0xc2 } };

若要将控件标记为安全的脚本和初始化,请按如下方式修改 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);


    if (FAILED( CreateComponentCategory(
CATID_SafeForScripting,
L"Controls that are safely scriptable") ))
    return ResultFromScode(SELFREG_E_CLASS);


    if (FAILED( CreateComponentCategory(
CATID_SafeForInitializing,
L"Controls safely initializable from persistent data") ))
    return ResultFromScode(SELFREG_E_CLASS);


    if (FAILED( RegisterCLSIDInCategory(
_ctlid, CATID_SafeForScripting) ))
    return ResultFromScode(SELFREG_E_CLASS);


    if (FAILED( RegisterCLSIDInCategory(
_ctlid, CATID_SafeForInitializing) ))
    return ResultFromScode(SELFREG_E_CLASS);


    return NOERROR;
}

这些原因有两个不正常情况下应修改 DllUnregisterServer 函数:
您不想删除组件类别,因为其他控件可能正在使用它。
虽然没有定义一个 UnRegisterCLSIDInCategory 函数,但默认情况下 DllUnregisterServer 控件的项,从注册表删除完全。因此,从控件的注册删除类别是几乎没有什么用处。
在编译并注册您的控件,会在注册表中找到以下项:
   HKEY_CLASSES_ROOT\Component
   Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}


   HKEY_CLASSES_ROOT\Component
   Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}


   HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented
   Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}


   HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented
   Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值