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  

MARCH 1992 VOLUME 4 NUMBER 3


INDEX


MAD'S COLUMN

Hello and welcome to the March 1992 issue of Bullets!

As you will very quickly notice, in this issue of Bullets,we have included a four-page technical marketing supplement.

This supplement provides our existing database programmers a quick look at the new functionality that is available in NWSQL v.3.0, as well as the enhancements and features added to version 6.0 of Btrieve. For those of you that are not currently using our database tools, we hope that these new features will entice you, too.

The excitement here at Novell Austin increased as NetWare SQL v3.0 neared completion and the scheduled release date inched closer and closer. The level of activity and teamwork also increased as each department prepared for the release. For the past three months, we have been involved in intensified in-house technical classes and presentations, marketing reseller seminars, software engineer training and long hours of coding and testing.

These activities have demonstrated our entire site's commitment to the success of NetWare SQL v3.0. All of our efforts will be worth it if you, the Novell developer, are satisfied with the final product. Let us know what you think!

Happy_Programming!

Mad Poarch
Director
Developer Support/Service


ARTICLES:

Capturing with the NetWare Print Services

One of the most commonly asked questions regarding the use of the NetWare C Interface for DOS APIs is, "How can I duplicate the functionality of the CAPTURE.EXE program?" The NetWare Print Services APIs are very useful for developers who need to control the printing capabilities of other applications. Applications can also use these services to handle their own printing needs, but may be better served by writing directly to print queues using Queue Services.

This article describes how to use the various NetWare Print Services APIs to control capturing of printed output and redirect it to a print queue or file on a NetWare file server. The code examples in this article are excerpts from a program called CAPIT. C, which reproduces much of the functionality of CAPTURE.EXE. Because of space limitations, the entire source code for CAPIT.EXE cannot be printed in this publication. Both the source code and the executable itself are available in Novell's CompuServe forum, NetWire (see details at end of article).

The CAPTURE.EXE program included with NetWare provides some additional capabilities over CAPIT.EXE. For example, it can retrieve default capture flags defined by PRINTCON in the file, PRINTCON.DAT. The format of the information in PRINTCON.DAT is proprietary to Novell and is subject to change without notice. If you need a mechanism to store or retrieve these default values, you should develop your own. This article will demonstrate how to "carry-forward" existing capture flags.

CAPIT.EXE uses "default" capture functions whenever they are available. This design simplifies the code for choosing the local printer to which printer output will be directed. These functions act on the printer port being captured, which is set by the function SetDefaultLocalPrinter(). There are also "specific" functions that act upon a specified local printer on each call. These functions are similar to their "default" counterparts, but include an extra parameter specifying the local printer.

The Capturing Process

The capturing process requires four basic operations:
  1. End any existing capture
  2. Set the capture print queue
  3. Set the capture flags
  4. Start the capture
To correctly capture printer ports, perform each of these operations in the sequence shown above.

Ending Existing Captures

To begin capturing, a program should first end any existing capture. Ending a capture clears existing capture flags and makes them irretrievable. So, CAPIT.EXE first saves the existing capture flags by calling the GetDefaultCaptureFlags() API. If a capture is still in progress, this API returns a number of valid flags that can be used when setting up the next capture. If no capture is active, these flags should be reset to their defaults, using the procedure shown in Figure 1.

FIGURE 1: Resetting capture flags to default values

SetDefaultLocalPrinter(localPrinterToCaptureTo);
  GetDefaultCaptureFlags(&setCaptureFlags);
  retCode = GetLPTCaptureStatus(&serverNumber);
  if (retCode == 0)  // Reset flags if not now captured
  {
setCaptureFlags.status = 0x00;
setCaptureFlags.flags = 0x00;
setCaptureFlags.tabSize = 0x08;
setCaptureFlags.serverPrinter = 0x00;
setCaptureFlags.numberOfCopies = 0x01;
setCaptureFlags.formType = 0x00;
setCaptureFlags.localLPTDevice = 0x00;
setCaptureFlags.flushCaptureOnDeviceClose = FALSE;
setCaptureFlags.flushCaptureTimeoutCount = 0x00;
setCaptureFlags.maxLines = 66;
setCaptureFlags.maxChars = 132;
setCaptureFlags.formName[0] = NULL;
setCaptureFlags.LPTCaptureFlag = FALSE;
setCaptureFlags.fileCaptureFlag = FALSE;
setCaptureFlags.printQueueFlag = FALSE;
setCaptureFlags.printQueueID = 0x00;
  }

End of Figure 1
After resetting the flags to default values, you can end the capture by calling the EndLPTCapture() API. CAPIT.EXE then parses the command line and determines which flags must change for the next capture. The flags will be covered in more detail in the section entitled "Setting Capture Flags."

The documentation for SetDefaultCaptureFlags() and SetSpecificCaptureFlags() incorrectly states that the parameter passed to each function should be a pointer to a structure of type, SET_CAPTURE_FLAGS. Although the function's prototype expects this type of pointer, additional flags in the CAPTURE_FLAGS structure are required. These functions should be passed the same structure that is passed to the appropriate GET functions, and cast to the expected structure. For example:

This is why the code required to get and clear the flags (shown in Figure 1) uses setCaptureFlags. The functions to set the flags require the entire structure as defined by CAPTURE_FLAGS, not the shortened version defined by SET_CAPTURE_FLAGS.

Capturing to a File or Print Queue

Next, define either a file or a print queue to which printer output will be directed. To define a file, set the preferred connection ID for the file server where the file is located, and call:
     specifyCaptureFile(directoryHandle, path);
The directory handle can be zero if the path is a fully qualified volume path (e.g., path = "SYS:USERS\GUEST \CAPTURE.TXT"). Otherwise, the directory handle and the path must make up a full path (e.g., handle = 1 and points to "SYS:USERS\GUEST" and path = "CAPTURE.TXT"). If capturing to a print queue, make the calls in Figure 2.

FIGURE 2: Calls necessary to capture to print queue

  SetPreferredConnectionID(printServerConnectionID);
  retCode = GetBinderyObjectID(queueName,
 OT_PRINT_QUEUE,
 &queueID);
  if (retCode != 0)
  {
   // Queue may not exist on server   handle the error
  }
  setCaptureFlags.LPTCaptureFlag = FALSE;
  retCode = SetCapturePrintQueue(localPrinterToCaptureTo,
   printServerConnectionID,
   queueID);

End of Figure 2
The CAPTURE_FLAGS structure member LPTCaptureFlag must be set to zero to inform the shell that a new queue has been specified, otherwise the queue/server association will not be handled correctly. Although it is cleared by ending the capture, the flags in this structure are acquired before ending the capture.

Setting Capture Flags

The capture flags must be set after designating a queue and before beginning the capture. To set the flags, call SetDefaultCaptureFlags() or SetSpecificCaptureFlags() and pass in a pointer to a CAPTURE_FLAGS structure (not the SET_CAPTURE_FLAGS structure). Most of these flags are clearly documented in the NetWare C Interface for DOS v1.2. A few of these flags are defined more clearly here. The flags field defaults to all bits turned off. The bits are defined in Figure 3.

FIGURE 3: Flags field of CAPTURE_FLAGS structure

Flag Definition
----------------------------------------------------------
0x01 Undefined

0x02 Undefined

0x04 If set, jobs get printed if workstation loses connection during capture

0x08 If set, form feeds will not be sent at the end of each job

0x10 If set, the user is notified when the job has printed

0x20 Undefined

0x40 If set, tabs are converted to spaces

0x80 If set, a banner page is printed before the print job

End of Figure 3
Bit position 0x04 is currently not set by CAPTURE.EXE or CAPIT.EXE. If bit position 0x80 is set, the banner that is printed consists of what is stored in bannerText and the user name stored by the function SetBannerUserName(). If bit position 0x40 is set, tabs are converted to the amount of spaces defined in tabSize. If bit position 0x10 is set, the user will be notified via a broadcast message when the job has printed.

The printerSetupBuffer and printerResetBuffer fields are used for placing printer controls before and after a print job. They are far pointers to the buffers created by the NetWare shell. The first word (not byte) in each buffer defines the size of the buffer. The second word defines the length of the printer control (how many bytes to send to the printer). The remaining bytes are sent to the printer.

The size of these buffers is determined by the PRINT HEADER= and PRINT TAIL= parameters inside the shell.cfg or net.cfg file. If these parameters are not set within these files, default sizes are used: 64 bytes for the printerSetupBuffer and 16 bytes for the printerResetBuffer.

Unless you need to modify the values inside these buffers, you only need to know how to treat the pointers to the buffers under various versions of the shell. With versions of NetWare shell before v3.00, the address of the buffers was returned long-swapped (i.e. in "hi-lo" or non-Intel format), but with v3.00 and above, the addresses are no longer swapped (they are returned in lo-hi, or Intel-readable, format).

The NetWare C Interface for DOS (v1.2 and earlier) swapped these bytes to compensate for the swapping performed with pre-v3.00 shells, but the interface does not check for the shell version before doing so. Therefore, if your application is running under shell versions 3.00 and above you must swap these values. Swapping can be performed with the code displayed in Figure 4.

FIGURE 4: Calls needed to manage differences between v2.x & v3.x shells

retCode = GetNetWareShellVersion(&majorVersion,
   &minorVersion,
   &revisionLevel);
if (retCode == 0)
{
  printf("Shell version too old\n");
  exit(1);
}
if (majorVersion > 2)
{
  setCaptureFlags.printerSetupBuffer =
   (char far *)LongSwap((long)setCaptureFlags.printerSetupBuffer);
  setCaptureFlags.printerResetBuffer =
   (char far *)LongSwap((long)setCaptureFlags.printerResetBuffer);
}

End of Figure 4
The flag used to enable/disable auto endcap is flushCaptureOnDeviceClose. This flag should be set to TRUE to disable auto endcap. The flushCaptureTimeoutCount flag defines the number of ticks to wait without any printing before the job is queued for printing.

The only remaining step is to start the capture, either with StartLPTCapture() or StartSpecificLPTCapture().

Capturing data intended for a printer and redirecting it to a file or print queue is a fairly simple matter. A few situations require special handling, but once these are resolved, applications that are not NetWare-Aware can be made to print to NetWare print servers or files. An alternative to capturing printer output is to write data directly to NetWare print queues.

The source code to CAPIT.EXE and the executable can be downloaded from NetWire (NOVLIB section, LIB 14, under filename CAPITx.ZIP, where "x" is the revision number if any). If you have additional questions on capturing with the NetWare Print Services, or if you need technical assistance, please contact the Developer Support Group at Novell Austin (See "Contacting Novell Austin" at the end of this issue).


SPECIAL PRODUCT SUPPLEMENT:

NetWare SQL New & Enhanced Features

NetWare SQL v3.0 offers new and enhanced features that improve performance and increase database integrity.

Even a novice database administrator will be able to install and use NetWare SQL v3.0 due to the new, simple Install utility We have improved the performance of many join and fetch functions at the NetWare SQL level and enhanced loading of large files. The documentation has been reorganized to better accommodate different expertise in the SQL level functions or relational primitives. Convenient quick reference cards provide easy access to SQL statements and status codes.

Cursor Stability, the ability to lock the page containing the record to which the cursor is currently pointing, has been added. Cursor stability ensures that the data each user reads remains stable, while still allowing other users access to other pages within the same data files. The cursor stability isolation level generally permits greater concurrency for all users on a network by limiting the number of records each user locks at any one time. This allows other network users to access more pages of the data file.

Btrieve Enhancements

Many enhancements of NetWare SQL v3.0 occur at the Btrieve v6.0 record manager level. The Btrieve file structure has been modified to support Referential Integrity, online backup, new caching algorithms, page allocation tables, and passive control. Since Btrieve v6.0 file structure has changed significantly, it is necessary to convert any existing Btrieve data to the new Btrieve v6.0 format. A utility is included to perform the conversion. If users choose not to take advantage of the new features and increased performance, the previous Btrieve v5.x files are still compatible.

Referential Integrity (RI) constraints ensure that cross references between tables are always valid. A Database Administrator can define RI restrictions with SQL statements. NetWare SQL enforces these constraints across all applications at the Btrieve level. Since these RI restrictions are enforced at the data dictionary level, developers are freed from having to include RI restrictions directly in their applications.

Online Backup or continuous operations allows users to backup the database currently in use at any time without closing the files. Online backup is implemented with a NetWare SQL utility which opens the original file in a read only mode. Btrieve backs up a "snapshot" of the file and creates a "Delta" file for operations occurring during the backup process. After turning off the backup utility, Btrieve issues a "commit" transaction.

New caching algorithms have been developed to provide hashing search methods for improved access, concurrent sharing of a single cache, and persistence of the cache across operations. The speed of building and loading supplemental indexes for large data files has been improved with merge sorts.

Page Allocation Tables (PATs) contain information about the file, such as file size and page size, as well as information about other current pages. PATs represent a departure from Btrieve's previous pre-imaging method. Btrieve's previous pre-imaging is the process of storing the image of a file page before a record on the page is updated. In the alternative, PATs are updates to the page or pages written into unused or "recycled" pages in the Btrieve file. During the commit, the PAT is updated to reflect any activity. This enhances performance because a pre-imaging file does not need to be maintained.

Because of the shift to PATs, a "roll-back" command is no longer necessary. The user is working with a "virtual" copy of the file. The file is always valid and internally consistent except during a controlled commit period.

Passive Control allows applications to expect the update or delete operation to complete successfully. Rather than requiring an application to lock a record before updating it, Btrieve returns a "conflict" status at update time if an application attempts to update a record that has been changed since the application last read it. Passive control supports updates of one record at a time outside of a transaction.

Passive control allows a single user application to run on the network without implementing locking. However, passive control is most effective when an application is operating in a lightly utilized network environment or on files in which the data is fairly static.

Packaging and Upgrades

NetWare SQL v3.0 is now user-count stratified exactly the same as NetWare v3.11. The 20, 50, 100, and 250 user versions include the NetWare Runtime components. Customers do not need to match NetWare and NetWare SQL user count versions. The user count of NetWare SQL is limited to the number of NetWare SQL logins not NetWare logins.

The NetWare SQL Developer's Kit will be offered concurrently (as a separate product) with the release of NetWare SQL v3.0. The developer's kit documents the NetWare SQL APIs and SQL statements. It also provides a comprehensive overview for new NetWare SQL developers who start writing applications for NetWare SQL. The language interfaces and embedded SQL preprocessor for DOS and libraries for OS/2 are a part of the kit.

Upgrades are offered from NetWare SQL 386 2.11 (NLM) and NetWare SQL 2.11 (VAP) for a limited time.

For more information about NetWare SQL v3.0, contact your local Novell reseller, or call 1-800-477-9139 (FAX 512-345-9509). Customers outside the USA, please contact your local Novell office or call 512-795-8094.


TECHNICAL INSIGHTS:

CLib API Update: GetVolumeNumber( ) (Network C for NLMs v2.0b)

With the Network C for NLMs SDK, if you call GetVolumeNumber() to get the number of a volume on a remote server, the function appears to returns incorrect information for the volume number. Actually, the volume number is retuned in the first byte. The remainder of the "int," however, is not cleared, and contains the information that it held before the call. For example:

Source:

int volNumber = 0xFFFFFFFF;

GetVolumeNumber("SYS", &volNumber);

printf("0x%X\n", volNumber);

Output:

0xFFFFFF00
To avoid confusion, clear the volume number to zeros before making the call.

Patches for 3270 LAN Workstation for DOS (3270 LAN Workstation for DOS v2.0)

The newly released patch file, PTF-283, fixes the following problems in the 3270 LAN Workstation for DOS v2.0:
  • Cursor movement problems on Printer Control Panel.
  • "No Resources Available" when WSLAN is configured for multiple gateways.
  • Incompatible keyboard BIOS problem with new IBM PS/2 model 35 and 40.
PTF-283 supercedes PTF-269, PTF-270, and PTF-273, and can be downloaded from NetWire (NOVLIB section, LIB 9). To apply PTF-283, copy all of the files into the current working directory.

Internals of the XQL Data Segment (XQL for DOS v2.11)

When XQL loads, it allocates a 64K data segment in which it stores all of its local variables when executing the functions requested by an application. Within this 64K data segment, a fixed amount of memory is filled with global data and data that is allocated at loadtime. The remaining memory is divided up according to the specified loadtime parameters. Figure 5 shows how this 64K buffer is divided.

FIGURE 5: Makeup of 64K XQL data segment

BYTES     DESCRIPTION
------------------------------------------------------
13856     XQL's global data
  980     Memory allocated to hold info about active dictionary
  539     Current Session data structure
  867     Current View data structure
 1400     Join List data structures
 2267     Data buffer (allocated at load-time) used for swapping data structures to disk
 2062     Memory used for extended Btrieve operations
  896     Dictionary position blocks
  817     Misc. key buffer, currency addresses, etc.
------------------------------------------------------
23684     This is the fixed size of data that resides in XQL's 64K data segment.  There is 41852
bytes of data left for the load-time parameters.  Space will be allocated in the data segment for
the /w, /t and /b parameters as follows:

          w  Fetch buffer.  w = value in /w: parameter

          t * 130    Trans. processing. t = value in /t: parameter.

           Defaults to 12.

          b * 1024   Heap buffer.  b = value in /b: parameter
------------------------------------------------------
65536     If this number is exceeded XQL will display an "insufficient memory" error and fail to
load.

End of Figure 5
For example, the following load parameters would require too much memory:
xql /t:12 /v:8 /w:8000 /b:32 /e

  23684
   (12 * 130)
   8000
+ (32 * 1024)
-------------
  66012

Reducing the /t parameter to eight will enable XQL to load.

xql /t:8 /v:8 /w:8000 /b:32 /e

  23684
    (8 * 130)
   8000
+ (32 * 1024)
-------------
  65492
Whether or not you use expanded memory, this information will not change. Expanded memory simply provides you with more free memory on your system after XQL is loaded.

SPXEstablishConnection( ) Uses "bp" Register (NetWare System Calls for DOS v1.0)

With the NetWare System Calls, the function, SPXEstablishConnection(), uses the "bp" register. Calling SPXEstablishConnection() requires that you "push" the "bp" register before the call and that you "pop" it after the call. Otherwise, some of the variables on the stack may be overwritten.

This requirement is undocumented in the current NetWare System Calls manual.

MapDrive & Search Drives (NetWare C Interface for DOS v1.2)

When you attempt to delete search drives with the MapDrive function, a number of situations may arise which prevent the deletion. The MapDrive function can successfully delete mapped search drives, but you must meet a few undocumented requirements. Figure 6 contains example code which demonstrates the steps needed to delete a mapped search drive.

FIGURE 6: Deleting mapped search drive with MapDrive function

GetSearchDriveVector(vectorBuffer);
for(i=0;i<16;i++)
if(vectorBuffer[i] == driveLetter - 'A') break;
 if(i == 16) i=0;
   else i++;   /* Search Drives are  */
/* relative to 1, not 0.   */
cCode=MapDrive(connectionID,  /* Server Connection ID    */
NO_BASE_DRIVE, /* No Relative drv Mapping */
"",  /* No Path Required   */
DRIVE_DELETE,  /* Delete This Drive  */
i,   /* Number Of Search Drive  */
&driveLetter); /* Drive To Be Deleted*/

End of Figure 6
The two most common mistakes when deleting a search drive with the Map Drive function are using the wrong connectionID and passing in an incorrect search drive number. The connectionID is the file server to which the drive is mapped. The search drive number is a number from one to sixteen which inidicates the order of the search drive in the search drive vector table.

PUBLIC User in Xtrieve PLUS v4.10 (Xtrieve Plus v4.10)

In version 4.10, Xtrieve PLUS introduced a user called PUBLIC to its security implementation. PUBLIC is not a username and cannot be used to access a dictionary that has security installed. PUBLIC also has no password.

PUBLIC functions like a group (as in NetWare, where there can be individual users and groups). The Master user can assign rights to PUBLIC. Then, as individual users are added, the Master user does not need to redefined each users rights individually; users can be assigned the rights that have been given to PUBLIC (this design is similar to security equivalences in NetWare).

GetBinderyObjectDiskSpaceLeft( ) Problem (NetWare C Interface for DOS v1.20)

When you call the GetBinderyObjectDiskSpaceLeft API, the value returned in "UnusedDiskBlocks" is the value for the used disk blocks of the specified object, not the unused disk blocks. The returned value also includes the used disk blocks for all the volumes on the specified server. This situation occurs with NetWare v3.11 servers and has been reported. There is no workaround at this time.

Calling GlobalAlloc( ) from Windows DLLs (Network C for Windows v1.22)

When allocating Event Control Blocks (ECBs) dynamically using GlobalAlloc(), specify the following flags:
  • GMEM_DDESHARE
  • GMEM_FIXED
  • GMEM_NOT_BANKED
You must then call GlobalLock() or GlobalWire(), and then GlobalPageLock(). GlobalPageLock() informs the Windows Kernel not to swap memory where the ECBs are located. This is very important when using Event Service Routines (ESRs). In most cases, you should lock the memory allocated to ECBs in the data segment. To do this, declare the data segment containing the ECBs and packet fragments to be "fixed" in the program's .DEF file.

ScanDirEntry Sequence Number (NetWare C Interface for DOS v1.2)

When using the NetWare C Interface for DOS API, ScanDirEntry, on a 286 server, only one or two files are returned. The sequence number is not updated by this function whenever a 286 server is detected. To obtain a valid sequence number, either modify the source code to update the sequence number, or use the sequence number returned by the DirStructure API.

Key Position & Create Operation (Btrieve (all versions))

When creating a Btrieve file, you must specify a Key Position for each key segment. The Key Position is the starting position of the segment within the data record. If you specify a Key Position of zero, Btrieve will return a status 27 (Invalid Key Position).

The Key Position must be set to a value between one and the specified record length. This requirement also applies with BUTIL -CREATE operations and any application that performs a Btrieve Create (14) operation.

CLib Rename API & Directories on NetWare 2.x Servers (Network C for NLMs v2.0b)

The Rename function supplied with CLib malfunctions when applied to directories located on NetWare 2.x file servers. The Rename function requires both an old name and a new name. Whenever you need to change the name of a directory on a NetWare 2.x file server, enter a full path for the old name and just the new directory name (no path) for the new name.

Btrieve Pascal Examples (Btrieve for DOS v5.10a)

The sample Pascal programs in the Btrieve Programmer's Manual (April 1990 edition) were written with Microsoft Pascal. Turbo Pascal programmers cannot use these example programs without modification because of differences in the way the two languages manage "string" variables. In Turbo Pascal, a variable declared as "string[4]" is actually five bytes long, because it includes a length byte indicating the significant amount of data in the remaining four bytes. Btrieve does not expect a length byte, and interprets it as a general data byte.

For instance, the Btrieve Create example in Appendix D results in a status 25 (Create I/O Error), a status 27 (Invalid Key Position) or possibly other errors if used in a Turbo Pascal program. The following changes should be made in order for the Btrieve Create example program to function properly:

  1. The key specification must include a four-byte "Not used" field. In the sample program, this field is declared as "NOT_USED : string[4];" which is actually a five-byte field. This will cause a status 27 to be returned on the Btrieve Create call. Change this variable to "NOT_USED : ARRAY [1..4] OF char;"
  2. Similarly, the file specification includes a four-byte "Not used" field, as well as a two-byte "Reserved" field. The sample program declares the fields as "NOT_USED : string[4];" and "RESERVED : string[2];" respectively. These may also produce a status 27 on the Btrieve Create call. Change the data type of these fields to ARRAY [1..x] OF char.
  3. The KeyBuffer parameter passed on the Btrieve Create call must contain the name of the file to be created. The example uses a variable declared as: "FILE_NAME : string[17];" and then calls Btrieve with this variable as the key buffer (fifth) parameter. When Btrieve reads FILE_NAME, it reads the length byte first, which usually is not a legal character for a DOS file name, and a status 25 will be returned.
To avoid problems, either declare this parameter as an "ARRAY [1..x] OF char" or pass it to Btrieve with a [1] subscript. For example:
   STATUS := BTRV (B_CREATE,
    POS_BLK,
    DATA_BUF,
    DATA_LEN,
    FILE_NAME[1],
    0);
Many of the sample Pascal programs in the Btrieve Programmer's Manual also define the data buffer with a variant record. This is not necessary in Turbo Pascal. For example, when converting the Pascal Get First example from Appendix D (see Figure 7) to Turbo Pascal, you can use a simple record type, as shown in Figure 8. Then, specify DATA_BUF as the third parameter.

FIGURE 7: Excerpt from Pascal Get First example in Btrieve manual

  type
    EMP_REC = record
 case integer of
 1: (NAME : string(20);
AGE  : string(2);
HIRE_DATE : string(6));
 2: (ENTIRE    : string(28));
    end;
  var
    DATA_BUF : EMP_REC;
    ...
  begin
    ...
    STATUS := BTRV(B_GET_FIRST, POS_BLK, DATA_BUF.ENTIRE,
    DATA_LEN, KEY_BUF, 2);

End of Figure 7
FIGURE 8: Turbo Pascal modifications to Get First example
  type
    EMP_REC = record
 NAME : string[20];
 AGE  : string[2];
 HIRE_DATE : string[6]
    end;
...

STATUS := BTRV( B_GET_FIRST,
 POS_BLK,
 DATA_BUF, {Use "DATA_BUF" as 3rd parameter}
 DATA_LEN,
 KEY_BUF,
 2);

End of Figure 8

Preventing NLMs from Unloading (Network C for NLMs SDK v2.0b)

If you want to prevent an NetWare Loadable Module (NLM) from unloading, here is one possible approach:
  1. Specify the CHECK option in your LNK file, giving it the name of a function that will be called on an unload attempt. The prompt from the loader will expect a "Yes/No" response. Forcing a "No" response and an "n" will prevent the NLM from unloading. For example:
         option check=NWNoUnload
    
  2. Insert the routine listed in Figure 9 into your code. This routine will "push" characters to the console screen using "ungetch" ("n").
  3. The routine in Figure 9 prevents NLMs from unloading, so you must provide an alternate method. Register a command processor using the RegisterConsoleCommand API.

FIGURE 9: Routine to prevent NLMs from unloading

#include 
#include 
#include 

int   NWNoUnload()
{
 LONG   OldScrID = GetCurrentScreen();
 LONG   NewScrID = CreateScreen("System Console",0);

 if( OldScrID != NewScrID) SetCurrentScreen(NewScrID);
 ungetch('n');
 if( OldScrID != NewScrID) SetCurrentScreen(OldScrID);

 return 1;   // ask NetWare to send a warning message
}

End of Figure 9

NetWare System Calls Clarification (NetWare System Calls v1.0)

The documentation for the Change Process VAP system call should state that only register DS is preserved when the call returns. All other registers are destroyed.

Stack Corruption on Paths Larger than 255 Bytes (Network C for NLMs SDK v2.0b)

Several CLib functions declare a local stack variable for paths that are 255 bytes long. However, if a path is larger than 255 bytes, the path parser will overwrite the stack. Functions exhibiting this behavior include __open() and opendir(). The __open function is the internal function used by all CLib file open APIs. To avoid this situation, do not use paths larger than 255 bytes.

WLINK & Redefining Imported Symbols (Network C for NLMs SDK v2.0b)

If you redefine any imported symbol in your NLM, WLINK always resolves any references to that symbol made by your NLM to the imported symbol. This WATCOM problem initially appeared in the Network C for NLMs SDK v2.0a, and was repaired. It subsequently reappeared in version 2.0b To avoid this situation, either remove the symbol you wish to redefine from the import file or symbol list, or rename the symbol.

IPXGetInternetworkAddress API Problem (Network C for Windows v1.22)

The IPXGetinternetworkAddress API returns garbage if IPX/SPX is initialized with zero maxECB's (meaning that the application will control its ECBs directly -not relaying the NWIPXSPX.DLL or VIPX.386). The API functions correctly if the IPX/SPX is initialize with any number of maxECB's other than zero. There is no workaround for this situation at this time.

EMSNETX Bug (EMSNETX v3.22)

Under certain conditions, file writes using EMSNETX v3.22 can become corrupted. Specifically, corruption occurs when the buffer being read or written and the buffers the shell is using are in EMS memory. The error does not usually occur immediately, but instead occurs within one or two hours, with one to six bytes typically being corrupted each time. To avoid this situation, either set CACHE BUFFERS=0 in NET.CFG or SHELL.CFG, or avoid using the EMS shell.

CLib Addition Error (Network C for NLMs SDK v2.0b)

If you compile with /FPC, and try to add the numbers 31.09 and 1.91, the internal CLib helper function, __FDA, will incorrectly yield 16.0. Currently, there is no workaround for this error.

NIBBLES AND BITS

Fast Answers to Common Questions

NetWare C Interface for DOS v1.2

Q - Why doesn't LoginToFileServer() from the NetWare C Interface for DOS run the login script?

A - There is no API to execute the login script.

NETX v3.22

Q - Under NETX v3.22, when I use the Borland Make utility to invoke BCCX v2.0, the system halts with an expanded memory error 12 or the machine reboots. Why does this occur?

A - Borland's Make utility has an option (-S) that allows you to swap the make utility out of memory while it compiles or links. Errors occur when the Make utility tries to reload itself into memory. Borland's C++ Compiler v3.0 does not include a BCCX file and functions correctly. Earlier shells seem to work properly; the problem seems to only occur when you use BCCX v2.0 with netx v3.22.

Network C for NLMs v2.0b

Q - Where can I find the tutorial examples in the Network C for NLM's SDK v2.0b? The documentation says it is on the "tutorial diskette," but I did not receive such a disk.

A - If you install Network C for NLMs according to Novell's installation defaults, the installation process places these tutorial examples in \WATCOM\NOVX\CS.

Q - When I use the AIOCOMX driver at high speeds, it frequently loses characters. What should I do?

A - The COMX driver does not guarantee that all characters will be received, because the LAN and disk drivers disable interrupts for too long. Drivers like the ARTIC driver and the WNIM driver will produce better results since they have their own CPU on the board.

NetWare C Interface for Windows v1.22

Q - While running my Windows application, an error pops up that says NETWARE.DLL cannot be found. What should I do?

A - Make sure that NETWARE.DRV is in the search path, or is located in the directory from which Windows is running. When Windows cannot find NETWARE.DRV, it returns the error message that it cannot find NETWARE.DLL.

Q - When using the DLLs provided with the NetWare C Interface for Windows SDK v1.22, what is maximum packet size that NetWare supports under Windows Standard mode?

A - The maximum packet size is 512 bytes, including the header.

DR DOS v6.0

Q - Have any patches been released for DR DOS v6.0? How can I obtain these patches?

A - A number of patches have been released for DR DOS v6.0 and can be acquired in several ways:

  1. From the Digital Research CompuServe forum, DRFORUM.
  2. Directly from Digital Research by calling 408-646-6464.
  3. From Digital Research by faxing your request to 408-649-8209.

NetWare OS/2 Developer's Kit v1.3a

Q - What additional programs and libraries do I need to write Windows applications for Named Pipes with the NetWare OS/2 SDK v1.3a?

A - You will need the DOSNP TSR that is provided with the NetWare OS/2 SDK and the specific libraries that are also available with that SDK.

Q - The Named Pipe status codes are not defined in the DOS Named Pipe headers in the NetWare OS/2 SDK v1.3. How can I check the status of a pipe without reading the data?

A - When you issue a DosPeekNamePipe API call while writing a DOS Named Pipe application, you will notice that some of the status return codes are not defined, and that they generate compiler warnings. The status codes describe the status of the Named Pipe. In the NetWare OS/2 SDK, there is also a NMPIPE header file under the WINNP directory for Windows and Named Pipes. If you need to use this API call, copy over the predefined status codes to the DOS NMPIPE header file.

Btrieve

Q - How can I obtain UPPER.ALT, the file containing the alternate collating sequence that sorts all characters as upper case? It was not shipped with Btrieve for Windows v5.10 and Btrieve for OS/2v5.10.

A - You can download this file from NetWire (NOVLIB, LIB1, filename: UPPER.ZIP).

Q - How can I define a C long integer as a key in Btrieve, when there is no long data type?

A - To define a C long integer in Btrieve, specify the key as an integer with a length of four bytes.


PATCH LISTINGS

Patches can be downloaded from NetWire, or obtained from the Developer Support Group at no charge. (See "Contacting Novell Austin" at the end of this issue).

NetWare Btrieve (VAP, NLM) v5.15 Patches

For a description of patches 1 through 50, refer to earlier issues of Bullets.
  • 51. (BTRIEVE.NLM) This patch corrects the following situation involving two workstations: the first workstation performs an Update (3) operation, but a status 80 (Conflict error) is returned because a second workstation updated the record after the first workstation read the record. If the first workstation then performs a Get Position (22) operation before rereading the record, an erroneous status 8 (Invalid Positioning) is returned. This patch allows the Get Position operation to succeed.
  • 52. (BTRIEVE.NLM) When you build a supplemental index, server utilization goes to 100% and any other stations making Btrieve calls "time out," receiving status 95 (Session No Longer Valid) errors. This patch corrects the situation by decreasing the time slice used by Btrieve while sorting the keys.

NetWare SQL/XQL v2.11 Patches

For a description of patches 1 through 66, refer to earlier issues of Bullets.
  • 67. NWSQL (NLM) This patch fixes a side-effect of patch #59 which could cause extraneous information to be returned in the bDataBuf parameter of xDDIndex. This situation only occurs if the Btrieve Stat (15) operation fails for option one of xDDIndex.

    This situation will cause the workstation to hang when you use Xtrieve PLUS to "SHOW" a file definition and the data file does not exist in the directory specified by the XTRPATH variable.

  • 68. NWSQL (NLM) The patch disables use of Btrieve extended filter operations when NetWare SQL is able to perform optimization based on indexed reads. In the case of a restriction which provides values for a segmented index, NetWare SQL can retrieve the records more quickly than a Btrieve filtered operation. The Btrieve filter operation will only optimize on the first segment of the index.
  • 69. NWSQL (NLM) This patch prevents server problems when you execute a non-stored statement after you execute (in succession) a stored statement containing a UNION which returns records and a stored statement containing a UNION which does not return any records.

Xtrieve PLUS for DOS v4.10 Patches

For a description of patches 1 through 9, refer to earlier issues of Bullets.
  • 10. When a title field is defined and you edit or modify the view, if you escape and then select CONTINUE, the data for the title field (or fields) will not show on the screen. The refresh key will redisplay the data, but it removes the heading for the title field(s). This patch corrects the situation.
  • 11. When editing a string field, the data for the string field does not appear on the screen after pressing ENTER, but the data is inserted or modified correctly. This patch ensures that the string field is properly displayed.
  • 12. This patch corrects the following situations:

    If you 1) create a view, 2) create and store a report based on that view (without storing and recalling the view first), and 3) store the view, then Xtrieve PLUS returns an error message when you try to recall the report.

    Also, if you 1) create, store and recall a view, 2) create and store a report, and 3) in a later session, recreate the view (without storing and recalling it first), then Xtrieve PLUS returns an error message when you try to recall the report.

  • 13. If you place "@esc" in a report (or "@hexXX," where "XX" represents non-printable characters), Xtrieve PLUS will not place the ESC character (or the unprintable XX character) in the report output. This patch ensures that these characters are included.
  • 14. Xtrieve PLUS does not detect duplicate field names with different cases until you try to complete the file definition (with "Finished-Create" or "Finished-Don't Create"). This patch corrects situation and returns the error, "Field names must be unique," when the field is entered.
  • 15. If you have a very large number of users (255 to 500) in your dictionary, then Xtrieve PLUS may experience problems when showing, modifying, or removing a user. This patch ensures that user information is displayed and utilized correctly.

    NOVELL EDUCATION

    Novell Education offers classes for many of the Development Products including Btrieve, XQL/NetWare SQL, Xtrieve PLUS and the NetWare Client APIs. These classes are designed to introduce participants to the powerful features of Novell's development tools, database products, and NetWare services. Nearly 50% of class time is devoted to hands-on activities.
    • 901 Programming with NetWare Client APIs
      Mar. 16-18Austin, TX
      Apr. 8-10 Washington, DC
    • 905 Programming with Btrieve
      May 12-14 Austin, TX
    • 906 Programming with Btrieve: Advanced Features
      Mar. 10-12Chicago, IL
    • 907 Xtrieve PLUS
      Mar. 17-18Washington, DC
      May 20-21 Sunnyvale, CA
    • 910 Programming with XQL
      Apr. 14-16Chicago, IL
    • 920 Programming with Network Communication Services
      Mar. 19-20Austin, TX
      Apr. 13-14Washington, DC
    • 930 Developing NetWare Loadable Modules (NLMs)
      Mar. 10-12Austin, TX
      Apr. 14-16Austin, TX
      May 13-15 Sunnyvale, CA
    To register or obtain information on pricing, location and course content for classes held in the US, call 1-800-233-3382, 1-801-429-5508 or 1-800-NET-WARE. International customers should call 1-801-537-8850. All courses are subject to cancellation or rescheduling within two weeks of the scheduled date, depending on enrollment.

    For information on availability, location, and prices of international classes, contact your local Novell office.


    FUN & FACTS QUIZ

    Test your "developing" skills with the various Professional Development Series products by taking our Fun & Facts quiz. Have fun and good luck! (See the end of this issue for answers.)
    1.   In XQL, if you have a BOOLEAN field, and you specify an EDIT mask of "-NO,"
    how would the value "false" be represented?
    
    A. NO
    
    B. (blank space)
    
    C. FALSE
    2.   In XQL, if you have a BOOLEAN field, and you specify an EDIT mask of "-NO," how
    would the value "true" be represented?
    
    A. Yes
    
    B. (blank space)
    
    C. TRUE
    3.   In XQL, what environment variable tells XQLI where the dictionaries are located?
    
    A. XQLIDD
    
    B. XQLIDDF
    
    C. XQLIDICT
    4.   What status code does Btrieve return when there is a CREATE I/O ERROR?
    
    A. 2
    
    B. 14
    
    C. 25
    5.   When using data compression in Btrieve, can the record be of variable length?
    
    A. Yes
    
    B. No
    6.   In Xtrieve PLUS, what is the key sequence used to chain command files?
    
    A. Alt-F8
    
    B. Shift-F6
    
    C. Shift-F7
    7.   Name the three queues within the Netware Operating System.
    
    A. Print Server Queue, Object IDs Queue, and Supervisor's Queue
    
    B. Job Queue, Print Queue, Users Queue
    
    C. Run Queue, Sleep Queue, Semaphore Queue
    8.   What is the maximum size of an SPX packet in OS/2?
    
    A. 576 bytes
    
    B. 534 bytes
    
    C. 540 bytes
    9.   What .OBJ file initializes all the CLIB.NLM data structures?
    
    A. Startup.OBJ
    
    B. Prelude.OBJ
    
    C. Init.OBJ
    10.  In the NetWare 2.x environment, what two files make up the bindery?
    
    A. Net$Bind.Sys and Net$Prop.Sys
    
    B. Net$Bind.Sys and Net$Obj.Sys
    
    C. Net$Bind.Sys and Net$Bval.Sys
    11.  What option in WDISASM will generate the .ASM format from a .OBJ file?
    
    A. /a
    
    B. /asm
    
    C. /80x86
    FUN & FACTS ANSWERS
    1.     A
    2.   B
    3.   A
    4.   C
    5.   A
    6.   C
    7.   C
    8.   A
    9.   B
    10.  C
    11.  A
    

    CONTACTING NOVELL

    Developer Support

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

    Voice

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

    Fax

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

    Developer BBS

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

    E-mail: CompuServe

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

    E-mail: MHS

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

    E-mail: Internet (SMTP)

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

    NetWire on CompuServe

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

    Novell Products and SDKs

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

    DeveloperNet Labs

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

    Novell Developer Relations

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

    Voice

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

    Fax

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

    NetWire on CompuServe

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

    E-mail: MHS or Internet (SMTP)

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

    ACKNOWLEDGEMENTS

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

    Contributing authors: Linda Anderson, Vitek Boruvka, Michael Eisa, David Harris, Sudz Khawaja, Ken Lowrie, Rudy McNeese, Clint McVey, Paige Parker, Randy Reddy, Carol Rylander, Glenn Stephens, Aslam Tejani, Maggie Walczynski

    Special thanks to the Developer Support, Development, Developer Relations, Product Marketing, and Marketing Communications staff who contributed time and valuable input.

    Novell, the N design, NetWare, Btrieve, XQL and LAN WorkPlace are registered trademarks, NetWare System Calls for DOS, NetWare Loadable Module (NLM), NetWare SQL, NetWare Btrieve, Xtrieve PLUS, NetWare C Interface for DOS, NetWare System Interface Technical Overview, NetWare RPC, NetWare RPC 386, TCPort, TTS, NetWare LU6.2, Report Executive, and Professional Development Series (PDS) are trademarks, and Professional Developers' Forum (PDF), NetWire, Direct Connect and Professional Developers' Program (PDP) are servicemarks of Novell, Inc. Apple, Macintosh, AppleTalk and HyperCard are registered trademarks of Apple Computer, Inc. CompuServe is registered trademark of CompuServe Corporation. Microsoft is a registered trademark, and Windows, Excel and Visual Basic are trademarks of Microsoft, Inc. IBM and OS/2 are registered trademarks, and SAA is a trademark of International Business Machines Corporation. Sun Microsystems and NFS are registered trademarks of Sun Microsystems, Inc. WATCOM is a trademark of WATCOM Systems, Inc.

    International Customers please contact your local Novell authorized dealer or nearest Novell office.

  •