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  

OCTOBER 1994 VOLUME 6 NUMBER 5


Index


ARTICLES

Print Server Services Add New Functions

With the advent of the Client SDK, Novell introduced Print Server Services to simplify modification of printers, print servers and print queues. In addition, these services add new functionality that manipulates Printcon and Printdef databases.
Four subset services are included in the Print Server Services:
  • Print Server Configuration
  • Print Server Job Configuration
  • Print Server Printer Definition
  • Print Server Communication
In this article, I will discuss Print Server Configuration Services in depth, while Print Server Job Configuration, Printer Definition and Communication Services will only be discussed briefly. Sample code illustrates the use of these services. Although I discuss Print Server Services under both Bindery and Directory Services, the sample code demonstrates Print Server Services used with the bindery. In a future issue of Novell Developer Notes, I will show how to use these functions under Directory Services.

Print Server Configuration Services

Print Server Configuration Services access the principle objects that support network printing such as print server, print queue and printer objects. The functions included in Print Server Configuration Services perform a few basic operations on these objects:
  • Scanning for objects
  • Creating and deleting objects
  • Scanning an object for specified attributes
  • Adding and deleting an object's attributes
You can also perform most of the operations of Print Server Configuration Services directly by using Bindery Services or Directory Services. Both methods, however, require more work for your application. For example, creating a print server object using Directory Services requires an input buffer. You need to make many calls to prepare the buffer before the object is added. Using Print Server Configuration Services, you can perform this operation using a single function.

The program in Figure 1 on page 2 uses a variety of the function calls in Print Server Configuration Services. I create a print server initially using the call NWPSCfgAddPrintServer(). The first parameter in this call is connType, required in all function calls for Print Server Services. The three connTypes available are as follows:

  • NWPS_BINDERY_SERVICE_PRE_40
  • NWPS_BINDERY_SERVICE
  • NWPS_DIRECTORY_SERVICE
These connTypes free the application programmer from the complexities of programming for multiple operating systems. For example, the Printcon database structure changes from NetWare v3.x to NetWare v4.x.

The programmer simply changes the connType, and the interface handles the rest.

NWPS_BINDERY_SERVICE_PRE_40: Novell recently implemented this type in the Client SDK. The CD-ROM containing the updated Client SDK will be available by the beginning of November 1994. The Client SDK version 1.0e does not have this type. You need this type to work in a pre-4.x environment.

NWPS_BINDERY_SERVICE: Use this type with a v4.x server and Bindery Emulation.

NWPS_DIRECTORY_SERVICE: Use this type with a v4.x server and Directory Services.

Once I create the print server, I call NWPSCfgAddPrintQueue() to create the print queue. Then I add the operator attribute to the print queue with the call NWPSCfgAddPrintQueueAttr(). The last parameter for this call is documented as void*attrValue. The type of buffer that attrValue points to depends on the type of attribute added to the print queue. Because this is an input parameter, you must ensure attrValue points to the correct buffer type for the attrID (attribute identifier).

The documentation for this call contains a chart of buffer types associated with their attribute identifiers. Studying this chart, in conjunction with the header files NWPS_CFG.H and NWDSATTR.H, will clarify use of the parameter attrValue.

I continue with a call to NWPSCfgAddPrinter(), which adds a printer to the print server. Then the call NWPSCfgAddPrinterAttr() adds a user name to contact when the printer requires some action.

To prepare to add the printer configuration attribute, I make a call to NWPSCfgGetPrinterDefaults(). In this case, the printer type is serial and the call returns the printer defaults associated with a serial printer. These defaults are then passed as a parameter to the call NWPSAddPrinterAttr(). Adding this attribute enables proper printer configuration.

Print Server Job Configuration Services

When creating a print job in NetWare, you can specify a job configuration to define its print job parameters. Commonly used print job parameters include number of copies, which LPT port to use, destination queue, banner text, print form and print mode.

Users create print job configuration records using the Printcon utility or NWAdmin. These records are stored in the Printcon database file. In the v3.x environment, the database is the file PRINTCON.DAT, located in the user's mail directory. In the v4.x environment, the database is associated with the owner through the Print Job Configuration attribute. The owner may be a User, an Organizational Unit or an Organization.

Print Server Job Configuration Services include the NetWare API calls you need to manipulate Printcon databases: you can read, write, scan and delete individual records. Figure 2 on page 4 is a program that shows some of these functions in addition to functions from Print Server Printer Definition Services.

In Figure 2, the call to NWPSJobGetDefault() returns the database owner's default print job configuration in the Printcon database. Using the job.device and job.mode that return in the structure NWPS_Job_Rec, I make a call to NWPSPdfReadModeFunction(). The first call returns the header string for the job.mode. I replace job.mode with NWPS_RESET_MODE in a second call to NWPSPdfReadModeFunction(). This time, the tail string is returned. I pass both the header and tail strings as parameters in the call NWPSSetPrinterStrings(). This call sets the header and tail strings necessary for the print job.

Print Server Printer Definition Services

Print Server Printer Definition Services give you access to data in the Printdef database. NetWare v4.x stores bindery-based Printdef information in a PRINTDEF.DAT file (NetWare v3.x calls the file NET$PRIN.DAT). In Directory Services the Printdef database is represented as a Printer Control attribute assigned to an Organization or an Organizational Unit object.

The Printdef database contains print device definitions. Each print device definition can have multiple print modes. The print device definitions allow a user to print to specific print devices, while the mode consists of printer function commands such as line spacing and character pitch. In addition to print device definitions, the Printdef database contains print form definitions. The print forms can specify the length and width of text on the printed page and are compatible with text-oriented print jobs only.

Print Server Communication Services

Print Server Communication Services give you control of a print server from a remote workstation over an SPX connection. Here are a few of the operations that can be performed with these services:
  • Return print server information
  • Shut down print server
  • Access print server's list of queues to be serviced
  • Control current print job
  • Send commands to attached printers
Figure 3 on page 5 demonstrates how to use Print Server Communication Services. NWPSComAttachToPrintServer() establishes the necessary SPX connection between the workstation and the print server. Then a call to NWPSComLoginToPrintServer() logs in the client as a user or an operator.

The call NWPSComGetPrintServerInfo() returns the structure, NWPS_PSInfo, which contains information regarding the print server. The final call, NWPSComDetachFromPrintServer(), logs the client out of the print server and releases the connection.

In a future issue of Novell Developer Notes, I will discuss Print Server Services under Directory Services. Marina Pimentel is an engineer in Novell's Developer Support Group. She has also worked for Novell in technical support and testing. She enjoys photography and gardening.

Figure 1: Function calls used in Print Server Configuration Services

/*______________________________________________________________
** File:  CFG.C
**
** Desc: Sample program demonstrating use of print server
**             configuration services
*/

#define NWDOS

#include 
#include 
#include 
#include 
#include 
#include 


void main(void)
{
  WORD ccode;
  NWCONN_ID connID;
  char buffer[48];
  char pserver[48],
       queue[48],
       printer[48],
       notify[48],
       oper[48];
  Typed_Name_T  *notifyTypedName;
  NWPS_Typed_Name notifyType,
            operatorType;
  WORD printerNum=-1;
  Octet_String_T *octet;
  NWPS_PConfig *pconfig;

/*________________________________________________________________
**  The following are the API calls initializing and returning
**  basic information needed for the subsequent print server
**  services calls.
*/
  ccode=NWCallsInit(NULL,NULL);
  if(ccode)
    printf("NWCallsInit returned a [%u]\n",ccode);
  ccode=NWGetConnectionIDFromName(strlen("FELIZ"),"FELIZ",&connID);
  if(ccode)
    printf("NWGetConnectionIDFromName returned a [%u]\n",ccode);

/*________________________________________________________________
**  NWPSCfgAddPrintServer() adds a print server to the fileserver.
*/
  printf("Please enter the name of the printserver you wish to create.\n");
  gets(buffer);
  strcpy(pserver,strupr(buffer));
  ccode=NWPSCfgAddPrintServer(NWPS_BINDERY_SERVICE_PRE_40,connID,pserver);
  if(ccode)
    printf("NWPSCfgAddPrintServer returned a [%u]\n",ccode);

/*________________________________________________________________
**  NWPSCfgAddPrintQueue() adds a print queue to the fileserver.
*/
  printf("Please enter the name of the queue you wish to create.\n");
  gets(buffer);
  strcpy(queue,strupr(buffer));
 
ccode=NWPSCfgAddPrintQueue(NWPS_BINDERY_SERVICE_PRE_40,connID,queue,"SYS");
  if(ccode)
    printf("NWPSCfgAddPrintQueue returned a [%u]\n",ccode);

/*________________________________________________________________
**  NWPSCfgAddPrintQueueAttr() adds a print queue attribute to the print queue.
**  In this case, the attribute is the name of a queue operator.
*/
  printf("Please enter the name of the queue operator.\n");
  gets(buffer);
  strcpy(oper,strupr(buffer));
  operatorType.objectType=OT_USER;
  strcpy(operatorType.tName,oper);

ccode=NWPSCfgAddPrintQueueAttr(NWPS_BINDERY_SERVICE_PRE_40,connID,queue,NWPS_ATTR_OPER,&operatorType);
  if(ccode)
    printf("NWPSCfgAddPrintQueueAttr returned a [%u]\n",ccode);

/*________________________________________________________________
**  NWPSCfgAddPrinter() adds a printer to the print server.  Having set
**  printerNum to -1, the printer number that will be returned is the next
**  printer number available for that print server.
*/
  printf("Please enter the name of the printer you wish to create.\n");
  gets(buffer);
  strcpy(printer,strupr(buffer));

ccode=NWPSCfgAddPrinter(NWPS_BINDERY_SERVICE_PRE_40,connID,pserver,printer,&printerNum);
  if(ccode)
    printf("NWPSCfgAddPrinter returned a [%u]\n",ccode);

/*________________________________________________________________
**  NWPSCfgAddPrinterAttr() adds a printer attribute to the printer.  In this
**  case, the printer attribute is the name of a person to be notified
**  when problems arise with the printer.
*/
  printf("Please enter the name of person to notify if printer problems.\n");
  gets(buffer);
  strcpy(notify,strupr(buffer));
  notifyTypedName=(Typed_Name_T*)malloc(sizeof(Typed_Name_T));
  strcpy(notifyTypedName->objectName,notify);
  notifyTypedName->level=1;
  notifyTypedName->interval=1;
  notifyType.objectType=OT_USER;
  notifyType.tName=notifyTypedName;

ccode=NWPSCfgAddPrinterAttr(NWPS_BINDERY_SERVICE_PRE_40,connID,pserver,printer,NWPS_ATTR_NOTIFY,
¬ifyType);
  if(ccode)
    printf("NWPSCfgAddPrinterAttr returned a [%u]\n",ccode);

/*________________________________________________________________
**  NWPSCfgGetPrinterDefaults() returns the printer defaults of the
**  printer type.  In this case, printerType has been defined as a
**  serial printer.  Thus, this call returns the printer defaults
**  associated with a serial printer.
*/
  octet=malloc(sizeof(NWPS_PConfig)+sizeof(Octet_String_T));
  octet->data=(BYTE *)(octet+1);
  pconfig=(NWPS_PConfig *)octet->data;
  pconfig->printerType=NWPS_P_SER;
  ccode=NWPSCfgGetPrinterDefaults(pconfig->printerType,0,pconfig);
  if(ccode)
    printf("NWPSCfgGetPrinterDefaults returned a [%u]\n",ccode);

/*________________________________________________________________
**  This call to NWPSCfgAddPrinterAttr() adds the printer attribute of the
**  printer configuration.
*/
ccode=NWPSCfgAddPrinterAttr(NWPS_BINDERY_SERVICE_PRE_40,connID,pserver,printer,NWPS_ATTR_CONF,octet);
  if(ccode)
    printf("NWPSCfgAddPrinterAttr returned a [%u]\n",ccode);
}

TECHNICAL INSIGHTS

Standard Mode IPX Data Corruption Under NetWare Client SDK 1.0e

IPX data corruption occurs in Windows Standard Mode when successive data packets overflow the TBMI2 packet buffer. To avoid this situation, check the ECB completionCode before processing received data.

When three 576 byte data packets are received in succession under Windows in Standard Mode, the data in the third packet is corrupted. This problem is caused by the TBMI2 packet buffer. The packet buffer used in TBMI2 is only large enough to accommodate two complete 576 byte IPX packets. There is additional buffer space for a third partial packet. The rest of the third packet is truncated. This situation is reported in the ECB completionCode as a 0xFD return value.

To solve this problem, check both the inUse flag and the ECB completionCode. When the inUse flag is zero, the ECB completionCode should also be zero before accessing the data. A nonzero ECB completionCode indicates that the data is invalid.

IPXGetLocalTarget() Documentation Bug Under NetWare Client SDK 1.0e

The transportTime parameter of the IPXGetLocalTarget() call is incorrectly documented in the IPX for DOS section on the NetWare Client Transport Protocol API for C.

The transportTime parameter is documented as type BYTE far * in the DOS section of the NetWare Client Transport Protocol API for C. The documentation should list the transportTime parameter as int far * instead.

NWScanConnectionsUsing File()_EMM386 Error Under NetWare Client SDK 1.0e

EMM386 exception errors and random hangs occur when calling NWScanConnectionUsingFile(). The machine will reboot, hang or an EMM386 exception error will occur.

The problem is caused by lack of stack space. The NWCALLS library requires approximately 4.5K-5K of stack space. This call, as well as other NWScan API function calls, requires additional stack space and will often overwrite the DOS stack if additional stack space is not allocated.

Increase the default stack size by including the following instructions for the appropriate compiler or linker.

  • Borland Compiler: Place the following line at the beginning of the source code below the #include and #define directives: extern unsigned _stklen = (1024 * 8);
  • Microsoft Linker: Include the following command line parameter with LINK.EXE:

LINK /STACK:8192

How To Get and Set Machine Name Under NetWare Client SDK 1.0e

This technical insight shows how to get and set the machine name variable using DOS system calls. Personal NetWare does not use the machine name as a means of identifying a machine. Other peer-to-peer networks do use the machine name as a way of uniquely identifying a node on the network. Personal NetWare uses the node address to identify other nodes on the network. Many applications designed to run on peer-to-peer networks will fail if no machine name is set.

Peer-to-peer network applications fail because the machine name is not set. Figure 4 on page 9 shows example code that outlines how to get and set the machine name.

Figure 4: How to get and set the machine name

GET NAME:

;*** Description:
;*** This program simply gets the current machine name and
;*** displays it on the screen.

     Ideal
     Model     Tiny
     P286
     CodeSeg
     Org       100h

Start:    jmp       INIT_CODE

CR        equ       13        ;carriage return
LF        equ       10        ;line feed

mname                         db 16 dup (0), 42
noname              db CR, LF, "No name is defined!!",42

                    Assume ds:DGROUP

INIT_CODE:
               mov       ax,05e00h ;Get machine name function.
               mov       dx, offset mname
               int       21h

               cmp       ch, 00h
               je        not_loaded
               mov       ax, offset mname
               call      Print     ;This routine simply prints
                                   ;string to screen.
               jmp            terminate

not_loaded:
               mov            ax, offset noname
               call      Print          ;This routine simply prints
                                        ;string to screen.

terminate:
               mov       ah, 04Ch       ;Return mem. used back to DOS
               mov       al, 01h        ;And terminate program.
               int       21h

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET NAME:

;*** This program sets the machine name to whatever the variable
;*** "mname" is set to below. Note the name must be 15 characters.
;*** If the machine name is less than 15 characters you MUST pad
;*** the remaining characters with spaces. One could alter this
;*** program to accept input from the command line or simply
;*** change the string below to the desired machine name.

          Ideal
          Model     Tiny
          P286
          CodeSeg
          Org       100h

Start:    jmp       INIT_CODE


mname     db "MNAME      "   ;15 character blank-padded ASCIIZ

          Assume ds:DGROUP


INIT_CODE:
          mov       ax, 05e01h     ;Set Machine Name Function
          push      cs
          pop       ds
          mov       cx, 00101h     ;Important! ch = 00h is undefined
                                   ;name. cl = name number. In order
                                   ;to set name the following must
                                   ;be true: ch > 0 and cl > 0.
          mov       dx, offset mname
          int       21h
terminate:
          mov       ah, 04Ch       ;Return mem. used back to DOS
          mov       al, 01h        ;And terminate program.
          int       21h
End  Start

NWReadQueueJobEntry2 () and QueueJobStruct Under NetWare Client SDK 1.0e

The documentation regarding QueueJobStruct initialization is incorrect. The Programmer's Guide for C, Client API Data Summary, states that the QueueJobStruct fields: servicingServerStation, servicingServerTask and servicingServerID are initially undefined. This is incorrect. The three fields are initialized to 0.

NWAFPGetEntryIDFrom PathName() Return Values Under NetWare Client SDK 1.0e

The following list contains the API NWAFPGetEntryIDFromPathName() return values not listed in the NetWare Client SDK v1.0e documentation. NWAFPGetEntryIDFromPathName() has some additional return values which are not documented. The return codes which should be added to the existing documentation are listed below.

0x8983    IO_ERROR_NETWORK_DISK
0x8993    NO_READ_PRIVILEGES
0x8996    SERVER_OUT_OF_MEMORY
0x8998    VOLUME_DOES_NOT_EXIST
0x899B    BAD_DIRECTORY_HANDLE
0x89A1    DIRECTORY_IO_ERROR
0x89A2    READ_FILE_WITH_RECORD_LOCKED
0x89FD    BAD_STATION_NUMBER
0x89FF    NO_FILES_FOUND_ERROR

TIUSER.H Produces Errors During Compile Under NetWare Client SDK 1.0e

Compiling an application with the TIUSER.H header file included produces errors. When compiling using the MSC compiler the following errors are returned:
d:\include\tiuser.h(171) : error C2054: expected `(` to follow `FAR'
d:\include\tiuser.h(171) : error C2059: syntax error : `*'
The Borland C++ compiler returns:
Syntax Declaration error in tiuser.h.
This occurs if the program is compiled without defining the proper header file macro. Use the following syntax to define the appropriate header file macro for the platform on which the program is being compiled. Include the following command on the command line for MSC or Borland compiler:
cl /DNWDOS ...
bcc /DNWDOS ...
NWDOS defines the DOS platform and NWWIN defines the windows platform.

NWSendBroadcastMessage() Returns 0x89FB Under NetWare Client SDK 1.0e

When building a list of connection numbers for an object using NWGetObjectConnectionNumbers(), an array of type NWCONN_NUM is returned.

If this array is passed as a parameter to the NWSendBroadcastMessage() error 0x89FB (invalid parameter) is returned.

When passing an array with elements of type NWCONN_NUM to NWSendBroadcastMessage(), this function fails with 0x89FB (invalid parameter).

This error is caused by an array with elements of an incompatible type passed to the function NWSendBroadcastMessage(). The initialized array returned from NWGetObjectConnectionNumbers() is of type NWCONN_NUM which are double words (four bytes) while the array passed in to NWSendBroadcastMessage() expects a pointer to an array with elements of type NWCONN_NUM_WORD which is a word (two bytes).

The following intermediary step can be used to perform the necessary conversion before passing the array pointer of type NWCONN_NUM to the function NWSendBroadcastMessage() which expects a pointer to an array of elements of type NWCONN_NUM_WORD.

NWCONN_NUM   doubleWordConnList[50]; NWCONN_NUM_WORD wordConnList[50];
...

for(i=0; i < numConnections; ++i)
  wordConnList[i] =
  (WORD)doubleWordConnList[i];

NWPS_ATTR_PRINT_SER Incorrectly Documented Under NetWare Client SDK 1.0e

The Client API for C online documentation is incorrect regarding NWPS_ATTR_PRINT_SER attribute value. The Client API for C online documentation shows NWPS_ATTR_PRINT_SER as an attribute identifier that contains the attribute value Queue Volume Name. This is incorrect. NWPS_ATTR_PRINT_SER contains the attribute value Print Server Name.

If a call is made to NWPSCfgAddPrinterAttr() with the attribute NWPS_ATTR_PRINT_SER and a queue volume name, error 0x7764, NWPSE_NO_SUCH_PRINTER_SERVER, will be returned.

NWPSCfgAddPrinterAttr() Returns 0x7764 Under NetWare Client SDK 1.0e

Error code 0x7764 is not currently documented in the error return values. The error code represents NWPSE_NO_SUCH_PRINTER_SERVER.

Client Record Area Structure Definition Under NetWare Client SDK 1.0e

Applications that submit print jobs directly to a queue must fill in the fields of the client record area themselves to set the number of copies, form feed and so on.

Applications that submit print jobs to a queue directly using NWCreateQueueFile2() and do not send the jobs to a redirected port must set the values in the clientRecordArea element of the NWQueueJobStruct structure. If these values are not set, the print job parameters such as tab size, number of copies and so on could become undefined and will produce unwanted results.

The NWCreateQueueFile2() requires that the address of the NWQueueJobStruct structure be passed as a parameter when submitting a queue job to a queue. An example of this structure is given below.


typedef struct
{
  DWORD clientStation;
  DWORD clientTask;
  DWORD clientID;
  DWORD targetServerID;
  BYTE  targetExecutionTime[6];
  BYTE  jobEntryTime[6];
  DWORD jobNumber;
  WORD  jobType;
  WORD  jobPosition;
  WORD  jobControlFlags;
  BYTE  jobFileName[14];
  DWORD jobFileHandle;
  DWORD servicingServerStation;
  DWORD servicingServerTask;
  DWORD servicingServerID;
  BYTE  jobDescription[50];
  BYTE  clientRecordArea[152];
} NWQueueJobStruct;
The last element of this structure clientRecordArea is used by the job server to acquire specific information about the print job. The structure of this 152 byte client record area is not documented.

Following is the structure definition of the clientRecordArea as indicated in the NWPS_JOB.H file.


typedef struct
{
     BYTE versionNumber;
     BYTE tabSize;
  WORD    numberOfCopies;
  WORD    printControlFlags;
  WORD    maxLinesPerPage;
  WORD    maxCharsPerLine;
  BYTE    formName[13];
  BYTE    reserve[9];
  BYTE    bannerNameField[13];
  BYTE    bannerFileField[13];
  BYTE    headerFileName[14];
  BYTE    directoryPath[80];
} NWPS_ClientRecord;
Note: Although this structure can be defined by the developer and passed as NWQueueJobStruct.clientRecordArea to the NWCreateQueueFile2 function, this structure was intended for use by Novell's NetWare Print Services only. Novell reserves the right to change this structure at any time.

This structure is overlayed on the QMS (Queue Management Systems) NWQueueJobStruct.clientRecordArea to define a print job. It is not used in any of the print services APIs. The numberOfCopies field must be byte swapped in order for the print server to interpret this value properly. This can be accomplished by using NWWordSwap() function.


FROM THE COCKPIT

Welcome to our latest edition of PDP Bullets! You will find many interesting items in this issue. We have an excellent lead article by one of our support engineers, Marina Pimentel, who gives plenty of practical information on how to use the wide variety of facilities in the NetWare Print Services area. We also have a number of technical tidbits that should prove valuable as you build products with our SDKs and tools.

We have enhanced our developer support services during September. Our newly installed Bulletin Board Service is up and active. Through the BBS, we have simplified code sharing between our support team and your development team. One benefit of this "developers' only" BBS is any code you provide for us is completely secure without opportunity for misuse. Look for more information about the BBS in this issue from Calvin Gaisford and Doug Durfey.

The Novell and WordPerfect merger is now complete. We are very excited about this change in our company and we hope that you are excited as well. Over time, Novell will provide additional opportunities to work with the Greater Novell with ways to integrate with the GroupWise groupware products and PerfectOffice as well as other products. Stay tuned during the next few months as we roll out these options.

And while we're talking about changes at Novell, you will see some significant and valuable enhancements to our Developer Program over the next couple of months. These modifications will allow us to provide a better, more complete level of service for your needs. As this firms up, more information will be available through future issues of PDP Bullets.

The partnerships that our companies build are vital to our mutual customers' success, and we are excited to work with you. I encourage you to answer our questionnaires, like this month's survey from our Education group, that will appear from time to time. We need to know what you think of us to continually improve our process of working and succeeding with you.

Jared Blaser Director of Developer Support


DEVELOPER NEWS

Novell Developer Support BBS

The Novell Developer Support BBS is now online. The BBS is designed for customers who need to send code to the Novell Developer Support Team but do not have access to the Internet or CompuServe. Developers can also upload sample code for any of Novell's SDKs that they would like to share with other developers. No messaging services will be enabled on the BBS.

Customers calling into the BBS for the first time will be prompted for some information to create the BBS account. Most of these items are self explanatory but the following items are not so obvious:

  • Hot Keys: This allows a user to enter a command from the menu without pressing return after each command. Answer "Y" to this option if you want to avoid pressing return after each command.
  • Online Editor: The full screen editor only works if your terminal emulator can handle ANSI codes. The full screen editor will show a whole page of the text as you edit, whereas the Line Editor only shows one line at a time.
After answering the questions, the user is authenticated and has full access to the BBS. You will be prompted to read the bulletins, and then the BBS takes you to the Main Menu. The bulletins on the BBS contain information about Novell's SDKs and the BBS.

From the main menu you have the ability to access the file menu. Seven file areas are available for downloading. If you know the name of the file to download, the download command will prompt you for the file name and allow you to download the file. If you don't know the file name, you can browse the seven file areas, choose the files to download and then download them. To upload a file use the upload command. You can upload sample code to be placed into one of the seven file areas or upload test code for engineers. In either case, the files are placed off line after they are uploaded and then later redistributed. When uploading a file for an engineer, please combine all files for uploading in a "zip" file and name the file .zip (i.e. 12345678.zip). Please note the guidelines for sending test cases to the Novell Developer Support below.

To access the BBS, set your communication software to N-8-1 and call 1-801-429-5836. Two nodes are available for connections; if one node is busy you are automatically connected to the second node.

Test Case Requirements

Developer Support intends to provide our developers with the highest level of support possible, given our resources and current work load. In many situations a test case can assist us in resolving our developers' problems. The following four basic components are our requirements for a test case.
  1. Working program: send an executable file that clearly shows the problem being addressed. We do not want a full-blown application that may contain other problems that may misdirect the focus of the issue. There may be exceptions to this, but please understand that we're working with many developers at the same time. When preparing your test case, please keep the application brief. The smaller the test case application, the faster we can get down to addressing your issue. The application should run with little or no user participation.
  2. Source Code: Send all the source code for the test application.
  3. Include and Make Files: Send all (non-Novell) include files, header files, data files and make files necessary if we decide to recompile this test application.
  4. Readme.doc file: Send an ASCII readme.doc file that fully explains what the problem is as you understand it. Provide as many details as possible about all aspects of the problem, including the following explanations:
    • Explain the types of systems this is or is not running on (if you have seen a difference).
    • Explain if this is a new application or if this is an existing application that just started to present a problem.
    • Explain how frequently the problem occurs.
    • Explain any version variations that change the problem.
Also, explain how to run the test case to duplicate the problem. Provide the following header information so that the test case will be routed to the appropriate Support Engineer.
  • Incident number
  • Assigned support engineer name
  • Novell SDK name and version
  • Compiler name and version
If you provide us with these four basic test case components, then it may not be necessary for us to ask you to send additional information at a later date. However, if you fail to provide these four basic components, the resolution to your problem may be delayed.

Test Case Delivery

There are several ways you can send a test case to Novell Developer Support after opening an incident with a Support Engineer.
  • E-mail: CompuServe, MHS or Internet (see page 14 of this issue, "Contacting Novell" for E-mail addresses)
  • BBS: call 1-801-429-5836, set modem to N-8-1 (see related article on this page)
  • Mail to our Developer Support office in Provo, UT (see back cover for address)
Test cases that arrive without an incident number will be placed into our unassigned queue.

Disclaimer

Any source code, include files, header files or data files that are sent to Novell Inc. Developer Support for the purpose of a test case are the sole property of the developer who sends the files. Any test case that Novell, Inc. receives will be used for the explicit purpose of problem resolution. When all tests are completed and the problem has been resolved, the entire test case will be destroyed.

TELETIPS

Teletip #5

Living in a World That Isn't Here

When writing professional applications, especially applications for a network environment, developers often need to write in a "clean environment" rather than placing the application where people might use it. The application may only be in the "pre-Beta" stage and may cause problems with different workstation configurations, or maybe you just don't have the necessary hardware to run the software in your environment. Whatever the reason, it would be nice to "simulate" the necessary program environment.

The ideal simulator, or "fake world," would not let your application know that it is not running in a production environment. The application would think it was running as it should and process information in its own naive way.

The idea of a simulator becomes particularly attractive when the necessary hardware is very expensive or hard to come by. Such can be the case when you develop applications for NetWare Telephony. Maybe your manager hasn't approved the budget for a new PBX yet. Maybe you have ordered the PBX, but it hasn't arrived yet. You still need to get to work on the application.

To help you get up and running in your blissful simulated world, a DEFINITY System Simulator by AT&T simulates a physical DEFINITY G3. This simulator runs on the Telephony server and appears to be a real PBX to any applications requiring PBX services. The simulator keeps PBX "configuration" information, which can be modified to the desired configuration, in a similar configuration file, and reads into memory at load time.

The key parts for simulator use are the SIM.NLM file on the server and the CLSIM.EXE utility on the Windows client machine. Use the CLSIM program to create the configuration files that the SIM.NLM program will use. When you have created one file, you can load the simulator on the NetWare Telephony Server. As far as your application is concerned, you live in your own happy world _a world totally custom-made for your needs. You can continue to use the CLSIM program to send test messages to the TServer, or you can use your application to make TSAPI calls to the TServer; either way, the simulator is now running and will respond to the application as if it were a real, physical PBX. Tip Use the simulator (SIM.NLM) and CLSIM.EXE to test your applications in a nonproduction environment.

TeleTip #6

"Abort, Abort, Abort!"

Ok, it's confession time. We've talked about not walking through open doors already (previous TeleTip on acsOpenStream). After the door is open, you can walk through it, stand under it, and basically do whatever you want. Then, when you're done with the door, you just close it behind you, and everything's fine, right? Well, that's how I had been working so far. But what if you pull the door closed and it doesn't shut all the way? All the heat in your house leaves, the cold air comes in, your heating bill goes up, everyone is cold and on and on.

It's the same with TSAPI. Let's assume we've already opened a stream with acsOpenStream() and received the appropriated confirmation event, either through polling or blocking. Then, our application did all sorts of fun things: calling people, conferencing calls and hanging up on people. Our killer app is getting bored now and decides to exit. First it knows it must close the stream so it calls acsCloseStream(). After that, the app exits. Then you start noticing errors showing up on your screen and maybe even lock up. What's wrong?

Well, our telephony programs need to clean up after themselves. The acsCloseStream() function is nonblocking, which means the function will return without the stream necessarily having been closed properly, and, more important to our application environment, the resources haven't been properly freed yet. The TServer will send a confirmation event, of the type ACS_CLOSE_STREAM, which signifies that the stream has been successfully closed, and all resources the TServer had open with the stream have been correctly freed. This event may not be the next event to come through from the TServer, however. As the documentation states, "The application must be prepared to receive multiple events on the ACS Stream after the acsCloseStream() function has completed, but the `ACS_CLOSE_STREAM event' is guaranteed to be the last event on the ACS Stream."

There is an alternative to waiting for the ACS_CLOSE_STREAM event. If you use the function acsAbortStream() instead of the acsCloseStream(), you need not check for confirmation events. The acsAbortStream() is a blocking function. When you receive a successful return code from acsAbortStream(), you are assured that the TServer has already freed all associated resources and it is safe to exit your program. Tip If you use the nonblocking acsCloseStream() function, be sure to check for the appropriate ACS_CLOSE_STREAM confirmation event. Otherwise, use the acsAbortStream(), which is a blocking function, and doesn't have an associated confirmation event. Kevin White is an engineer in Novell's Developer Support Group. He has used computers with his father, also a Novell engineer, for many years. He enjoys eating, martial arts and eating. Kevin is engaged to be married in January.


NIBBLES AND BITS

NetWare Client SDK 1.0e

Q - What are the TLI t_open() protocol device parameters?

A - The path parameter of the t_open() call specifies which type of transport endpoint should be opened. The following list shows supported options for this parameter:

  • /dev/nipx
    for transport provider IPX
  • /dev/nspx
    for transport provider SPX
  • /dev/nspx2
    for transport provider SPX2
  • /dev/udp
    for connectionless TCP/IP
  • /dev/tcp
    for connection-oriented TCP/IP
Q - What are the return values for BeginDiagnostics()? A - Return values for the BeginDiagnostics() function call should be documented as follows:
  • 0x00 Successful
  • 0xFC Could Not Establish Connection
  • 0xFD Could Not Begin Connection
  • 0xFE Could Not Open Socket
Q - How do I determine the activity of a job in a queue?

A - To determine if a job is active, you must make a call to NWReadQueueJobEntry2() to obtain the queue job information contained in the QueueJobStruct structure. Once you make this call, you can test the servicingServerID field for a nonzero value. Because this field is initialized to 0, a non-zero value indicates that the job is currently being serviced by a queue server.

Q - What values does NWDSCreateContext() return?

A - The documentation for NWDSCreateContext() states that 0x0000 will be returned if the call was SUCCESSFUL, and ERR_CONTEXT_CREATION (-328 decimal) otherwise. This is misleading since the call should return a valid NWDSContextHandle when it has been successful.

To determine if the NWDSCreateContext() call has failed, test for a return value equal to ERR_CONTEXT_CREATION. Otherwise, the NWDSCreateContext() call succeeded and a valid context handle was returned. A valid NWDSContextHandle runs from 0 to 23 for Windows and OS/2 and runs from 0 to 7 for DOS.

Q - What is the maximum number of TLI connections supported?

A - The maximum number of connections TLI supports for DOS and Windows is 40. For OS/2, the absolute limit is 128 minus the number of connections used by other IPX/SPX applications.

Q - Why does NWScanConnectionsUsingFile() turn 0x0000 when a nonexistent or an unopened file is passed in as a parameter?

A - This function was not designed to verify the existence of a file but to determine whether a connection currently has the file open. The sixth parameter passed into the function is the address of structure type CONNS_USING_FILE. One of the elements of this structure, connCount, contains the number of connections that currently have the file open. Ensure that this value is greater than zero before acting on data returned from the function. Use this course of action rather than assuming that a return code of 0x0000 from NWScanConnectionsUsingFile indicates that the file is in use by a connection.

NetWare System Calls 1.0

Q - How do I get and set capture flags using VLMs?

A - When using the VLMs after ending a capture, the flags field information is no longer available. This information should be saved before ending the capture and then restored after completing the capture. When you use the VLMs, you need to save the flag information with a call to GetSpecificCaptureFlags(), and then end the capture. After ending the capture, you can restore the flags by using the function SetSpecificCaptureFlags().

NetWare C Interface for Windows 1.3

Q - Why does IPXInitialize() return 0xF5 with Windows for Workgroups v3.11?

A - IPXInitialize() returns 245 (0xF5) OVER_MAX_LIMIT when run in a Windows for Workgroups 3.11 environment. This problem is caused by the Windows for Workgroups v3.11 NWLINK.386 driver and can be resolved by replacing NWLINK.386 with VIPX.386. This process is described in the WINVLM.EXE file on the NOVFILES forum of CompuServe which outlines the steps necessary to replace the NWLINK.386 with Novell's VIPX.386.


DEVELOPER EDUCATION

Available Novell Developer Education Courses

Novell Developer Education offers several courses for developers who use Novell's development tools.
930  Developing NetWare Loadable Modules (NLMs)
940  NetWare Programming: Basic Services
941  Directory Services
945  NetWare Programming: Protocol Support
950  Visual AppBuilder
954  ALM Development

Novell Authorized Education Centers

The following Novell Authorized Education Centers (NAECs) offer developer training:
    Alternative Computer with sites in Mt. Laurel, NJ; Albany, NY; Pittsburgh, Allentown and Bluebell, PA offers courses 930, 940 and 945. Contact Jamie Anewalt at 1-800-321-1154.
  • C-Trec in Houston, TX offers courses 930, 940, 941 and 945, and plans to teach 950 and 954. Contact Conni Templin at 1-713-871-8411.
  • Clarity located in San Jose, CA offers courses 930, 940 and 945, and plans to teach 941, 950 and 954. Contact Kirstin Hills or Cyd Simerville at 1-800-729-9995.
  • Professional Computer Development Corp. with sites in Norcross, GA; Shaumburg and Mt. Prospect, IL; Livonia, MI; Edina, MN; Cincinnati and Maumee, OH; and Pittsburgh, PA offers course 930. Contact Larry Guyette at 1-800-322-7232.
To obtain information on pricing, location, scheduling and course content for classes held in the U.S. call 1-800-233-3382 or 1-801-429-5508. For information on classes in all other locations, contact your local Novell office.

NOVELL PROFESSIONAL DEVELOPERS' PROGRAM

How to Become One of Our Developers

Developing computing systems is a complex, time-consuming and expensive task. Novell understands this and is committed to its developer partners. The Novell Professional Developers' Program allows you, our developer, to access our broad base of 40 million NetWare users to develop and market your products.

This program is designed for a wide range of developers who design and create commercially available solutions. This includes commercial developers, called Independent Software Vendors (ISVs), and vertical application developers who create applications for specialized markets such as manufacturing, medicine and law.

Key Features

Members of the Novell Professional Developers' Program receive the following benefits.
  • Co-Marketing Support
    Members can participate in the Yes Program, which offers a variety of co-marketing opportunities as well as ongoing information about Novell's direction. The ultimate goal of the Yes Program is to make it easy for customers to identify and purchase products that are optimized for Novell platforms.
  • Technical Support
    To obtain product information and technical support, phone 1-800-RED-WORD (1-800-733-9673) or 1-801-429-5281.
  • Skills Transfer
    Members may participate in the Skills Transfer Workshops conducted by a Novell specialist. The workshops offer cutting-edge training on solution design, development and implementation. Members may also attend Novell Compass Special Interest Groups, where they have the chance to review products and provide feedback directly to Novell development teams.
  • Project/Opportunity Services
    Members have access to Novell expertise through the developer forums on CompuServe. These forums address developer issues including technical information and support for Novell products and development tools.
  • Information Services
    As a developer, you receive Novell Developer Notes, a publication targeted at network software developers. Other publications are also available: Bullets, a monthly technical journal; Appnotes (subscription only), a technical journal for network design; and the annual Developer Guide to Programs, Products, and Services. Members also get access to Novell's NDEVSUP CompuServe forum_an electronic meeting place where developers can exchange information with each other and with Novell staff members.
  • No Program Fees
    Membership in this program is free of charge and open to all developers. If you would like further information about the Professional Developers' Program or would like to apply for membership, please phone 1-800-RED-WORD (1-800-733-9673) or 1-801-429-5281. If you would like to order Novell development tools, please call 1-800-RED-WORD. You may also contact the program administrator by E-mail at the following address: devprog@novell.com.

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.