您的位置:首页 > 其它

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

2012-06-12 14:17 671 查看
本文转自:http://support.microsoft.com/kb/161873/zh-cn

默认状态下,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}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: