You are currently offline, waiting for your internet to reconnect

How To IObjectSafety Marks ATL Controls Safe for Initializing

This article was previously published under Q168371
Retired KB Content Disclaimer
This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.
Summary
You can use the default implementation of IObjectSafetyImpl to mark acontrol as safe for scripting. In many cases, you will also want to markthe control as safe for initialization.

NOTE: Only mark your control as safe for scripting or initialization if itreally is safe. If the control is potentially unsafe and it is marked assafe, you may be held liable for damages. See the REFERENCES section belowfor more information.
More information
The steps you need to take to get the desired functionality involve usingIObjectSafetyImpl as one of the classes that your control derives from andoverriding GetInterfaceSafetyOptions and SetInterfaceSafetyOptions. Thisallows you to implement the desired functionality, which in this case meansmarking the control as safe for scripting and initialization.

To use IObjectSafetyImpl, you need to add it to the list of classes yourcontrol is derived from. For example, in the Polygon tutorial you see thefollowing:
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// GetInterfaceSafetyOptionsm_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;}}...}				

In ATL 3.0, the implementation of IObjectSafetyImpl has changed so that you can now provide the safety options as a template parameter. For example, the declaration of the class above would appear as
class ATL_NO_VTABLE CPolyCtl :...   public IObjectSafetyImpl<CPolyCtl,      INTERFACESAFE_FOR_UNTRUSTED_CALLER |         INTERFACESAFE_FOR_UNTRUSTED_DATA>{public:   BEGIN_COM_MAP(CPolyCtl)...				
and you would not have to override the two methods. For additional information, click the article number below to view the article in the Microsoft Knowledge Base:
192093 PRB: Compiler Errors When Porting IObjectSafetyImpl to ATL 3.0
References
For additional information about marking ActiveX controls as safe forscripting and initialization, please see the following articles in theMicrosoft Knowledge Base:
161873How To Mark MFC Controls Safe for Scripting/Initialization

164119SAMPLE: Implementing IObjectSafety in an ActiveX control
ATLIss ATLControl InetSDKSafeControl mfcole
Properties

Article ID: 168371 - Last Review: 09/03/2012 09:15:00 - Revision: 3.0

Microsoft ActiveX Template Library 3.0

  • kbctrl kbhowto kbinprocsvr KB168371
Feedback
c=""> var varAutoFirePV = 1; var varClickTracking = 1; var varCustomerTracking = 1; var Route = "76500"; var Ctrl = ""; document.write("