procedure TfrmMAIN.btOKClick(Sender: TObject);
const
Classes : array [0..1] of PChar = ('Addr-Type',nil);
var
bep:BEXPORT_PARMS;
deAttributes:PDAPI_ENTRY;
avAttrName:PATT_VALUE;
CountAtt:Integer;
dwResult:DWORD;
begin
if SaveDialog1.Execute then
begin
if Assigned(SiteInfo) then FreeAndNil(SiteInfo);
SiteInfo:=TSiteInfo.Create(Trim(ebESA.Text));
if SiteInfo.GetInfo then
begin
ZeroMemory(@bep, SizeOf( BEXPORT_PARMS ));
// Initialize BEXPORT_PARMS struct
bep.dwDAPISignature := DAPI_SIGNATURE;
bep.pszDSAName:=PCHAR(SiteInfo.SrvName);
bep.dwFlags := DAPI_EXPORT_ALL_CLASSES or
DAPI_EXPORT_HIDDEN or
DAPI_EXPORT_SUBTREE or
DAPI_RAW_MODE;
bep.pszExportFile := PCHAR(SaveDialog1.FileName);
// Base point is current organization object
bep.pszBasePoint := PCHAR(SiteInfo.OrganizationDNString);
// Specify which objects to export. This overrides DAPI_EXPORT_ALL_CLASSES
// in dwFlags.
bep.rgpszClasses := @Classes;
CountAtt:=4;
avAttrName:=DAPIAllocBuffer(SizeOf(ATT_VALUE)*CountAtt,nil);
ZeroMemory(avAttrName,SizeOf(ATT_VALUE)*CountAtt);
PATT_VALUE(ULONG(avAttrName)+ULONG(SizeOf(ATT_VALUE)*(CountAtt-4)))^:=
PATT_VALUE(ToAttValue('Object-Class',DAPI_TEXT))^;
PATT_VALUE(ULONG(avAttrName)+ULONG(SizeOf(ATT_VALUE)*(CountAtt-3)))^:=
PATT_VALUE(ToAttValue('Directory Name',DAPI_TEXT))^;
PATT_VALUE(ULONG(avAttrName)+ULONG(SizeOf(ATT_VALUE)*(CountAtt-2)))^:=
PATT_VALUE(ToAttValue('Proxy-Generator-DLL',DAPI_TEXT))^;
PATT_VALUE(ULONG(avAttrName)+ULONG(SizeOf(ATT_VALUE)*(CountAtt-1)))^:=
PATT_VALUE(ToAttValue('File-Version',DAPI_TEXT))^;
deAttributes:=DAPIAllocBuffer(SizeOf(DAPI_ENTRY), nil);
ZeroMemory(deAttributes, SizeOf(DAPI_ENTRY));
deAttributes.unAttributes := CountAtt;
deAttributes.ulEvalTag := TEXT_VALUE_ARRAY;
deAttributes.rgEntryValues:=DAPIAllocBuffer(SizeOf(ATT_VALUE)*(CountAtt),deAttributes);
ZeroMemory(deAttributes.rgEntryValues, SizeOf(ATT_VALUE)*(CountAtt));
deAttributes.rgEntryValues:=avAttrName;
bep.pAttributes := deAttributes;
dwResult:=BatchExport(@bep);
if Assigned(avAttrName) then
DAPIFreeMemory(avAttrName);
if Assigned(deAttributes) then
DAPIFreeMemory(deAttributes);
end;
end;
if Assigned(SiteInfo) then FreeAndNil(SiteInfo);
end;
The file named "Dump.txt" may be found in example with the result of this export operation on my Exchange server. In my particular
case it contains 10 exported objects.
If you like to export Mailboxes and DList, change classes to this:
procedure TfrmMAIN.btOKClick(Sender: TObject);
const
Classes : array [0..2] of PChar = ('Mailbox','Distribution-List',nil);
var
....
begin
......
end;
procedure TfrmMAIN.btOKClick(Sender: TObject);
var
bep:BEXPORT_PARMS;
deAttributes:PDAPI_ENTRY;
avAttrName:PATT_VALUE;
CountAtt:Integer;
dwResult:DWORD;
begin
if SaveDialog1.Execute then
begin
if Assigned(SiteInfo) then FreeAndNil(SiteInfo);
SiteInfo:=TSiteInfo.Create(Trim(ebESA.Text));
if SiteInfo.GetInfo then
begin
ZeroMemory(@bep, SizeOf( BEXPORT_PARMS ));
// Initialize BEXPORT_PARMS struct
bep.dwDAPISignature := DAPI_SIGNATURE;
bep.pszDSAName:=PCHAR(SiteInfo.SrvName);
bep.dwFlags := DAPI_EXPORT_ALL_CLASSES or
DAPI_EXPORT_HIDDEN or
DAPI_EXPORT_SUBTREE or
DAPI_RAW_MODE;
bep.pszExportFile := PCHAR(SaveDialog1.FileName);
bep.pszBasePoint := PCHAR(SiteInfo.OrganizationDNString);
bep.rgpszClasses := nil;
CountAtt:=2;
avAttrName:=DAPIAllocBuffer(SizeOf(ATT_VALUE)*CountAtt,nil);
ZeroMemory(avAttrName,SizeOf(ATT_VALUE)*CountAtt);
PATT_VALUE(ULONG(avAttrName)+ULONG(SizeOf(ATT_VALUE)*(CountAtt-2)))^:=
PATT_VALUE(ToAttValue('Object-Class',DAPI_TEXT))^;
PATT_VALUE(ULONG(avAttrName)+ULONG(SizeOf(ATT_VALUE)*(CountAtt-1)))^:=
PATT_VALUE(ToAttValue('Obj-Dist-Name',DAPI_TEXT))^;
deAttributes:=DAPIAllocBuffer(SizeOf(DAPI_ENTRY), nil);
ZeroMemory(deAttributes, SizeOf(DAPI_ENTRY));
deAttributes.unAttributes := CountAtt;
deAttributes.ulEvalTag := TEXT_VALUE_ARRAY;
deAttributes.rgEntryValues:=DAPIAllocBuffer(SizeOf(ATT_VALUE)*(CountAtt), deAttributes);
ZeroMemory(deAttributes.rgEntryValues, SizeOf(ATT_VALUE)*(CountAtt));
deAttributes.rgEntryValues:=avAttrName;
bep.pAttributes := deAttributes;
dwResult:=BatchExport(@bep);
if Assigned(avAttrName) then
DAPIFreeMemory(avAttrName);
if Assigned(deAttributes) then
DAPIFreeMemory(deAttributes);
end;
end;
if Assigned(SiteInfo) then FreeAndNil(SiteInfo);
end;
This code exports only class names and distinguished names for all objects in the organization. Again, the result of the dump may be found together with source files. If you look into Dump.txt file in BatchExportAll example, you'll notice that most of its contents is occupied by Class-Schema and Attribute-Schema objects, and only a small fraction in the end - by real physical "instances" of them. This is because my test installation of MS Exchange is very small - it contains only a few mailboxes.
The fragment above is different from the first one because I don't specify class names here. In the first sample I have initialized rgpszClasses member of BEXPORT_PARMS, thus telling that I specifically request Addr-Type objects only. Also, the number of exported attributes is different - I have decided for the sake of simplicity only export distinguished names (and class names). If you want to export other attributes - you need to do extra work initializing its pAttributes member.