Registering for Event Notifications in ABO

You can design ABO applications so that they are notified when certain events occur. To receive event notifications, you can create an ABO application that works as a listener object. The listener object must implement a COM sink of a class inherited from the IMSAdminBaseSink interface. Also, the listener object should be free-threaded because notifications are asynchronous and might arrive out of order.

Note

IIS does not make secure calls to remote machines. If your program implements a sink and is executing on a machine other than the machine on which IIS is running, you must set security by calling the COM CoInitializeSecurity function with the dwImpLevel parameter set to RPC_C_AUTHN_LEVEL_NONE. For a code example, see Calling CoInitializeSecurity in a Secure Manner.

This topic contains the following sections that describe how to work with notifications once you have implemented the IMSAdminBaseSink interface:

  • Registering an Event Sink

  • Unregistering an Event Sink

  • Shutdown Notify Sink

  • Change Notify Sink

Registering an Event Sink

The following code shows you how to use the C++ programming language to register a listener object so that it receives metabase change notifications. When an application no longer needs to receive notifications, unregister the listener object (with the next code example) to improve performance. This example requires the header files iadmw.h and iiscnfg.h.

HRESULT 
RegisterForMetabaseNotifications( 
  IMSAdminBase        *pAdminBase, 
  IMSAdminBaseSink      *pAdminBaseSink, 
  DWORD             *pdwCookie) 
{ 
  HRESULT           hr = S_OK; 
  IConnectionPointContainer   *pContainer = NULL; 
  IConnectionPoint      *pConnectionPoint = NULL; 

  if ( !pAdminBase || !pAdminBaseSink || !pdwCookie ) 
  { 
    hr = E_INVALIDARG; 
    goto exit; 
  } 

  *pdwCookie = 0; 
  hr = pAdminBase->QueryInterface( IID_IConnectionPointContainer, (VOID**)&pContainer ); 
  if ( FAILED( hr ) ) 
  { 
     goto exit; 
  } 

  hr = pContainer->FindConnectionPoint( IID_IMSAdminBaseSink, &pConnectionPoint ); 
  if ( FAILED( hr ) ) 
  { 
     goto exit; 
  } 

  hr = pConnectionPoint->Advise( pAdminBaseSink, pdwCookie ); 
  if ( FAILED( hr ) ) 
  { 
     goto exit; 
  } 

exit: 
  if ( pConnectionPoint ) 
  { 
    pConnectionPoint->Release(); 
  } 

  if ( pContainer ) 
  { 
    pContainer->Release(); 
  } 
}

Unregistering an Event Sink

The following code example shows you how to use the C++ programming language to register a listener object so that it no longer receives metabase change notifications. When you unregister a listener object, it frees memory and improves the performance of your application. This example requires the header files iadmw.h and iiscnfg.h.

HRESULT  
UnregisterMetabaseNotificationSink( 
  IMSAdminBase        *pAdminBase, 
  DWORD             dwCookie) 
{ 
  HRESULT           hr = S_OK; 
  IConnectionPointContainer   *pContainer = NULL; 
  IConnectionPoint      *pConnectionPoint = NULL; 

  if ( !pAdminBase ) 
  { 
    hr = E_INVALIDARG; 
    goto exit; 
  } 

  if ( !dwCookie ) 
  { 
    goto exit; 
  } 

  hr = pAdminBase->QueryInterface( IID_IConnectionPointContainer, (VOID**)&pContainer ); 
  if ( FAILED( hr ) ) 
  { 
    goto exit; 
  } 

  hr = pContainer->FindConnectionPoint( IID_IMSAdminBaseSink, &pConnectionPoint ); 
  if ( FAILED( hr ) ) 
  { 
    goto exit; 
  } 

  hr = pConnectionPoint->Unadvise( dwCookie ); 
  if ( FAILED( hr ) ) 
  { 
    goto exit; 
  } 

exit: 
  if ( pConnectionPoint ) 
  { 
    pConnectionPoint->Release(); 
  } 

  if ( pContainer ) 
  { 
    pContainer->Release(); 
  } 
} 

Shutting down Notify Sink

This sink method is called when the IISADMIN service stops. The metabase is open during this call, but it is possible that handles that prevent you from reading or writing to portions of the metabase are open. In addition, an event sink should release its interface during this call. The metabase waits for five seconds, or until all interfaces have been released, before shutting down.

A callback method must implement the following prototype as a minimum:

HRESULT STDMETHODCALLTYPE ShutdownNotify( void)
{
  return E_NOTIMPL;
}  

Changing Notify Sink

If an ABO application needs to be notified whenever a key or its associated data changes, it must implement the SinkNotify method.

This method will receive a notification whenever one of the following events occurs.

  • A key that has been changed is closed by the CloseKey method.

  • Permissions on a handle to a key are changed from write or read/write to read-only by the ChangePermissions method.

The SinkNotify method is not called if the handle is closed by the instance of the IMSAdminBase interface that registered the sink. In other words, a client receives notifications of changes made only by other clients.

A callback method must implement the following prototype as a minimum. The parameter dwMDNumElements receives the number of elements that have changed. The maximum number of change entries that are sent on a single call to the callback method is specified by the constant MD_MAX_CHANGE_ENTRIES. If more notifications are required, the method is called multiple times:

HRESULT SinkNotify(
  DWORD dwMDNumElements
  MD_CHANGE_OBJECT pcoChangeList[] 
); 

See Also

Other Resources

IConnectionPoint COM Interface