Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

How To Create an Exchange 2000 Store Event Sink in Visual C++


View products that this article applies to.

Summary

This article demonstrates how to write a Store Event sink for Exchange Server 2000 by using Visual C++.

↑ Back to the top


More information

To create a Store Event sink, follow these steps. Note that you must do your development on an Exchange 2000 server.
  1. In Visual C++, create a new project. In the dialog box, select ATL COM AppWizard and accept the default settings.
  2. On the Insert menu, click New ATL Object. Select Simple Object and click Next. Type a name for the object, and then click OK.
  3. Click the ClassView tab to switch to the ClassView in your workspace browser. Right-click the class that was created, click Implement Interface, and then click OK.
  4. In the list of available type libraries, select EXOLEDB Type Library (1.0), and then click OK.
  5. In the Implement Interface dialog box, select the ones you want to implement and click OK. For store events, you must select at least one of the following interfaces:
    • IExStoreAsyncEvents: OnSave, OnDelete
    • IExStoreSyncEvents: OnSyncSave, OnSyncDelete
    • IExStoreSystemEvents: OnMDBStartup, OnMDBShutdown, OnTimer

  6. To avoid redefinition errors, rename the _SID_IDENTIFIER_AUTHORITY and the _SID structures in the EXOLEDB library. To do this, open the header file that was created for you, and change the following line
    #import "C:\Program Files\Exchsrvr\bin\exoledb.dll" raw_interfaces_only, raw_native_types, no_namespace, named_guids
    					
    to:
    #import "C:\Program Files\Exchsrvr\bin\exoledb.dll" raw_interfaces_only, raw_native_types, no_namespace, named_guids,\ 
    	rename ("_SID_IDENTIFIER_AUTHORITY","EXOLEDB_SID_IDENTIFIER_AUTHORITY"), rename("_SID","EXOLEDB_SID")
    					
  7. You can now expand the class that was created and see the list of functions for the interfaces that you chose. Double-click a function to go to the function definition. These functions are in a header file, and are inline functions that return the COM return code that indicates that they have not been implemented. For example:
    STDMETHOD(OnSyncDelete)(IExStoreEventInfo * pEventInfo, BSTR bstrURLItem, LONG lFlags)
    {
        return E_NOTIMPL;
    }
    					
  8. For the functions that you want to implement, remove the inline function, leaving just the function prototype. Be sure to end the prototype with a semicolon (;).
  9. Switch to the source (.cpp) file that matches the name of the header. Place your function implementations here. For example:
    // Import the ADO and CDOEX DLLs.
    #import "C:\Program Files\Common Files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF"), named_guids
    #import "C:\Program Files\Common Files\Microsoft Shared\CDO\cdoex.dll" no_namespace
    
    STDMETHODIMP CATLSink::OnSyncSave(IExStoreEventInfo * pEventInfo, BSTR bstrURLItem, LONG lFlags)
    {
    	HRESULT hr = S_OK;
    
    	// Only do this at the beginning of the transaction.
    	if (lFlags & EVT_SYNC_BEGIN)
    	{
    		// Cast pEventInfo to a IExStoreDispEventInfoPtr.
    		IExStoreDispEventInfoPtr pDispInfo = pEventInfo;
    		
    		// Create a new message.
    		IMessagePtr iMsg(__uuidof(Message));
    		
    		_RecordPtr rec;
    		char szSubject[256];
    		char szTextBody[256];
    
    		// Get the record that caused the event.
    		// This is the new message.
    		pDispInfo->get_EventRecord((IDispatch**)&rec);
    
    		// Set up a reply.
    		iMsg->From = "notifier@microsoft.com";
    		
    		// Set the recipient to the sender of the message that caused the event.
    		iMsg->To = rec->Fields->GetItem("urn:schemas:httpmail:fromemail")->Value.bstrVal;
    		
    		// Set up the subject string to contain the subject of the message that caused the event.
    		sprintf(szSubject,"Message Received: %s", (char*)(_bstr_t)rec->Fields->GetItem("urn:schemas:httpmail:subject")->Value.bstrVal);
    		iMsg->Subject = szSubject;
    		
    		// Set up the text of the message to contain the URL to the message that caused the event.
    		sprintf(szTextBody, "The following item was received:\n%s", (char*)(_bstr_t)bstrURLItem);
    		iMsg->TextBody = szTextBody;
    
    		// Send the message.
    		iMsg->Send();
    
    		iMsg = NULL;
    	}
    	return hr;
    }
    					
  10. Compile and link your code. This automatically builds and registers a dynamic-link library (DLL). For the event sink to function, place the DLL in a COM+ application.

↑ Back to the top


Keywords: KB288156, kbmsg, kbhowto

↑ Back to the top

Article Info
Article ID : 288156
Revision : 6
Created on : 2/22/2007
Published on : 2/22/2007
Exists online : False
Views : 493