> developer support home

JANUARY 1992 VOLUME 4 NUMBER 1


INDEX


MAD'S COLUMN

Hello and welcome to the January 1992 issue of Bullets!

You have seen it in writing, you have heard the name, and you may have even spoken the words: "1-800-SAY-HELP," the phone number for Novell's Developer Support Hotline. After some discussion, Novell's technical support site managers have decided to channel all technical support calls through a common telephone number, 1-800-NETWARE. This single number will serve as a clearinghouse for information on all of Novell's products and services.

What does this mean for you as a developer? A faster response. 1-800-NETWARE has more incoming lines and more operators to register your calls. Using one common telephone number also makes it easier for the individual Novell support sites to transfer calls between product lines.

While the old number was fun (and I personally got a few laughs with it at Novell's Professional Developers' Forums over the years), it is time for one common Novell support phone number.

In the very near future, 1-800-SAY-HELP will be disconnected. We hope you have never needed to call for support, but we always want you to have the current number to reach us in case you do 1-800-NETWARE!

Happy_Programming!

Mad Poarch
Director
Developer Support/Service


ARTICLES:

Writing NLMs that Call Btrieve

Server-based applications are becoming more and more widely-used as developers become aware of the benefits of client-server architecture. Two advantages of running server-based applications are reduced network traffic and increased availability of memory at the individual clients.

This article discusses the procedures involved in creating server-based Btrieve applications, called NetWare Loadable Modules (NLMs), for the NetWare 3.x environment, and discusses some possible problems and solutions. When any reference to a specific NLM is made, the ".NLM" extension is used. "Btrieve" refers to the product as a whole, and not any individual component of it (such as BTRIEVE.NLM).

Two Types of NLM Requests

Generally, two types of requests are used in server-based applications. Usually when an application requests that an operation be performed on a particular file, the application is running on the server where the file physically resides. This type of request is called a local request. Sometimes, an application that is running on one server will request that some action be taken on a file residing on another server. This type of request is called a remote request.

When your NLM issues a local Btrieve request, if BROUTER.NLM is loaded at the server, the request is passed to BTRIEVE.NLM via BROUTER.NLM. If BROUTER.NLM is not loaded, the request goes directly to BTRIEVE.NLM. The request is processed at the server and the result is returned to your NLM's workspace. The result is returned via BROUTER.NLM if it is loaded or directly if BROUTER.NLM is not loaded.

When a server-based Btrieve application (your NLM) makes a remote request, BROUTER.NLM must be loaded at the server on which the request originates. First, your NLM issues a Btrieve request. The request is trapped by BROUTER.NLM at your server and sent to BSPXCOM.NLM on the remote server. BSPXCOM.NLM then relays the request to the BTRIEVE.NLM on the remote server. Next, the request is processed at the remote server. Finally, the result is returned to your NLM's workspace via BSPXCOM.NLM on the remote server and BROUTER.NLM on the local server.

Single- and Multiple-Client NLMs

Client-server Btrieve applications can be classified into two categories:
  • NLMs that manage calls for a single client, and
  • NLMs that manage calls for multiple clients.
The proper method for interfacing with Btrieve depends on the category of your NLM. If the NLM manages calls for a single client, the function call is identical to the Btrieve call used in client applications. If the NLM simultaneously manages calls for multiple clients, an additional parameter is required and the NLM uses a different function call to communicate with BTRIEVE.NLM.

In either case, the functions called are actually symbols exported by BTRIEVE.NLM. These symbols are accessible by the NetWare 3.x dynamic link mechanism and can be imported into your NLM. When you create an NLM to manage calls for a single client, you should use the btrv() API. The prototype for this API is shown in Figure 1.

FIGURE 1: Prototype for the btrv() API

#define  WORD    unsigned short integer

extern   WORD    btrv ( WORD     operation_code,
                        void     *position_block,
                        void     *data_buffer,
                        WORD     *data_buffer_length,
                        void     *key_buffer,
                        short    key_number
                      );

{end of Figure 1}

When you create an NLM to simultaneously manage calls for multiple clients, you will use the btrvID() API which has an additional parameter, Client_ID. This parameter contains the unique identification for each client.. The prototype for the btrvID() API is shown in Figure 2.

FIGURE 2: Prototype for the btrvID() API

#define  WORD    unsigned short integer

typedef  struct  {

         char    addr[12];

         char    NLMid[2];

         char    id[2];

} B_USER;

extern   WORD    btrvID ( WORD     operation_code,
                          void     *position_block,
                          void     *data_buffer,
                          WORD     *data_buffer_length,
                          void     *key_buffer,
                          short    key_number,
                          B_USER   *Client_ID
                        );

{end of Figure 2}

The Client_ID Parameter

Btrieve reserves the first 12 bytes of the Client_ID parameter for use in network node identification (the server's internet address). This portion enables Btrieve to distinguish the client (the server on which the request originated) from other clients (other servers) on the network. The last four bytes are to be used by your NLM to identify itself and its client within the node.

Of the last four bytes of Client_ID, the first two bytes should contain a unique two character ASCII identifier that Btrieve can use to distinguish your NLM. This code will appear in the menus of utilities provided with NetWare which monitor network activity. For example, NetWare SQL, Novell's relational data access system, uses "NS" to identify itself. Your NLM's two-character identifier must have a value greater than or equal to 4141h (ASCII equivalent "AA").

Your NLM should fill the last two bytes of Client_ID with a unique identifier that distinguishes one client from another. This unique identifier is required to establish concurrency and for transaction processing purposes.

The first time a request is made by a specific client, the first 12 bytes of Client_ID should be set to binary zero. Btrieve will recognize this as a new client and assign a network node identifier before processing the request. Subsequent calls for this client should pass these 12 bytes unchanged to maintain the client's identity.

When creating a multiple-client NLM, carefully decide what value you will assign to the last four bytes of the Client_ID parameter. The first two bytes can be anything meaningful, and can be reserved by calling Novell Austin. Using a unique ID that is registered with Novell Austin ensures no two NLMs will use the same identifier.

Setting the last two bytes of Client_ID to the connection ID for the connection between the client and the server ensures the uniqueness of each Client_ID parameter. However, using the connection ID can cause other problems. Btrieve establishes a session whenever a unique ID is passed in the last two bytes of Client_ID. If the current connection is reset and a new connection is established, the new connection ID may be different from the original. If so, a new Btrieve session will be established, causing a status 96 (Communications Environment Error) to be returned to the application by Btrieve.

Suppose that BSPXCOM.NLM is loaded with the "s" parameter set to 15. The maximum number of concurrent Btrieve SPX sessions allowed is now 15. Also, the maximum number of Btrieve sessions allowed is 30, since Btrieve determines the (default) maximum number of sessions to be twice the maximum number of concurrent sessions. After 30 connects and disconnects, a status 96 (Communications Environment Error) is returned. Btrieve thinks there are 30 active sessions. The current documentation for status 96 states that SPX should be reloaded. In fact, you have two options:

  • For a temporary solution, unload Btrieve and reload it with a higher value for the BSPXCOM.NLM "s" parameter.
  • For a more permanent solution, instruct your NLM to perform a Btrieve Reset (28) operation before terminating. This operation resets all the resources for the current client and also resets the Btrieve session. All NLMs communicating with BTRIEVE.NLM, should perform this Reset operation. (Manuals discussing creating server-based Btrieve applications are currently being updated to include this procedure.)
With single-client NLMs, a unique identity based on the client identification number is generated for the NLM. Since there is only one client, the status 96 situation will not occur.

If you are using NetWare Btrieve (NLM) v5.10a (which shipped with NetWare v3.10a) and creating a multiple-client application, you may notice however that the first 12 bytes of Client_ID are not filled by BTRIEVE.NLM. In this version of Btrieve, BROUTER.NLM assigns a value to these 12 bytes. However, if BROUTER.NLM is not loaded, then Btrieve will be unable to communicate with Btrieve at another server.

In NetWare Btrieve v5.15 (for NetWare v3.11), both BTRIEVE.NLM and BROUTER.NLM can assign a value to the first 12 bytes of Client_ID. If BROUTER.NLM is not loaded, the 12 bytes will still be assigned a value, but again, the application will not be able to communicate with Btrieve at another server (because BROUTER.NLM is not loaded).

A Sample NLM

The code example in Figure 3 is a utility NLM that creates a file called "HOME.BTR" in the \TEMP subdirectory off the root level of the SYS volume. (The \TEMP subdirectory must exist for the code to work.) It should be possible to port a client-based application to the server-based environment, but there could be a few subtleties involved. For example, in 16-bit architecture, when creating applications in C language, integers (int) are usually two bytes. If you try to port an application that uses integers to run as a server-based application with 32-bit architecture, you can receive Btrieve errors, depending on the circumstances, because, in this environment, integers are four bytes. If you require integers to be two bytes, then your application should declare them as short integers (short int).

FIGURE 3: A Sample NLM

/* This utility NLM illustrates how to make Btrieve */
/* calls. It creates a file called "home.btr" in    */
/* the "\temp" subdirectory off the root level of   */
/* SYS volume. For NetWare 3.x environment only.    */

#include 
#include 
#include 
#include 

typedef  unsigned   short   WORD;

WORD     Status;
WORD     Op_Code;
char     Position_Block[128];
WORD     Data_Buffer_Length;
char     Key_Buffer[500];
short    Key_Number;

extern   WORD  btrv  (WORD, void *, void *,
                      WORD *, void *, short);

#define  B_Create        14
#define  BZSTRING        11
#define  NO_FILE_FLAGS    0
#define  DUPLICATES       1
#define  MODIFIABLE       2
#define  SEGMENTED       16
#define  EXTENDED_TYPE  256

struct   Key_Spec_Type
{
  WORD      Key_Position;
  WORD      Key_Length;
  WORD      Key_Flags;
  char      Not_Used[4];
  char      Extended_Key_Type;
  char      Null_Value;
  char      Reserved[4];
};

struct   File_Spec_Type
{
  WORD      Fixed_Record_Length;
  WORD      Page_Size;
  WORD      Number_Of_Indexes;
  char      Not_Used[4];
  WORD      File_Flags;
  char      Reserved_Word[2];
  WORD      Allocation;
  struct    Key_Spec_Type Key_Specs[3];
};

struct File_Spec_Type File_Specs;

struct Record_Type
{
  char      Name_Of_Apartments[25];
  char      Street_Address[25];
  char      City[15];
  char      State[2];
  char      ZIP[5];
  char      Phone1[12];
  char      Phone2[12];
  char      Contact_Person[25];
  float     Price1;
  short     Area1;
  char      Rooms1[6];
  float     Price2;
  short     Area2;
  char      Rooms2[6];
} Data_Buffer;

     struct Entered_Data_Type
{
  char       Name_Of_Apartments[26];
  char       Street_Address[26];
  char       City[16];
  char       State[3];
  char       ZIP[6];
  char       Phone1[13];
  char       Phone2[13];
  char       Contact_Person[26];
  float      Price1;
  short      Area1;
  char       Rooms1[7];
  float      Price2;
  short      Area2;
  char       Rooms2[7];
};
main ()
{
  create_file ();
}

     create_file ()
{
  WORD       i;

       File_Specs.Fixed_Record_Length = 145;
  File_Specs.Page_Size = 4096;
  File_Specs.Number_Of_Indexes = 2;
  File_Specs.File_Flags = 0;
  File_Specs.Allocation = 0;

       File_Specs.Key_Specs[0].Key_Position = 1;
  File_Specs.Key_Specs[0].Key_Length = 25;
  File_Specs.Key_Specs[0].Key_Flags =
    MODIFIABLE + EXTENDED_TYPE;
  File_Specs.Key_Specs[0].Extended_Key_Type = BZSTRING;
  File_Specs.Key_Specs[0].Null_Value = 0;

       File_Specs.Key_Specs[1].Key_Position = 68;
  File_Specs.Key_Specs[1].Key_Length = 5;
  File_Specs.Key_Specs[1].Key_Flags =
    DUPLICATES + MODIFIABLE + SEGMENTED + EXTENDED_TYPE;
  File_Specs.Key_Specs[1].Extended_Key_Type = BZSTRING;
  File_Specs.Key_Specs[1].Null_Value = 0;

       File_Specs.Key_Specs[2].Key_Position = 1;
  File_Specs.Key_Specs[2].Key_Length = 25;
  File_Specs.Key_Specs[2].Key_Flags =
    DUPLICATES + MODIFIABLE + EXTENDED_TYPE;
  File_Specs.Key_Specs[2].Extended_Key_Type = BZSTRING;
  File_Specs.Key_Specs[2].Null_Value = 0;

       Data_Buffer_Length = sizeof(File_Specs);
  strcpy (Key_Buffer, "sys:temp\\home.btr ");
  Key_Number = 0;
  Op_Code = B_Create;
  Status = btrv(Op_Code, Position_Block, &File_Specs,
          &Data_Buffer_Length, Key_Buffer, Key_Number);

  if (Status != 0)
     printf ("Error creating file. Status = %d\n",
             Status);
  else
     printf ("Successful CREATE operation\n");

       printf ("\n");
}

{end of Figure 3}

For more information on writing NLMs that call Btrieve, consult the documentation provided with the Network C for NLMs SDK or the NetWare Btrieve (NLM) Installation and Operation Manual.


TECHNICAL INSIGHTS:

Documentation Update [Network C for NLMs v2.0b]

The documentation for the Network C for NLMs SDK incorrectly states that the trusteePathName returned by the ScanBinderyObjectTrusteePaths API will contain a maximum of 255 bytes. Up to 318 bytes are actually returned by this API, which is used to identify the file server name, volume name, and full path. The character array for the trusteePathName should always be defined as 318 bytes to prevent overwriting data past byte 256 and possibly causing server abends and hangs.

Btrieve, TTS & Large Environments [NetWare Btrieve (NLM) v5.15]

In very large environments, Btrieve may respond slowly due to cache buffer/TTS conflicts. Customer sites that have reported this situation had Btrieve files flagged as "transactional" and were running very fast servers with large drives. For example, one of the sites was running an EISA-based server. Another site was running a server using a microchannel bus with fast network interface cards installed. In each case, the operatiing system's dirty cache was filling up. The term "dirty cache" refers to cache buffers whose information has been changed and needs to be written out to disk.

When dirty cache fills up, the cache is flushed, but during the write to disk, no transactions may take place, the Btrieve application is halted, and network communications can slow down. Cache buffers can fill up if the server is overloaded with TTS requests submitted by a large number of Btrieve NLM threads.

Btrieve may exhibit erratic behavior when the TTS back-out file, the file used by NetWare TTS to track updates to transactional files, grows large enough to fill the SYS volume. This situation occurs when the server is busy processing TTS requests and does not truncate the TTS back-out file. The default maximum truncation wait time is 59 minutes and 19.2 seconds. This can be too long in some environments. If a server is busy, it will wait the default period before truncating the back-out file. If a large number of transactions from multiple stations take place and the SYS volume is small, the back-out file grows until it exhausts all available space. At this time, Btrieve may return a status 14 (Pre-image Open Error) for each file in the transaction.

The system disk block size defined when the volum e is created during the INSTALL (rather than the record size) contributes to the size of the TTS back-out file. TTS writes to the back-out file on a block-by-block basis. For example, consider a system using 16k disk block sizes and records of 20 to 120 bytes in length. Each write to these records will consume 16k of the TTS back-out file. To avoid these situations:

  • Use the console "Set TTS Back-out File Truncation Time" command to lower the maximum truncation wait time,
  • Use a smaller NetWare disk block size or
  • Use Btrieve's pre-imaging instead of TTS.

NetWire Update

Novell's NetWire forum on CompuServe will undergo some changes this January as Novell reorganizes its libraries. In the past, users were required to search two separate libraries to find a file. These areas were in forum NOVA and NDD. In January, all library files will be moved to a new library called NOVLIB. The new NOVLIB forum will be the only library area and it will be used exclusively for library purposes. The one message section in this forum will be reserved for library-related questions only. New uploads will reside in Data Library 1 for 30 days. After 30 days, files will be moved to their respective locations. Figure 4 shows the layout of the new NOVLIB forum.

FIGURE 4: New NOVLIB Forum Layout

|======================|===============================|
| NOVLIB MESSAGES      | CONTENTS                      |
|======================|===============================|
| 1) Library questions | Customer message area for     |
|    ONLY!             | questions on files            |
|======================|===============================|

|======================|===============================|
| NOVLIB LIBRARIES     | CONTENTS                      |
|======================|===============================|
| 1) Novell new uploads| Files uploaded by Novell Inc. |
|----------------------|-------------------------------|
| 2) General Novell    | General info, Education,      |
|    Information       | Press releases                |
|----------------------|-------------------------------|
| 3) NetWare 2.x       | Files pertaining to           |
|    Specific Info     | NetWare 2.x                   |
|----------------------|-------------------------------|
| 4) NetWare 3.x       | Files pertaining to           |
|    Specific Info     | NetWare 3.x                   |
|----------------------|-------------------------------|
| 5) Client/Shell      | Workstation shells, drivers,  |
|    Drivers           | Windows files, etc.           |
|----------------------|-------------------------------|
| 6) NetWare           | Utilities that pertain to     |
|    Utilities         | NetWare 2.x and 3.x           |
|----------------------|-------------------------------|
| 7) Btrieve/Xtrieve/  | Development Division Products |
|    NetWare SQL/XQL   | Btrieve, Xtrieve PLUS, XQL    |
|                      | and NetWare SQL               |
|----------------------|-------------------------------|
| 8) Macintosh/UNIX    | Files for Macintosh, UNIX     |
|    LANalyzer         | and LANalyzer                 |
|----------------------|-------------------------------|
|                      |                               |
| 9) Communications    | Novell's Communications       |
|    Products          | Products Division             |
|----------------------|-------------------------------|
|10) NetWare Lite      | NetWare Lite-specific files   |
|----------------------|-------------------------------|
|11) TechInfo, IMSPs   | Technical Bulletins, FYIs,    |
|                      | IMSPs, Application Notes      |
|----------------------|-------------------------------|
|12) CLOSED            |                               |
|----------------------|-------------------------------|
|13) Other Patches     | Third-party patches and       |
|                      | drivers                       |
|----------------------|-------------------------------|
|14) Independent       | Third-party code examples     |
|    Development       | including NTJ code            |
|----------------------|-------------------------------|
|15) Shareware/Demo    | Shareware and Demo files      |
|----------------------|-------------------------------|
|16) Public Domain     | Public domain software        |
|    and Text          | and message threads           |
|----------------------|-------------------------------|
|17) Other New Uploads | Third-party new uploads       |
|======================|===============================|

{end of Figure 4}

GetDiskUtilization API [NetWare C Interface for DOS v1.2]

With NetWare 3.x, the GetDiskUtilization API returns an incorrect "usedblocks" value. To prevent this, perform a WORD swap on the LONG value that is returned, as shown below:

usedblocks = (usedblocks >> 16) | (usedblocks < 16);

Brequest & VIPX.386 [NetWare Btrieve (NLM) v5.1x]

In Windows 3.0 enhanced mode using versions of VIPX before v1.1, Brequest can hang in a DOS box. If you use the new version, VIPX.386 v1.1, with IPX.COM v3.10, Brequest will function properly in a Windows DOS box. VIPX.386 and IPX.COM v3.10 are available on NetWire in NOVLIB, Data Library 5.

To use VIPX.386, first generate a new IPX. Then, modify the SYSTEM.INI file under the heading, [386enh], by adding "VIPX.386" as follows:

[386enh]
network=vnetware.386,vipx.386
With this modification, the driver will load when Windows 3.0 loads.

PATCH311, sopen() & Binary Mode [Network C for NLMs v2.0b]

If PATCH311.NLM is loaded on your file server, files are opened in binary mode, even if you specify a different mode. The O_BINARY flag is hard coded in the underlying CLib open API.

When calling a function like sopen(), if you pass the O_TEXT flag, it will be ignored because the O_BINARY is set for you automatically. If you use the same file handle that you received from sopen() and pass it to fdopen(), specify that the file be opened in binary mode. Otherwise, fdopen() will try to open the file in TEXT mode, in conflict with the mode in which the file was originally opened.

Currently, you cannot use fdopen() to open a file descriptor in TEXT mode. If you want to open files in TEXT mode, use "fopen("file","r+t")" instead.

Xtrieve PLUS & Lotus 1-2-3 [Xtrieve PLUS v4.10]

If you attempt to import dates into Lotus 1-2-3 using a file created by Xtrieve PLUS v4.10 with the "Translate to DIF" option, the dates will be off by one. This situation occurs because Xtrieve PLUS considers the date 01/01/1900 as "day zero," whereas Lotus 1-2-3 considers the same date as "day one." Use a formula to subtract one from the date in Lotus 1-2-3 to convert the date properly.

DOS Shell v3.22a Update [NetWare System Calls for DOS v1.2]

The DOS shell v3.22a contains an error that allows more than twenty file handles to be inherited by a child process. DOS restricts child processes to inheriting only twenty files. If a child process inherits more than twenty file handles, the DOS file handle table can be corrupted. File handles inherited by a child process may not be closed when the parent process eventually closes them, but no error will be returned.

Do not increase the size of the file handle table when spawning a child process. The next version of the shell will correct this situation.

ARTIC Board/Port Problems [Network C for NLMs v2.0b]

At present, there are two ways to place an ARTIC board in a state where it cannot be reloaded until the PC is powered off and on, thus resetting the ARTIC board hardware.

Incorrect Memory Addresses

The default MEM= value for the 8KB memory window used by the AIOARTIC driver to access the ARTIC board is set to C0000. This memory address is acceptable for PS/2s, but often incompatible with other kinds of PCs. On many PCs, this address is the location of the EGA or VGA BIOS ROM code. Reusing these addresses can cause conflicts with the hardware on the ARTIC board.

If you load AIOARTIC.NLM with no parameters or use the MEM=C0000 parameter value, the ARTIC board can lock up. Further attempts to load AIOARTIC.NLM with correct parameters may not succeed.

To remedy this situation, find out which memory address ranges in high memory are free for use by new hardware. Use a utility like Manifest (from QuarterDeck) to locate the "holes" in high addresses. You must supply the correct addresses in the MEM= parameters.

Parity and Framing Errors

An ARTIC port or board can also be disabled after receiving an input character which has a parity error or framing error. Problems with ports and boards can also be caused by simply changing data rates while input characters are being received. At the very least, the port becomes unusable, and about 50% of the time the whole board locks up. This condition persists until the PC is powered off and then rebooted, completely resetting and reloading the code for the ARTIC board itself.

To correct these situations and prevent errors, change the A745th byte of AIOARTIC.NLM from EE to EA (DEBUG offsets have 100 hex added to them). The temporary patch shown Figure 5 can be applied using DEBUG. Apply the patch only to AIOARTIC.NLM v1.01 (dated 9/18/91).

FIGURE 5: Patch for AIOARTIC.NLM v1.01 (dated 9/18/91)

DEBUG  AIOARTIC.NLM     must be version dated 9/18/91
eA845  
             should display the byte value EE
EA     
             type in EA, then hit enter
w      
             write the modified file
q      
             DEBUG
{end of Figure 5}

Btrieve Extended Operations [Btrieve for DOS v5.10, NetWare Btrieve (NLM, VAP) v5.15]

When using extended operations, Btrieve returns a status 62 (Invalid Descriptor) after the first extended operation performs successfully. Since the descriptor information is stored as a union in C or a redefinition in COBOL, this data gets overwritten by the output data buffer when the first extended call is issued. Therefore, you must update the descriptor information before each extended operation.

NIBBLES AND BITS

Fast Answers to Common Questions

General Questions

Tip When loading the server operating system, you can avoid loading the AUTOEXEC.NCF file by using the "SERVER NA" option. This procedure can save you a lot of time and trouble if your AUTOEXEC.NCF file is damaged in some way.

Btrieve

Q - Should I flag my Btrieve files as "sharable" to NetWare?

A - No. Doing so disables Btrieve's ability to detect when other applications (including backup packages and different versions of Btrieve used to access the same data file simultaneously) are accessing Btrieve files, and it can result in file corruption.

Q - Does Btrieve for Windows work with Windows 3.1?

A - Yes, in all modes except REAL.

NetWare SQL/XQL

Q - What embedded SQL preprocessor should I use if I am writing an application with Microsoft C or Turbo C?

A - WCSQLPP.EXE is the preprocessor provided by WATCOM and shipped with XQL for DOS v2.11 that can be used to preprocess Microsoft C or Turbo C applications containing embedded SQL statements. Separate libraries for each compiler are also provided with XQL. These libraries must be linked in when compiling the preprocessed code

Xtrieve PLUS

Q - What is the difference between the "Finished - Don't Create" option and the "Finished - Create" option when I am defining or reorganizing the dictionary definitions in Xtrieve PLUS?

A - Both options store your dictionary definitions. "Finished - Create" will make a new Btrieve file in the specified location which matches the specified fields and indexes. The new Btrieve file will also overwrite any existing data file. "Finished - Don't Create" will not create a new file or overwrite an existing file.

Communications Tools

Q - What is involved in converting a standalone communications package to using NASI?

A - NASI is a TSR run at the workstation where the communications program is running. NASI is not a redirector that is, will not trap calls targeted for a COM port and redirect them to a modem pool. The application to be converted must be rewritten to use function calls which are interpreted by the NASI TSR.

Network C for NLMs v2.x

Q - From an NLM, how can I tell if a particular module is loaded on the server?

A - Use the function, FindNLMHandle() (provided with v2.0a and greater). If the function returns a non-zero value, the module is loaded; otherwise, the module is not loaded.

NetWare System Calls for DOS

Q - Why do the Save/Restore Directory Handle APIs return 0xFB on a NetWare 3.x server?

A - The Save and Restore Directory Handle APIs are not supported in NetWare 3.x. The NetWare C Interface documents this fact, but it is undocumented in the NetWare System Calls for DOS manual. Developers using the Save/Restore Directory Handle APIs to "remember" drive mappings on a given workstation must remember the entire path in order to have both a NetWare 2.x and 3.x solution.

Q - Is it necessary to pack structures used in the NetWare C Interface for DOS and the NetWare System Calls for DOS API functions?

A - Yes. When data is returned from function calls, the data is written from the starting address of the structure in contiguous bytes. If you do not pack structures, the optimizing compiler may add additional bytes to the structure to align variables on even word boundaries which would misrepresent the data being returned.

Q - How do I obtain the file server serial number with an API call?

A - See Figure 6.

FIGURE 6: Server Serial Number API

ON ENTRY:

Register   Content

AH         E3h

DS:SI Request Buffer Address

ES:DI Reply Buffer Address

ON RETURN:

Register   Content

AL         Completion Code

REQUEST BUFFER:
|==========|============|============|============|
|  Offset  |  Content   |    Type    |    Order   |
|==========|============|============|============|
|    0     |     1      |    WORD    |    lo-hi   |
|----------|------------|------------|------------|
|    2     |    12h     |    BYTE    |            |
|----------|------------|------------|------------|

REPLY BUFFER:
|==========|============|============|============|
|  Offset  |  Content   |    Type    |    Order   |
|==========|============|============|============|
|    0     |     6      |    WORD    |    lo-hi   |
|----------|------------|------------|------------|
|    2     | serial no. |   BCD[4]   |            |
|----------|------------|------------|------------|
|    6     | appl. no.  |   BCD[2]   |            |
|----------|------------|------------|------------|

{end of Figure 6}

PATCH LISTINGS:

Btrieve v5.10 Patches

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). For a description of patches 1 through 110, refer to earlier issues of Bullets.

111. Btrieve (DOS, Windows, OS/2, VAP) Dug insertion and update operations, this patch prevents unnecessary key pages being recorded in the .PRE file.

112. Btrieve (DOS, Windows, OS/2, VAP) This patch prevents file corruption on files opened in accelerated mode that return status 5s (Duplicate Key Value) during an update operation. Damaged files may not display obvious symptoms of the corruption. (In the reported case, a key was lost from the B-tree.)

113. Btrieve (DOS, Windows, OS/2, VAP) The patch corrects the following problems with the Get Direct operation:

  • Performing a Get Direct operation after deletion of the record by another application returns a status 2 (I/O Error) instead of a status 8 (Lost Position).
  • If a file contains records with duplicate values, a Get Next operation performed after a Get Direct returns a status 9 (End of File) instead of the next record.
  • The status codes returned by a Get Direct operation following a Delete operation are inconsistent
  • In certain cases, after deletion of the last record, Get Direct operations do not return a status code on the record just deleted.
114. Btrieve (DOS, Windows) When performing an End Transaction operation with logging enabled, sometimes an open Btrieve file may open again and remain open after the application terminates. This patch ensures that the file is closed properly.

NetWare Btrieve (VAP, NLM) v5.15 Patches

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). For a description of patches 1 through 36, refer to earlier issues of Bullets.

37. (BTRIEVE.NLM v5.15)
When an extended Get operation following a key-only operation returns a status 9 (End of File), the data buffer may be unchanged or contain garbage. This patch completes the handling of extended operations after key-only operations.

38. (BREQUEST.EXE v5.16, BROUTER.NLM v5.15)
When you perform an Insert operation when the data buffer is big enough to contain the fixed-portion of the record but too small for the whole record, a status 22 (Data Buffer Length) is returned and the record is not inserted. However, the key buffer may be incorrectly altered. This patch ensures that the key buffer is not altered during unsuccessful Insert, Insert Extended, and Update operations.

39. (BTRIEVE.NLM v5.15)
When a large (32+K) pre-image file is produced, as in a large transaction, a value greater than 32k may be erroneously treated as "signed" and is sign-extended with FFs. This is later interpreted as an extremely large unsigned value when it is passed to the operating system, causing a GPI. This patch ensures that conversions are performed without sign-extension.

40. Not yet ready for release.

41. (BTRIEVE.NLM v5.15)
This patch causes a status 19 (Unrecoverable Error) to be returned when Btrieve attempts to read or update a corrupted file.

42. (BTRIEVE.NLM v5.15)
This patch ensures that the correct position is reached when performing a Get Next (6) or Get Previous (7) operation following a Delete (4) operation on a file which contains a supplemental index with duplicates values.

43. (BTRIEVE.NLM v5.15)
If a Btrieve transaction file exists at the time BTRIEVE.NLM is loaded and is not flagged transactional, when the NLM is unloaded, BTRIEVE.TRN will not be erased. This patch ensures that the transaction file is always erased when BTRIEVE.NLM is unloaded.

44. Not yet ready for release.

45. (BTRIEVE.NLM v5.15) Btrieve v5.10 Patches, #112.

BTRIEVE.NLM v5.15) Btrieve v5.10 Patches, #113.

Netware SQL/XQL v2.11 Patches

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). For a description of patches 1 through 59, refer to earlier issues of Bullets.

60. XQLUTIL (DOS)
This patch ensures that the buffer length is correct for a call to XQLMask. Without this patch, XQLUtil may return an incorrect status on the load or copy options when fields are defined to the view which use a default mask.

61. XQL (OS/2)
This patch prevents segmentation violations occurring on an xInsert call when the file name is 20 characters in length.

62. NWSQL (NLM)
This patch will return a status 228 for xInsert operations with a data length that is less than zero.

63. NWSQL (NLM)
This patch will return a status 228 for xUpdate operations with a data length that is less than zero.

64. XQL (DOS) NWSQL (NLM)
If a restriction on a view is in the format:

     "field = 'value' OR field = 'value' OR..."
when "field" is an index on the base file and no sort is defined, then the xFetch/XQLFetch CURRENT operation will skip the current record and return the next record which meets the restriction. This patch ensures that the current record is returned if it meets the restriction.

65. NWSQL (NLM)
This patch prevents situations that can cause the server to abend on an UPDATE statement.

66. NWSQL (NLM, VAP), XQL (DOS, OS/2)
This patch prevents server abends when the following sequence occurs:

  1. Tables are defined,
  2. A view is created on the tables,
  3. The tables are altered,
  4. An attempt is made to execute a query against the view which is no longer applicable.

Xtrieve PLUS v4.10 Patches

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). For a description of patches 1 through 4, refer to earlier issues of Bullets.
  1. When a report contains nested groups and the outer group fields are modified, if the outer group has no fields, or the last field is removed, the machine locks. This patch allows the modification and prevents locking.
  2. This patch ensures that when you have security installed on your dictionary files and you are using NSREQ to access your files, you are able to access the file or field level rights for a user profile.
  3. This patch ensures that correct results are printed in reports when a line of output in the report is exactly the width of the page, and it is not the last line on the page.
  4. This patch corrects the offset display of the BIT fields when you print file definitions.
  5. This patch prevents the following situation from occuring in 25-line mode on a VGA monitor (after exiting Xtrieve PLUS):
    • The screen goes blank, but characters can still be entered at keyboard.
    • Keyboard character are displayed as different characters on the screen.

NOVELL EDUCATION:

Upcoming Classes

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 services. Nearly 50% of class time is devoted to hands-on activities.
  • 901 - Programming with NetWare Client APIs
    March 16-18 Austin, TX
    April 8-10 Washington, DC
  • 905 - Programming with Btrieve
    February 11-13 Chicago, IL
  • 906 - Programming with Btrieve: Advanced Features
    March 10-12 Chicago, IL
  • 907 - Xtrieve PLUS
    March 17-18 Washington, DC
  • 910 - Programming with XQL
    February 18-20 Austin, TX
    April 14-16 Chicago, IL
  • 920 - Programming with Network Communication Services
    February 19-20 Dallas, TX
    March 19-20 Austin, TX
    April 13-14 Washington, DC
  • 930 - Developing NetWare Loadable Modules (NLMs)
    February 11-13 Austin, TX
    March 10-12 Austin, TX
    April 14-16 Austin, TX
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-NETWARE. All courses scheduled are subject to cancellation or rescheduling within two weeks of the scheduled date, depending on enrollment.

International customers should call 1-801-537-8850. For information on availability, location, and prices of international classes, contact your local Novell office.


FUN & FACTS:

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.   What command boots the server without executing the AUTOEXEC.NCF file?

A.   SERVER noauto
B.   SERVER -na
C.   SERVER -n
2.   What is the name of the file that includes all the public symbols made available by
CLIB.NLM?

A.   CLIB.IMP
B.   CLIB.PUB
C.   CLIB.SYM
3.   Windows 3.0 can operate in three different modes. What are they?

A.   Real, Protected, Enhanced
B.   Real, Standard, Enhanced
C.   Standard, Protected, Real
4.   In which programming languages can NLMs be written?

A.   C
B.   C and Assembly
C.   C and COBOL
5.   What console command shows the name of the file server?

A.   NAME
B.   WHOAMI
C.   SHOWNAME
6.   Name the three debug server applications that come with WATCOM WVIDEO Debugger
for NLMs?

A.   NOVSERV.NLM, SERSERV.NLM, PARSERV.NLM
B.   WATSERV.NLM, NOVSERV.NLM, NETSERV.NLM
7.   What is the Btrieve operation code for a Get Previous with a Multiple NoWait Lock?

A.   407
B.   207
C.   107
8.   What is the maximum length of any Btrieve key?

A.   512 bytes
B.   255 bytes
C.   100 bytes
9.   What symbol is used to identify a substitution variable in a SQL statement?

A.   '='
B.   '@'
C.   '*'
10.  What SQL keyword is used to restrict data in a view?

A.   WHERE
B.   RESTRICT
C.   LIMIT
11.  What is the result of using the XQL LENGTH scalar function on a field of type TIME?

A.   8
B.   4
C.   1
12.  In Xtrieve PLUS, what is the environment variable that specifies the directory and
filename for the Xtrieve PLUS message file?

A.   XTRSGN
B.   XTRMGF
C.   XTRMSG
13.  Which DDF contains the compiled structure information for stored SQL statements?

A.   PROC.DDF
B.   STORED.DDF
C.   SQL.DDF
D.   SQLSTRUC.DDF
FUN & FACTS ANSWERS:
1.   B
2.   A
3.   B
4.   B
5.   A
6.   A
7.   A
8.   B
9.   B
10.  A
11.  B
12.  C
13.  A

FUN & FACTS

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.

Novell Labs

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

Novell Developer Relations

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

Voice

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

Fax

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

NetWire on CompuServe

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

E-mail: MHS or Internet (SMTP)

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

ACKNOWLEDGEMENTS

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

Contributing Authors: Gaurang Amin, Vitek Boruvka, Michael Eisa, Laura Heater, Sudz Khawaja, Clint McVey, Jose Pruneda, 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, 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 and AppleTalk are registered trademarks of Apple Computer, Inc. CompuServe is registered trademark of CompuServe Corporation. Microsoft is a registered trademark, and Windows, Microsoft QuickBasic, and Microsoft Visual Basic are trademarks of Microsoft, Inc. IBM and OS/2 are registered trademarks, and NetBIOS and SAA are trademarks of International Business Machines Corporation. Sun Microsystems and NFS are registered trademarks of Sun Microsystems, Inc. WATCOM is a trademark of WATCOM Systems, Inc.