Are you a world traveler? ZoneTick is a cool utility that'll help you stay in touch over multiple time zones!
 
Dumping Attribute Names and Values for Directory Items  
Nik Okuntseff  MS Exchange Server Programming 

Dumping Attribute Names and Values for Directory Items

I have showed previously how you can retrieve MS Exchange directory items with DAPI functions. The example presented there, however, did not show how you can traverse or dump to all this data to the screen. It would be a good idea to have a helper function which allows for that. This topic describes how this function may be written.

Basically, all you need to do is call DAPIRead, obtain two DAPI_ENTRY pointers (one with attribute names and the other with their values), then traverse them and dump whatever you'll find to the screen.

The following sample (Dir/DumpItemAttributes) demonstrates how this may be accomplished.

#include <afxwin.h>
#include <dapi.h>

void DumpItemAttributes( DAPI_ENTRY * pdeAttributes, DAPI_ENTRY * pdeValues )
{
    #define BUFFER_SIZE 256

    // We assume both pointers to be valid
     if ( !pdeAttributes || !pdeValues ) {

        printf( "ERROR! One of DAPI_ENTRY pointers is NULL...\n" );
        return;
    }

    // We also assume number of attributes and values equal
    if ( pdeAttributes->unAttributes != pdeValues->unAttributes ) {

        printf( "ERROR! Number of attributes is not equal to number of values...\n" );
        return;
    }

    int iCount = pdeAttributes->unAttributes;
    printf( "Total number of attributes: %d\n\n", iCount );

    char buffer[BUFFER_SIZE]; // This buffer will hold attribute names and values
    for ( int i = 0; i < iCount; i++ ) {
 
        ZeroMemory( buffer, BUFFER_SIZE );
        memcpy( buffer, pdeAttributes->rgEntryValues[i].Value.pszA, pdeAttributes->rgEntryValues[i].size );
        printf( buffer );
        printf( "\t" );

        if ( BUFFER_SIZE <= pdeValues->rgEntryValues[i].size ) {

            printf( "ERROR! Buffer too small...\n" );
            throw ( -1 );
        }
 
        switch ( pdeValues->rgEntryValues[i].DapiType ) {

        case DAPI_NO_VALUE:
            printf( "NO VALUE" );
            break;
        case DAPI_INT:
            printf( "%d", pdeValues->rgEntryValues[i].Value.iValue );
            break;
        case DAPI_STRING8:
            ZeroMemory( buffer, BUFFER_SIZE );
            memcpy( buffer, pdeValues->rgEntryValues[i].Value.pszA, pdeValues->rgEntryValues[i].size );
            printf( buffer );
            break;
        case DAPI_UNICODE:
            printf( "Unicode string here..." );
            break;
        case DAPI_BOOL:
            if ( pdeValues->rgEntryValues[i].Value.bool )
                printf( "TRUE" );
            else
                printf( "FALSE" );
            break;
        case DAPI_BINARY:
            printf( "Binary Data Here..." );
            break;
        default:
            // We are not supposed to get here...
            throw ( -1 );
            break;
        }
        printf( "\n" );
    }
    return;
}

You may insert a call to this function after you have successfully called DAPIRead. It will conveniently dump all retrieved data to the screen. For the sake of experiment I have done this for my Addr-Type object and was amazed to see 50 (!) attributes dumped, many of them with no values (DAPI_NO_VALUE). However, important attributes such as "Obj-Dist-Name" (Object distinguished name), "Admin-Display-Name" and some others have been dumped with values that make sense.

One interesting nuance about using this function after DAPIRead is that if you use DAPI_READ_ALL_ATTRIBUTES flag in DAPIRead, you would not be able to see a very important attribute called Proxy-Generator-DLL in your list. However, it will appear with DAPI_READ_DEFINED_ATTRIBUTES. In fact, using this flag will return only attributes with defined values. It is unclear to me why neither DAPI_READ_ALL_ATTRIBUTES, nor combination of it with DAPI_READ_DEFINED_ATTRIBUTES does not return  Proxy-Genereator-DLL value and a few others (also very important). Perhaps it is what Microsoft sometimes calls a "feature" (this has been tested with the code as listed in this book on Exchange server 5.0).

Anyway, using DAPI_READ_DEFINED_ATTRIBUTES for an Addr-Type object have returned 15 attributes to me, which is equal to what Exchange Admin lists when asked for raw properties. The only difference between Exchange Administrator output and that of the DumpItemAttributes function seems to be the Obj-Class attribute. Exchange Admin lists it as "Object-Class" which is obviously similar but not quite the same. Also, the value for Object-Class is binary and the dialog allows you to choose between two values there. Contrary to this, the Obj-Class attribute is text and the value is "Addr-Type".
 

[ Contents | Home ]

Send comments and suggestions to niko@wrconsulting.com
Copyright © 1997-1998 by Nik Okuntseff