我們在編寫ActiveX控件時,如果用在瀏覽器中,經常都會彈出現在運行的腳本不安全的提示, 如果給客戶使用,將會帶來極大不便。按照MSDN的介紹通常有兩種一種是實現IObjectSafe接口,一種是通過修改註冊表的方法。一般如果用ATL開發ActiveX控件,就用實現ObjectSafe接口的方法。如果用MFC開發,我覺得還是用修改註冊表的方法比較方便。下面我們將第二種方法:
要包括兩個文件
#include "comcat.h" #include "Objsafe.h"
// 本控件的CLSID,註冊表用
const GUID CDECL CLSID_SafeItem = { 0x7AE7497B, 0xCAD8, 0x4E66, { 0xA5,0x8B,0xDD,0xE9,0xBC,0xAF,0x6B,0x61 } };
// 創建組件種類
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; }
// 註冊組件種類
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(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; }
// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void) { HRESULT hr; AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid)) return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE)) return ResultFromScode(SELFREG_E_CLASS); // 標記控件初始化安全. // 創建初始化安全組件種類 hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data!"); if (FAILED(hr)) return hr; // 註冊初始化安全 hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing); if (FAILED(hr)) return hr; // 標記控件腳本安全 // 創建腳本安全組件種類 hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!"); if (FAILED(hr)) return hr; // 註冊腳本安全組件種類 hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting); if (FAILED(hr)) return hr; return NOERROR; }
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void) { HRESULT hr; AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor)) return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE)) return ResultFromScode(SELFREG_E_CLASS); // 刪除控件初始化安全入口. hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing); if (FAILED(hr)) return hr; // 刪除控件腳本安全入口 hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting); if (FAILED(hr)) return hr; ////////////////////////// return NOERROR; }
(全文完)
如果在本地使用ocx,那麼需要人工註冊,這種情況下您自己完全可以控制ocx的安全,如果想用,那麼您就認爲他是安全的了。
如果在internet上用,則一定要數字簽名,所以控件的安全由數字簽名來保證! ( rainsoft 發表於 2003-7-2 16:49:00)
如果說實現了這個接口就不會出提示,那麼不是想做什麼都可以,可以隨意控制客戶端的機器?邏輯上是可能的嗎? ( zerochang 發表於 2003-7-1 11:31:00)
這個好像不好用呀。沒有註冊過的機器不行。我試了。
那位可以的可以給我個例子嗎?[email protected]
我再想如果,真的可以隱式下載,那WIN系統豈不是很不安全了嗎?如何去控制惡意代碼?暈!!! ( lrcstar 發表於 2003-6-30 21:34:00)
希望樓主總結一下他們的觀點。 ( sander 發表於 2003-6-28 19:28:00)
不加入數字簽名,IE會禁止下載,
那樣只能夠保證下載後在本機執行時不彈出
警告。
實現IObjectSafet接口
添加到類別:
BEGIN_CATEGORY_MAP(Cctrl)
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
END_CATEGORY_MAP() ( xwtwho 發表於 2003-6-27 14:11:00)
就話新說。。。。 ( zfive5 發表於 2003-6-27 13:06:00)
我在一本實例書上看見過,好象不買證書籤名還是不行的 ( peterlcm 發表於 2003-6-27 10:56:00)
控件下載前代碼不會被執行
需要在控件中實現IObjectSafety接口
在網上搜索一下就行了 ( 家寶 發表於 2003-6-27 10:44:00)
呵呵,偶前兩天爲這個問題困擾,才做過。方法一樣,不過我的註冊和卸載函數在BOOL CGraphView2ZTCtrl::CGraphView2ZTCtrlFactory::UpdateRegistry(BOOL bRegister)裏面添加的,效果一樣,不會有安全提示,^_^ ( warmchang 發表於 2003-6-27 9:32:00)