Novell is now a part of Micro Focus

Integrating with the NetWare Administrator Utility Using the Snapin Services SDK

Articles and Tips: article

KARL BUNNELL
Developer Support Engineer
Developer Support

01 Dec 1996


Discusses what an NWAdmin Snapin is and outlines three levels of integration to NWAdmin, including how to add a menu item, how to add a "Details Page," and how to extend the NWAdmin main browser to accomodate a custom object class.

Introduction

Novell Directory Services is a distributed, hierarchical, extensible database that provides the application developer with a multitude of services that greatly enhance the power of enterprise network-aware applications. One of the most powerful capabilities provided by NDS is an extensible schema. The Novell SDK provides the developer with APIs that can be used to add custom object and attribute class definitions to the NDS schema. NDS can then be used as the single source for the location of object names and attributes such as telephone number, E-mail address and location for any application that would normally have it's own, proprietary name database.

Once NDS has been extended to accommodate the object names and attributes for your application it would be great to have one utility for configuring and administering them. This is where the NetWare Administrator (NWAdmin) utility comes in. The NetWare Administrator utility is the network administrator's view and configuration console for the NDS tree. The Novell SDK provides the Snapin Services SDK to allow application developers to extend the NetWare Administrator utility to accommodate custom extensions to the NDS schema.

This article will discuss what an NWAdmin Snapin is, outline three levels of integration to NWAdmin- how to add a menu item to the "Tools" pull-down menu, how to add a "Details Page" to an existing object class Multi-Page Edit Window (MPEW) and maintain the NWAdmin "look and feel" by using NWAdmin custom controls and how to extend the NWAdmin main browser to accommodate a custom object class.

What Is an NWAdmin Snapin?

A Snapin is a Windows DLL that is loaded by NWAdmin at load time. Snapins are developed using the Snapin Services SDK. The Snapin SDK is a 'C' interface library that includes import libraries for both the Borland and Microsoft compilers. NWAdmin uses an INI file or a system registry setting to determine which Snapin DLLs to load (search for Technical Information Document 100660 at http://devsup.novell.com/sample.htm for additional information on INI and registry settings).

The quickest and simplest way to integrate with NWAdmin is to add an item to the "Tools" drop-down menu (see Figure 1). This option is well suited for launching standalone network-administration utilities.

Figure 1: Adding a Menu Item to the Tools Menu.

The code for adding this menu selection is very straightforward (see Figure 2). The Snapin DLL must export a function called InitSnapin(). NWAdmin looks for this function after loading the Snapin DLL in order to determine what work will be accomplished by the Snapin. Adding a menu item requires that you call NWARegisterMenu(). The first parameter is a window class name that indicates to NWAdmin when the menu selection should appear under the "Tools" menu. If NWA_VIEW_BROWSER is passed as the first parameter then the selection will only appear when an NDS browser window is open. NWA_VIEW_CONSOLE indicates that the menu item appear even when no NDS browser window is open.

The second parameter menu parent ID, should be NULL unless a hierarchical menu is desired, in which case, this should be set to the menu ID of its parent menu. The next significant parameter is the Menu Action Proc. This is a pointer to the action procedure that will execute when the menu item is selected from the "Tools" menu. The action code can reside within the Snapin DLL itself or this function could call the Windows API WinExec() (16-bit) or CreateProcess() (32-bit) which can be used to launch an external DOS or Windows application. The next parameter of note is the Menu Valid Proc. This callback is called by NWAdmin to determine whether the menu selection should be enabled or not (greyed out).

Upon the successful return code from NWARegisterMenu() return NWA_RET_SUCCESS to indicate all is well for the Snapin to proceed. The complete example on how to add a selection to the tools menu can be downloaded from http://devsup.novell.com/sample.htm (search for TID number 100393).

Figure 2: The code for adding a Menu Item to the Tools Menu.

int _export FAR PASCAL InitSnapin()

{

nuint16 menuIDPlain = 0;

NWARegisterMenu (

/* > Menu location  */   NWA_VIEW_CONSOLE,

/* > Menu Parent Id */   0,

/* > Menu Parent  */   NULL,

/* > Menu Option  */   MF_STRING,

/* < Menu ID  */   &menuIDPlain,&
/* > Menu String  */   "P&lain Menu",&
/* > Menu Hint  */   "This is a plain menu",

/* > Menu Action Proc */  PlainMenuAction,

/* > Menu Valid Proc */  PlainMenuValid,

/* > NWAdmin ver.  */   NWA_SNAPIN_VERSION);

    return NWA_RET_SUCCESS;

}

Adding a Details Page to an Existing Object

The NWAdmin NDS browser presents bitmap representations for most of the base-class effective object classes that are part of the base NDS schema. These include "User," "Group," and "Volume" objects, just to name a few. Suppose you extend the base-schema object class "User" to include a new attribute definition named "Photo." NWAdmin already displays a Multi-Page Edit Window (MPEW) dialog for the "User" object when double-clicked but you want to add a Details Page to the existing pages for administration and viewing of "Photo." Each Details Page is used to configure an attribute or logical grouping of attributes.

Figure 3: Multi-Page Edit Window (MPEW) for Object Details.

The first step in adding a Details Page to an MPEW is to call NWARegisterObjectProc() (Figure 4) from within your InitSnapin() function. This function indicates to NWAdmin the object class to which this Details Page will be added. The first parameter, Class Type, specifies that the Snapin references an NDS object. The Class Type of NWA_FS_OBJECT_TYPE can be specified to operate on a file system object. Class Name specifies the base object class to which the Details Page will be added.

Figure 4: Adding a Details Page to an Existing Class.

NWARegisterObjectProc(

   /* Class type */ NWA_DS_OBJECT_TYPE,



   /* Class name */ C_USER, 



   /* Devel. Info */ "Novell, Inc.  All rights reserved.",



   /* HINSTANCE    */ hDLL, 



   /* Obj Call back    */ (NWASnapinObjectProc) contrlsProc, 



   /* Version              */ NWA_SNAPIN_VERSION

);

This must be an existing object class that NWAdmin already provides an MPEW for, such as "User" or "Group", in order to add a Details page to the MPEW. The third parameter, Developer Information, is set to reflect information about the Snapin developer. The fourth parameter, HINSTANCE, should be set to the instance handle of the Snapin DLL. The fifth parameter, Object Callback Procedure, specifies a callback procedure that serves as the communication medium between the Snapin DLL and NWAdmin. NWAdmin sends Windows messages to the Snapin via this callback procedure, and the Snapin replies by returning the requested data in response to the message. The final parameter is the NWAdmin Snapin version.

The first message that NWAdmin sends the Object Callback Proc is NWA_MSG_INITSNAPIN. In response to this message, allocate a NWAPageStruct (see Figure 5) for each Details Page you will be adding to the MPEW. Set dlgProc to the dialog box callback procedure that will handle control messages for that Details Page. Specify the resource name for the dialog box control in resName and the title you want to appear on the Details Page button of the MPEW in pageTitle.

Figure 5: NWAPageStruct as Defined in NWSnapin.h.

typedef struct tagNWAPageStruct

{

  DLGPROC dlgProc; /* dialog procedure       */

  HINSTANCE hDLL;  /* resource DLL handle    */

  LPSTR resName;   /* resource name          */

  LPSTR pageTitle; /* title of the page in the listbox */

  LPARAM initParam; /* initialization parameters   */

} NWAPageStruct;

The next message NWAdmin will send to the Object Callback Proc is NWA_MSG_GETPAGECOUNT. In response to this message, return the number of Details Pages the Snapin will add to the MPEW. This is also a good time to read information from NDS in preparation to populate the dialog box controls for your Details Pages. Now that NWAdmin knows the number of Details Pages to register, it sends a NWA_MSG_REGISTERPAGE for each page. You need to send back a pointer to a NWAPageStruct with all of the appropriate fields populated in the param2 parameter. The param1 parameter indicates the page number to register.

Because param1 returns the page number, it is convenient to allocate an array of NWAPageStruct and populate each in response to NWA_INIT_SNAPIN, and then index into the array using the value of param1 to populate the fields for the NWAPageStruct sent back in param2. Set the hDLL field of NWAPageStruct to the instance handle of the Snapin DLL. Once the Details Pages are registered, NWAdmin has established the relationship between the Details Page button and a dialog box callback procedure that will handle the interaction with that page.

Developing the Details Page Dialog Box Procedure

The dialog box callback procedure for the Details Page is coded just like any other Windows dialog box control callback, with one important constraint. The definition for the height and width constraints of the dialog box control must lie within the size constraints of the MPEW (see Figure 6). The dialog box control itself can contain any of the standard dialog box controls such as Buttons, Combo Boxes, Lists, etc. NWAdmin communicates with the dialog box callback by sending it Windows messages. The NWA_WM_F1HELP message is sent when the "Help" button is clicked on the MPEW to allow context-sensitive help to be provided for that Snapin Page.

The dialog box callback procedure is responsible for indicating to NWAdmin that a change has occurred in one of its controls. This is accomplished by sending the NWA_WM_SETPAGEMODIFY message to the window handle passed to the Object Callback Procedure. This causes the corner of the corresponding Details Page to turn black, indicating to the administrator that a change was made on that Details Page and that clicking "OK" will make the changes permanent. The NWA_WM_CANCLOSE message is sent when a modification is made to the Details Page and the MPEW is closed by clicking on the "OK" button.

Figure 6: Example of Resource Compiler Script for Dialog Box Control Size.

CONTRLS DIALOG 19, 20, 234, 200



STYLE WS_CHILD | WS_BORDER



FONT 8, "MS Sans Serif"

{

   Controls....

}

NWAdmin sends the Snapin DLL the NWA_MSG_MODIFY message if a change is made on any of the Snapin DLL's Details Pages when the "OK" button is clicked on the MPEW. You can either save changes to NDS in response to the NWA_WM_CANCLOSE message for each Details Page or store modifications for all Details Pages at once in response to NWA_MSG_MODIFY.

The NetWare Administrator Custom Controls

The NetWare Administrator provides access to some custom controls that facilitate making the best use of the limited real-estate afforded to the Details Page Dialog Box Control. The NWAdmin Snapin SDK makes these custom controls available to allow your Snapin DLL to have the same look and functionality as other NWAdmin-provided Details Pages. These include the Multi-Value Edit Dialog (MVED) (see Figure 7), the NDS Flat Browser (see Figure 8) and the File System Flat Browser.

Figure 7: NWAdmin Multi-Value Edit Dialog Control.

The Multi-Value Edit Dialog Control

The amount of space on the screen afforded to the dialog box control is limited. NWAdmin therefore provides a control that is an Edit Box with spinner controls to iterate through entries in a list. Just to the right of this control is a Button that allows entries to be added or removed from the list. By clicking on this button the MVED is presented (see Figure 7). This control is well-suited to attributes that have multiple values. The MVED can be configured to accept only specific input such as numbers, strings and NDS distinguished names. When the MVED is configured to accept only distinguished names, the DS Flat Browser (see Figure 8) is launched to allow the administrator to "walk" the tree to select NDS objects.

Figure 8: NWAdmin NDS Flat Browser Control.

This control is well suited for selecting values for "User" or "Operator" attributes. The MVED control is launched by calling NWACreateMVED() (see Figure 9). The MVED callback proc is used to initialize the control and to retrieve values from the control. NWAdmin sends the MVED callback proc the NWA_MSG_MVED_INITCOUNTand the NWA_MSG_MVED_INITVALUE messages to initialize the control with values. Set the param1 to the number of initial values, NWAdmin will send that number of NWA_MSG_MVED_INITVALUE messages, one for each value. Set param2 to the value to be placed in the control.

The initial values must conform to the edit type defined for the MVED control (see Figure 10). If the MVED control is configured as edit type NWA_MVED_VALUE_DISTNAME, NWAdmin will send the NWA_MSG_FBFILTER_COUNT and NWA_MSG_FBFILTER_VALUE messages to configure the object types that can appear in the NDS Flat Browser. Set param1 to the count of filter types and set param2 to the value of the filter (e.g., "User" or "Group").

Figure 9: NWACreateMved().

NWACreateMved( 

   /* hwnd           */ hwnd,  

   /* User Parameter */ 0,       

   /* ID Edit        */ IDD_EDIT,

   /* ID Spin        */ IDD_SPIN, 

   /* ID Button      */ IDD_BUTTON, 

   /* Edit Type      */ NWA_MVED_VALUE_PRINTABLE,

   /* Edit Length    */ 32,

   /* Label          */ "Add Strings",

   /* Context str    */ DS_ROOT_NAME,

   /* Browser flags  */ 0,

   /* MVED callback  */ MvedProc);

The functions NWAGetMvedCount() and NWAGetMvedValue() are used to retrieve the values from the MVED control. The count is used to iterate through the values contained within the control. In order for these functions to be made available to the Snapin DLL you must load the appropriate DLL (e.g. LoadLibrary(NWA_SCROLL_DLL)) in the Object Callback Procedure.

Figure 10: MVED Control Edit Types.

NWA_MVED_VALUE_STRING     0x0000



NWA_MVED_VALUE_READONLY   0x0001



NWA_MVED_VALUE_DISTNAME   0x0002



NWA_MVED_VALUE_DIGITSONLY 0x0004



NWA_MVED_VALUE_PRINTABLE  0x0005

The NDS and File System Flat Browsers

The Flat Browser controls can be launched independent from the MVED add-distinguished-names control. The browser can be configured to filter specific object classes so that only objects that fit the criteria of the filter will be displayed in the browse window.

The NDS Flat Browser is launched using the NWALaunchDSFlatBrowser() (see Figure 11) function and the FS Flat Browser is created by calling the NWALaunchFSFlatBrowser() function. The NDS Flat Browser control is used to "walk" the NDS tree hierarchy (see Figure 8) to select NDS objects, while the File System Flat Browser is used to bridge the gap between the NDS Tree hierarchy and the file system. The browser will only display NDS Volume objects when traversing the tree and file system objects such as files and directories when the NDS volume object is double-clicked. As you might expect, NWAdmin communicates with this control just as it does with the MVED control, by sending messages to its callback procedure.

The object filter is configured using the same messages as described for the MVED control. The object count and values are retrieved by NWA_MSG_FBOBJECT_COUNT and NWA_MSG_FBOBJECT_VALUE messages. One NWA_MSG_FBOBJECT_VALUE message will be sent for each value and a pointer to the value is stored in param2. I have concentrated on the NDS Flat Browser here, but the details for handling the File System Flat Browser are the same. A complete example on how to add a Details Page to an existing object and how to use the NWAdmin custom controls can be downloaded from http://devsup.novell.com (search for SNAPCTRL.EXE).

Figure 11: NWALaunchDSFlatBrowser() Function.

NWALaunchDSFlatBrowser(

/* Window handle           */ hwnd,

/* User Parameter          */ hwnd,

/* context string          */ ndsContext,

/* Selected object string  */ NULL,

/* Navigator Object String */ NULL,

/* Selected Object Label   */ "Selected Object",

/* Browser Flag            */ NWA_FB_MULTIPLE_SELECT,

/* NWAFlatBrowser CB Proc  */ DSFlatBrowserLaunchProc);

Extending the NetWare Administrator To Recognize a NewObject Class

The NWAdmin main NDS browser view supports the standard NDS schema object classes that ship with NetWare 4.x. If the NDS Schema Services APIs are used to extend the NDS schema to accommodate a new effective object class, NWAdmin cannot without the aid of a Snapin DLL, to create or display an instance of this new class. Adding this capability via a Snapin DLL is similar to adding a Details Page to an existing object class. The first step to adding this capability to the Snapin DLL is to call NWARegisterObjectProc() from within your InitSnapin()function.

Figure 12: Snapin Object Operations.

NWA_OP_CREATE        0x00000004L

NWA_OP_DETAILS       0x00000008L

NWA_OP_MOVE          0x00000010L

NWA_OP_COPY          0x00000020L

NWA_OP_RENAME        0x00000040L

NWA_OP_DELETE        0x00000080L

NWA_OP_USERTEMPLATE  0x00000100L

NWA_OP_SEARCH        0x00000200L

The new object class must be passed as the second parameter to NWARegisterObjectProc() to register this new object class to NWAdmin. This establishes the callback procedure that NWAdmin uses to communicate with the Snapin DLL. All of the work described in the section on adding Details Pages to an existing object class is identical for adding Details Pages to a new object class; therefore, that information will not be repeated here. NWAdmin sends the NWA_MSG_INITSNAPIN to start things off. In response to this message the Snapin DLL must load three bitmaps that represent the new object class using the LoadBitmap() function. Each bitmap must represent one of the three possible object types that the NWAdmin main browser supports. These are:

  • the standard bitmap to represent the new object class

  • an alias bit map to represent aliases to the new object class

  • a read-only bitmap for read-only NDS objects.

The alias bitmap should be the standard bitmap with a mask next to it and the read only bitmap should be the standard bitmap with an "x" superimposed over it. Once a handle to each bitmap has been obtained with LoadBitmap(), these handles, along with a translated name for the new object class, are passed to NWAAddClassData(). The translated name is the name that will appear in the New Object Dialog within NWAdmin (see Figure 14). This is especially useful if the NDS schema object class name you have registered (see http://devsup.novell.com/doc.htm to register NDS schema extensions) does not clearly represent what the object class is. (For example, the object class defined as "MYORG765:ObjectClass1566Q" may actually be "Fax Server.")

Figure 13: Object Create Dialog.

Use the function NWAAddPropertyNameTranslation() to add name translations for schema attribute class definitions. You have learned how to handle the next two messages: NWA_MSG_GETPAGECOUNTand NWA_MSG_REGISTERPAGE. NWAdmin discovers the operations allowed against the object by sending the NWA_MSG_GETVALIDOPERATIONS message. In response, the Snapin DLL returns all of the allowed operations on the object combined using a bitwise OR (see Figure 12).

Any operations not allowed on the object will cause these operations to be disabled in the "Object" menu selection of NWAdmin. If the Snapin DLL responds with NWA_OP_CREATE as one of the valid operations, NWAdmin will send the message NWA_MSG_CREATEOBJECT when object is selected from the New Object Dialog (see Figure 14). The Snapin DLL is responsible for creating the NDS object within the tree. This includes presenting the Create Dialog box with check box control options to "Create Another Object" or "Define Additional Properties" (see Figure 13). If the object class has mandatory attributes, the create dialog must prompt the user for these attribute values.

Figure 14: NWAdmin New Object Dialog.

If "Create Another Object" is selected, return NWA_RET_CREATEANOTHER, and if "Define Additional Properties" check box is selected, return NWA_RET_SHOWDETAILS. NWAdmin will handle these operations on behalf of the Snapin DLL. The context of where the object is to be created is passed as the first parameter to the Object Callback Procedure. This allows you to concatenate the name typed into the Create Dialog with this context and pass this string to NWDSAddObject(). Fortunately, NWAdmin will handle the other operations, such as move, copy, rename and delete for you.

NWAdmin sends a message that corresponds to the operation about to take place on the object (e.g., NWA_MSG_QUERYMOVE, NWA_MSG_QUERYCOPY, NWA_MSG_RENAME, and NWA_MSG_QUERYDELTE). The Snapin DLL allows NWAdmin to perform the default operation by returning NWA_RET_DODEFAULT in response to these messages to perform some other operation before allowing the operation to continue. The last message the Snapin DLL receives is NWA_MSG_CLOSESNAPIN. In response to this message, free the bitmaps registered to NWAdmin with NWARemoveClassData() and free the bitmaps themselves with DeleteObject(). Any attribute class translations should be removed with NWARemovePropertyNameTranslation(). Once the Snapin DLL is loaded, NWAdmin presents the registered bitmap and translated name for the object class in the New Object Dialog (see Figure 14). A complete example can be downloaded from http://devsup.novell.com/sample.htm. Search for JSERVOBJ.C.

The Snapin SDK eliminates the need to write your own administration utility, greatly reducing the development time of your application and allowing you to use one NDS administration console to manage all NSD objects on the network. Imagine a world where all of the disparate databases on the network share a common name space (NDS) and a common administration tool! The dream has finally become a reality with NetWare 4.x, Novell NDS, the NetWare Administrator, and the Snapin SDK.

* Originally published in Novell AppNotes


Disclaimer

The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© Copyright Micro Focus or one of its affiliates