ActiveX控件如何标记控件为安全(摘抄)
2011-10-24 01:11
344 查看
ActiveX控件如何标记控件为安全(摘抄)
博客分类:基础知识
MFCIE.netBlogMicrosoft
原文:http://blog.csdn.net/xiaoqiangXX/archive/2009/08/04/4408650.aspx
因项目需要,我们采用了ActiveX的方式开发了一个嵌入到页面的小程序,可以实现对多文件的上传。因为还不能支持断点续传所以只支持小文件的传输,但是能一次传输多个小文件对于邮件方面的应用也是很方便的。而且有进度条显示这也给了用户较好的提示。同时我们支持拖入功能,用户可以直接将文件拖入到控件中,即完成对上传文件的选取。
下面对开发中遇到的一些问题进行说明,全文基本为原创,其中参考了很多他人的经验和资料,参考处我会注明原出处。
第一个问题如何标记控件为安全
控件发布第一步如何将控件标记为安全的。如果不将控件标记为安全,浏览器将会web页面与控件交互时提示如下信息:
MSDN上对这的解释是:默认,MFC ActiveX控件不被标记为可安全编写脚本和可安全初始化。当IE运行安全级别设置为中等或高时,都回提示控件不安全。
消除提示有两种办法,The first method uses the Component Categories Manager to create the appropriate entries in the system registry.即修改控件的DllRegisterServer函数来,在注册表中标记控件为安全的。The second method implements an interface named IObjectSafety on your control.第二种方法可以详见
http://dcs.isa.ru/www/vladimirv/inetsdk/inet0002.htm。
这里就第一种方法进行说明,在MSDN上也有第一种方法的详细说明。网址:
http://support.microsoft.com/kb/161873/zh-cn
但是该方法有一些不足,这里结合Phinecos(洞庭散人)的blog
(/article/4620025.html)进行说明。
1.添加辅助函数
控件的基本结构中含有xxApp,xxCtrl,xxPropPage三个类。找到xxApp的头文件,添加三个辅助函数。
// 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); // Helper function to unregister a CLSID as belonging to a component // category HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid); 找到xxApp的实现文件,添加三个辅助函数的实现。 // 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; } // HRESULT UnRegisterCLSIDInCategory - Remove entries from the registry 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)) { // Unregister this category as being "implemented" by the class. CATID rgcatid[1] ; rgcatid[0] = catid; hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid); } if (pcr != NULL) pcr->Release(); return hr; }
2.定义GUID
需要定义两个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。
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} 同时需要定义要注册为安全的CLSID。
控件有四个UUID,这里我们需要将xxCtrl的UUID注册成为安全的CLSID,因为我们控件的主体功能是在这个类中实现的。
const GUID CDECL BASED_CODE _tlid = { 0x7DE84B6C, 0x9969, 0x4DE0, { 0xBE, 0x25, 0xC6, 0xC0, 0x63, 0x20, 0xA3, 0x70 } }; const WORD _wVerMajor = 1; const WORD _wVerMinor = 0; const CATID CLSID_SafeItem = {0x4e586c5a, 0xfd41, 0x4e4c, {0xb6, 0x6d, 0x63, 0xf1, 0x10, 0xc8, 0xc4, 0xb9}}; 这里的CLSID_SafeItem就是xxCtrl的UUID。
3.修改注册代码
// DllRegisterServer - 将项添加到系统注册表 STDAPI DllRegisterServer(void) { /*这里是原来的注册代码 OLD AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid)) return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE)) return ResultFromScode(SELFREG_E_CLASS); return NOERROR;*/ //NEW下面是新的注册代码 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( CLSID_SafeItem, CATID_SafeForScripting) )) return ResultFromScode(SELFREG_E_CLASS); if (FAILED( RegisterCLSIDInCategory( CLSID_SafeItem, CATID_SafeForInitializing) )) return ResultFromScode(SELFREG_E_CLASS); return NOERROR; } // DllUnregisterServer - 将项从系统注册表中移除 STDAPI DllUnregisterServer(void) { /* OLD这里是原来的代码 AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor)) return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE)) return ResultFromScode(SELFREG_E_CLASS); return NOERROR;*/ //NEW下面是新的代码 HRESULT hr; AFX_MANAGE_STATE(_afxModuleAddrThis); // Remove entries from the registry. 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; }
到此完成了控件的安全标记。
相关文章推荐
- ActiveX控件开发的一些问题一,如何标记控件为安全
- ActiveX控件开发的一些问题一,如何标记控件为安全
- ActiveX控件如何标记控件为安全(Safe Initialization and Scripting for ActiveX Controls)
- 如何将MFC ActiveX 控件标记为可安全编写脚本和初始化
- 如何将 MFC ActiveX 控件标记为脚本和初始化安全
- \t\t用C#编写ActiveX控件 自定义html控件 ActiveX 控件注册 标记Activex控件为脚本安全
- 如何将标记为可安全编写脚本和初始化的 MFC ActiveX 控件
- 如何将MFC ActiveX 控件标记为可安全编写脚本和初始化
- 如何将标记为可安全编写脚本和初始化的 MFC ActiveX 控件 (转)
- 如何标记为安全 MFCActiveX 控件对于脚本和初始化
- 如何标记为安全 MFCActiveX 控件对于脚本和初始化
- 使用MFC开发ActiveX控件时修改注册表来标记控件为安全
- 必须要实现IObjectSafety接口,把ActiveX控件标记为安全的ActiveX控件,可以不这样做的。可以把控件注册一下就可以了
- 如何将 MFC ActiveX 控件作为安全标记为脚本和初始化
- 如何将MFC ActiveX控件标记为安全
- 如何将 MFC ActiveX 控件作为安全标记为脚本和初始化
- C# Winform项目中多线程环境下, 如何跨线程对Window窗体控件进行安全访问?
- 如何下载被标记为不安全的文件?
- Win8中标记为不安全的文件如何强制下载
- web上面开发安全控件使用Activex控件