Modifying Properties of a Directory Object with DAPIWrite

I have shown how attributes of a MS Exchange Directory item may be retrieved with DAPI functions, and dumped to the screen. Let us examine whether we could modify some attributes and write them to the directory.

The following two items are important when dealing with the DAPIWrite function.

Creating a New Mailbox with DAPIWrite

The following sample code illustrates how you can create a new Windows NT user account and associate it with MS Exchange mailbox with help of the DAPIWrite function:

procedure TfrmMain.btStartClick(Sender: TObject);
var
   
ObjectToRead:Array [0..255] of Char;
    TempStr:String;
    userprop:TStrings;
    i,ct:Integer;
    p:PCHAR;

    deAttributes,
    deValues:PDAPI_ENTRY;

    rgEntryAttributes,
    rgEntryValues:PATT_VALUE;

    pAccount,
    pPassword:PChar;

   
ulUSN:ULONG;

    FlagRandPass:DWORD;
begin 
    TempStr:=Trim(ebMailbox.Text);

    if cbCP.Checked then FlagRandPass:=
DAPI_CREATE_RANDOM_PASSWORD else
        FlagRandPass:=0;

FlagRandPass:=FlagRandPass or
DAPI_CREATE_NT_ACCOUNT;  


if TempStr=EmptyStr then
begin 
    ShowMessage('Please, type some value!');
    Exit;
end

if Assigned(SiteInfo) then SiteInfo.Free;
SiteInfo:=TSiteInfo.Create(Trim(ebESName.Text));

if SiteInfo.GetInfo then
begin 
// Check for started DAPI Session
    if DSession=DAPI_INVALID_HANDLE then
        begin 
            DAPIParms.dwDAPISignature:=DAPI_SIGNATURE;

       
DAPIParms.dwFlags := DAPI_EVENT_ALL or //Logs start...
                                           
FlagRandPass

DAPIParms.pszDSAName:=PChar(SiteInfo.SrvName);

// Initialize base point and container
DAPIParms.pszBasePoint := PChar(SiteInfo.SiteDNString);
DAPIParms.pszContainer := '/cn=Recipients';


ct:=3; //Number of Params

deAttributes:=DAPIAllocBuffer(SizeOf(DAPI_ENTRY), nil);
ZeroMemory(deAttributes, SizeOf(DAPI_ENTRY));


deAttributes.unAttributes := ct; //# of attributes
deAttributes.ulEvalTag := TEXT_VALUE_ARRAY;

rgEntryAttributes:=DAPIAllocBuffer(SizeOf(ATT_VALUE)*ct,nil);
ZeroMemory(rgEntryAttributes, SizeOf(ATT_VALUE)*ct);

PATT_VALUE(ULONG(rgEntryAttributes)+ULONG(SizeOf(ATT_VALUE)*(ct-3)))^:=
PATT_VALUE(ToAttValue('Object-Class',DAPI_TEXT))^;

PATT_VALUE(ULONG(rgEntryAttributes)+ULONG(SizeOf(ATT_VALUE)*(ct-2)))^:=
PATT_VALUE(ToAttValue('Common-Name',DAPI_TEXT))^;

PATT_VALUE(ULONG(rgEntryAttributes)+ULONG(SizeOf(ATT_VALUE)*(ct-1)))^:=
PATT_VALUE(ToAttValue('Home-Server',DAPI_TEXT))^;

deAttributes.rgEntryValues:=DAPIAllocBuffer(SizeOf(ATT_VALUE)*(ct), deAttributes);
ZeroMemory(deAttributes.rgEntryValues, SizeOf(ATT_VALUE)*(ct));

deAttributes.rgEntryValues:=rgEntryAttributes;

deValues:=DAPIAllocBuffer(sizeof(DAPI_ENTRY), nil);
ZeroMemory(deValues, sizeof(DAPI_ENTRY));

deValues.unAttributes := ct; //# of attributes
deValues.ulEvalTag := VALUE_ARRAY;

rgEntryValues:=DAPIAllocBuffer(SizeOf(ATT_VALUE)*ct,nil);
ZeroMemory(rgEntryValues, SizeOf(ATT_VALUE)*ct);

PATT_VALUE(ULONG(rgEntryValues)+ULONG(SizeOf(ATT_VALUE)*(ct-3)))^:=
PATT_VALUE(ToAttValue('Mailbox',DAPI_TEXT))^;

PATT_VALUE(ULONG(rgEntryValues)+ULONG(SizeOf(ATT_VALUE)*(ct-2)))^:=
PATT_VALUE(ToAttValue(TempStr,DAPI_TEXT))^;

PATT_VALUE(ULONG(rgEntryValues)+ULONG(SizeOf(ATT_VALUE)*(ct-1)))^:=
PATT_VALUE(ToAttValue('~SERVER',DAPI_TEXT))^;

deValues.rgEntryValues:=DAPIAllocBuffer(sizeof(ATT_VALUE)*(ct), deValues);
ZeroMemory(deValues.rgEntryValues, sizeof(ATT_VALUE)*(ct));

deValues.rgEntryValues:=rgEntryValues;


pAccount := Nil;
pPassword := Nil;
ulUSN := 0;


//Initialize DAPI   

(*
The DAPIStart function initializes a directory operation session.
*)

pDAPIEvent:=
DAPIStart(@DSession,@DAPIParms);

if Assigned(pDAPIEvent) then
begin 
    RaiseDAPIError(pDAPIEvent);
    DAPIFreeMemory(pDAPIEvent);
end 
else
// We have DAPI session. We can use it here...
begin 

pDAPIEvent :=
DAPIWrite(DSession,
DAPI_WRITE_CREATE,
deAttributes,
deValues,
@ulUSN,
@pAccount,
// Account
@pPassword); // Password

if Assigned(pDAPIEvent) then
    RaiseDAPIError(pDAPIEvent)
else
    ShowMessage('Account is Created!' + #13+#10+
                            'NT Account is: ' + StrPas(pAccount) + #13+#10+
                            'with Password: ' +StrPas(pPassword));

... etc....

Compiled DELPHI 5 example