Novell is now a part of Micro Focus

AppNote: Getting Settable Parameter Values in NetWare

Novell Cool Solutions: AppNote
By Russell Bateman

Digg This - Slashdot This

Updated: 13 Jul 2005

Russell Bateman
Senior Software Engineer
Server-library Development

7/13/2005 Update: After the updated publication of this AppNote, Russell discovered problems with the underlying OS primitives, and we have updated his article to reflect what there is to learn there.

9/22/2004 Update: After the initial publication of this AppNote on 7 July 2004, Russell discovered an improvement to his process, and we have updated his article to reflect those changes.

This How-to AppNote discusses how to obtain the values of command-line-settable parameters from a NetWare-loadable Module (NLM) and explores creating and maintaining your own settable parameters.


Introduction and Interfaces
Getting Settable Parameter Values from NetWare
Managing Your Own Settable Parameters for NetWare
Registering to Implement a Settable Parameter for NetWare
Topics NLM development, kernel and low-level code
Products NetWare 5, NetWare 6, NetWare 6.5
Audience Developers
Level Advanced

Introduction and Interfaces

Many aspects of NetWare are configured using a "set command" facility that has been present on NetWare since the beginning. The current state or value of set parameters on NetWare can be very useful to an NLM application.

The header, netware.h, prototypes the interfaces for this feature. The original function signatures were misspelled and have remained that way. The header uses the C preprocessor to correct this. I say this only because if you go into the system debugger and type

# b=GetSettableParameterValue

you will be disappointed because the entry point is really GetSetableParameterValue.

It is possible to set as well as get a set parameter, but you must be very careful in setting it. Experiment and test to make certain you do not crash the server. Here are all the prototypes:

int GetSettableParameterValue( int slot, const char *name, void
     *value );
int ScanSettableParameters( int scanCategory, uint32_t
     *scanSequence, const char *name, int *type, uint32_t *flags,
     int *category, void *description, void *value, int
     *lowerLimit, int *upperLimit );
int SetSettableParameterValue(int slot, const char *name, void

The scan function allows you to list all the settable parameters currently extant. You can also get their type and category for whatever use those might be to you. Look at the documentation at instead.

The slot argument actually holds the connection to NetWare the NLM has. I use 0 consistently. Since LibC doesn't accept or give out connection slots as CLib does and as 0 always works, it seems pointless to go beyond this explanation except to say that I don't believe that using a non-zero connection slot belonging to an actual, authenticated object has any effect upon the success of failure of these calls.

Getting Settable Parameter Values from NetWare

For getting a value, you have to know what data type a value is. If it is a string, then you pass a pointer to a buffer (value) with ample room to handle anything that will get copied into it. If an integer, then to a 4-byte wide integer.

String Data
For example, in the library time code, I have to find out what the rules for time zones in effect are:

char   buffer[80];

err = GetSettableParameterValue(0,
               "Start of Daylight Savings Time", buffer);

The set parameter is represented by an ASCII string containing the exact wording of the parameter. It is case-insensitive.

If you lived in my locale, the following response would come back:

"(April Sunday First 2:00:00 AM)"

I parse this into a rule formalism in order to calculate whether a given date and timestamp, say one passed to ANSI function localtime, is on summer time or not.

Integer Data
Elsewhere, in CLib for example, I get the daylight offset in this manner:

int   daylightOffset;

err = GetSettableParameterValue(0,
               "Daylight Savings Time Offset", &daylightOffset);

This offset is recorded in seconds off standard time, usually 3600 (1 hour).

Managing Your Own Settable Parameters for NetWare

It is just as useful to create, initialize and dispose of new settable parameters for NetWare as it is to read the ones it already has. Many of the existing ones are created by loaded NLMs. This is how the monolithic CLib in the days of NetWare 4.11 handled whether to track memory allocations or not.

Registering to Implement a Settable Parameter for NetWare

First, we start by allocating a resource tag as shown. Subsequently, we must register our settable parameter. There used to be two interfaces to do this, the newest one appeared at least by NetWare 5.0. However, the categories which used to be fixed values prior to some point in the development of NetWare 5.x no longer are. Therefore, using the old interface isn't any good unless you happen to be writing for a pre-5.x platform.

While the third argument to RegisterSetParameter was originally an integer, the actual values associated with parameter categories fluctuates now with the order of registration. New categories are now being registered and old ones no longer exist, so these values must float.

If you are pretty certain that your category already exists, i.e.: you have chosen a category you are already seeing at the console or in the NetWare Remote Manager, you can just use the string in the exact spelling and capitalization. The example published in the original version of this article used the integer. Here, we've eliminated the older, alternative call and begun using a string name.

Despite this, however, the category number could be useful in this function, a less common case and for that you will have to define USE_CATEGORY_NUMBER before including netware.h so that the correct prototype for RegisterSetParameter comes into the compilation. To find out what an existing settable parameter's category number is (so you can reuse it for one you're registering), call ScanSettableParameters until the name you know matches the one returned in that function's third argument.

If your copy of netware.h doesn't contain USE_CATEGORY_NUMBER, then it is probably an old version that only has the prototype for RegisterSetParameter with an integer third argument. That was the usual prototype in force when this article was originally written.

#include <netware.h> 
#define NAME        "CLIB Memory Checking" 
#define DESCRIPTION "Toggle memory checking support for CLib on/off."\
" This controls whether CLib memory checking is active or not which" \
" is of use to developers of certain applications, libraries or"     \
" drivers."

int     gMemTrack = FALSE;
void   *gNlmHandle = (void *) NULL;
rtag_t  gMemTrackRTag = (rtag_t) NULL; 

void ToggleMemTrackSettableParmCB
   uint32_t	oldValue
#pragma unused(oldValue)

   // this toggles our memory tracking stuff on and off...
   gMemTrack = (oldValue != FALSE) ? FALSE : TRUE;

void SetUpCLibDebugParameters( void ) 
   gMemTrackRTag = AllocateResourceTag(getnlmhandle(), 
                                 "CLIB Memory Tracking", 
   gNlmHandle = getnlmhandle();

   RegisterSetParameter(gNlmHandle, gMemTrackRTag, "Miscellaneous",
	ToggleMemTrackSettableParmCB, SP_HIDE|SP_USE_CATEGORY_NAME,

SP_USE_CATEGORY_NAME (0x40000000) is a new flag added to netware.h.

Once this is done, the new set command can be used to turn memory tracking on and off:

MYSERVER: Set CLIB Memory Checking ON

The value field of the structure points to the place in memory where the state of the registered settable parameter will be recorded and examined. Remember that this place must be absolutely reliable as commands issued from the console will access it whether or not your NLM ever does. Don't drop your NLM without removing your settable parameter formally.

Note that ON and OFF, TRUE and FALSE, etc. are interpreted as 1 and 0 and set into the space provided, here, gMemTrack. You should never use any other category than "Miscellaneous" unless you know exactly what you are doing. I believe that a type of SP_TYPE_STRING makes the value field of the structure char *, while SP_TYPE_NUMBER makes it int or long, etc. At least, this seems obvious even though I cannot lay claim ever to have used it.

Neither I have never used the lower_limit or upper_limit fields of the settableparms_t structure. I believe they are somehow related to the scan function.

Call DeRegisterSettableParameters when your NLM unloads and the settable parameter will no longer be there. If you do not do this, the OS will think the location pointed at by value in the register structure is valid and will dereference it resulting in getting unstable and unrelated values, overwriting data that this address wrongly references, or even page faulting.

Since we don't know for certain what the integer value associated with our category really is, it won't matter what we pass in the third argument. We'll just pass 0. This value is only used to pass to the event-report call-back of the Event Notification manager for EVENT_SET_PARM_REMOVE (see event.h and documentation for RegisterForEventNotification). The event structure has been enhanced starting in the next version of NetWare to contain the category name and the number no longer comes from this argument; instead, it comes from the appropriate category node for the removing settable parameter.

void RemoveCLibDebugParameters( void ) 
   DeRegisterSetParameter(gNlmHandle, gMemTrackRTag, 0, NAME);


Settable parameters in NetWare are a useful feature to which few know how to code and fewer still have coded. This article is not written in exhaustive detail, but it should give you enough information to create some useful parameters for debugging or even for active functionality if your application needs it.

In particular, we have not explained how to create new categories, but the comments on set parameter categories in this updated article should clear that process up enough to enable you to do this.

Finally, we did not discuss SetSettableParameterValue in this article but its use should follow easily from what is given here.

Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions.

© Copyright Micro Focus or one of its affiliates