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

 解决方案有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 IObjectSafety

BEGIN_INTERFACE_MAP( CRiH_LicenseCtrl, COleControl ) 
	INTERFACE_PART(CRiH_LicenseCtrl, IID_IObjectSafety, ObjSafe) 
END_INTERFACE_MAP()

// IObjectSafety member functions

// Delegate AddRef, Release, QueryInterface

ULONG 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); 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值