Skip to content

Domino Upgrade Services (DUS)

Chapter 9-10
Domino Upgrade Services (DUS)

Introduction

The DUS SPI (Domino Upgrade Services/Service Provider Interface) allows developers to develop a Domino Upgrade Service DUS DLL. This DUS DLL is an extension to the Domino Administration/Registration User Interface. The DUS DLL can be invoked at the time of User Registration. Domino Administrators will now have the ability to easily register users from other directories. Domino provides DUS services which allow user conversion from cc:Mail, MS Mail, Exchange, Windows 32-bit, or another LDAP directory. The SPI will allow you to integrate your own migration tool.

This chapter gives an overview of the SPI calls along with an illustration of the sample DUS found under sample directory ...\admin\samples\dussp.

Overview of the SPI calls

The DUS calls are defined in dus.h. Also refer to the HCL C API Reference for further information.

  • DUSGetName - Provides a name and description of the DUS at the time the 'People and Groups Migration' dialog is displayed.
  • DUSStart - Signifies that this DUS has either been selected from the 'Foreign Directory Source ' source list in the 'People and Groups Migration' dialog or registration is about to begin on users selected for this DUS. Also 'Migration Options' and 'Advanced' dialog is done here by setting options defined in fDUSxxx. Please refer to the HCL C API Reference for further definition of fDUSxxx. Any secondary UI necessary to gather more information concerning this DUS is handled within DUSStart. For example, more information may be needed before retrieving all the users/groups pertaining to this DUS.
  • DUSRetrieveUsers - This function allocates and passes back an array of DUS_ENTRY structs containing information about the users available for this migration.
  • DUSRetrieveGroups - This function allocates and passes back an array of DUS_ENTRY structs containing information about the users, within a group, available for this migration.
  • DUSGetUserInformation - This function returns full information about a user/group selected to be migrated.
  • DUSGetGroupInformation - This function returns information about the group selected to be migrated.
  • DUSGetGroupMembers - This function returns membership information about the group. This function is called after DUSGetGroupInformation.
  • DUSAdvancedDlg - If the flag fDUSAdvancedDlg is passed into DUSStart, then the 'Advanced....' button on the 'People and Groups Migration' dialog will be highlighted. When this button is activated DUSAdvancedDlg will be called to display the modal dialog box created for this particular DUS. This dialog box may ask for specific options relating to this DUS.
  • DUSRegistrationNotify - Notifies the DUS that Domino User Registration for the user represented by UserName is about to start or has just finished.
  • DUSConvertMailFile - Converts DUS mail into a Domino mail file.
  • DUSExtendedErrorText - This call retrieves the text to be displayed in the event that a call to the DUS extension DLL fails and the DLL wishes to return an error string.
  • DUSStop - Notifies the DUS that this session (started with DUSStart) is over.
  • DUSTerm - Terminates the DUS.

Getting Started

A DUS application involves migrating users/groups from a foreign directory source to a Domino source. All of the DUS functions will be called by the DUS framework. However your DUS may not require processing for all the DUS functions. Keep in mind your DUS application will need to declare all of the DUS functions. Any DUS function that is not applicable to your application should return NOERROR. The following is a brief description of the DUS functions which make up a DUS application (please refer to the DUS sample found in the samples directory ..\samples\admin\dusspi):

  • DUSGetName is essential for passing in a DUS name and description.
A resource file would need to be set up for <b>DUSGetName </b>to include, for example :<br>
    <i>mswin32.rc</i><br>

STRINGTABLE DISCARDABLE
BEGIN
#include <globerr.h>
MSG_DUS_ADDIN_NAME "C API DUSSPI Sample"
MSG_DUS_ADDIN_VERSION "Version 1.0"
STR_DUS_NAME "C API DUS SPI Sample"
STR_DUS_DESCRIPTION "C API Domino Upgrade Service Sample"
END
....

duspierr.h
/ String 0 must always be the application's task name.
String 1 must be the version.
/
#define PKG_DUS PKG_ADDIN
#define MSG_DUS_ADDIN_NAME (PKG_DUS+0)
#define MSG_DUS_ADDIN_VERSION (PKG_DUS+1)
#define STR_DUS_NAME (PKG_DUS+2)
#define STR_DUS_DESCRIPTION (PKG_DUS+3)
...

dusname.c

DUSGetName(HMODULE hInstance, char *DUSNameBuf, WORD DUSNameBufLen, char *DUSDescriptionBuf,
WORD DUSDescriptionBufLen)

{

...

OSLoadString(hInstance, STR_DUS_NAME, DUSNameBuf, DUSNameBufLen);
OSLoadString(hInstance, STR_DUS_DESCRIPTION, DUSDescriptionBuf, DUSDescriptionBufLen);

.....

}

  • DUSStart is essential for starting the DUS. This is where a DUS context is initialized, a secondary user interface is established and other DUS environment information is set such as the setting of any fDUSxxx flags. Although not necessary each DUS function allows for a handle to the context of the DUS running. A DUS Context may include some of the following when set up:
dusspi.h
typedef struct
{
HMODULE hDUSModule;
WORD ExtendedError;
WORD ExtendedErrorLevel;
DUSPROGRESSBARPROC ProgressBarProc;
DUSLOGEVENTPROC LogEventProc;
}DUS_CONTEXT, *PDUS_CONTEXT;
....

dusspi.c
DUSStart(HMODULE hInstance, HANDLE *pRethContext, NOTEHANDLE hUserNote, DWORD *pRetStartFlags, DUSPROGRESSBARPROC DUSProgressBar, DUSLOGEVENTPROC DUSLogEvent)
{
...
/* This is where the following flags would be set.
- fDUSDoMailConversion
- fDUSGenerateRandPWs
- fDUSAdvancedDlg
- fDUSUseFullNameProvided
- fDUSUseMailFileNameProvided
- fDUSAllowEmptyGroups
*/
/* In our case we want this DUS to:
1) generate random passwords
*/
*pRetStartFlags = fDUSGenerateRandPWs;

/* Allocate the DUS Context Buffer. */
pDUSCtx = NULL;
size = sizeof(DUS_CONTEXT);
if(error = OSMemAlloc(0, size, pRethContext))
pRethContext = NULLHANDLE;
else
{
pDUSCtx = OSLock(DUS_CONTEXT, *pRethContext);
memset(pDUSCtx, 0, (size));
}

pDUSCtx->hDUSModule = hInstance;
pDUSCtx->ProgressBarProc = DUSProgressBar;
pDUSCtx->LogEventProc = DUSLogEvent;
if(pDUSCtx != NULL)
{
OSUnlock(*pRethContext);
pDUSCtx = NULL;
}
.....
return(error);
}

  • DUSRetrieveUsers and/or DUSRetrieveGroups will be called by the DUS framework to retrieve the people/groups available for migration. It is not necessary to provide processing for both. For example you may only be interested in specific users and not groups or the reverse. This information can come in any form in which your users/groups are stored. For example the information may come from an input file. Whatever form the information is in, the DUS application must take that information and fill in a DUS_ENTRY for each user/group that is to be chosen for migration.
  • If you are interested in group information within your DUS application then you may want to provide processing within DUSGetGroupInformation. A NOTEHANDLE to a group document is available within DUSGetGroupInformation. This NOTEHANDLE is supplied from the DUS framework. It is either a NOTEHANDLE to an existing group found in the Domino Directory or it is a NOTEHANDLE to a newly created group just added to the Domino Directory. With this NOTEHANDLE to the group it is possible to set certain fields found within a Group. Such as ADMINP_GROUP_TYPE, which defines the type of group, and MAIL_LISTDESCRIPTION_ITEM, which gives a description of the group Please refer to stdnames.h for some of the field descriptions defined for a Group document. The DUS framework also supplies a dialog box with 'Group Import Options' which allow the administrator to make changes to any of the group information previously set.
  • Along with DUSGetGroupInformation there is DUSGetGroupMembers which will get called after DUSGetGroupInformation. This is where processing is done to get a list of actual members within the group selected. The member list will be passed back to the DUS framework via handles to a group members list and a user members list. The DUS framework will display the group(s) and their member(s) under 'People/Groups to migrate'.
  • Once the administrator executes the 'Migrate' button then the DUS framework will call DUSGetUserInformation within your DUS. A NOTEHANDLE to a user note is available to set name, address, etc., for this user about to be migrated. Refer to stdnames.h , User registration document field definitions. The users are then added to the registration queue. DUSStop is called within your DUS to signify this DUS session is over and this would be the time to free up any memory allocated for the DUS context. This is followed by a call to DUSTerm which allows for any other additional cleanup that may be necessary within your DUS application.
  • An optional function to implement within your DUS would be DUSAdvancedDlg. With this function an additional dialog box can be implemented to support additional information that may be needed when migrating users. The flag fDUSAdvancedDlg must be set in DUSStart in order for this function to be called within the DUS. The 'Advanced' button on the People and Groups Migration' screen will be enabled.

When Registration Begins

Once registration begins for the users in the registration queue, your DUS application will be started again which allows for additional processing on the user about to be registered. Therefore when coding DUSStart a check should be made on the NOTEHANDLE passed in. If the NOTEHANDLE is a NULLHANDLE then the DUS application is being called from the 'People and Groups Migration' screen. Otherwise DUSStart is being called from user registration.

The function which will be called within your DUS application is DUSRegistrationNotify. The first time the DUS framework calls this function the parameter bAfterEvent will be FALSE. This will signify registration is about to begin on this user. When DUSRegistrationNotify is called a second time, the parameter bAfterEvent will be TRUE to signify registration has completed for this user. Processing within DUSRegistrationNotify allows the DUS to take pre or post registration action to supplement registration-related activity.

The function DUSDoMailFileConversion will be called within your DUS after registration is complete only if the fDUSxxx flag has been set to fDUSDoMailConversion. This flag along with all other fDUSxxx flags get set in DUSStart.

The registration process finishes up and DUSStop and DUSTerm are called to complete and unload your DUS application.

Error Handling

The function DUSExtendedErrorText is available to handle errors within a DUS application. There is the option for an information message (DUS_ERROR_LEVEL_INFO), a warning message (DUS_ERROR_LEVEL_WARNING) or an error message (DUS_ERROR_LEVEL_ERROR), which allows the shutdown of the DUS application.

To activate the error handling within the DUS framework the DUS application must return a legitimate error. One such legitimate error would be ERR_DUS_EXTENDED_ERROR, which for most error conditions will be sufficient. This error is defined in the header file regerr.h. Another possible error could be ERR_DUS_CONTEXT_CORRUPTED, which is also defined in regerr.h

For a corrupted context handle, all that is necessary to return is the error ERR_DUS_CONTEXT_CORRUPTED. For all other errors it is necessary to set up parameters ErrorBuffer and pErrorLevel. ErrorBuffer contains an error string defined within the DUS application and pErrorLevel is the type of error to be displayed (refer to DUS_ERROR_LEVEL_XXX within the API reference guide).

How the DUS is Activated

From 'Register Person -- New Entry' there is a 'Migrate people....' button which will send you to the 'People and Groups Migration' Screen where selection of a DUS is made and the activation of a DUS begins.



First the notes.ini file will be searched for the environment string 'UpgradeApps'. 'UpgradeApps' will specify the name(s) of the DUS DLL(s), comma delimited if more than one, to be loaded and initialized. All third party DUS DLLs will need to be referenced in the 'UpgradeApps' environment variable in order to be recognized by Domino. For example:

UpgradeApps=NDUSSPI.DLL

After the 'UpgradeApps' environment variable is read a call to DUSGetName is made for each DUS to provide a name and description of the DUS.
Since the 'NT Users' DUS is part of Domino core there is no need to have the DUS supplied in the 'UpgradeApps' environment variable.

In this example we are selecting the 'C API DUS SPI Sample' DUS.



Once selected DUSStart is called to get any additional information needed for this DUS. In this case DUSStart is only going to initialize the context for this DUS. If further information was required then a secondary UI would need to be implemented within DUSStart.

Once DUSStart has successfully completed DUSRetrieveUsers and DUSRetrieveGroups are called allocating an array of DUS_ENTRY structs containing information about the users/groups available for this migration. This is shown in the display labeled 'Available people/groups'. Also passed into DUSStart is the 'Migration Options' fDUSGenerateRandPWs 'Generate random passwords' is checked off. The DUS sample NDUSSPI is only concerned with Users and not groups.




The administrator can now select users/groups to migrate.

If any group is selected the DUS framework will first call DUSGetGroupInformation within your DUS application. Once processing has completed within DUSGetGroupInformation the DUS framework will display the following screen, which displays the current 'Group Import Options'. From this screen the administrator has the option to make different choices for migration of this group. Once the administrator completes his/her choices control is brought back to the DUS framework where a call to DUSGetGroupMembers is made to your DUS application.





Once all of the users/groups have been selected within the 'People and Groups Migration' screen and the administrator activates 'Migrate', the DUS function DUSGetUserInformation will be called to provide all information for each of the users selected for import/registration. Control is returned back to the 'Register Person -- New Entry' screen. The users/groups selected will be added to the 'User Registration Queue' database 'userreg.nsf'. From there the administrator is all set to register the users. When the administrator begins registration via the 'Register' or 'Register All' button, not only will User registration begin but the DUS will be called again to complete the migration of this particular user.

---