转自:http://www.cnblogs.com/carekee/articles/1772201.html
感谢原作者!
ActiveX控件打包成cab后,在脚本中调用中时,要保证控件的安全性才能在你的网页上安全运行,有两种方法来实现这一保证:实现一个名称为IObjectSafe的接口到你的控件。如果IE发现你的控件支持IObjectSafety,它调用 IObjectSafety::SetInterfaceSafetyOptions 方法然后才载入你的控件。另外一种方法需要修改注册表,我将会在另外一篇文章中详细介绍。
1。创建了一个叫做“tryISafeObject.ocx”的MFC ActiveX控件。
2。在tryISafeObjectCtrl.h中定义ISafeObject接口:
1 #include <objsafe.h> // for IObjectSafety; in ActiveX SDK
2 class CtryISafeObjectCtrl : public COleControl 3 { 4 DECLARE_DYNCREATE(CtryISafeObjectCtrl) 5 //........................................................................ 6 //ISafeObject
7 DECLARE_INTERFACE_MAP() 8 BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety) 9 STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) ( 10 /* [in] */ REFIID riid, 11 /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions, 12 /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions 13 ); 14
15 STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) ( 16 /* [in] */ REFIID riid, 17 /* [in] */ DWORD dwOptionSetMask, 18 /* [in] */ DWORD dwEnabledOptions 19 ); 20 END_INTERFACE_PART(ObjSafe); 21 //ISafeObject 22 //........................................................................
23 。。。。。 24 }; 25 在objsafe.h头文件中有ISafeObject接口的相关定义 26 3。在tryISafeObjectCtrl.cpp中ISafeObject接口的相关实现: 27 //............................................................................. 28 // Interface map for IObjectSafety
29 BEGIN_INTERFACE_MAP( CtryISafeObjectCtrl, COleControl ) 30 INTERFACE_PART(CtryISafeObjectCtrl, IID_IObjectSafety, ObjSafe) 31 END_INTERFACE_MAP() 32 //............................................................................. 33 // IObjectSafety member functions 34 // Delegate AddRef, Release, QueryInterface
35 ULONG FAR EXPORT CtryISafeObjectCtrl::XObjSafe::AddRef() 36 { 37 METHOD_PROLOGUE(CtryISafeObjectCtrl, ObjSafe) 38 return pThis->ExternalAddRef(); 39 } 40 ULONG FAR EXPORT CtryISafeObjectCtrl::XObjSafe::Release() 41 { 42 METHOD_PROLOGUE(CtryISafeObjectCtrl, ObjSafe) 43 return pThis->ExternalRelease(); 44 } 45 HRESULT FAR EXPORT CtryISafeObjectCtrl::XObjSafe::QueryInterface( 46 REFIID iid, void FAR* FAR* ppvObj) 47 { 48 METHOD_PROLOGUE(CtryISafeObjectCtrl, ObjSafe) 49 return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); 50 } 51 const DWORD dwSupportedBits =
52 INTERFACESAFE_FOR_UNTRUSTED_CALLER |
53 INTERFACESAFE_FOR_UNTRUSTED_DATA; 54 const DWORD dwNotSupportedBits = ~ dwSupportedBits; 55 //............................................................................. 56 // CStopLiteCtrl::XObjSafe::GetInterfaceSafetyOptions 57 // Allows container to query what interfaces are safe for what. We're 58 // optimizing significantly by ignoring which interface the caller is 59 // asking for.
60 HRESULT STDMETHODCALLTYPE 61 CtryISafeObjectCtrl::XObjSafe::GetInterfaceSafetyOptions( 62 /* [in] */ REFIID riid, 63 /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions, 64 /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions) 65 { 66 METHOD_PROLOGUE(CtryISafeObjectCtrl, ObjSafe) 67 HRESULT retval = ResultFromScode(S_OK); 68 // does interface exist?
69 IUnknown FAR* punkInterface; 70 retval = pThis->ExternalQueryInterface(&riid, 71 (void * *)&punkInterface); 72 if (retval != E_NOINTERFACE) { // interface exists
73 punkInterface->Release(); // release it--just checking!
74 } 75
76 // we support both kinds of safety and have always both set, 77 // regardless of interface
78 *pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits; 79 return retval; // E_NOINTERFACE if QI failed
80 } 81 /////
82 // CStopLiteCtrl::XObjSafe::SetInterfaceSafetyOptions 83 // Since we're always safe, this is a no-brainer--but we do check to make 84 // sure the interface requested exists and that the options we're asked to 85 // set exist and are set on (we don't support unsafe mode).
86 HRESULT STDMETHODCALLTYPE 87 CtryISafeObjectCtrl::XObjSafe::SetInterfaceSafetyOptions( 88 /* [in] */ REFIID riid, 89 /* [in] */ DWORD dwOptionSetMask, 90 /* [in] */ DWORD dwEnabledOptions) 91 { 92 METHOD_PROLOGUE(CtryISafeObjectCtrl, ObjSafe) 93
94 // does interface exist?
95 IUnknown FAR* punkInterface; 96 pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface); 97 if (punkInterface) { // interface exists
98 punkInterface->Release(); // release it--just checking!
99 } 100 else { // interface doesn't exist
101 return ResultFromScode(E_NOINTERFACE); 102 } 103 // can't set bits we don't support
104 if (dwOptionSetMask & dwNotSupportedBits) { 105 return ResultFromScode(E_FAIL); 106 } 107
108 // can't set bits we do support to zero
109 dwEnabledOptions &= dwSupportedBits; 110 // (we already know there are no extra bits in mask )
111 if ((dwOptionSetMask & dwEnabledOptions) !=
112 dwOptionSetMask) { 113 return ResultFromScode(E_FAIL); 114 } 115
116 // don't need to change anything since we're always safe
117 return ResultFromScode(S_OK); 118 }