Cómo IObjectSafety marcas ATL controles seguros para inicialización

Exención de responsabilidades de contenido KB retirado

Este artículo se refiere a productos para los que Microsoft ya no ofrece soporte técnico. Por tanto, el presente artículo se ofrece "tal cual" y no será actualizado.

Resumen

Puede utilizar la implementación predeterminada de IObjectSafetyImpl para marcar un control como seguro para secuencias de comandos. En muchos casos, también deseará marcar el control como seguro para la inicialización.


NOTA: Sólo marcar el control como seguro para secuencias de comandos o la inicialización si realmente es seguro. Si el control es potencialmente inseguro y está marcado como seguro, puede ser responsables por daños y perjuicios. Consulte la sección REFERENCIAS a continuación para obtener más información.

Más información

Los pasos que debe seguir para obtener la funcionalidad deseada implican utilizando IObjectSafetyImpl como una de las clases que se deriva el control y reemplaza GetInterfaceSafetyOptions y SetInterfaceSafetyOptions. Esto le permite implementar la funcionalidad deseada, que en este caso significa marcar el control como seguro para inicialización y secuencias de comandos.


Para utilizar IObjectSafetyImpl, debe agregarlo a la lista de clases que se deriva de su control. Por ejemplo, en el tutorial de polígono verá lo siguiente:
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;
}
}
...
}


En ATL 3.0, la implementación de IObjectSafetyImpl ha cambiado de modo que ahora puede proporcionar las opciones de seguridad como un parámetro de plantilla. Por ejemplo, la declaración de la clase anterior aparecería como

class ATL_NO_VTABLE CPolyCtl :...
public IObjectSafetyImpl<CPolyCtl,
INTERFACESAFE_FOR_UNTRUSTED_CALLER |
INTERFACESAFE_FOR_UNTRUSTED_DATA>
{
public:
BEGIN_COM_MAP(CPolyCtl)
...

y no tendría que reemplace los dos métodos. Para obtener información adicional, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:

192093 PRB: errores del compilador al trasladar IObjectSafetyImpl a ATL 3.0

Referencias

Para obtener información adicional acerca de cómo marcar los controles ActiveX como seguro para inicialización y secuencias de comandos, consulte los artículos siguientes en Microsoft Knowledge Base:

161873 Cómo marcar los controles MFC como seguros para scripts e inicialización



164119 EJEMPLO: Implementar IObjectSafety en un control ActiveX
Propiedades

Id. de artículo: 168371 - Última revisión: 01/09/2017 - Revisión: 1

Comentarios