使用 IObjectSafety 标记 ATL 控件初始化的安全

MSDN原文。这里我将代码使用到了BHO里面,运行调试没问题。拿来分享一下

Collapse image概要

您可以使用 IObjectSafetyImpl 的默认实现来标记为可安全执行脚本的控件。在许多情况下,您需要将标记为可安全执行初始化的控件。

注意: 如果它真正是安全只是标注为可安全执行脚本或初始化控件。如果该控件是潜在的不安全和被标记为可安全执行,您可能应承担相应责任的损害。请参阅下面的参考资源部分,有关的详细信息。

Collapse image更多信息

如何才能获取所需的功能所需的步骤涉及到使用 IObjectSafetyImpl 作为一个从派生的控件的类和重写 GetInterfaceSafetyOptions 和 SetInterfaceSafetyOptions。这允许您实现所需的功能,在这种情况下意味着标记为可安全执行脚本和初始化控件。

若要使用 IObjectSafetyImpl,您需要将其添加到您的控件派生自的类的列表。例如,多边形教程中,您看到如下:
class ATL_NO_VTABLE CPolyCtl :

...

   public IObjectSafetyImpl<CPolyCtl> // ATL's version of

                                     // IObjectSafety

{

public:

   BEGIN_COM_MAP(CPolyCtl)

...

      COM_INTERFACE_ENTRY_IMPL(IObjectSafety) // Tie IObjectSafety

                                              // to this COM map

   END_COM_MAP()



STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid,

                                  DWORD *pdwSupportedOptions,

                                  DWORD *pdwEnabledOptions)

{

ATLTRACE(_T("CObjectSafetyImpl::GetInterfaceSafetyOptions\n"));

if (!pdwSupportedOptions || !pdwEnabledOptions)

   return E_FAIL;

LPUNKNOWN pUnk;

if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) {

   // Our object doesn't even support this interface.

   return E_NOINTERFACE;

}else{

   // Cleanup after ourselves.

   pUnk->Release();

   pUnk = NULL;

}

if (riid == IID_IDispatch) {

   // IDispatch is an interface used for scripting. If your

   // control supports other IDispatch or Dual interfaces, you

   // may decide to add them here as well. Client wants to know

   // if object is safe for scripting. Only indicate safe for

   // scripting when the interface is safe.

   *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;

   *pdwEnabledOptions = m_dwSafety &

                        INTERFACESAFE_FOR_UNTRUSTED_CALLER;

   return S_OK;

}else if ((riid == IID_IPersistStreamInit) ||

          (riid == IID_IPersistStorage)) {

   // IID_IPersistStreamInit and IID_IPersistStorage are

   // interfaces used for Initialization. If your control

   // supports other Persistence interfaces, you may decide to

   // add them here as well. Client wants to know if object is

   // safe for initializing. Only indicate safe for initializing

   // when the interface is safe.

   *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;

   *pdwEnabledOptions = m_dwSafety &

                        INTERFACESAFE_FOR_UNTRUSTED_DATA;

   return S_OK;

}else{

   // We are saying that no other interfaces in this control are

   // safe for initializing or scripting.

   *pdwSupportedOptions = 0;

   *pdwEnabledOptions = 0;

   return E_FAIL;

}

}



STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid,

                                  DWORD dwOptionSetMask,

                                  DWORD dwEnabledOptions)

{

ATLTRACE(_T("CObjectSafetyImpl::SetInterfaceSafetyOptions\n"));

if (!dwOptionSetMask && !dwEnabledOptions) return E_FAIL;

LPUNKNOWN pUnk;

if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) {

   // Our object doesn't even support this interface.

   return E_NOINTERFACE;

}else{

   // Cleanup after ourselves.

   pUnk->Release();

   pUnk = NULL;

}

// Store our current safety level to return in

// GetInterfaceSafetyOptions

m_dwSafety |= dwEnabledOptions & dwOptionSetMask;

if ((riid == IID_IDispatch) &&

    (m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER)) {

   // Client wants us to disable any functionality that would

   // make the control unsafe for scripting. The same applies to

   // any other IDispatch or Dual interfaces your control may

   // support. Because our control is safe for scripting by

   // default we just return S_OK.

   return S_OK;

}else if (((riid == IID_IPersistStreamInit) ||

           (riid == IID_IPersistStorage)) &&

          (m_dwSafety & INTERFACESAFE_FOR_UNTRUSTED_DATA)) {

   // Client wants us to make the control safe for initializing

   // from persistent data. For these interfaces, this control

   // is safe so we return S_OK. For Any interfaces that are not

   // safe, we would return E_FAIL.

   return S_OK;

}else{

   // This control doesn't allow Initialization or Scripting

   // from any other interfaces so return E_FAIL.

   return E_FAIL;

}

}

...

}

				

在 ATL 3.0 中,IObjectSafetyImpl 的实现已更改,以便可以作为模板参数现在提供的安全选项。例如,上面的类声明将显示为
class ATL_NO_VTABLE CPolyCtl :

...

   public IObjectSafetyImpl<CPolyCtl,

      INTERFACESAFE_FOR_UNTRUSTED_CALLER |

         INTERFACESAFE_FOR_UNTRUSTED_DATA>

{

public:

   BEGIN_COM_MAP(CPolyCtl)

...

				
和您不需要重写两个方法。有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
192093 PRB: 编译器错误时将移植到 ATL 3.0 IObjectSafetyImpl

Collapse image参考

有关标记为可安全执行脚本和初始化的 ActiveX 控件的其他信息,请参阅下列文章 Microsoft 知识库中相应的文章:
161873 如何将标记为脚本初始化 MFC 控件安全
164119示例: 在 ActiveX 控件中实现 IObjectSafety

你可能感兴趣的:(object)