转自: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 }