设为首页 加入收藏

TOP

Internet上用ActiveX发布软件(四)
2012-11-04 15:27:05 来源: 作者: 【 】 浏览:661
Tags:Internet 上用 ActiveX 发布 软件
  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;

首页 上一页 1 2 3 4 下一页 尾页 4/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇VC++中使用内存映射文件处理大文件 下一篇WinSock网络通信程序设计入门

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: