Sample Code
-----------
//--dsexport-mod.c--------------------------------------------------
//
// MODIFIED Directory Service Export Sample.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
//
// Modified to allow the export of user defined attributes of
// objects.
// This code is not guaranteed to be memory safe.
//------------------------------------------------------------------
#include "edk.h"
#include "dapi.h"
//
// Names of Command Line Arguments
//
#define ARG_FILE "FILE"
#define ARG_BASEPOINT "BASEPOINT"
#define ARG_CONTAINER "CONTAINER"
#define ARG_CLASSES "CLASSES"
#define ARG_DSA "DSA"
#define ARG_HELP1 "?"
#define ARG_HELP2 "HELP"
#define ARG_SERVER "SERVER"
#define ARG_ALL_RECIPIENTS "ALL_RECIPIENTS"
#define ARG_ONLY_BASEPOINT "ONLY_BASEPOINT"
#define ARG_DIST_LIST "DIST_LIST"
#define ARG_MAILBOX "MAILBOX"
#define ARG_REMOTE_ADDRESS "REMOTE_ADDRESS"
#define ARG_ALL_CLASSES "ALL_CLASSES"
#define ARG_HIDDEN "HIDDEN"
#define ARG_SUBTREE "SUBTREE"
#define ARG_EXPLIST "EXPLIST"
//
// Table of Command Line Switches for _HrExpandCommandLineArgument()
//
static char * rgpszArgArray[] = {
ARG_FILE,
ARG_BASEPOINT,
ARG_CONTAINER,
ARG_CLASSES,
ARG_DSA,
ARG_HELP1,
ARG_HELP2,
ARG_SERVER,
ARG_ALL_RECIPIENTS,
ARG_ONLY_BASEPOINT,
ARG_DIST_LIST,
ARG_MAILBOX,
ARG_REMOTE_ADDRESS,
ARG_ALL_CLASSES,
ARG_HIDDEN,
ARG_SUBTREE,
ARG_EXPLIST
};
//
// Variables For Command Line Arguments
//
char szExportFile[MAX_PATH+1] = {0};
char szDsaName[MAX_PATH+1] = {0};
char szServerName[MAX_PATH+1] = {0};
char szBasePoint[MAX_PATH+1] = {0};
char szParentContainer[MAX_PATH+1]= {0};
DWORD ControlFlags = 0;
ULONG cClasses = 0;
LPSTR* lppszClasses = NULL;
char szExportList[MAX_PATH+1] = {0};
//
// Other Variables
//
BOOL fDisplayedHelp = FALSE;
DWORD cLoggedErrors = 0;
//
// Function Declarations
//
static HRESULT HrParseCommandLine(
IN int argc,
IN char *argv[]);
static VOID ShowUsage(
void);
static VOID ShowHelp(
void);
static HRESULT HrDoBatchExport(
void);
//
// Functions
//
//$--main------------------------------------------------------
// Main function that performs directory export.
//-------------------------------------------------------------
int main( // RETURNS: exit code
IN int argc, // number of arguments on command line
IN char *argv[]) // array of command line arguments
{
HRESULT hr = NOERROR;
BOOL IsMAPIInit = FALSE;
DEBUGPUBLIC("main()\n");
printf( "\n" );
hr = MAPIInitialize(NULL);
if(FAILED(hr))
{
goto cleanup;
}
IsMAPIInit = TRUE;
// Get export parameters from the command line.
hr = HrParseCommandLine(argc, argv);
if (FAILED(hr))
{
goto cleanup;
}
// Do batch export.
hr = HrDoBatchExport();
if (FAILED(hr))
{
goto cleanup;
}
cleanup:
if(IsMAPIInit == TRUE)
{
MAPIUninitialize();
}
// Successful completion.
if (fDisplayedHelp)
{
hr = NOERROR;
}
else if (SUCCEEDED(hr))
{
fprintf(stderr,
"Export operation completed successfully.\n");
}
// Error completion.
else if (cLoggedErrors == 1)
{
fprintf(stderr,
"ERROR: 1 error written to NT Event Log.\n");
}
else if (cLoggedErrors > 1)
{
fprintf(stderr,
"ERROR: %d errors written to NT Event Log.\n",
cLoggedErrors);
}
MAPIFREEBUFFER(lppszClasses);
return _nEcFromHr(hr);
}
//$--HrParseCommandLine---------------------------------------------
// Read export configuration from command line.
//------------------------------------------------------------------
static HRESULT HrParseCommandLine( // RETURNS: HRESULT
IN int argc, // Number of arguments on command line
IN char *argv[]) // Array of command line arguments
{
HRESULT hr = NOERROR;
HRESULT hrT = NOERROR;
char * pszArgument = NULL;
char * pszValue = NULL;
int i = 0;
LPTSTR lpszSep = "%\0";
DEBUGPRIVATE("HrParseCommandLine()\n");
// If there are no command line arguments then show a usage
// message.
if (argc < 2)
{
ShowUsage();
hr = E_FAIL;
goto cleanup;
}
// Do an initial check for /? or /HELP. If found, show a help
// message and do not do any other parsing.
for (i = 1; i < argc; i++)
{
hr = _HrExpandCommandLineArgument(
argv[i], rgpszArgArray,
ARRAY_CNT(rgpszArgArray), NULL,
&pszArgument, &pszValue);
if (SUCCEEDED(hr) && pszArgument &&
(!_stricmp(pszArgument,ARG_HELP1) ||
!_stricmp(pszArgument,ARG_HELP2)))
{
ShowHelp();
hr = E_FAIL;
goto cleanup;
}
}
// Loop through and parse all the command line arguments.
for (i = 1; i < argc; i++)
{
hrT = _HrExpandCommandLineArgument(
argv[i], rgpszArgArray,
ARRAY_CNT(rgpszArgArray), NULL,
&pszArgument, &pszValue);
if (FAILED(hrT))
{
hr = hrT;
if (hr == EDK_E_NOT_FOUND)
{
fprintf(stderr,
"ERROR: unknown command line flag: %s\n",
argv[i]);
continue;
}
else
{
fprintf(stderr,
"ERROR: unable to parse command line.\n");
goto cleanup;
}
}
// Parse flag arguments that do not take a value.
if (pszArgument != NULL && pszValue == NULL)
{
// ALL_RECIPIENTS
if (!_stricmp(pszArgument,ARG_ALL_RECIPIENTS))
{
ControlFlags |= DAPI_EXPORT_RECIPIENTS;
}
// ONLY_BASEPOINT
else if (!_stricmp(pszArgument,ARG_ONLY_BASEPOINT))
{
ControlFlags |= DAPI_EXPORT_BASEPOINT_ONLY;
}
// DIST_LIST
else if (!_stricmp(pszArgument,ARG_DIST_LIST))
{
ControlFlags |= DAPI_EXPORT_DIST_LIST;
}
// MAILBOX
else if (!_stricmp(pszArgument,ARG_MAILBOX))
{
ControlFlags |= DAPI_EXPORT_MAILBOX;
}
// REMOTE_ADDRESS
else if (!_stricmp(pszArgument,ARG_REMOTE_ADDRESS))
{
ControlFlags |= DAPI_EXPORT_CUSTOM;
}
// ALL_CLASSES
else if (!_stricmp(pszArgument,ARG_ALL_CLASSES))
{
ControlFlags |= DAPI_EXPORT_ALL_CLASSES;
}
// HIDDEN
else if (!_stricmp(pszArgument,ARG_HIDDEN))
{
ControlFlags |= DAPI_EXPORT_HIDDEN;
}
// SUBTREE
else if (!_stricmp(pszArgument,ARG_SUBTREE))
{
ControlFlags |= DAPI_EXPORT_SUBTREE;
}
// Other flag (must take a value).
else
{
fprintf(stderr,
"ERROR: flag /%s requires a value\n",pszArgument);
hr = HR_LOG(E_FAIL);
}
}
// Parse flag arguments that take a value.
else if (pszArgument != NULL && pszValue != NULL)
{
if (!_stricmp(pszArgument,ARG_DSA))
{
strncpy(szDsaName, pszValue, MAX_PATH);
szDsaName[MAX_PATH] = 0;
}
else if (!_stricmp(pszArgument,ARG_SERVER))
{
strncpy(szServerName, pszValue, MAX_PATH);
szServerName[MAX_PATH] = 0;
}
else if (!_stricmp(pszArgument,ARG_FILE))
{
strncpy(szExportFile, pszValue, MAX_PATH);
szExportFile[MAX_PATH] = 0;
}
else if (!_stricmp(pszArgument,ARG_BASEPOINT))
{
strncpy(szBasePoint, pszValue, MAX_PATH);
szBasePoint[MAX_PATH] = 0;
}
else if (!_stricmp(pszArgument,ARG_CONTAINER))
{
strncpy(szParentContainer, pszValue, MAX_PATH);
szParentContainer[MAX_PATH] = 0;
}
else if (!_stricmp(pszArgument,ARG_CLASSES))
{
hr = HrStrTokAll(pszValue,
lpszSep,
&cClasses,
&lppszClasses);
if(FAILED(hr))
{
fprintf(stderr,
"ERROR: syntax error in /%s\n",
pszArgument);
goto cleanup;
}
}
// EXPLIST
else if (!_stricmp(pszArgument,ARG_EXPLIST))
{
strncpy(szExportList, pszValue, MAX_PATH);
}
// Other flag (must not take a value).
else
{
fprintf(stderr,
"ERROR: flag /%s does not take a value\n",
pszArgument);
hr = HR_LOG(E_FAIL);
}
}
// Catch unknown arguments.
else
{
fprintf(stderr, "ERROR: unknown argument %s\n", argv[i]);
hr = HR_LOG(E_FAIL);
}
}
// Make sure we have all the info we need.
if (SUCCEEDED(hr))
{
if (*szDsaName == 0)
{
fprintf(stderr, "ERROR: please specify /%s\n", ARG_DSA);
hr = HR_LOG(E_FAIL);
}
if (*szExportFile == 0)
{
fprintf(stderr, "ERROR: please specify /%s\n", ARG_FILE);
hr = HR_LOG(E_FAIL);
}
}
cleanup:
RETURN(hr);
}
//$--ShowUsage-----------------------------------------------------
// Show usage information.
//-----------------------------------------------------------------
static VOID ShowUsage(void) // RETURNS: nothing
{
DEBUGPRIVATE("ShowUsage()\n");
printf("USAGE: DSEXPORT [Flags]\n\n");
printf(" [Flags] Enter DSEXPORT /? for details\n");
fDisplayedHelp = TRUE;
}
//$--ShowHelp------------------------------------------------------
// Show help information.
//-----------------------------------------------------------------
static VOID ShowHelp(void) // RETURNS: nothing
{
DEBUGPRIVATE("ShowHelp()\n");
printf(
"Directory Service Export sample.\n\n");
printf(
"USAGE: DSEXPORT [Flags]\n\n");
printf(
" /FILE= Name of export file\n");
printf(
" /SERVER= Exchange server name\n");
printf(
" /DSA= Directory Service Agent name\n");
printf(
" /BASEPOINT= DN of Directory basepoint object\n");
printf(
" /CONTAINER= RDN of Directory container beneath "
"BASEPOINT\n");
printf(
" /CLASSES= Object classes (separated by '%%')\n");
printf(
" /EXPLIST= Attribute list for Export\n");
printf(
" /HELP or /? Display help screen\n");
printf(
" /ONLY_BASEPOINT Export only the BASEPOINT object\n");
printf(
" /ALL_RECIPIENTS Export all recipients\n");
printf(
" /DIST_LIST Export distribution list "
"recipients\n");
printf(
" /MAILBOX Export mailbox recipients\n");
printf(
" /REMOTE_ADDRESS Export remote address recipients\n");
printf(
" /ALL_CLASSES Export all classes\n");
printf(
" /HIDDEN Export hidden objects of the selected "
"classes\n");
printf(
" /SUBTREE Export subtree\n");
fDisplayedHelp = TRUE;
}
//$--DoBatchExport-------------------------------------------------
// Do batch export of directory objects.
//-----------------------------------------------------------------
static HRESULT HrDoBatchExport(void) // RETURNS: HRESULT
{
HRESULT hr = NOERROR;
BEXPORT_PARMS BexportParms = {0};
LPBEXPORT_PARMS lpBexportParms = {0};
DAPI_ENTRY AttributesEntry = {0};
ATT_VALUE AttributesValue = {0};
LPTSTR pszExportListCopy = NULL;
hr = MAPIAllocateBuffer(strlen(szExportList) + 200,
&pszExportListCopy);
DEBUGPRIVATE("HrDoBatchExport()\n");
lpBexportParms = &BexportParms;
lpBexportParms->dwDAPISignature = DAPI_SIGNATURE;
lpBexportParms->pszExportFile = szExportFile;
lpBexportParms->pszBasePoint = szBasePoint;
lpBexportParms->dwFlags = ControlFlags | DAPI_EVENT_ALL;
if (*szParentContainer)
{
lpBexportParms->pszContainer = szParentContainer;
}
if (*szDsaName)
{
lpBexportParms->pszDSAName = szDsaName;
}
if (*szServerName)
{
lpBexportParms->pszHomeServer = szServerName;
}
if(lppszClasses != NULL)
{
lpBexportParms->rgpszClasses = lppszClasses;
}
if(&AttributesEntry != NULL)
{
strcpy(pszExportListCopy, "Obj-Class,");
strcat(pszExportListCopy, szExportList);
lpBexportParms->pAttributes = &AttributesEntry;
AttributesEntry.unAttributes = 1;
AttributesEntry.ulEvalTag = TEXT_LINE;
AttributesEntry.rgEntryValues = &AttributesValue;
AttributesValue.DapiType = DAPI_TEXT;
AttributesValue.Value.pszValue = pszExportListCopy;
AttributesValue.size = lstrlen(pszExportListCopy);
}
lpBexportParms->chColSep = DAPI_DEFAULT_DELIM;
lpBexportParms->chQuote = DAPI_DEFAULT_QUOTE;
lpBexportParms->chMVSep = DAPI_DEFAULT_MV_SEP;
cLoggedErrors = BatchExport(lpBexportParms);
if (cLoggedErrors)
{
hr = HR_LOG(E_FAIL);
}
RETURN(hr);
}