Developer Links
SUPPORT FORUMS  
SAMPLE CODE & TIDS  
TEST/DEVELOPMENT KIT INFO
 
DEVELOPER LABS  
NOVELL SUPERLAB  
SUPPORT DOCUMENTS  
STRATEGIC/EXECUTIVE ISSUE TRACKING  
SYSOP PROGRAM  
     
Related Links
 
 
 
 
 
Related Links  
 

 
DEVELOPER SUPPORT HOME  

MAY 1993 VOLUME 5 NUMBER 5


INDEX


MAD'S COLUMN

Hello and welcome to the May 1993 issue of Bullets!

It has been several years since I left the hallowed halls of Academiaville, so I admit that my interest was piqued when the University of Texas asked if the Novell Developer Support Group would like to participate in a study.

Why study support? Or, what does improved service buy? The study was based on the idea that there is a correlation between higher customer satisfaction levels and how processed information flows within a support organization. If this theory were true, then we would be able to use the results of the study to improve the support we give customers. I felt we were duty bound to take part.

May is Customer Awareness month at Novell, and in keeping with our updated slogan, "Customer Driven and Living It," I quickly assessed that this study could be a simple, yet insightful self-appraisal.

Introspective processes like this study and Novell's Customer Satisfaction surveys of supported developers are essential to our organizations preventative health program. We appreciate the time that you spend answering questions about the support you've received.

Happy_Programming!

Mad Poarch
Director
Developer Support/Service


ARTICLES:

Capturing with NetWare 4.0 Directory Services

NetWare 4.0 Directory Services is the implementation of Novell's strategy to create global access to network services. Directory Services improves the Bindery environment with which NetWare 2.x and 3.x developers are familiar.

The NetWare 4.0 Directory takes its name from the conventional term referring to a information book full of names, addresses, telephone numbers and other data. No matter where they are located, the Directory allows you to locate services like queues in a network-wide fashion. The NetWare 2.x and 3.x server-based binderies only viewed information on a server-by-server basis.

This article explains the steps required to locate a print queue in the Directory, capture data to the queue, and finally print the data. The example program discussed in this article, DSCAP.ZIP, can be downloaded from Novell's NOVLIB forum on CompuServe. The file will be stored in Library 1 initially; after thirty days, it will be moved to Library 7.

Directory Services Terminology

A basic understanding of Directory Services terminology is required before attempting to capture to a queue.
Contex
The position in the Directory tree relative to the root.
Object
An entry in the directory tree.
Schema
Definition of the information types that dictate the way information is stored in the Directory. The types of information that are defined by the schema are inheritance, subordination, naming and attributes.
Inheritance
Directory Services' method for determining which objects will inherit the information types of other objects.
Subordination/Naming
Determines the structure of the Directory tree, thus identifying and showing objects' location in the tree.
Attribute Information
Describes what type of additional information an object can or must have associated with the object. Attribute types are defined within the schema by specific constraints and a specific syntax for their values.
Locale
Language-specific information for a particular location or region.
Unicode
Wide character encoding scheme that provides the basis for internationalization of the information in the Directory. All character strings exchanged between a directory server and a workstation are in unicode. The directory client agent handles the translation of unicode strings.

Capturing to a Print Queue

The basis for all entries in the Directory is a set of defined object classes referred to as the "base" schema. A Queue is one of the base object classes defined by the "base" schema. Other base object classes include Users, Computers, NCP Servers, etc. For a complete list of the base object classes, as well as other Directory information, see the NetWare 4.0 Directory Services Schema Specification provided with the NLM SDK for NetWare 4.0.

The Queue object class contains the following mandatory attributes:

  • Common Name
  • Host Server
  • Object Class
  • Queue Directory
The object ID of the queue on the server where the queue resides is required to issue the capture APIs. To find the queue and the queues Host Server attribute in the Directory, use the Directory Services NWDSSearch function.

Initializing

To use Directory Services to find the queue, you must initialize the requester and locale information as shown in Figure 1.

FIGURE 1: Initializing the requester and locale information

cCode=NWCallsInit(NULL,NULL);
if(cCode != 0)
  {
  printf("\nError in NWCallsInit.  Status: %04X  Line: %d",cCode,
            __LINE__);
  exit(1);
  }
NWLsetlocale(LC_ALL, "");
NWLlocaleconv((LCONV NWFAR *)&convert);

NDSPresent = NWIsDSAuthenticated();
if (NDSPresent)
  {
  cCode = NWInitUnicodeTables(convert.country_id,
convert.code_page);
  if (cCode)
    {
    printf("\nNWInitUnicodeTables: failed %04x", cCode);
    exit(1);
    }
  }
else
  {
  printf("\nNot a DS connection...program terminating...");
  exit(0);
  }

END of FIGURE 1
Before initializing locale information, an application must verify that it is running on an authenticated Directory Services connection. The authentication system makes it possible for an application or user to supply a password only once and gain access to multiple servers across the network. To verify authentication, you call NWIsDSAuthenticated(). Following a successful authentication, the locale specific unicode tables of the client agent are initialized and Directory Services specific functions can be issued.

Defining Context

Most Directory Services functions require context in the Directory tree. Therefore, the next step is to define the context to the Directory by calling NWDSCreateContext(). This application assumes the users current context in the Directory when locating the queue, including the object's subordination and inherited directory access.

Buffer Allocation

Most Directory Service functions require buffers of information to be passed and returned. These buffers must be allocated by Directory Services functions before they can be used. The search of the directory tree will require three different buffers:
  • Attribute Names buffer (attrNames)
  • Filter buffer (myFilter)
  • Object Information buffer (objectInfo)
The attrNames buffer explicitly specifies which attributes are to be returned. The filter parameter eliminates objects from the search space if they are superfluous to the client; information is only returned on objects which satisfy the filter conditions. The objectInfo buffer is returned when you issue a call to NWDSSearch() and search the Directory Services database for a queue.

To define the attribute information for the search, you use the attrNames buffer. First, you allocate the buffer by calling NWDSAllocBuf(). Then, initialize the buffer by indicating that the buffer will be used to search the Directory as shown in Figure 2.

FIGURE 2: NetWare 4.0 Directory Services buffer allocation

cDSCode = NWDSAllocBuf(DEFAULT_MESSAGE_LEN, &Names);
if(cDSCode)
  {
  printf("Error in NWDSAllocBuf: %d  Line: %d\n",cDSCode,
__LINE__);
  cleanup(cDSCode);
  }
cDSCode=NWDSInitBuf(context, DSV_SEARCH, Names);
if(cDSCode)
  {
  printf("Error in NWDSInitBuf: %d  Line: %d\n", cDSCode,
__LINE__);
  cleanup(cDSCode);
  }

END of FIGURE 2

Defining Search Filters

A filter Buffer must be allocated and initialized as a search filter. Doing so indicates to the Directory that the filter will be used as a search filter. The completed filter buffer stores the filter information supplied to NWDSSearch() and narrows the scope of the Directory search.

Filters require a filter cursor before data can be placed in the filter buffer. Calling NWDSAllocFilter() allocates a filter expression tree and initializes a cursor to the current insertion point. In short, the cursor provides the basis for the filter decision tree as the filter expression is built.

Building Decision Trees

The next step is building the filter decision tree, but the filter expression must be known before the filter tree expression can be built. The example code's expression is as follows:

Search the Directory for an object class equal to a queue and the name of the queue must be equal to the name of the queue passed as an argument to the example program.

With a filter tree expression in mind, you build the actual filter by appending filter tokens to the filter cursor. Tokens are pieces of the expression and each one represents a part of the filter expression (see Figure 4).

FIGURE 3: "Tokens" in filter expression

cDSCode = NWDSAddFilterToken(filterCursor, FTOK_ANAME,
                             A_OBJECT_CLASS, SYN_CLASS_NAME);
if(cDSCode)
  {
  printf("Error in NWDSAddFilterToken: %d  Line: %d\n",cDSCode,
            __LINE__);
  NWDSFreeFilter(filterCursor,NULL);
  cleanup(cDSCode);
  }
cDSCode = NWDSAddFilterToken(filterCursor, FTOK_EQ,
                             NULL, NULL);
if(cDSCode)
  {
  printf("Error in NWDSAddFilterToken: %d  Line: %d\n",cDSCode,
            __LINE__);
  NWDSFreeFilter(filterCursor,NULL);
  cleanup(cDSCode);
  }
cDSCode = NWDSAddFilterToken(filterCursor, FTOK_AVAL, A_QUEUE,
                             SYN_CLASS_NAME);
if(cDSCode)
  {
  printf("Error in NWDSAddFilterToken: %d  Line: %d\n",cDSCode,
            __LINE__);
  NWDSFreeFilter(filterCursor,NULL);
  cleanup(cDSCode);
  }
.
.
.
cDSCode = NWDSAddFilterToken(filterCursor, FTOK_END, NULL, NULL);
if(cDSCode)
  {
  printf("Error in NWDSAddFilterToken: %d  Line: %d\n",cDSCode,
            __LINE__);
  NWDSFreeFilter(filterCursor,NULL);
  cleanup(cDSCode);
  }
END of FIGURE 3
Once your have built the filter, you must terminate it with a FTOK_END filter token. The FTOK_END token indicates the end of the filter expression tree for the appropriate filter buffer and expression tree.

Finally, you must place the search filter into an input buffer for the subsequent call to NWDSSearch() with NWDSPutFilter(). NWDSPutFilter() frees the memory area allocated to the expression tree, including the memory area referenced by the filter cursor. Your application should save the filter buffer before calling NWDSPutFilter() if the filter is to be reused for successive filter searches.

Defining Attributes

After you have specified the filter, you can indicate the type of attributes to be returned. To do this, place the names of the attributes to be returned in the previously allocated AttrName buffer. The Host Server where the queue resides is the attribute required to satisfy the search in the example in Figure 4.

FIGURE 4: Host Server assignment and search

cDSCode = NWDSPutFilter(context, myFilter, filterCursor, NULL);
if(cDSCode)
  {
  printf("Error in NWDSPutFilter: %d  Line: %d\n",cDSCode,
__LINE__);
  cleanup(cDSCode);
  }
cDSCode = NWDSPutAttrName(context, Names, attrName);
if(cDSCode)
  {
  printf("Error in NWDSPutAttrName: %d  Line:  %d\n",cDSCode,
            __LINE__);
  cleanup(cDSCode);
  }
iterationHandle=0xFFFFFFFF;
cDSCode = NWDSSearch(context, DS_ROOT_NAME, DS_SEARCH_SUBTREE,
FALSE,
                     myFilter, DS_ATTRIBUTE_VALUES, FALSE, Names,
                     &iterationHandle, 1, &objectsSearched,
objectInfo);
if(cDSCode)
  {
  printf("Error in NWDSSearch: %04X  Line: %d\n",cDSCode,
__LINE__);
  cleanup(cDSCode);
  }

END of FIGURE 4

Searching the Directory

Finally, the objectInfo buffer must be allocated and initialized. This buffer returns the information that satisfies the search parameters. Once you have allocated and intialized objectInfo and set the iterationHandle to 0xFFFFFFFF, you can search the Directory by calling NWDSSearch(). Since NWDSSearch may return more than one queue satisfying the search criteria, it must be called repetitively until all matching objects are found. You may then decide to let the user select a queue, or automatically select the first queue returned. For simplicity, the example in this article uses the first queue object returned.

Extracting Search Results

The objectInfo buffer cannot be read by the example application when it is returned by NWDSSearch. The information required by the application must be extracted from the buffer by calling NWDSGetObjectName() for the object returned to verify it matches the name of our Queue. The Attributes can then be extracted from the search buffer as shown in Figure 5.

FIGURE 5: Extracting attributes from the search buffer

cDSCode = NWDSGetObjectCount(context, objectInfo, &objectCount);
if(cDSCode)
  {
  printf ("Error in NWDSGetObjectCount: %d  Line: %d\n", cCode,
             __LINE__);
  cleanup(cDSCode);
  }
if(objectCount == 0)
  {
  printf("%s was not found in your default context.\n",objectName);
  printf("\tPlease specify a valid queue name.\n");
  putch(7);
  cDSCode=0xFFFF;
  cleanup(cDSCode);
  }
info = malloc(sizeof(Object_Info_T));

for(;objectCount>0; -objectCount)
  {
  cDSCode = NWDSGetObjectName(context, objectInfo, objectName,
                              &attrCount, info);

  if(cDSCode)
    {
    printf("Error in NWDSGetObjectName: %d  Line:  %d\n", cCode,
              __LINE__);
    objectCount = -1;
    attrCount = -1;
    }

  for (;attrCount>0; -attrCount)
    {
    cCode = NWDSGetAttrName(context, objectInfo, attrName,
                            &attrValCount, &syntaxID);
    if (cDSCode)
      {
      printf ("Error in NWDSGetAttrName: %d  Line:
              %d\n",cCode,__LINE__);
      break;
      }
    if (attrValCount > 1)
      {
      printf ("Invalid DS Connection.  Line: %d\n",__LINE__);
      break;
      }
    for (;attrValCount>0; -attrValCount)
      {
      cDSCode = NWDSComputeAttrValSize(context, objectInfo,
syntaxID,
                                       &attrValSize);

      if(cDSCode)
        {
        printf ("Error in NWDSComputeAttrValSize: %d  Line:
                %d\n",cCode,__LINE__);
        break;
        }

      if((attrVal = malloc(attrValSize)) == NULL)
        {
        printf ("Unable to allocate memory for attribute value.
Line:
                %d\n",cCode,__LINE__);
        cleanup(cDSCode);
        }

      cCode = NWDSGetAttrVal(context, objectInfo, syntaxID,
attrVal);
      if(cDSCode)
        {
        printf ("Error in NWDSGetAttrVal: %d  Line:
                %d\n",cCode,__LINE__);
        free(attrVal);
        break;
        }
      strcpy(serverName,attrVal);
      free(attrVal);
      }
    }
  }

END of FIGURE 5
The attribute requested in the example is the Host Server attribute. The value of the Host Server attribute provides the location of the requested queue. Before the object ID can be returned by the server, the application must ensure that the user is attached to the Host Server. To attach to the Host Server, call NWAttachToFileServer().

QMS calls require a Bindery object ID. Therefore, to obtain the Bindery object ID of the queue on the Host Server, NWDSMapNameToID() requires that the Host Server name be in Bindery form. However, the search may not return the Host Server name in this form. To obtain a useable name, the Bindery name must be extracted from the Directory Name by extracting all periods and Directory Services identifiers. This procedure will produce a usable name for the queue object as long as typeless names are specified which can be passed to NWDSMapNameToID().

Directory Services Cleanup

Finally, you must free the buffers and context handle allocated for the search by calling NWDSFreeBuf() and NWDSFreeContext() for the buffers and the context handle that were allocated for the call to NWDSSearch as shown in Figure 6.

FIGURE 6: Cleanup routine

cleanup(int cDSCode)
  {
  if( Names )
    NWDSFreeBuf(Names);
  if( objectInfo )
    NWDSFreeBuf(objectInfo);
  if( myFilter )
    NWDSFreeBuf(myFilter);
  if(cDSCode)
    {
    NWDSFreeContext(context);
    exit(1);
    }
  }

END of FIGURE 6
From this point, capturing with Directory Services is identical to the process for previous versions of NetWare. The example program initiates the capture and sets various capture flags. Then, it ouputs one page to the queue that says, "This is a printer test" (Figure 7).

FIGURE 7: Initiating capture, setting flags, and generating output

LPTDevice=0x01;
cCode=NWCancelCapture(LPTDevice);
if((cCode != 0) && (cCode != 0x884C))
  {
  printf("\nUnable to cancel capture.  Status:  %04X  Line:
         %d",cCode,__LINE__);
  exit(1);
  }
cCode=NWStartQueueCapture(connHandle,LPTDevice,queueID);
if(cCode != 0)
  {
  printf("\nError starting queue capture.  Status = %04X",cCode);
  exit(1);
  }

cCode=NWGetCaptureFlags(LPTDevice,&captureFlags1,&captureFlags2);

captureFlags1.numCopies=0x05;
captureFlags1.flushCaptureTimeout=(36);
captureFlags1.printFlags += 0x10; /* Notify When Done */
strcpy(captureFlags1.bannerText,"DS Capture!");
cCode=NWSetCaptureFlags(connHandle,LPTDevice,&captureFlags1);
if(cCode != 0)
  {
  printf("Error Setting Capture Flags.  Status: %04X  Line:
         %d\n",cCode,__LINE__);
  exit(1);
  }
PrintOut();
cCode=NWEndCapture(LPTDevice);
if(cCode != 0)
  {
  printf("Error in NWEndCapture.  Status: %04X  Line:
            %d\n",cCode,__LINE__);
  exit(1);
  }
printf("Successfully sent print data to %s.\n",objectName);
exit(0);

END of FIGURE 7
Capturing with Directory Services requires more coding than the Bindery. However, a global view of the Directory and access to any queue to which the user can be authenticated vastly improves an application's robustness and utility for users. NetWare 4.0 Directory Services provides a dynamic platform for global network application development.

For More Information

For more information on the procedures described in this article, consult the NetWare 4.0 Directory Services Schema Specification and NetWare 4.0 Directory Services Technical Overview supplied with the NLM SDK for NetWare 4.0 and the NetWare Client SDK, or contact the Developer Support Group via Novell's NDEVSUP CompuServe forum (sections 4 & 5). To purchase the NetWare Client Software Developer's Kit (SDK) or the NLM SDK for NetWare 4.0, contact Novell Developer Relations at 1-800-NETWARE (1-800-638-9273) or 1-801-429-8855.

TECHNICAL INSIGHTS:

Accessing Integer Keys in Visual Basic for Windows (Btrieve for Windows (all versions))

In Visual Basic for Windows, there are only two accepted methods for passing the key buffer parameter:
  • As a string
  • As a user-defined TYPE (structure)
Attempting to access integer keys by passing the key buffer as a string poses the problem of converting an integer to a two-byte string. In other Microsoft Basic compilers, this conversion can be accomplished with the MKI$ function. In Visual Basic for Windows, this function is not available so you must convert the integer in one of two other ways.

One method is to use the user-defined TYPE structure. First, pass an integer key value on a Get Equal operation as shown in the following code segment:

Type Index3Search
        Age    As Integer
End Type

Dim SearchOnKey3 As Index3Search
Then, make a Btrieve call similar to the following:
SearchOnKey3.Age = 38
KeyBufLen = LEN(SearchOnKey3)
KeyNum = 3

status = btrcall(BGETEQUAL,
                 PosBlk$,
                 DataBuf,
                 DataBufLen,
                 SearchOnKey3,
                 KeyBufLen,
                 KeyNum)
Another method of handling integer key types is to write an MKI$ Function equivalent to the one provided with the Microsoft QuickBasic compilers. One example of such a function call is shown in the following code segment.
Function MKI$ (I%)
  TempI& = I%
    If TempI& < 0 Then
      TempI& = TempI& + 65536
    End If
    Byte1% = TempI& / 256
    Byte2% = TempI& Mod 256
    C1$ = Chr$(Byte1%)
    C2$ = Chr$(Byte2%)
    MKI$ = C2$ + C1$
End Function
The parameter setup and Btrieve call you would issue next would look like:
SearchOnKey3$ = MKI$(38)
KeyBufLen = LEN(SearchOnKey3$)
KeyNum = 3

status = btrcall(BGETEQUAL,
                 PosBlk$,
                 DataBuf,
                 DataBufLen,
                 SearchOnKey3$,
                 KeyBufLen,
                 KeyNum)

Server "Up Time" Discrepancy (Network C for NLMs v2.0)

A call to GetCurrentTicks() returns a server's "up time" in ticks. MONITOR.NLM displays the server's "up time" in days, hours, minutes, and seconds. When the value returned from GetCurrentTicks() is converted to days, hours, minutes, and seconds, the converted value is lower (slower) than the value in MONITOR.NLM.

MONITOR.NLM calculates the server's "up time" in seconds using the formula:

SECONDS =
(((GetCurrentTicks() / 13) * 10) / 14)  OR  ticks / 18.2
The call to TicksToSeconds() uses the following formula:
SECONDS =
GetCurrentTicks() * (1193180 / 65536)
You can use either formula, depending on which time you actually want.

In the PC/AT architecture the input frequency to the 8253/8254 timer chip is 1.19318 MHz. Normally, the chip is programmed with a 64K divisor giving a timer interrupt frequency of 1,193,180 / 65536. PC BIOS assumes that there are 6 timer ticks in an hour, giving a timer interrupt frequency of 65536 / 3600. These frequencies yield the comparative settings shown in Figure 8.

FIGURE 8: Comparative seconds-to-ticks settings

Actual frequency: 1193180/65536 = 18.20648193 or .054925493
secs/tick
PC BIOS assumes:     65536/3600 = 18.20444444 or .054931641
secs/tick
Some software assumes:            18.2        or .054945054
secs/tick

END of FIGURE 8
In this case, TicksToSeconds() is as accurate as possible, PC BIOS is somewhat less accurate, and MONITOR is the least accurate.

Status 96 & Windows Workstations (NetWare Btrieve (NLM) v5.15)

When using the NetWare Btrieve NLM v5.15, a status 96 (Communications Environment Error) means that the SPX connection table is full. This status can usually be prevented by increasing the Number of Sessions configuration option through BSETUP. However, Windows workstations that run multiple Btrieve applications simultaneously require more than one session per workstation. In this case, NetWare Btrieve can return a status 96 when the Number of Sessions is set to the maximum of 250 and BCONSOLE shows only 225 sessions being used. BCONSOLE only shows one session per Windows workstation even if multiple Btrieve applications are running on that workstation.

The June 1990 Bullets article, "Btrieve NLM Parameters," shows that the maximum setting for the Btrieve "-s" (number of sessions) parameter is 500. This number is twice the maximum setting for the BSPXCOM "-s" (number of concurrent sessions) parameter. In reality, the Btrieve "-s" parameter can be increased even more to prevent a status 96 when using Windows workstations. The Btrieve "-s" parameter can be modified in the BSTART.NCF file. The maximum setting is approximately 35,000, and the memory consumption is approximately 100 bytes for each session. After making any changes to BSTART.NCF, be sure to unload the Btrieve NLM (type "BSTOP" at the server console) and reload the Btrieve NLM (type "BSTART") for the changes to take effect.

Configuring NetWare Lite for Btrieve (Btrieve for DOS v5.10a)

With NetWare Lite, there are two ways to access files from the server while ensuring you are using the same drive letter that the other clients are using. One method is to execute a "DOS SUBST" command at the server. For example:
SUBST F: C:\
After executing this command, when you access the F: drive, the files actually being accessed are at the root of the C: drive. This command can be performed from the command line or inside a batch file. This can be done before or after loading the server/client software. The clients will then NET MAP their F: drives to the root of the server, and will be looking at the same files as the server.

In this situation, all I/O requests sent from the server for files are being handled by DOS and NOT the NetWare Lite redirector (the CLIENT.EXE software). As a result, NetWare Lite file sharing mechanisms are not being used, which may produce a Btrieve status 2 (I/O Error), or situations where incorrect data is returned to the application. For example, while the server was inserting data into a Btrieve file, and another client was attempting to read this data, the other client would occasionally be returned a partial record, as if it was reading the record that was still in the process of being inserted.

To make sure all file sharing is handled properly by the NetWare Lite redirector, there are two alternatives:

  • Avoid using the SUBST command. After loading SERVER.EXE and CLIENT.EXE at the server, use the NET MAP command to set up the drive letter to match the other clients. This is the preferred method in this case.
  • Use the SUBST command as described above, but insert the statement "NETWORK SHARING=ON" in NET.CFG in the server's \NWLITE directory. This solution produces side effects which make it less preferable: if network sharing is enabled this way, Windows v3.x cannot run on the server, and the server will not be able to attach any CDROM devices as shared devices. Attempting either of these will produce errors in opening files at the server.

Maximum Number of OS/2 Named Pipes Sessions (NetWare OS/2 Developer's Kit v2.0)

A default of 14 Named Pipes sessions can be established from an OS/2 v2.0 client to an OS/2 v1.3 server, even though the documentation states that more can be established. You must set the following parameters to increase the default number of Named Pipes sessions:
  • In the CONFIG.SYS file, set "FILES='xxx'" to a number greater than the number of Named Pipes sessions desired. However, the sum of 'xxx' and the value specified for the "File Handles='xxx'" parameter in the NET.CFG file (if a value is specified) must not exceed 254.
  • In the "protocol stack spx" section of NET.CFG, set "sessions 'xxx'" to a number at least two greater than the number of Named Pipes sessions desired. The OS/2 requester uses two sessions for overhead (one is for network managment and one is for listening to Named Pipes socket 0x9100).
  • In the "Named Pipes" section of NET.CFG, set "client sessions 'xxx'" to a number greater than the number of Named Pipes sessions desired. Also, assume the following:
  • The Named Pipes client attempts to establish sessions with only one Named Pipes server; if you want to use more than one server, set the "server sessions 'xxx'" parameter (in the "named pipes" section of the NET.CFG file) to an appropriate value.
  • The NET.CFG parameters are specified according to proper syntax. For example, of all the NET.CFG parameters mentioned above, only the "File Handles" parameter requires the equal sign (=). If you use improper syntax, default values will be assigned to these parameters, which may result in fewer Named Pipes sessions than desired.

IPX/SPX NLM Performance (Network C for NLMs v2.0 (e))

There are two types of semaphores available for use inside an NLM: local semaphores and network semaphores. Network semaphores can be accessed from any server or workstation on the net as long as they know the semaphore's name. Local semaphores are specific to a single server and cannot be used from a remote node.

If a semaphore is used to wake a thread up when an IPX or SPX receive completes, be sure to use a local semaphore instead of a network semaphore. IPX and SPX communications are designed to be used with local semaphores. At the very least, using network semaphores will result in poor IPX/SPX performance due to the extra overhead involved in managing network semaphores.

Always use OpenLocalSemaphore and WaitOnLocalSemaphore instead of OpenSemaphore and WaitOnSemaphore for IPX/SPX communications.

Console Operator Rights & NetWare (Network C for NLMs v2.0d)

If using GetVolumeInfoWithNumber() on a remote NetWare 3.x file server, console operator rights are not required. Any logged in object can successfully call GetVolumeInfoWithNumber() on a remote NetWare 3.x server.

The documentation does not mention that console operator rights are required when this call is made to a remote NetWare 2.x file server. When you are using the GetVolumeInfoWithNumber API on a remote 2.X file server, make sure the remote user has the necessary console operator rights.

NetWare SQL & NSSPXCOM Compatibility (NetWare SQL v3.00c)

When using NetWare SQL v3.0 patched to revision C or higher, NSSPXCOM revision A or later must also be used. If NetWare SQL 3.0c is used with NSSPXCOM v3.0, a CLib breakpoint will be reached when attempting to run NSSTOP to unload the NLMs.

Always use the current versions of NWSQL.NLM and NSSPXCOM.NLM that ship together in a patch revision. The current versions are NWSQL v3.0d and NSSPXCOM v3.0a.

BETWEEN Operator & sub-SELECT Statements (NetWare SQL v3.00b)

SQL statements which use a BETWEEN operator in a WHERE CLAUSE under a sub-SELECT statement will cause the server to abend. For example, the statement shown in part A of Figure 9 makes use of a BETWEEN operator and will cause the server to abend.

FIGURE 9: NetWare SQL examples using sub-SELECT statements

Part A:

  SELECT field1 FROM table1 WHERE NOT EXISTS
  (SELECT field2 FROM table2 WHERE (( table1.field1 = table2.field2
)
  AND
  (table1.datefield1 BETWEEN table2.datefield1 AND
table2datefield2)))

Part B:

  WHERE ((table1.field1 = table2.filed2) AND
  (table1.datefield1 >= table2.datefield1 AND
   table1.datefield1 >= table2.datefield2)))

Part C:

  SELECT field1 FROM table1 WHERE NOT EXISTS
   (SELECT field2 FROM table2 a, table1 b
     WHERE a.field2 = b.field1
     AND b.datefield BETWEEN (a.datefield1 AND a.datefield2)
     AND (table1.field1 = a.field2))

END of FIGURE 9
When you remove the BETWEEN operator and rewrite the WHERE clause, the statement functions correctly. In this case, you would rewrite the sub-query WHERE clause as shown in part B.

Alternatively, the patches that bring NetWare SQL up to v3.00d include the workaround shown in part C of Figure 9. Either rewritten version of the statement will function properly.

NetWare 3.11 Trustee Path Anomaly (NetWare v3.11)

The NWScanObjectTrusteePaths and ScanBinderyObjectTrusteePaths API calls will not return a trustee path if only one exists for the user and the user does not have any rights to the trustee path. For example, through SYSCON, if you add a trustee path to SYS:PUBLIC for a user, then select SYS:PUBLIC and remove the File Scan and Read rights, when you try to display the trustee directory assignments through SYSCON or using the above API calls, nothing is returned for display.

If you use TLIST, or if you simply add another trustee directory assignment for the user, the rights to SYS:PUBLIC are returned.

Btrieve Status 94 on Read-Only Files (NetWare Btrieve (NLM) v5.15)

If a Btrieve data file is flagged "read-only," performing an Open operation on the file with NetWare Btrieve (NLM) v5.15 will return a status 94 (Permission Error). This status will return even if the user has all rights in the directory and the file is opened in "read-only" mode through Btrieve.

When using NetWare Btrieve (NLM) v5.15, do not flag Btrieve data files "RO." To prevent "write" access to the files, use directory level rights of Read and File Scan.

With NetWare Btrieve (NLM) v6.x, the status 94 will not be returned if the file is flagged "RO." A "read-only" Open operation on the file will succeed, while a status 46 (Access to File Denied) will be returned when a user attempts to write to the file.

Floating Icons Hang SQLScope (NetWare SQL v3.0)

If Windows is configured with an icon that is set to "Float Always" or is configured to be "Always On Top," this may cause SQLScope to hang. For example, the Clock program from the Accessories group can be configured as "Always On Top." When SQLScope is run in conjunction with this, SQLScope will hang when an attempt is made to exit the program. Some users may only experience this when running SQLScope in full screen mode, while others experience it whether SQLScope is in full screen mode or windowed mode.

Do not run SQLScope while you have floating icons.


NIBBLES AND BITS

Fast Answers to Common Questions

NetWare SQL

Q - Can the embedded SQL libraries be used with the WATCOM C Compiler v9.00 in 32-bit mode?

Q - No, there are no libraries available at this time to support 32-bit compilers.

Btrieve

Q - Does NetWare Btrieve v6.10 still use /P: parameter?

Q - In NetWare Btrieve v6.10, the Maximum Page Size parameter (/P:) is no longer required. NetWare Btrieve can now open any Btrieve file with any page size. NetWare Btrieve v6.10 will not return status 24 from the Open operation and will ignore any value given for the /P: startup parameter.

Q - Using NetWare Btrieve (NLM) v5.15 and Brequest v6.00b, the following syntax generates a status 12 (File Not Found) on a Btrieve Open operation: \\server\vol\dir\sub-dir\file

Q - To avoid this status code, either:

  1. Use the patched version of Brequest v5.16.
  2. Add a colon (:) after the volume name when using Brequest v6.00b. For Brequest 6.00b the syntax would be:

    \\server\vol:\dir\sub-dir\file

Q - The Btrieve Installation and Operation Manual for NetWare Btrieve (NLM) v6.0 states that more than one BUTIL command may be placed in a command file. For example, according to the manual, I should be able to place a -CLONE and -COPY in the same command file. However, if I place more than one command in a command file, NetWare Btrieve returns an error message stating that the format for the command file is unrecognizable. What should I do?

Q - The information in the manual is incorrect. you may only place one BUTIL command in the command file.

Q - When attempting to IMPORT a Btrieve file into a Microsoft Access database, Microsoft Access returns the message "Disk or Network Error" when it attempts to read FILE.DDF. Why?

Q - This error is similar to a Btrieve status 2 (I/O Error). Btrieve v5.x returns status 2 when you attempt to use it to access Btrieve files stored in v6.x format. Microsoft Access returns "Disk or Network Error" under the same circumstances. When using Microsoft Access to IMPORT Btrieve files, either run BTRIEVE.NLM v6.x with Brequest v6.x and WBTRCALL.DLL, or make sure all files accessed with the client WBTRCALL.DLL are stored in v5.x format.

Network C for NLMs

Q - The documentation for the Network C for NLMs v2.0 does not say why AllocateResourceTag() would return 0 (unsuccessful). What does the zero return code indicate?

Q - There are four reasons why this function could fail:

  • A bad NLM handle was passed as the first parameter.
  • A bad resource type (resource tag signature) was passed as the third parameter.
  • The description string passed as the second parameter was already in use.
  • The resource type (resource tag signature) was passed as a NULL.
Tip Developing Client-Server NLMs (page 3-4) contains an explanation of how to write a reentrant NLM. This explanation includes example source code, but fails to mention a situation that generates the console error message, "Attempt to reinitialize reentrant module FAILED," when you load the NLM for the second time. Despite this error message, the reentrant NLM still functions properly.

At the end of the code to handle reentrant load, there should be a return statement added, as shown in the following code segment:

if (LoadedFlag == TRUE)

   {

    /* Code for reentrant load goes here

       (such as start new thread) */

    return(0);

   }
A zero will be returned to the loader, indicating that the module has loaded successfully. Without this return(0) statement, the return value is undefined and could be any value.

NetWare C Interface for Windows

Tip When loading IPXODI.COM with the /a option, IPXODI does not load the diagnostic services or the SPX services. In this case, neither diagnostic services calls or any of the SPX services calls can be made. The /a option is primarily used with NetWare Lite. Attempting to call PSAttachToPrintServer(), for example, will lock up the workstation, since this function requires SPX to be installed.

Do not load IPXODI with the /a option if you need to use diagnostic or SPX services in the Windows environment.


NOVELL DEVELOPER RELATIONS

New Image-Enabled SDKs for NetWare 4.0 Developers (Special Supplement)

In November of 1991, Novell signed a development agreement with Eastman Kodak to "image-enable" NetWare 4.0. The agreement specifically stated that Kodak and Novell would exclusively market a set of NetWare server-based services designed to support images as another data type of the network. These server-based services would be provided to developers through Novell SDKs.

Novell is proud to announce the upcoming Image-Enabled NetWare SDKs. These SDKs will bring image management, document management and hierarchical storage management technology to the NetWare 4.0 environment.

These Image-Enabled NetWare SDKs will include the following components:

  • Image-Enabled NetWare IMS (Image Management Service)
  • Image-Enabled NetWare DMS (Document Management Service)
  • Image-Enabled NetWare MSS (Mass Storage Service) SDK
You can use each service separately, or combine them to enable your NetWare-Aware, desktop applications to work with objects, share them across a local or enterprise-wide network, and manage storage in a cost effective, efficient way.

Image-Enabled IMS SDK

Image Management Service (IMS) supplies APIs that allow you to provide your customers with imaging capabilities from their desktop. IMS allows you to create applications that can capture paper-based documents electronically and convert them into digitized images that resemble the original paper document. Digitized images of the paper document can be displayed on the computer screen.

IMS functions are provided for capturing images using a scanner, importing an image from a variety of industry-standard formats, or pasting an image from the clipboard. IMS functions allow manipulation of these images in a number of ways, for example, by rotating, sizing or scaling them. Images can then be printed, sent to a fax machine directly from a computer, or sent to an OCR device for conversion to editable text.

IMS complements desktop applications by letting you perform a variety of functions using three distinct levels of image functionality: Image Document functions, Import/Export functions, and Image Peripheral functions.

With Image Document functions, your application can do the following:

  • Create, delete, open, close, and save changes to image documents
  • Create, add, delete, copy, and access image document elements (pages, layers, and frames)
  • Obtain information about pages, layers, frames, and images, such as size, name, type, etc.
  • Control access to document elements
  • Manipulate pages (rotate, size, etc.)
  • Reorder pages, layers, or frames containing images and annotations
  • Perform such miscellaneous functions as initialize IMS library, terminate an IMS session, free memory, etc.
The Import/Export functions allow access to image files stored in a variety of industry-standard image file formats such as TIFF, BMP, PCX, PICT, EPS, PhotoCD (import only), TGA, GIF, and JFIF. With Import/Export functions, your can import images in these standard-format files directly into image documents.

The Image Peripheral functions let your application print or fax pages from an image document and provide control for scanning paper documents, for importing incoming fax documents, and for OCR-interpreting the resultant images. Following is a list of the capabilities that the Image Peripheral functions provide.

  • Print one or more pages of an image document
  • Scan pages and append them to an image document
  • Read pages from an entry in an incoming fax queue and append them to an image document, or send pages to a fax machine
  • Send specified pages in an image document to an OCR device for converting a digitized image into editable text
  • Select and return capability and availability information regarding a peripheral device
  • Obtain the status of one or more device transactions

Image-Enabled DMS SDK

Document Management Services is a set of APIs that provide the capability to build a document management system for a NetWare 4.0 network. The DMS APIs provide an open architecture for managing all types of objects, including image files and documents. DMS lets developers create documents and folders for managing files, and lets users and applications share the folders throughout the entire network.

You can use DMS to create a new application. For example, you can create a distributed document/object management system, such as a work flow application. You can enhance an existing application. For example, you can incorporate the model of documents and folders into a word processor, spreadsheet, or imaging application. A DMS application can serve as a front end to the file system or complement the file system by making files appear in a database.

The developer tools provided in this SDK for the DMS include the DMS APIs and the DMS DLL, the run-time client component of a DMS application. The DMS APIs let you create and maintain the following:

  • A DMS database to manage a variety of files and other objects
  • Documents and folders for managing files or other objects
  • Index cards for managing documents and folders
  • Access control lists for documents and folders
  • Locks on documents and folders
  • Multiple versions of documents and folders
  • Event logs for database objects
  • Search and sort criteria for searching and sorting a database and processing the results

Image-Enabled MSS SDK

The Mass Storage Service allows you to integrate hierarchical storage management into your applications that run NetWare 4.0. MSS provides its comprehensive storage management by keeping frequently accessed objects on high speed devices such as server hard drives (relatively expensive per megabyte of storage) and moving less frequently accessed objects to slower devices such as optical jukeboxes (relatively less expensive per megabyte of storage).

As MSS transparently moves objects from a server's hard disk to other storage devices in the hierarchy, end users are unaware of where or how objects are stored. To the end user, objects always appear to be stored locally. Using the services provided by MSS, applications can optimize the use of each storage device and minimize storage costs while meeting the individual access requirements of end users on the network.

The MSS API consists of C functions that provide the following services:

  • Removes the burden of file management from an application and its end users. They need not be concerned with how or where an object (file) is stored.
  • Provides an MSS client API library that enables communication with the MSS server through the Transport Layer Interface. The API lets a client application create MSS objects, assign objects to appropriate groups for management purposes, open MSS objects, read, write or seek MSS objects, close MSS objects, and delete MSS objects.
  • Provides access to a virtual copy of an object when the object is opened for write access. This allows more than one end-user to open the original object for read access.
  • Provides a query capability that allows an application to find out where an object is stored. If it is stored offline, the application can give the end user the choice of waiting or not waiting for the object to be brought online.
  • Enforces network security on remote calls and maintains the same access rights for clients that NetWare provides.
An MHS Administrator utility is provided to let the system administrator configure the hardware and software needed to move objects though the hierarchical storage of MSS.

Image-Enabled SDK Availability

If you would like to receive additional information on the availability of this SDK and be included in a Special Interest Group (SIG) on Document Management and Imaging, please do the following:
  • Send your name, address and phone number via e-mail to "Library@Novell."
  • Include in the subject header the phrase "PDP-DOCMGMT" and briefly state your interest in this SIG.
  • Indicate the best way to contact you.
If you want to send a message via fax, use our main fax number at 512-345-7478, attention Novell Developer Relations.

Telephony Services for NetWare SDK (Special Supplement)

Provided as a core NetWare service, NetWare 4.0 provides the ability to link the capabilities of NetWare computer networks with the features and functionality of telephone PBXs.

To deliver this technology, Novell, the leading provider of computer networking products and services, and AT&T, the leading expert in the telecommunications industry, have teamed together to develop product solutions which address the integration of the telephone and computer desktop.

Computer-Telephone Integration (CTI) combines telephone and computer technology to provide access and control telephone functionality from a computer terminal. CTI is not a new concept. However, in the past, CTI has only been available in mini and mainframe computer environments. CTI in a NetWare environment not only makes the technology cost-effective, but also provides for the integration of CTI with other NetWare 4.0 technologies such as Directory Services, Imaging, and Multimedia.

Telephony Basic Concepts

This article assumes that you are familiar with the following terms:
Party -
a telephony user.
First-party -
the party requesting the service is an end-point to the call being controlled. Usually associated with the call processing at the user's desktop
Third-party -
the controlling party requests services on behalf of other end-points on the switch. Usually associated with a call center environment.
Call -
a switching function communications relationship between two or more devices. During some circumstances, including setup and release, there may be only one device. A call is an API Object.
Object -
an abstract entity for modeling purposes to embody an aspect of the externally visible functional characteristics of a physical entity.
State -
an indication of an object's current condition based on its past events, permitting a prediction of its future behavior.
PBX -
a box containing a set of wires that controls telephone switch functions at a given site.

Telephony Services Application Overview

In its basic form, Telephony applications consist of three main components:
  • Server component
  • PBX
  • Client component
The Server component includes the Telephony Server library, the Telephony NLM, PBX driver, and link hardware. The PBX includes all of the functionality required to perform switching functions. The Client component includes the client library. In addition to these three components, documentation is provided for the common Client/Server APIs.

The Telephony Server

The Telephony Server is at the central core of providing telephony services through NetWare. The Telephony Server logically integrates the existing analog, digital, and ISDN telephones already on the user desktop with telephony-enabled or telephony-based applications running in the client or server. This logical association is accomplished through the use of client and server software without the need for special telephones or hardware devices at the client desktop.

In most implementations of Telephony Services, hardware will only be required at the server to support the physical control link between the server PC and the switch or PBX which is providing services to the end user. In other words, there will be no hardware (no phone hookup) required at the client site.

The logical software integration provided by the Telephony Server will provide customers with additional options and flexibility in deploying CTI applications for the multimedia desktop environment and for call center customers with LAN-based networking solutions. The Telephony Server API can support telephony applications for either the multimedia desktop or the call center environments.

Telephony Client/Server API Overview

The Telephony Services API will provide services primarily associated with control of the phone on the user's desktop and/or with monitoring other telephones on the switch. The Telephony Client/ Server API is directly based on services and functionality defined by international standards for CTI implementations.

Specifically, the API is based on the European Computer Manufacturer's Association (ECMA) definition of Computer-Support Telecommunications Applications (CSTA) CTI standard. ECMA is currently the only standards body which has completed and published a standard for CTI interfaces for the PBX environment.

The Telephony Client/Server API is designed to support telephony control capabilities for a generic, vendor independent PBX environment. This architecture will allow and support PBX drivers from other switch vendors in order to provide telephony services for a variety of different PBX environments. This architecture maximizes the number of client end-points which can be supported behind the Telephony Server using the same client/server API.

Telephony Client/Server API Functions

The following services are provided via the Telephony Client Server API:
  • Switching Function Services - operate on calls and activate switch-related features that are associated with the user desktop telephone or any other device defined by the switching domain. Examples of these services include establishing, controlling and tear-down calls at a device or within a switch, answering incoming calls into a device, activating/deactivating features and capabilities supported by the switch or server, and manipulating telephony objects related to a desktop telephone device.
  • Status Reporting Services - include the functions required to establish and request unsolicited event reporting for a specific telephony device or for calls being controlled by the application through the API.
  • CSTA Computing Functions Services - allow the client/server role between the application and the switch to be reversed where the application becomes the "server" for call routing requests being originated by the switch. Call routing allows the switch to pass any available call-related information to the application and request routing information for the call from the application. The application typically uses this information to determine a route for the call based on call service levels assigned to the caller associated with the inbound call.
  • CSTA Interface Control Services (ICS) - handle the characteristics of the API interface (for example, opening and closing the CSTA interface) and the function call and messaging mechanisms supported by the API client library. The CSTA ICS provide the application with the ability to open and initialize a virtual communication channel (CSTA stream) with any Telephony server defined by the system, the use of blocked or polling mechanism to receive events, the initialization of a mechanism for the notification of the arrival of even messages for the server or client library, the ability to poll the Telephony Server for the support capabilities.

Telphony Services API Example

Following is an example of the cstaMakeCall() API service. The cstaMakeCall() service originates a call between two devices on the switch. The service attempts to create a new call and establish a connection between the calling device (originator) and the called device (destination). The Make Call service also provides a CSTA connection identifier that indicates the connection of the originating device:
#include 

Retcode_t cstaMakeCall (
  CSTAHandle_ cstaHandle,
  DeviceID_T  *callingDevice,
  DeviceID_t  *calledDevice,
  CSTAPrivateDAta_t *private);

Telephony Services Event Example

The following is an example of the CSTAMakeCallConfEvent. This confirmation event provides the positive response from the Telephony Server for a previous Make Call service request:
typedef struct {
  CSTAHandle_t    cstaHandle;
  InvokeID_t      invokeId;
  ConnectionID_t  newCall;
  CSTAPrivateData_t  private;
}CSTAMakeCallConfEvent_t;

Telephony Services for NetWare: Leading the Competition

Telephony Services are not new to the network computing environment. However, Telephony Services for NetWare provides some benefits that typical telephony solutions available today do not:
  • No hardware is required at the client (in other words, no phone hookup is required).
  • First- and third-party call control is provided.
  • Telephony Services API is based on the ECMA CTI standard.
  • Heterogeneous client support; initially supports Windows, OS/2 and Macintosh; additional support for UnixWare expected.
  • Tightly integrated with other NetWare services. For example, the Telephony Services platform can be enhanced to provide desktop voice messaging capabilities from a voice messaging server, facsimile capabilities from a fax server, voice response capabilities from a voice response server, etc.
  • Telephony Services architecture allows and supports PBX drivers from other switch vendors in order to provide telephony services for a variety of different PBX environments.
  • A single API for both client and server applications.

Telephony Services SDK Availability

If you would like to receive additional information on the availability of this SDK and be included in a Special Interest Group (SIG) on Telephony, please do the following:
  • Send your name, address and phone number via e-mail to "Library@Novell."
  • Include in the subject header the phrase "PDP-TELEPHONY" and briefly state your interest in this SIG.
  • Indicate the best way to contact you.
If you want to send a message via fax, use our main fax number at 512-345-7478, attention Novell Developer Relations.

NOVELL DEVELOPER EDUCATION:

Available Novell Developer Education Courses

Novell Developer Education offers several courses for developers who use Novell's development & database tools, including NetWare SQL, Btrieve, Xtrieve PLUS, and the NetWare Client APIs.
904 - Btrieve: An Overview
905 - Programming with Btrieve
907 - Xtrieve PLUS
911 - NetWare Database Administrator
912 - Programming with NetWare SQL
930 - Developing NetWare Loadable Modules (NLMs)
940 - NetWare Programming: Basic Services
945 - NetWare Programming: Protocol Support
To obtain information on pricing, location, scheduling, & course content for classes held in the US, call 1-800-233-3382, 1-801-429-5508 or 1-800-NETWARE. For information on availability, location, and prices of classes outside of the US, contact your local Novell office.

New Computer-Based Training (CBT) Courses

You can now offer your users a series of two CBT courses along with your NetWare SQL or Btrieve application. These courses provide users with an active and flexible way to learn about NetWare SQL, Novell's relational data access system for Btrieve-based data.

The courses present information through IMS/BehaviorTech's Exemplar Learn system. This system offers users the benefits of studying with an exemplary tutor; it constantly measures their responses and adapts the instructions to accommodate their needs and learning styles.

Accessing Data Through NetWare

This course is intended for persons who are interested in learning relational database concepts. The course includes introductory material about distributed computing, relational databases, SQL syntax in general and NetWare SQL syntax in particular, and NetWare Btrieve.

Users who are already familiar with the history and evolution of relational databases may prefer to work through the second CBT course in this series, NetWare SQL Database Administrator.

NetWare SQL Database Administrator

This course is intended for database administrators who work at sites that use NetWare SQL with Novell's NetWare Btrieve key-indexed record management system. The course provides an overview of how to install, load, configure and maintain NetWare SQL's components and utilities.

The material in this course assumes that users are already familiar with Novell's NetWare operating system, basic Structured Query Language (SQL) syntax and basic database concepts covered in the Accessing Data Through NetWare CBT course.

Pricing and Availability

Both courses are available in 5-packs of 5 1/4" diskettes and 3 1/2" diskettes. Installation and operation support is available for both courses from IMS/ BehaviorTech. To order copies of either of these CBT courses, call 800-346-7177 or 1-801-429-7401.

CURRENT PATCHES FOR NOVELL DEVELOPMENT TOOLS

Many problems encountered by Novell developers can be resolved by using the current drivers and applying the latest patches. In many cases, proper patching can save you a call to the Developer Support Group.

NetWire

The latest NetWare drivers, example code for NetWare API development tools, OS/2 requester patches, and patches for Novell's database products are available on Novell's NetWire forum on CompuServe. Back issues of Bullets and developer FYIs are also available (NOVLIB, library 11). New information is first stored in NOVLIB library 1, and moved to library 7 after a period of 30 days. If you do not have access to CompuServe, request these files from Novell's Developer Support Group at 1-800-NETWARE (1-800-638-9273) or 1-801-429-5588.

When calling, be ready to provide a shipping address, disk preference (5.25", 3.5", HD, or DD) and, if you prefer overnight delivery, your company's Federal Express account number. If you do not provide a Fed Ex account number, the patch disk will be sent to you via regular mail.

Updated NetWare API SDK components can be obtained from Novell's NDEVREL forum on CompuServe. For more information on Novell developer programs contact Novell at 1-800-NETWARE (1-800-638-9273) or 1-801-429-5588.

For a Complete List...

A document describing available patches and other files and their location on CompuServe is available through Novell Developer Relation's Automated Fax System (AFS). This system can provide you other useful information as well.

To use the AFS, call 1-800-RED-WORD (1-800-733-9673) or 512-794-1796 from a touchtone phone. Then, choose the option for the Automated Fax System, select the documents you wish to receive, and supply your fax number (the fax number to which you want the document(s) sent). Document #7805 describes the patches. Document #1 lists all other documents available through the Automated Fax System. Up to five documents can be requested per call.


CONTACTING NOVELL

Developer Support

Developers in the U.S. and Canada may contact Novell Developer Support via telephone, fax, BBS or electronic mail via CompuServe, MHS or the Internet.

Voice

For both presales and postsales support, call Novell Developer Support between 8:00 a.m. and 5:00 p.m. Mountain Time at 1-801-429-5588. Many calls to Novell Developer Support are passed to a software support engineer immediately. Calls to Novell Developer Support generally will be acknowledged or answered within four hours.

Fax

If you prefer, you may contact Novell Developer Support via fax at 1-801-429-2990. Faxed questions are acknowledged or answered within 24 hours.

Developer BBS

If you do not have access to either CompuServe or the Internet, send test cases to our BBS. Set your communication software to N-8-1 and call 1-801-429-5836.

E-mail: CompuServe

Post your messages in the appropriate section addressed to Novell at 76701,171. These messages will receive a response within 24 hours.

E-mail: MHS

You may direct your questions and comments to Novell Developer Support via Novell's Message Handling Service E-mail facility. Address your messages to devsup@novell. These messages will receive a response within 24 hours.

E-mail: Internet (SMTP)

An alternative method of contacting Novell Developer Support is through the Internet E-mail system. Send your messages to devsup@novell.com. These messages will receive a response within 24 hours.

NetWire on CompuServe

Novell's NetWire forum is open to all registered CompuServe subscribers. Through the NDEVSUP forum, professional developers writing applications with Novell development tools can gain access to information specific to Novell development. Support, patches, periodicals and product information, as well as information on all of the programs and services provided for Novell developers are accessible through this forum. Post your messages in the appropriate section addressed to Novell at 76701,171. Technical questions will be acknowledged or answered by Novell Developer Support within 24 hours.

Novell Products and SDKs

Novell products on the "Currently Shipping Developer Products" list (see page 15 of this issue), including the Red Box Products, are available to Novell Professional Developer's Program members. Call 1-800-RED-WORD (1-800-733-9673) or 1-303-894-4135 to order these products or to receive additional information. To order other Red Box Products not listed, contact your local Novell office or Novell Authorized Reseller.

DeveloperNet Labs

For information on DeveloperNet Labs development tools, education classes and product certification, in the U.S. and Canada call 1-800-453-1267 ext. 5544 or 1-801-429-5544, or call your local Novell office (see back cover of this issue).

Novell Developer Relations

Novell Professional Developers or those wishing to become members may contact Novell Developer Relations via telephone, fax, or electronic mail via Compuserve, MHS or the Internet.

Voice

For general information or questions on Novell Developer Relations programs, in the U.S. or Canada call 1-800-RED-WORD (1-800-733-9673). All others call 1-801-429-5281.

Fax

If you prefer, you may contact Novell Developer Relations via fax at 1-801-429-7207.

NetWire on CompuServe

Novell's NetWire forum is open to all registered Compuserve subscribers. Through the NDEVREL forum, Novell Professional Developer's Program-related issues or general questions may be posted. Through the NDEVINFO forum, customers who do not have products may post pre-sales product information questions on all Novell SDKs.

E-mail: MHS or Internet (SMTP)

You may direct your questions and comments to Novell Developer Relations via Novell's Message Handling Service E-mail facility. Address your messages to devprog@novell.com. Use the same address when going through the Internet E-mail system.

ACKNOWLEDGEMENTS

Publisher: Mad Poarch
Editor: Kirk R. Humphries
Design: Creative Services, Provo

Articles: Clint McVey, Holly Roff

Contributors: Linda Anderson, Kathie Banta, Michael Eisa, Kumar Gaddam, Sadruddin Khawaja, Nancy Kromar, Chris Ojeda, Paige Parker, Matt Pinsonneault, Bill Prentice, Mike Shoemaker, Michael A. Spano, Howard C. Thamm, and Brenda Wallace

Novell Professional Developer Bullets is a publication from Novell's Developer Support Group. Special thanks to the Developer Support, Development, Developer Relations, Product Marketing, and Marketing Communications staff who contributed time and valuable input.

(c) 1993 Novell, Inc. All rights reserved. Novell, the N design, NetWare, Btrieve, XQL, LAN WorkPlace and LANalyzer are registered trademarks; NetWare Loadable Module (NLM), NetWare Global Messaging, NetWare System Calls for DOS, NetWare Runtime, NetWare SQL, NetWare Btrieve, NetWare C Interface for DOS, NetWare System Interface Technical Overview, NetWare RPC, NetWare RPC 386, NetWare LU6.2, Report Executive, NetWare MHS, NetWare Asynchronous Communication Services (NACS), NetWare Management System, NetWare 3270 LAN Workstation, SFT III, and Xtrieve PLUS are trademarks; and NetWire and Professional Developers' Program are service marks of Novell, Inc. IBM and OS/2 are registered trademarks, and NetBIOS and SAA are trademarks of International Business Machines Corporation. Microsoft is a registered trademark, and Windows and QuickBasic are trademarks of Microsoft Corporation. Apple, AppleLink, AppleTalk, and Macintosh are registered trademarks of Apple Computer, Inc. CompuServe is a registered trademark of CompuServe Corporation. NFS is a registered trademark of Sun Microsystems, Inc. UNIX is a trademark of UNIX Systems Laboratories, Inc., a subsidiary of AT&T. Univel is trademark of Univel, Inc.