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 demonstrates how this may be accomplished.

function DumpItemAttributes(pdeAttributes, pdeValues:PDAPI_ENTRY):TStrings;
var
   
i,
    iCount:Cardinal;
    pAttributeLoc,
    pdeValuesLoc:PATT_VALUE;
begin
   
Result:=TstringList.Create;
    // We assume both pointers to be valid
    if (not Assigned(pdeAttributes) or not Assigned(pdeValues)) then
        begin
            ShowMessage('ERROR! One of DAPI_ENTRY pointers is NIL...');
            exit;
        end;

// We also assume number of attributes and values equal
if (pdeAttributes.unAttributes <> pdeValues.unAttributes ) then
begin
    ShowMessage('ERROR! Number of attributes is not equal to number of values...');
    Exit;
end;

iCount := pdeAttributes.unAttributes;
ShowMessage('Total number of attributes: ' + IntToStr(iCount));


for i:= 0 to iCount-1 do
begin
    pAttributeLoc := PATT_VALUE(ULONG(pdeAttributes.rgEntryValues) + (sizeof(ATT_VALUE)*i));
    pdeValuesLoc := PATT_VALUE(ULONG(pdeValues.rgEntryValues) + (sizeof(ATT_VALUE)*i));

    case pdeValuesLoc.DapiType of

DAPI_NO_VALUE: Result.Add(StrPas(pAttributeLoc.Value.pszA) + #0 +'NO VALUE'); 
DAPI_INT: Result.Add(StrPas(pAttributeLoc.Value.pszA) + #0 + IntToStr(pdeValuesLoc.Value.iValue));
DAPI_STRING8:Result.Add(StrPas(pAttributeLoc.Value.pszA) + #0 +StrPas(pdeValuesLoc.Value.pszA));
DAPI_UNICODE:Result.Add(StrPas(pAttributeLoc.Value.pszA) + #0 +'Unicode string here...');
DAPI_BOOL:
    if (pAttributeLoc.Value._bool) then
            Result.Add(StrPas(pAttributeLoc.Value.pszA) + #0 +'TRUE')
    else
        Result.Add(StrPas(pAttributeLoc.Value.pszA) + #0 +'FALSE');
DAPI_BINARY:Result.Add(StrPas(pAttributeLoc.Value.pszA) + #0 +'Binary Data Here...');
else
// We are not supposed to get here...
    Result.Add(StrPas(pAttributeLoc.Value.pszA) + #0 +'We are not supposed to get here...');
end;

end;

end;

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.

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".

We have DELPHI Class that process reading and writing with DAPI.

Compiled DELPHI 5 Apllication