Directory API - Starting and Ending a DAPI Session
One of the ways to access MS Exchange directory objects
programmatically is to use Directory API. This topic describes - how. It has a
few sample code fragments to illustrate the concept.
Starting and Ending a DAPI Session
There are a couple of functions that you would perhaps see quite often: they are
DAPIStart and DAPIEnd. The first one initializes a DAPI session and the last one
terminates it. When you initialize DAPI session with DAPIStart, a handle is
returned. This handle is required as a parameter to a few other DAPI functions
(such as DAPIRead). The following simple code fragment (DAPIStartEnd sample)
illustrates how to use this pair of functions.
uses DAPI;
procedure TForm1.Button1Click(Sender: TObject);
var
DSession:DAPI_HANDLE; (* Output parameter. Points to
the handle of the directory operation session *)
DAPIParms:DAPI_PARMS; (* Input parameter. Points to a DAPI_PARMS
structure containing the directory interface object. *)
pDAPIEvent:PDAPI_EVENT; (* The DAPI_EVENT structure
contains information about errors that are encountered during the execution of a
DAPI function *)
begin
DAPIParms.dwDAPISignature:=DAPI_SIGNATURE;
DAPIParms.dwFlags := DAPI_EVENT_ALL;
// Initialize DAPI
pDAPIEvent:=DAPIStart(@DSession,@DAPIParms);
if Assigned(pDAPIEvent) then
ShowMessage('Error')
else
// We have DAPI session. We can use it here...
begin
...
...
...
// Terminate DAPI session
DAPIEnd(@DSession);
end;
end;
DAPIStart creates a DAPI session, and DAPIEnd terminates it. If you run the
above fragment in the debugger, there are a few things that you could notice:
- DAPIStart function is expensive. It requires significant amount of time.
For example, it may take 10 seconds to complete on a Pentium-200 system
under average load.
- DAPIStart creates second thread.
- DAPIEnd terminates this thread.
The above code assumes that Auto Naming rules are properly defined (use Tools -
Options menu of the Exchange Administrator program to see and modify current
settings). Both the "Display name generation" and "Alias name
generation" rules are required. If you try to execute the DAPIStart without
them it'll fail with pDAPIEvent.dwDAPIError
error $80001010.
Starting a DAPI Session on a Remote Machine
You may easily access a remote Exchange server directory. This is accomplished
by specifying the directory service agent (DSA) name in the DAPI_PARMS structure
before calling the DAPIStart:.
DAPIParms.pszDSAName :=
'MyRemoteExchangeServer'; // Exchange server computer name
If you don't specify DSA name the DAPIStart will attempt to use the local
one. If local one is not found, the first one found on the network will be used.
There are two important potential points of failure when communicating to a
remote DSA.
Registry
Local registry must be
properly set up. DAPI relies on two registry values under
HKEY_CURRENT_USER\Software\Microsoft\Exchange\MSExchangeAdminCommon key. If this
key was never set up the DAPIStart will fail with the following result:
"No Auto Naming rule was defined for %1. The default rule %2 will be
used if no value for %1 is specified in the import file. An Auto Naming rule can
be defined using the Options menu item in the Exchange Administrator
program."
A clean machine does not have this key. You'll need to either set up the
Exchange Administrator on such machine (the setup program takes care of the
registry), or import the registry data (use Import Registry File / Export
Registry File menu options of your regedit program).
The following two REG_SZ values are needed for DAPI: ANGAutotextFormat and
DNGAutotextFormat. Set first to "%First%1Last" and second to %First
%Last". Also, you'll need a REG_DWORD value named AdminLangID set up to
0x409 as described in MSDN Library article "INFO: Items Required to Use
DAPI". However, I was able to use DAPI without it. I have provided
the DAPI.reg file in the Bin directory in my samples. This file contains all
three entries. If you double-click it when using Windows NT Explorer, it will
import them into appropriate place in the registry.
DLLs
Make sure you have the following DLLs in
your path: Dapi.dll, Libxds.dll, Exchmem.dll. If you install Exchange
Administrator on the system, they will be in your path. A clean machine,
however, does not have them. You need to copy them from the machine where you
have Exchange Administrator installed.
Right Security Context
You need to use correct security context for remote calls. The account used for
remote access should be given appropriate permissions on Exchange server (or
site). This may be done with Exchange Administrator as follows: invoke
Properties dialog for the site, and on its Permissions tab add needed account.
Only globally visible domain accounts may be used. If you try to use DAPI
without proper security setup, it is likely to fail with the following error:
"Could not bind to the Microsoft Exchange Directory server %2. %1".
This is an insufficient security permissions error.
Using DAPI Calls in a Windows NT service
You may want to use DAPI in your Windows NT service application. The same two
problems (registry and correct security context) apply here as well.
Registry
You need to configure the system registry as I have described above. Importing
the registry file works fine. However, in case of the Windows NT service
you may run the service under different account. You will need to configure this
service account for DAPI access by logging on interactively and setting up the
HKEY_CURRENT_USER\Software\Microsoft\Exchange\MSExchangeAdminCommon key. Then
the system will know how to obtain Exchange entries for the service even when
nobody is logged on.
Right Security Context
It is possible to run a Windows NT service in the SYSTEM security context.
However, the SYSTEM account is useless in this situation. If you try to access
DAPI in the system context, the DAPIStart will fail with confusing "No Auto
Naming rule was defined..." error. The error means DAPI can't find registry
value that defines Auto Naming rule. Using the SYSTEM account for network
activities is usually not a good idea. This account uses NULL credentials (no
password and no domain name). It is possible to configure a remote system for
such access. However, in case of DAPI, the problem occurs earlier when
DAPI can't locate necessary registry key. It will fail even when you run the
service on an Exchange server computer.
Performance Drawback of DAPIStart
One thing that you should consider when deciding whether to use DAPI or not is
the performance drawback of the DAPIStart function. As I have mentioned, it may
take 10 seconds to complete. Obviously, it is not a good sign. The other thing
that you may discover is the need to call DAPIStart/DAPIEnd pairs many times if
you want to modify objects in different containers with DAPIWrite. This is
because DAPIWrite requires proper initialization of DAPI_PARMS pszContainer
member. This initialization is done during the DAPIStart call. On a good sign,
only the first call to the DAPIStart is so time-consuming. Subsequent calls to
DAPIEnd and DAPIStart again go much faster.
An alternative here is to use MAPI for access to directory objects. However,
this requires logging on to a MAPI profile with MAPILogonEx function. This
profile may not be available. For example, this may not be appropriate for
writing setup programs for end users.
Compiled DELPHI 5
Application
|