OCTOBER 1994 VOLUME 6 NUMBER 5
Index
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);
}
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.
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
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.
- 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.
- Source Code: Send all the source code for the test application.
- 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.
- 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.
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.
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.
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.
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.
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.
|