MFC ActiveX Control在WEB页面中的安全应用

来源:互联网 发布:上海mac口红专柜 编辑:程序博客网 时间:2024/05/18 22:55
 解决方案有2种:

1、OCX注册同时注册安全入口

2、实现安全接口IObjectSafety

 

1、OCX注册同时注册安全入口

  • 修改注册接口
STDAPI DllRegisterServer(void){AFX_MANAGE_STATE(_afxModuleAddrThis);HRESULT hr;// 标记控件初始化安全.// 创建初始化安全组件种类hr = CreateComponentCategory(CATID_SafeForInitializing, L"RIH_License safely initializable from persistent data!");if (FAILED(hr)){return E_FAIL;}// 注册初始化安全hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);if (FAILED(hr)){return E_FAIL;}// 标记控件脚本安全// 创建脚本安全组件种类hr = CreateComponentCategory(CATID_SafeForScripting, L"RIH_License safely scriptable!");if (FAILED(hr)){return E_FAIL;}// 注册脚本安全组件种类hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);if (FAILED(hr)){return E_FAIL;}if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))return ResultFromScode(SELFREG_E_TYPELIB);if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))return ResultFromScode(SELFREG_E_CLASS);return NOERROR;}// DllUnregisterServer - 将项从系统注册表中移除STDAPI DllUnregisterServer(void){AFX_MANAGE_STATE(_afxModuleAddrThis);HRESULT hr;// 删除控件初始化安全入口.hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);if (FAILED(hr))return E_FAIL;// 删除控件脚本安全入口hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);if (FAILED(hr))return E_FAIL;if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))return ResultFromScode(SELFREG_E_TYPELIB);if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))return ResultFromScode(SELFREG_E_CLASS);return NOERROR;} 


  • 其中具体函数
// 创建组件种类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;}

 

2、实现安全接口IObjectSafety

  • 在***Ctrl.h中添加头文件 #include "objsafe.h"
  • 在类声明中添加如下代码
class CRiH_LicenseCtrl : public COleControl{DECLARE_DYNCREATE(CRiH_LicenseCtrl)DECLARE_INTERFACE_MAP()BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety) STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) ( /* [in] */ REFIID riid, /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions, /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions ); STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) ( /* [in] */ REFIID riid, /* [in] */ DWORD dwOptionSetMask, /* [in] */ DWORD dwEnabledOptions ); END_INTERFACE_PART(ObjSafe);// 构造函数public:CRiH_LicenseCtrl();......}
  • 在***Ctrl.cpp 中添加代码
// Interface map for IObjectSafetyBEGIN_INTERFACE_MAP( CRiH_LicenseCtrl, COleControl ) INTERFACE_PART(CRiH_LicenseCtrl, IID_IObjectSafety, ObjSafe) END_INTERFACE_MAP()// IObjectSafety member functions// Delegate AddRef, Release, QueryInterfaceULONG FAR EXPORT CRiH_LicenseCtrl::XObjSafe::AddRef() { METHOD_PROLOGUE(CRiH_LicenseCtrl, ObjSafe) return pThis->ExternalAddRef(); }ULONG FAR EXPORT CRiH_LicenseCtrl::XObjSafe::Release() { METHOD_PROLOGUE(CRiH_LicenseCtrl, ObjSafe) return pThis->ExternalRelease(); }HRESULT FAR EXPORT CRiH_LicenseCtrl::XObjSafe::QueryInterface( REFIID iid, void FAR* FAR* ppvObj) { METHOD_PROLOGUE(CRiH_LicenseCtrl, ObjSafe) return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); }const DWORD dwSupportedBits = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; const DWORD dwNotSupportedBits = ~ dwSupportedBits; ///////////////////////////////////////////////////////////////////////////// // CStopLiteCtrl::XObjSafe::GetInterfaceSafetyOptions // Allows container to query what interfaces are safe for what. We're // optimizing significantly by ignoring which interface the caller is // asking for. HRESULT STDMETHODCALLTYPE CRiH_LicenseCtrl::XObjSafe::GetInterfaceSafetyOptions( /* [in] */ REFIID riid, /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions, /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions) { METHOD_PROLOGUE(CRiH_LicenseCtrl, ObjSafe)HRESULT retval = ResultFromScode(S_OK);// does interface exist? IUnknown FAR* punkInterface; retval = pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface); if (retval != E_NOINTERFACE) { // interface exists punkInterface->Release(); // release it--just checking! } // we support both kinds of safety and have always both set, // regardless of interface *pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits;return retval; // E_NOINTERFACE if QI failed }///////////////////////////////////////////////////////////////////////////// // CStopLiteCtrl::XObjSafe::SetInterfaceSafetyOptions // Since we're always safe, this is a no-brainer--but we do check to make // sure the interface requested exists and that the options we're asked to // set exist and are set on (we don't support unsafe mode). HRESULT STDMETHODCALLTYPE CRiH_LicenseCtrl::XObjSafe::SetInterfaceSafetyOptions( /* [in] */ REFIID riid, /* [in] */ DWORD dwOptionSetMask, /* [in] */ DWORD dwEnabledOptions) { METHOD_PROLOGUE(CRiH_LicenseCtrl, ObjSafe) // does interface exist? IUnknown FAR* punkInterface; pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface); if (punkInterface) { // interface exists punkInterface->Release(); // release it--just checking! } else { // interface doesn't exist return ResultFromScode(E_NOINTERFACE); }// can't set bits we don't support if (dwOptionSetMask & dwNotSupportedBits) { return ResultFromScode(E_FAIL); } // can't set bits we do support to zero dwEnabledOptions &= dwSupportedBits; // (we already know there are no extra bits in mask ) if ((dwOptionSetMask & dwEnabledOptions) != dwOptionSetMask) { return ResultFromScode(E_FAIL); }        // don't need to change anything since we're always safe return ResultFromScode(S_OK); }