如何做一个标记为安全的ACTIVEX控件

使用MFC做控件时,放到网页上,时常会跳出来安全提示,或者禁止ACTIVEX操作,或者提示:"末标记为安全的控件操作"

 

如何做一个被标记为安全的控件(AtiveX)呢?有三种方法:

1:向MS交钱,数字签名。

2:修改注册表:

方法如下:

使用MFC开发ActiveX控件时可以修改注册表来标记控件为安全的,具体做法:  
          YourApp.ccp里增加  
          #include   "comcat.h"  
          #include   "Objsafe.h"  
  //   本控件的CLSID,注册表用-  
  const   GUID   CDECL   CLSID_SafeItem   =  
  {   0x94BE7FE8,   0xCF75,   0x4FD3,   {   0x8A,0x41,0x9D,0x5F,0xE7,0x13,0x55,0x11}   };     //这个需要根据你的控件的classid来修改,也就是YourApp.odl里的   [   uuid(94BE7FE8-CF75-4FD3-8A41-9D5FE7135511),  
      helpstring("UTPKES   Control"),   control   ]这个.  
   
  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}};  
  加这两句的时候可能会报重复定义,把旧的找到删除掉  
   
  然后在YourApp.ccp中加入下面三方方法:  
  //   创建组件种类  
  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;  
  }  
  然后修改YourApp.cpp里的STDAPI   DllRegisterServer(void)方法和STDAPI   DllUnregisterServer(void)方法:  
   
  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;  
  }  

 

2。如果这种方法还不行,那么还有一个办法:通过实现IObjectSafety接口来解决问题

 

使用MFC开发ActiveX控件,在IE中会提示安全问题,这个可以通过实现IObjectSafety接口来解决问题

 

1.首先要包含头文件#include <ObjSafe.h>

2.然后在你的ActiveX头文件中添加   就是在你的XmyactiveCtrl.h文件中增加。

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);

3.然后在ActiveX对应的cpp文件中添加(XmyactiveCtrl.cpp文件中增加),将其中MyActiveCtrl替换成自己的ActiveCtrl类

//接口映射
BEGIN_INTERFACE_MAP(MyActiveXCtrl,COleControl)  
 INTERFACE_PART(MyActiveXCtrl,IID_IObjectSafety,ObjSafe)  
END_INTERFACE_MAP()  

//   IObjectSafety   member   functions  
//   Delegate   AddRef,   Release,   QueryInterface  
ULONG FAR EXPORT MyActiveXCtrl::XObjSafe::AddRef()  
{  
 METHOD_PROLOGUE(MyActiveXCtrl,ObjSafe)  
 return pThis->ExternalAddRef();  
}  

ULONG FAR EXPORT MyActiveXCtrl::XObjSafe::Release()  
{  
 METHOD_PROLOGUE(MyActiveXCtrl,ObjSafe)  
 return pThis->ExternalRelease();  
}  

HRESULT FAR EXPORT MyActiveXCtrl::XObjSafe::QueryInterface(REFIID iid,void FAR* FAR* ppvObj)  
{  
 METHOD_PROLOGUE(MyActiveXCtrl,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    
MyActiveXCtrl::XObjSafe::GetInterfaceSafetyOptions(    
 /*   [in]   */   REFIID   riid,  
 /*   [out]   */   DWORD   __RPC_FAR   *pdwSupportedOptions,  
 /*   [out]   */   DWORD   __RPC_FAR   *pdwEnabledOptions)  
{  
 METHOD_PROLOGUE(MyActiveXCtrl,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    
MyActiveXCtrl::XObjSafe::SetInterfaceSafetyOptions(    
 /*   [in]   */   REFIID   riid,  
 /*   [in]   */   DWORD   dwOptionSetMask,  
 /*   [in]   */   DWORD   dwEnabledOptions)  
{  
 METHOD_PROLOGUE(MyActiveXCtrl,   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);  
}

编译成功后,浏览器默认安全级别也不会再报安全问题了

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值