Microsoft KB Archive/184268

From BetaArchive Wiki

Article ID: 184268

Article Last Modified on 3/12/2004



APPLIES TO

  • Microsoft Exchange Development Kit 5.5
  • Microsoft Exchange Development Kit 5.5
  • Microsoft Exchange Server 2003 Software Development Kit
  • Microsoft Exchange Server 4.0 Standard Edition
  • Microsoft Exchange Server 5.0 Standard Edition
  • Microsoft Exchange Server 5.5 Standard Edition



This article was previously published under Q184268

SUMMARY

This C++ sample application demonstrates the use of the DAPIRead command. It reads the Exchange Server Directory for a particular object and a particular attribute. Once the DAPIRead is complete, the Object name, Attribute name and the Attribute value is displayed. Errors generate an event log entry you can see in the Application log of the Event Viewer.

MORE INFORMATION

Required command line arguments are:

  • Argument 1: The Exchange server name.
  • Argument 2: The Distinguished Name (DN) of the object in question.
  • Argument 3: The name of one of the Object's string Attributes.

To build the application include the sample code below in your Win32 console project. You also need to add the Dapi.lib file to your project's Link object/library modules list.

Sample Application

   #include <windows.h>
   #include <stdio.h>
   #include <string.h>
   #include <lmcons.h>
   #include <tchar.h>

   #include <dapi.h>
   #include <dapimsg.h> // Error codes


   void ReadAttr(DAPI_HANDLE hDAPISession, LPTSTR szObjectDN,
                 LPCTSTR  szAttrName );

   void ReportDAPIEvent(DAPI_EVENT* pDAPIEvent);

   void main(int argc, char* argv[])
   {
      DAPI_HANDLE hDAPISession;
      DAPI_EVENT* pDAPIEvent = NULL;
      DAPI_PARMS DAPIParms = {0};

      if (3 > argc) {
        printf("\nReadAttr ExchangeServerName DNofobject attributename");
        return;
      }

      printf("\nExchange Server: %s", argv[1]);

      // Start DAPI for this session.
      // Initialize the DAPI Parms structure and the DAPI
      // operation session.
      DAPIParms.dwDAPISignature = DAPI_SIGNATURE;
      DAPIParms.dwFlags = DAPI_EVENT_ALL ;
                //|DAPI_READ_DEFINED_ATTRIBUTES|DAPI_RAW_MODE ;
      DAPIParms.pszDSAName = argv[1];
      DAPIParms.pszBasePoint = NULL;  // Set object DN in DAPIRead code
      DAPIParms.pszContainer = NULL;
      DAPIParms.pszNTDomain = NULL;
      DAPIParms.pszCreateTemplate = NULL;
      DAPIParms.pAttributes = NULL;

      //struct with DAPI params
      pDAPIEvent = DAPIStart(&hDAPISession, &DAPIParms);

      if(pDAPIEvent) {
        printf("\nDAPIStart() returned %08x - check app eventlog",
                pDAPIEvent->dwDAPIError);
        ReportDAPIEvent(pDAPIEvent);

        // Note: dwDAPIError < 0 does NOT necessarily mean DAPIStart
        // failed. Please see Microsoft KB article Q169551.
        if (0==hDAPISession || INVALID_HANDLE_VALUE == hDAPISession)
          return;
      } else
          printf("\nDAPIStart() was successful");
       ReadAttr(hDAPISession, argv[2], argv[3]);

      DAPIEnd(&hDAPISession);

      printf("\nEND PROGRAM");
   }

   ATT_VALUE * AddAttrName(_TINT i, LPCTSTR szClass,
                           DAPI_ENTRY * dapiAttr)
   {

      ATT_VALUE * AttName = &(dapiAttr->rgEntryValues[i]);
      AttName->DapiType = DAPI_STRING8;
      AttName->Value.pszValue = const_cast <LPTSTR> (szClass);
      AttName->size = _tcslen(AttName->Value.pszValue);
      AttName->pNextValue = NULL;

      return AttName;
   }


   void ReadAttr(DAPI_HANDLE hDAPISession, LPTSTR szObjectDN,
                 LPCTSTR szAttrName )
   {
      DAPI_EVENT* pDAPIEvent = NULL;

      // Query structures.
      DAPI_ENTRY Attributes;
      ATT_VALUE AttName[2];

      //Response pointer.
      DAPI_ENTRY * pResponseValues;

      int i=0;

      printf("\nIN ReadAttr()");

      //Set up the requested attributes.

      Attributes.unAttributes = 2;                  //# of attributes
      Attributes.ulEvalTag = TEXT_VALUE_ARRAY;      //Value Type
      Attributes.rgEntryValues = &AttName[0];

      AddAttrName( i++, TEXT("Object-Class"), &Attributes);
      AddAttrName( i++,  szAttrName, &Attributes);

      // Read the server's attributes.
      pDAPIEvent = DAPIRead(hDAPISession,
                    NULL,  // no flags, read specified attributes
                    szObjectDN,
                    &Attributes,
                    &pResponseValues,
                    NULL);

      if(pDAPIEvent) {
         // write FAILED
         printf("\nDAPIRead ERROR %08x check app eventlog",
                pDAPIEvent->dwDAPIError);
         ReportDAPIEvent(pDAPIEvent);
      } else {
           printf("\nDAPIRead() was successful for object:");
           printf("%s\n\nAttribute %s is\n %s\n\nObject Class is %s",
                 szObjectDN,szAttrName,
                 pResponseValues->rgEntryValues[1].Value.pszValue,
                 pResponseValues->rgEntryValues[0].Value.pszValue);
      }

      DAPIFreeMemory (pResponseValues);

   }

   void ReportDAPIEvent(DAPI_EVENT* pDAPIEvent)
   {
      HANDLE hDAPIEventSource = RegisterEventSource(NULL,
        TEXT("MSExchangeDSImp"));

       ReportEvent(
            hDAPIEventSource,
            (WORD)EVENTLOG_ERROR_TYPE,
            0xFFFF,
            pDAPIEvent->dwDAPIError,
            NULL,
            (WORD)pDAPIEvent->unSubst,
            0,
            (const char**) pDAPIEvent->rgpszSubst,
            NULL);

       DAPIFreeMemory(pDAPIEvent);

       DeregisterEventSource(hDAPIEventSource);
    }
                

REFERENCES

If you have not set up DAPI on your system, you need to follow the steps in the following article in the Microsoft Knowledge Base:

169551 INFO: Items Required to Use DAPI



Additional query words: DAPI

Keywords: kbhowto kbapi kbmsg KB184268