科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Internet上用ActiveX发布软件

Internet上用ActiveX发布软件

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

互连网的广泛应用使得基于网络的软件成为现今软件应用的主流......

作者:Micronet 来源:yesky 2007年10月21日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
2.4 使用组件分组管理器确保控件初始化和脚本操作安全性:

  如果一个控件使用组件分组管理器将自己注册为安全,则该控件的注册表入口就包含一个分组关键字,该关键字含一个或者两个子键,其中一个设置控件支持安全性初始化,另一个设置支持安全性脚本操作。安全性初始化子键对应CATID_SafeForInitializing,安全性脚本操作子键对应CATID_SafeForScripting(组件分组子键定义在 Comcat.h 文件,而安全性初始化和脚本操作子键定义在 Objsafe.h 文件)。

  要创建一个组件分组的子键,控件必须实现以下步骤:

  (1)创建一个组件分组管理器实例来接收 ICatRegister 接口的地址;

  (2)设置CATEGORYINFO结构变量;

  (3)调用ICatRegister::RegisterCategories方法,将以上设定的CATEGORYINFO结构变量作为参数传递。
在控件编写时就需添加如下的全局函数:

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;//英语
//确信提供的描述在127个字符以内
int len = wcslen(catDescription);
if (len>127) len = 127;
wcsncpy(catinfo.szDescription,catDescription,len);
//确信描述使用'\0'结束
catinfo.szDescription[len] = '\0';
hr = pcr->RegisterCategories(1,&catinfo);
pcr->Release();
return hr;
}

  当一个子键被创建到需要的分组,控件应该按以下步骤注册到该分组:

  (1)创建一个组件分组管理器实例接收ICatRegister接口地址;

  (2)调用ICatRegister::RegisterClassImplCategories方法,将控件的CLSID和需要的category ID 作为参数传递。

  对应的全局函数为:

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;
}

  ActiveX的注册是在函数DLLRegisterServer中进行的,在组件中 DLLRegisterServer 函数调用了CreateComponentCategory和RegisterCLSIDInCategory函数来保证控件的安全性初始化和脚本操作。所以DLLRegisterServer应添加如下代码:

//注册控件是安全性初始化的
hr=CreateComponentCategory(CATID_SafeForInitializing,L"Controls safely initializable from persistent data!");
if(FAILED(hr))return hr;
CLSID m_clsid;//本控件的的clsid
CLSIDFromString(L"{0F968806-D214-11D5-9022-5254AB123A61}",&m_clsid);
hr=RegisterCLSIDInCategory(m_clsid,CATID_SafeForInitializing);
if(FAILED(hr))return hr;
//注册控件是安全性脚本操作的
hr=CreateComponentCategory(CATID_SafeForScripting,L"Controls safely scriptable!");
if(FAILED(hr))return hr;
hr=RegisterCLSIDInCategory(m_clsid,CATID_SafeForScripting);
if(FAILED(hr))return hr;

  注意,一个创建安全性分组入口到注册表的控件,也应该负责卸载所有分组信息。要卸载一个已经安全性初始化和脚本操作的控件,应该按以下步骤:

  (1)创建一个组件分类管理器实例接收ICatRegister接口地址;

  (2)调用ICatRegister::UnRegisterClassImplCategories方法,将控件的CLSID和必要的category ID作为参数传递。

  对应全局函数如下:

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;
}

  控件卸载时调用的是DLLUnRegisterServer函数,故需在该函数中添加如下代码:

CLSID m_clsid; //本控件的clsid
CLSIDFromString(L"{0F968806-D214-11D5-9022-5254AB123A61}",&m_clsid);
hr=UnRegisterCLSIDInCategory(m_clsid,CATID_SafeForInitializing);
if(FAILED(hr))return hr;
hr=UnRegisterCLSIDInCategory(m_clsid,CATID_SafeForScripting);
if(FAILED(hr))return hr;
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章