*********************************************
*********************************************
Professional Development Series
B  U  L  L  E  T  S
*********************************************
July 1992
Volume 4, Number 7
*********************************************
*********************************************


*********************************************
*********************************************
MAD'S COLUMN
*********************************************
*********************************************

Hello and welcome to the July 1992 issue of Bullets!

I am never sure what to expect at computer conferences. Last month,
two potentially different conferences were held: Novell's
Brainshare/Japan and Microsoft's NT Developers Conference. The
audiences and their expectations could have been quite different.
I wondered what would the attendees be looking for and what
messages would be delivered.

I was surprised to discover that the developers, their needs and
their wishes were not that different. One of the keynote speakers
at Brainshare reminisced about a conference he attended during the
mid-1980's. At that conference, he said developers wanted three
things: performance, stability and consistency. (I am surprised
that, back then, it wasn't performance, performance and
performance.) He said these are still the basic developer needs.

If he is correct, what does this say about the past decade? Have
we been unsuccessful?

I think we have been successful in fulfilling some basic
programming requirements and, while the computer industry continues
to change as rapidly as ever, we are constantly working to meet the
others. It is a very positive development to see the companies at
these conferences asking their customers what their specific needs
are. This trend can only help to "accelerate the growth of the
network computing industry" in the next decade.

Happy_Programming!

Mad Poarch
Director
Developer Support/Service



*********************************************
*********************************************
ARTICLES:
Keeping Your Database in Sync
*********************************************
*********************************************

NetWare SQL v3.0 is the latest version of Novell's relational data
access system developed specifically as a NetWare Loadable Module
(NLM) for the NetWare v3.11 platform. NetWare SQL v3.0 offers Named
Database support, page-level transactions (cursor stability),
continuous operations during backups, and referential integrity
(RI), which ensures that cross references between tables are always
valid. This article will familiarize you with RI, NetWare SQL 3.0's
implementation of it and how to install RI to keep your database
in sync.


NetWare SQL's Implementation of Referential Integrity

Keeping a database in sync requires two types of data integrity:
physical and logical. NetWare v3.11 works with NetWare Btrieve
v6.0, a server-based version of the Btrieve record manager included
as a component of NetWare SQL v3.0, to provide the physical data
integrity with their automatic recovery functions. NetWare SQL v3.0
provides logical data integrity through two mechanisms: transaction
control and RI.

NetWare SQL's transaction control utilizes the transaction and
record-locking capabilities of NetWare Btrieve. In NetWare SQL
v3.0, RI is initially established by the system administrator or
application developer, and once established, it is transparent to
any application development.

RI ensures that, when a field or group of fields in one table
reference a field or group of fields in another table, any changes
made to these fields are synchronized. A set of rules, referred to
as referential constraints, define the relationships between
tables. Several definitions are useful in understanding RI:

*    A primary key is a field or group of fields whose collective
     key value uniquely identifies each record in a table. Primary
     keys are implemented as unique, non-null indexes.

*    A foreign key is a field or group of fields that reference a
     primary key in the same or a different table. A foreign key
     cannot contain null values.

*    A parent table is a table containing a primary key referenced
     by a foreign key.

*    A dependent table is a table containing a foreign key that
     references a primary key in the same or a different table. A
     dependent table can contain multiple foreign keys.

*    A dependent row is a record in a dependent table whose foreign
     key value matches a primary key value in the referenced parent
     table.

*    A self-referencing table is a table which is its own parent
     table; in other words, it contains a foreign key that
     references its primary key.

*    A cycle is a reference path in which the parent table is its
     own descendant.

Every foreign key value in a dependent table must have a matching
primary key value in the referenced parent table. Consequently, an
attempt to insert a record with an unmatched foreign key value into
a dependent table will fail. Similarly, an attempt to delete a
record in a parent table to which a foreign key currently refers
may fail, depending on how the foreign key is defined.

Managing an invoice tracking system is one example of a task in
which RI is useful. Suppose that customer information is contained
in one table and invoice information for each customer is kept in
a second table. If a customer is deleted from the database while
the customer had an outstanding invoice, the database would be
logically corrupted because an invoice would exist for a customer
that does not exist. If you used RI on this database, you could
establish constraints to prevent customer information from being
deleted if invoices exist.

Btrieve fully enforces all referential constraints defined by
NetWare SQL. This prevents both Btrieve and NetWare SQL
applications from compromising integrity constraints when modifying
data. To implement RI, two new files have been added to the NetWare
SQL system (which only exist if referential constraints have been
defined via NetWare SQL). A file called RELATE.DDF is located with
the rest of the dictionary files and contains the relationships
between the primary and foreign keys in the tables. In addition,
the SYS:\SYSTEM directory contains the file, DBNAMES.CFG, which is
created when you define a Named Database. DBNAMES.CFG contains the
descriptive name of the database and the location of the dictionary
files associated with that database. Named Database support is a
new feature of NetWare SQL v3.0 that allows you to define a name
for a database, and associate a dictionary path and datafile paths
with that name. You can then use this name to access the database.
A Named Database is required to set up RI and, by default, RI is
enabled when you define a new Named Database.

When you define a referential constraint for a field in a given
table, information is added to the physical Btrieve file to
indicate that the file has RI constraints. Included in this
information is the SQL database name and the SQL table name.
NetWare Btrieve uses this information to look up the location of
the dictionary files in DBNAMES.CFG, and then to check the
relationships in RELATE.DDF. Based on the information in
RELATE.DDF, NetWare Btrieve may access other Btrieve files involved
in the relationship to verify data prior to performing the
modification to the Btrieve file. As a result, NetWare Btrieve is
opening more than just the file being modified. This can be seen
using the NetWare SQL Monitor Utility (NDBMON.NLM), and should also
be taken into account when configuring the maximum number of open
files in the NetWare SQL Setup Utility (NDBSETUP.NLM).


Establishing RI

Establishing RI with NetWare SQL v3.0 is very easy. There are a few
simple guidelines for defining referential constraints.

*    The database must be defined as a "Named Database" using the
     NDBSETUP utility.

*    All of the files in the database must reside on a single
     server; they can, however, be split across multiple volumes
     on that server.

*    Data paths defined in the dictionary cannot contain drive
     letters. Paths must be simple file names or relative paths.

*    If security is enabled on the database, a user must have the
     References right on a table to define referential constraints
     on the database.

*    SQL statements are used to define referential constraints.
     Referential constraints can not be defined using the
     primitives.

*    RI can be defined on both new and existing databases. All
     files need to be in the NetWare Btrieve v6.0 file format. For
     existing databases, files can be rebuilt to the new format
     using the BREBUILD utility.

*    Referential constraints are easy to define by using either the
     "CREATE TABLE" or "ALTER TABLE" SQL statement. These
     statements are used to define primary and foreign keys. The
     "ALTER TABLE" statement can also be used to remove referential
     constraints. These statements can be executed from one of the
     interactive utilities provided with NetWare SQL v3.0 (SQLScope
     or XQLI), or can be executed from an application using
     SQL-Level function calls. Figure 1 shows how to define RI with
     SQL statements.

*********************************************
Figure 1: Defining RI using SQL Statements

CREATE TABLE CUSTOMER
   USING 'CUST.BTR'
(    PRIMARY KEY (ID),
     ID          INT(2),
     NAME        CHAR(20),
     ADDR        CHAR(20),
     CITY        CHAR(10),
     STATE       CHAR(2),
     ZIP         CHAR(10))
WITH INDEX (ID UNIQUE)

ALTER TABLE INVOICE
ADD FOREIGN KEY custID (CUSTID)
REFERENCES CUSTOMER
ON DELETE RESTRICT

<END of FIGURE 1>
*********************************************

     The "WITH INDEX" clause on the create table statement is
     optional, since NetWare SQL will automatically create the
     first index according to the field(s) specified as the primary
     key. Also notice that a "delete rule" is specified for
     deleting records in the INVOICE table.

With NetWare SQL, there are rules to Insert, Update and Delete
foreign keys.

*    The Insert rule is RESTRICT. This means that for each foreign
     key in the record being inserted, the foreign key value must
     have an equivalent primary key value in the parent table.

*    The Update rule is RESTRICT. This means that a foreign key
     value must be updated to a new value that has an equivalent
     primary key value in the parent table.

*    The Delete rule can be either RESTRICT or CASCADE. If you
     specify RESTRICT as the delete rule, when you attempt to
     delete a record from the parent table, NetWare SQL first
     checks to see if a foreign key exists in any of the dependent
     tables before it allows the delete. For example, in Figure 2,
     the EMPLOYEE table has a foreign key, DeptID, which references
     the DeptID field from the DEPARTMENT table. If you try to
     delete an DeptID from the DEPARTMENT table which is referenced
     by a matching ID in the EMPLOYEE table, the delete will fail.

*********************************************
Figure 2: NetWare SQL CASCADE and RESTRICT delete rules


                     DEPARTMENT table
                    ͻ
                       DeptID    <RESTRICTͻ
                    ͼ                    
                                                      
                                                      
     EMPLOYEE table                                   
    ͻ
>   Employee      Employee      Employee     Dept  
         ID           Name        Location      ID   
   ͼ


CASCADEͻ
                                                    
                                                    
    PROJECTS table                                  
    ͻ
       Project    Project      Project      Employee  
         ID        Name      Description       ID     
    ͼ


END of FIGURE 2
*********************************************

     If you specify CASCADE as the delete rule, when you attempt
     to delete a record from the parent table, NetWare SQL will
     check to see if a matching foreign key value exists in any of
     the dependent tables. In Figure 2, the EMPLOYEE table has a
     primary key, EmployeeID, which is referenced by the EmployeeID
     field in the PROJECTS table. With the CASCADE delete rule, if
     you delete an EmployeeID from the EMPLOYEE table, NetWare SQL
     will delete all dependent rows from the PROJECTS table as
     well. If all descendants of a primary key have CASCADE as the
     delete rule, NetWare SQL will delete all dependent rows on a
     reference path to the original parent table.

When specifying the delete rule for a given foreign key, use the
following guidelines:

*    The delete rule for a self-referencing table must be cascade.

*    A cycle with two or more tables cannot be delete-connected to
     itself. This means that the delete rule for at least two of
     the dependent tables in the cycle must be restrict.

*    Delete rules from multiple paths (dependent tables that
     reference the same parent table) must be the same.


Installing RI on a New Database

To setup RI on a new database, use the following steps:

*    Create a dictionary

*    Establish a database name for the dictionary with the NDBSETUP
     utility. You may wish to disable RI for the database until you
     have finished defining your constraints.

*    Design your database

     1)   Decide how many tables the database will contain, what
          fields will be in each of the tables, and how the tables'
          fields relate to each other.

     2)   Decide what fields need referential constraints and what
          the delete rules will be for the foreign keys; this step
          is sometimes easier if it is done graphically as in the
          diagram in Figure 2.

*    Define your tables and your referential constraints to the
     dictionary. Referential constraints can be added when tables
     are created, or after the tables have been created.

*    Enable RI for the database through NDBSETUP and populate the
     tables. These two steps can be interchanged depending on how
     you plan to populate your tables. If you are loading data into
     your tables from some type of sequential file, you may want
     to do this without enabling RI. Then, after you have added all
     the data, you can use the RIUTIL utility to check the
     consistency of your existing data, based on the referential
     constraints defined. If you are adding new data into a new
     system, you may want to enable RI from the start to ensure
     that all new data complies with the defined constraints.


Installing RI on an Existing Database

Before setting up referential constraints on an existing database,
check with the application vendor or developer to make sure the
restraints you install will not interfere with the applications.
Some applications might allow null values for fields you wish to
define as a primary or foreign key, or might perform inserts on
dependent tables with no matching primary key values. In these
cases, RI will cause new status codes to be returned which the
application is not expecting. If the vendor or developer indicates
that RI will not interfere with the application, follow these steps
to install RI.

*    Convert all files created with version of Btrieve before v6.0,
     including the dictionary files, to the NetWare Btrieve v6.0
     file format using BREBUILD.

*    Establish a database name for the dictionary with NDBSETUP.
     You may wish to disable RI until you finish defining your
     constraints.

*    Plan your referential constraints based on the existing
     indexes, or add new indexes as necessary to implement the
     constraint that you want. Again, this process may be easier
     if it is done graphically as in Figure 2.

*    Define your referential constraints to the dictionary using
     the ALTER TABLE statement.

*    Use the RIUTIL utility to check the consistency of your
     existing data based on the referential constraints that have
     been defined.

*    Make any necessary modifications to your data so that it
     conforms to the referential constraints defined. This can be
     done manually, or by using the RIUTIL -CHECK utility. RIUTIL
     -CHECK has an option that will remove any records that violate
     the RI constraints.

*    Once the RIUTIL utility reports that the database is "in
     sync," enable RI using NDBSETUP.

NetWare SQL v3.0 has been released only for the NetWare v3.11
environment as a NetWare v3.11 NLM. For additional product
information, please contact 1-800-RED-WORD (1-800-733-9673) or
1-512-794-1796. For technical and developer support questions
regarding any released Novell products, please call 1-800-NETWARE
(1-800-638-9273) or 801-429-5588.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
New ReturnVersion API for DLLs
(NetWare C Interface for Windows v1.3)
*********************************************
*********************************************

The function, GetDLLVersion( ), was not exported or supported by
the NetWare C Interface for Windows v1.3. However, Figure 3
contains an API, ReturnVersion( ). which, when placed directly into
applications or an OBJ file, returns DLL version information.

*********************************************
Figure 3: Replacement for GetDLLVersion API

extern void ReturnVersion( BYTE far *majorVersion,
                           BYTE far *minorVersion,
                           BYTE far *revisionLevel,
                           BYTE far *betaReleaseLevel );
   :

void GetDLLVersionInfo( char far *DLLName,
                        BYTE far *majorVersion,
                        BYTE far *minorVersion,
                        BYTE far *revisionLevel,
                        BYTE far *betaReleaseLevel )
{
   HANDLE           hDriver;
   static FARPROC   lpfnReturnVersion;
   hDriver = LoadLibrary( DLLName );
   lpfnReturnVersion = GetProcAddress( hDriver, "ReturnVersion" );
   if ( lpfnReturnVersion != NULL )
      ( *lpfnReturnVersion )( (BYTE far *)&majorVersion,
                              (BYTE far *)&minorVersion,
                              (BYTE far *)&revisionLevel,
                              (BYTE far *)&betaReleaseLevel );
   if( lpfnReturnVersion == NULL ) {
      majorVersion = 0;
      minorVersion = 0;
      revisionLevel = 0;
      betaReleaseLevel = 0;
      }
} /* GetDLLVersionInfo */

/* Usage example */
   :
   static char DLLName[20] = "NWIPXSPX.DLL";
   BYTE majorVersion;
   BYTE minorVersion;
   BYTE revisionLevel;
   BYTE betaReleaseLevel;
   :
   GetDLLVersionInfo(DLLName, (BYTE far *)&majorVersion,
                              (BYTE far *)&minorVersion,
                              (BYTE far *)&revisionLevel,
                              (BYTE far *)&betaReleaseLevel );

<END of FIGURE 3>
*********************************************



*********************************************
*********************************************
TECHNICAL INSIGHTS:
IPX Function Calls in a WEP Fail
(NetWare C Interface for Windows v1.3)
*********************************************
*********************************************

DLLs can use a Windows Exit Procedure (WEP) that is executed before
unloading the DLL from memory. When the WEP procedure is called,
your data or code segments may no longer be valid. For example,
calling   an IPX/SPX function where one of the parameters is an ECB
will result in an invalid memory reference.

Instead of cleaning up IPX/SPX resources in a WEP procedure, you
should write a function for clients to call to clean up resources
before exiting. Novell's IPXSPX.DLL is an example of this design.
This DLL exports a function called IPXSPXDeinit that clients call
to clean up resources.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
TTS & Pre-Imaging
(NetWare Btrieve (NLM) v5.15)
*********************************************
*********************************************

If TTS is disabled at the server   and the Btrieve data files to
be accessed with the NetWare Btrieve v5.15 are flagged
"transactional" (T), Btrieve will return a status 15 (Pre-image I/O
Error) on all updates (Insert, Update and Delete operations) to the
data files between Begin Transaction (19) and End Transaction (20)
operations.

The status 15 is not returned when:

*    The update is performed outside of a Btrieve transaction

*    Before the update is performed inside of a Btrieve
     transaction, a successful update has occurred outside of a
     transaction with the current instance of Brequest. This case
     is reinitialized once Brequest is unloaded and loaded again
     on the workstation.

In all cases, even when the status 15 is not returned, no
pre-imaging is performed if TTS is not enabled at the server.

If Btrieve data files are flagged transactional, TTS must be
enabled at the server for pre-imaging to be performed. When TTS is
disabled, flag all Btrieve files non-transactional (-T).




*********************************************
*********************************************
TECHNICAL INSIGHTS:
How To Get NetWare SQL v3.0
(NetWare SQL (NLM) v3.0)
*********************************************
*********************************************

New customers can obtain NetWare SQL v3.0 through an authorized
Novell reseller. Registered users of NetWare SQL v2.x can upgrade
to any user count of NetWare SQL v3.0. Registered users of XQL v2.x
can only upgrade to the NetWare SQL Developer's Kit v3.0.

*    To upgrade a copy of NetWare SQL v2.x or XQL v2.x, customers
     should contact their local Novell resellers.

*    Customers in the U.S. and Canada may also order upgrades by
     calling Novell After Market Products (AMP) at 1-800-346-7177.
     Novell resellers are now able to furnish NetWare SQL v3.0
     upgrades through the NetWare upgrade program.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
Windows, TBMI, VIPX.386, & DOS Applications
(NetWare Btrieve v5.x)
*********************************************
*********************************************

Within Windows, running Brequest and a DOS application in a DOS box
requires different setups depending on which version of Windows you
use and whether or not you run Windows in standard mode or enhanced
mode.

*    If you run Windows v3.0 in standard mode, load TBMI.COM before
     starting Windows. In the DOS box, load TASKID.COM,
     BREQUEST.EXE, and the DOS application (in that order).
     TBMI.COM and TASKID.COM are currently available on Novell's
     CompuServe forum, NetWiresm (NOVLIB, LIB 1 or 5, WINUP6.ZIP).

*    If you run Windows v3.1 in standard mode, load TBMI2.COM
     before starting Windows. In the DOS box, load BREQUEST.EXE and
     then the DOS application. TBMI2.COM is provided with Windows
     v3.1.

*    If you run either Windows v3.0 or v3.1 in enhanced mode, then
     you should use VIPX.386. Modify the SYSTEM.INI file under the
     [386Enh] header by adding the line: "network=VIPX.386."

     After starting Windows, load BREQUEST.EXE in the DOS box, and
     then load the DOS application. Use the VIPX.386 that is
     included in WINUP6.ZIP on NetWire. Do not use the version
     included with Windows v3.0.

*    If a Windows application (not DOS) requires BREQUEST.EXE, then
     load BREQUEST.EXE before you start Windows.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
Pre-imaging in NetWare Btrieve v6.0
(NetWare Btrieve (NLM) v6.0)
*********************************************
*********************************************

NetWare Btrieve v6.0 creates a pre-image file when writing to a
Btrieve file created with an earlier version of Btrieve. However,
the format of this pre-image file is different from the format of
a pre-image file created by earlier versions of Btrieve. Earlier
versions of Btrieve cannot accurately interpret a pre-image file
created by NetWare Btrieve v6.0 and vice versa.

If you need to interchange the Btrieve engine that will be
accessing the pre-v6.0 Btrieve file, all pre-image files must be
cleaned up prior to swapping engines. Use the following procedure
to clean up these pre-image files:

1.   Check to see if a .PRE file exists for any Btrieve files

2.   If a .PRE file exists with a pre-v6.0 version of Btrieve:

     *    open the Btrieve file in Exclusive mode

     *    perform a Get First operation

     *    perform an Update operation

     *    close the Btrieve file (this should cause the .PRE file
          to be deleted)

3.   Switch engines

Remember that a Btrieve file can not be accessed simultaneously
with a client Btrieve engine and the NetWare Btrieve server-based
engine. This procedure should be used if it is necessary to swap
between a pre-v6.x client engine and a v6.x server engine.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
Novell Database Products & Case-Insensitivity
(NetWare SQL (NLM) all versions)
*********************************************
*********************************************

With Btrieve, if a string, lstring or zstring key is created with
the alternate collating sequence, UPPER.ALT, the case of the data
in the key is ignored when performing a search on that key. For
example, if a record is inserted with the key value "test," this
record can be retrieved by performing a Get Equal operation with
a Key Buffer parameter containing the value "TEST," "Test," "test"
or any other combination of upper and lower case letters.

In addition, if two records are inserted with the values "test" and
"TEST," they are considered duplicate key values. Get Equal on any
case representation of "test" will always return the first record
entered. When scanning the key values for this key, it may appear
that Btrieve is not sorting the values properly, since "test" will
be returned before "TEST" if the records were inserted in that
order.

Case searches work differently with NetWare SQL. There is a CASE
key-word which indicates that a field or index should be treated
as case-insensitive (i.e. upper and lower case letters will be
treated the same). There are two situations to consider. The CASE
keyword can be specified for any string, lstring or zstring field
in the dictionary and/or for any string, lstring or zstring index.
For a case-insensitive field, restrictions are evaluated regardless
of case. So, a record containing a Name field with the value "John"
will be returned when a restriction of "Name = 'JOHN'" is
specified. If CASE is not specified for a field, only exact matches
with the value in the restriction will be returned, regardless of
whether or not there is a case-insensitive index specified for this
field.

For a case-insensitive index, the case of the data is ignored when
sorting the data. Specifying that an index is case-insensitive
causes Btrieve to create and maintain that key using the UPPER.ALT
alternate collating sequence.

Figure 4 contains an example that demonstrates the different types
of fields. Notice that the Name1 index is case-insensitive, but the
Name2 index is case-sensitive.

*********************************************
Figure 4: CASE sensitivity and field types

CREATE TABLE Test USING "TEST.DAT"
  (Name1 CHAR(10) CASE, Name2 CHAR(10)) WITH INDEX (Name1 CASE, Name2)

INSERT INTO Test
  VALUES("John", "Doe")  VALUES("jane", "doe")  VALUES("JOHN", "BROWN")

  SELECT * FROM Test     SELECT * FROM Test     SELECT * FROM Test
  WHERE Name1 = "john"   WHERE Name2 = "Doe"    ORDER BY Name1


Name1    Name2         Name1    Name2         Name1    Name2
---------------------------------------------------------------
John     Doe           John     Doe           jane     doe
JOHN     BROWN                                John     Doe
                                              JOHN     BROWN

<END of FIGURE 4>
*********************************************

When using Xtrieve PLUS v4.1x to create tables, case-insensitivity
for a field is specified by selecting "No" for the "Case?" option
for a string, lstring or zstring field on the field definition
screen. When the cursor is in the "Case?" column, the help text at
the bottom of the screen reads "Specify Case-sensitivity when used
in view restrictions?"

Case-insensitivity for indexes is also specified by selecting "No"
at the "Case" prompt on the index definition screen. When the Case
selection box appears, the help text reads "Treat upper and lower
case letters differently in sort?" Answering "No" to this question
implies case-insensitivity. Figure 5 contains the Xtrieve PLUS
definition for the table Test described above.

*********************************************
Figure 5: Example Xtrieve PLUS definition table

FIELD DEFINITIONS
----------------------------------------------------------------
Position   Key    Name    Type     Size    Dec   Delimiter   Case
----------------------------------------------------------------
   1        *     Name1   String    10                        No
  11        *     Name2   String    10                        Yes


INDEX DEFINITIONS
----------------------------------------------------------------
Key   Name     Field     Type     Dups   Mod   Case   Asc   Total
----------------------------------------------------------------
 0             Name1     String   Yes    No    No     Yes    0
 1             Name2     String   Yes    No    Yes    Yes    0

<END of FIGURE 5>
*********************************************

A confusing situation might occur if a field is defined as
case-insensitive and that field is also an index, but the index is
defined as the opposite: case-sensitive. Usually, a
case-insensitive field implies that case is ignored on
restrictions. However, if an index exists, NetWare SQL/Xtrieve PLUS
will use that index to optimize the search. If the index is not
defined with case-insensitivity (thus Btrieve is NOT using
UPPER.ALT for this index), the optimized search will only find
exact matches, and the restriction will only find exact matches.
In this situation, the case-insensitivity of the field is
overridden by the case-sensitive index. Therefore, if a
case-insensitive field is also part of an index, that index should
also be defined as case-insensitive.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
Record Locking In Embedded SQL
(NetWare SQL (NLM) all versions)
*********************************************
*********************************************

Record locking is not part of the industry standard for embedded
SQL, so NetWare SQL's implementation of embedded SQL does not
support it. Guaranteed access is only available through the use of
transactions. In fact, by default, transaction processing is
automatically enabled, causing all embedded SQL calls to be
performed within NetWare SQL transactions.
Record locking is supported by both the Relational Primitive and
SQL-Level functions, which can also be used to develop NetWare SQL
applications.



*********************************************
*********************************************
TECHNICAL INSIGHTS:
Lotus Configuration for DataLens Driver
(NetWare SQL (NLM) v3.0)
*********************************************
*********************************************

If a drive letter and path are used in the LOTUS.BCF file to
specify the location of the Datalens Driver for NetWare SQL (NLM)
v3.0, and this location is not the Lotus directory or the current
working directory, the driver will not be found.

Always place the Datalens Driver (LTSNWSQL.DLD or LTSNWSQL.DLL) in
the Lotus directory or in the current working directory.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
NetWare Btrieve v6.0 & Patch311.NLM
(NetWare Btrieve (NLM) v6.0)
*********************************************
*********************************************

When using BTRIEVE.NLM v6.0 with NetWare v3.11, make sure that
PATCH311.NLM (the patch file for the version of CLIB.NLM released
with NetWare v3.11) is in the SYS:\SYSTEM directory before you
attempt to load BTRIEVE.NLM, regardless of which version of
CLIB.NLM the network     uses.
BTRIEVE.NLM v6.0 always attempts to automatically load this patch
file. PATCH311.NLM will only load if the released CLIB.NLM is
running. If the system uses a newer version of CLIB.NLM,
PATCH311.NLM will detect it and do nothing. As long as the Btrieve
NLM can locate the patch file, it will load whether PATCH311.NLM
successfully loads or not.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
Using Brequest in Multiple Desqview Sessions
(NetWare Btrieve (NLM) v5.x)
*********************************************
*********************************************

With Desqview v2.40, if you have multiple sessions running Btrieve
applications using the NetWare Btrieve requester (BREQUEST.EXE),
Btrieve may return a status 79 (Programming Error). The Desqview
v2.40 configuration option, "Network Buffers," can be increased to
resolve this status code.

From a Desqview window, run the program DVSETUP. Then, select the
advanced setup procedure. From the advanced menu, select the
Network option. One of the network options is called "Network
Buffers." The default for this parameter is 8. Raising this value
to 16 will usually resolve the status 79.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
Is TBMI/TBMI2 Loaded?
(NetWare C Interface for Windows v1.x)
*********************************************
*********************************************

You can determine if TBMI/TBMI2    is loaded by using the interrupt
INT 2Fh with 7A10h in AX with DX initialized to zero. The version
will be returned in DX (Major version in DH, minor version in DL).
The values in these registers will be zero if TBMI/TBMI2 is not
installed. Using IPX/SPXInitialize can serve the same purpose by
indicating that IPX could not be initialized (error 240 or 0xF0).

If you use the INT 2Fh method, remember that TBMI/TBMI2 are TSRs
and run in REAL mode. If you run a Windows application which needs
to check on TBMI, use DPMI to simulate the REAL mode interrupt.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
Error Using Turbo Pascal Interface for NetWare SQL
NetWare SQL (NLM) v3.0
*********************************************
*********************************************

The Turbo Pascal interface included with NetWare SQL (NLM) v3.0
lets you specify whether the application will use SQL-level
functions, primitive functions, or both. To choose one type of
function or both, "comment out" one or both of the following lines,
which appear at the top of the interface file NWSQLINT.PAS:

{$DEFINE NWSQL_RELATIONAL_PRIMITIVES}
{$DEFINE NWSQL_SQL_FUNCTIONS}

If the second $DEFINE line (for the SQL-level functions) is
"commented out," this indicates that only the primitive calls will
be included and the interface cannot be compiled into a Turbo
Pascal Unit. The compiler will return an error 59 (Undefined
Forward).

Two of the prototypes defined in the miscellaneous section of this
interface should be moved into the SQL-level prototype section:

*    PROCEDURE SQLLevelCall;

*    FUNCTION SQLManagerLoaded : BOOLEAN;




*********************************************
*********************************************
TECHNICAL INSIGHTS:
Passing Parameters with XQLP & Visual Basic
(NetWare SQL (NLM) v3.0)
*********************************************
*********************************************

To pass Visual Basic strings "by reference," the function
declaration section must specify "ByVal" on any string parameter.
According to the Microsoft Visual Basic Programmer's Guide (1991)
(pg. 382, "Calling DLL Routines with Specific Data Types"), the
routines in most DLLs expect standard C strings which end in a null
character. If a DLL routine expects a C string as an argument,
declare the argument as a string with the "ByVal" keyword. When
used with a string argument, "ByVal" tells Visual Basic to pass the
string as a C string ending with a null character.

The "ByVal" clause tells Visual Basic to pass the string address
by value (not by reference), instead of just passing the string
itself. So, if the XQLP documentation requires a string parameter
to be passed by reference, the Visual Basic Function Declaration
needs to specify "ByVal." If XQLP requires the string by value, the
Visual Basic function declaration needs to specify "as String" or
"as VarName$."

Integers work just the opposite. If XQLP requires the integer by
value, the Visual Basic function declaration must specify "ByVal."
If XQLP requires the integer by reference, the Visual Basic
function declaration needs to specify "as Integer" or "as
VarName%." If XQLP requires a structure, which is generally the
data buffer, Visual Basic stores "TypeDefs" in a different area
than strings, and as such, it gets handled the same way as integers
with respect to the "ByVal" clause in the Function Declaration.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
Status 2001 with WBTRCALL
(NetWare Btrieve (NLM) v5.15)
*********************************************
*********************************************

With the Windows Btrieve requester, WBTRCALL.DLL v5.17a (date:
6-28-91), Btrieve returns a status 2001 (Insufficient Memory) on
any Btrieve call issued after a WBTRVSTOP call. The status 2001
only occurs within a single task or program. If an application that
makes Btrieve calls is running and that application, or any other
application calls WBTRVSTOP, the NetWare Btrieve NLM will return
a status 2001 on each successive Btrieve call in all Btrieve
applications that are running until the applications are restarted.

This situation has been resolved in the version of WBTRCALL.DLL
(NetWare Btrieve v6.0) that ships with NetWare SQL (NLM) v3.0. If
you use the v6.0 WBTRCALL.DLL, you also need WBTRVRES.DLL (also
included with NetWare Btrieve v6.0).




*********************************************
*********************************************
TECHNICAL INSIGHTS:
IPXODI Options Affect SPX & Diagnostics
(NetWare C Interface for DOS v1.2)
*********************************************
*********************************************

IPXODI allows certain options to be specified when it is loaded
that affect what protocol support is installed. Specifically, the
D option tells IPXODI NOT to load Diagnostics support. The A option
tells IPXODI not to load Diagnostics support or SPX support. If
diagnostics support is not loaded, BeginDiagnostics() will return
0xFE (254). If SPX support is not loaded, SPXInitialize() will
return a zero.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
Retrieving     NetWare Volume Serial Numbers
(NetWare System Calls for DOS v1.0)
*********************************************
*********************************************

Beginning with DOS v4.x, volume serial numbers were introduced.
This information could usually be retrieved from the DOS BOOT
sector. Under NetWare volumes, there is no DOS BOOT sector.

You can use an undocumented DOS function to retrieve volume serial
numbers: INT 21h, function 69h. The example code in Figure 6 shows
how you can retrieve data from drive I.

*********************************************
Figure 6: Retrieving NetWare Volume Serial Numbers

union REGS inRegs, outRegs;
struct SREGS segRegs;

struct MID {
     WORD midInfoLevel;
     LONG midVolumeSerialNumber;
     BYTE midVolumeLabel[11];
     BYTE midFileSystemType[8];
  } MidInfo;

far *pMidInfo;

void main (void)
{

   memset (&MidInfo, 0, sizeof (MidInfo));

   pMidInfo = (int *)&MidInfo;

   segread (&segRegs);
   inRegs.h.ah = 0x69;
   inRegs.h.al = 0x00;
   inRegs.h.bh = 0x08; /* drive letter to target */
   segRegs.ds =  FP_SEG (pMidInfo);
   inRegs.x.dx = FP_OFF (pMidInfo);

   int86x (0x21, &inRegs, &outRegs, &segRegs);
     printf ("\nSerial Number: %lx", MidInfo.midVolumeLabel,
                               MidInfo.midVolumeSerialNumber);
} /* main */

<END of FIGURE 6>
*********************************************




*********************************************
*********************************************
NIBBLES & BITS
(Fast answers to common questions)
*********************************************
*********************************************

*********************************************
NetWare C Interface for Windows

Q    What drivers do I need to develop and run Windows v3.1
     applications?

A    The current driver requirements for developing and running
     Windows v3.1 applications are:

     1)   the versions of VNETWARE.386, NETWARE.DRV, and VIPX.386
          supplied with Windows v3.1.

     2)   the DLLs supplied with the NetWare C Interface for
          Windows v1.3 (not the drivers mentioned in the '\DRVRS'
          directory).

     3)   for Standard mode, the version of TBMI2.COM supplied with
          the NetWare C Interface for Windows v1.3.

*********************************************
NetWare C Interface for DOS

Q    I have a TSR which manages IPX/SPX communications to other
     nodes. I do not have to login to NetWare, so I only load
     IPX.COM. When I unload my TSR, the SHORT_LIVED socket I opened
     remains open. Are SHORT_LIVED sockets supposed to remain open
     upon program termination?

A    When a program terminates, the NetWare shell (e.g., NETX)
     closes Sockets opened as SHORT_LIVED. However, if the shell
     is not loaded, all sockets are treated like
     LONG_LIVED_SOCKETS. In this case, call IpxCloseSocket ()
     before terminating the program.

*********************************************
NetWare & OS/2

Q    When will the NetWare OS/2 v2.0 requester be available?

A    The OS/2 v2.0 requester is available now from 1-800-UPDATE1.
     The price includes documentation. Members of the Professional
     Developers' Program (PDP), can also obtain the requester for
     the NOVDEV forum on NetWire. (Remember to unzip the file with
     the d option.)

Q    Can 32-bit OS/2 v2.0 applications call the 16-bit Novell
     libraries?

A    Yes, but a thunk is required. A thunk is the procedure of
     telling a 32-bit function to handle a 16-bit API call.

*********************************************
NetWare for SAA LU6.2 Tools

Q    When I recompile the NLM example, CPIS.C, that is supplied
     with NetWare for SAA LU6.2 Tools (Feb. release) with the
     WATCOM v8.0 compiler, the example will not run correctly. What
     should I do?

A    This situation occurs with v8.x (and above) of the WATCOM
     compiler, which has been updated to define "far." In the NLM
     environment, the normal definition of "far" causes "far"
     pointers to be 48-bit (not 32-bit) and will not work with
     NetWare Lu6.2. For usable "far" pointer definitions, delete
     lines 40 through 42 of the header file CPIC_NET.H and insert
     the following four lines:

     #ifdef far
        #undef far
     #endif
     #define far

*********************************************
Btrieve

Q    With NetWare Btrieve v6.0, when I perform an Insert (2)
     operation, NetWare Btrieve inserts for a while, then it
     returns a status 84 (Record in Use). What should I do?

A    Your application should retry if it receives a status 84. In
     this case,  NetWare Btrieve is locking the key page for a
     brief moment and at this time another user is trying to access
     it.

Q    After I create a Btrieve file with an alternate collating
     sequence, is the alternate collating sequence file (the file
     that contained the new collating sequence) still required?

A    No. Btrieve stores the new collating sequence within the
     Btrieve file.

Q    If you create a supplemental index and then close the Btrieve
     file, does the supplemental index disappear from the file?

A    No, the supplemental index remains in the file until you
     perform a Drop Supplemental Index operation.

*********************************************
NetWare SQL (NLM) v3.0

Q    When I received NetWare SQL v3.0, I was surprised to find a
     NetWare Btrieve v5.15 diskette in the package. Why was this
     diskette included?

A    The NetWare Btrieve (NLM) v5.15 diskette is always shipped
     with NetWare v3.11, and since NetWare SQL v3.0 (20+ user)
     packages include a copy of NetWare Runtime, they also include
     a NetWare Btrieve (NLM) v5.15 diskette. This should not be
     used on the NetWare Runtime server; you should use the NetWare
     SQL v3.0 install utility to load NetWare Btrieve v6.0.

Q    Does NetWare SQL (NLM) v3.0 support Lotus 1-2-3 for Windows
     at this time?

A    No, there is currently no interface for Lotus 1-2-3 for
     Windows.

*********************************************
Xtrieve PLUS for DOS v4.10

Q    If I install Xtrieve PLUS for DOS v4.10 on a network, will the
     license agreement be violated if more than one person uses it?

A    No. Xtrieve PLUS 4.10 is licensed per server. Everyone who has
     access to the server where Xtrieve PLUS resides can use it
     without violating the license.




*********************************************
*********************************************
NOVELL EDUCATION
*********************************************
*********************************************

Novell Education is now offering several new and updated courses
for developers who use Novell's development and database tools,
including Btrieve, Xtrieve PLUS, and the NetWare Client APIs.

*********************************************
904: Btrieve: An Overview

This new course provides a general overview of Btrieve and its new
features. Covers file structures, indexing, data integrity, record
and file locking, caching, operating modes, segmented keys,
backward compatibility and utilities.

Aug. 11   Sunnyvale, CA
Sept. 15  Chicago, IL

*********************************************
905: Programming with Btrieve

This course has been enhanced to cover all Btrieve operations &
environments, including COBOL. Provides a complete introduction to
Novell's server-based record manager. 50% of class time is spent
in programming workshops. Working knowledge of C, BASIC, Pascal,
or COBOL required. Prerequisite: 904: Btrieve: An Overview

Aug. 1214          Sunnyvale, CA
Sept. 1618    Chicago, IL

*********************************************
907: Xtrieve PLUS

This course has been updated to include new features introduced
with NetWare SQL v3.0. Teaches application developers to use
Xtrieve PLUS as a Btrieve or NetWare SQL programming utility.
Trains users of Btrieve- or NetWare SQL-based database applications
to work effectively with this menu driven utility.

Sept. 2223    Austin, TX

*********************************************
930: Developing NetWare Loadable Modules (NLMs)

This course introduces C programmers to server-based application
development in the 32-bit NetWare 3.x environment. Covers basic
concepts for writing server-based C applications that access the
NetWare 3.x C library (CLib). Requires working knowledge of the C
language.

Sept. 1517    Austin, TX

*********************************************
940: NetWare Client Programming: NWCALLS

This new lab-oriented course (40% lab work) introduces network
programming concepts and topics like bindery services, file system
services, print services, queue management, connection and file
server services and accounting and synchronization services.
Requires knowledge of the C programming language.

Sept. 2224    Provo, UT
Oct. 1315          Chicago, IL

*********************************************
945: NetWare Client Programming: Protocol Support

This new course covers Protocol Support features. Covers network
programming concepts and techniques for developing client-side
applications, including SAP, IPX/SPX, diagnostics, NetBIOS
emulation, TLI, & Named Pipes. Requires strong knowledge of C
programming language.

Sept. 1517    Austin, TX
Oct. 2021          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-NETWARE. International customers should
call 1-801-429-5508. For information on availability, location, and
prices of international classes, contact your local Novell office.




*********************************************
*********************************************
FUN & FACTS
*********************************************
*********************************************

Test your "developing" skills by taking our Fun & Facts quiz. Have
fun and good luck! (See the end of this section for answers.)

1.   Which of the following statements is true of BREBUILD.NLM?

     A.   It allows you to redirect the file to another server
     B.   It keeps a copy of the file in 5.x format
     C.   It preserves the owner name after the conversion

2.   How many NLMs work together to provide communication services
     to the NetWare v3.11 operating system?

     A.   8
     B.   7
     C.   6

3.   What Btrieve data type does not exist in Xtrieve PLUS?

     A.   Bit
     B.   Unsigned Binary
     C.   Money

4.   What module standardizes and manages the primary details of
     interfacing ODI multi-link interface drivers to the LSL and
     the NetWare operating system?

     A.   MSM.NLM
     B.   HSM.NLM
     C.   TSM.NLM

5.   What DDF file contains information about referential integrity
     constraints?

     A.   VIEW.DDF
     B.   FILE.DDF
     C.   RELATE.DDF

6.   What NLM allows you to use connection encapsulating IPX
     packets within IP packets?

     A.   SNMP.NLM
     B.   TCPIP.NLM
     C.   IPTUNNEL.NLM

7.   How do you initialize Btrieve for OS/2 (client-only version)
     within an application?

     A.   Cannot be initialized through an application
     B.   Use function BTRVINIT(char *)
     C.   Use function WBTRINIT(char *)

8.   Name the socket number for the Diagnostic Packet

     A.   0x454
     B.   0x455
     C.   0x456

9.   What console command is used to address memory above 16 MB on
     EISA computers ?

     A.   None
     B.   Register Memory
     C.   Auto Register Memory Above 16 Meg




*********************************************
*********************************************
FUN & FACTS ANSWERS
*********************************************
*********************************************

1.   C
2.   A
3.   B
4.   A
5.   C
6.   C
7.   B
8.   C
9.   A




*********************************************
*********************************************
CURRENT VERSIONS OF NOVELL PRODUCTS
*********************************************
*********************************************

NetWare

     NetWare 3.x                             3.11
     NetWare 2.x                             2.2
     NetWare Lite                            1.0
     NetWare for VMS                         2.1

NetWare Services

     NetWare for Macintosh                   3.01
     NetWare NFS                             1.2
     NetWare FTAM                            1.2
     NetWare for SAA                         1.1
     NetWare RMS                             n/a
     NetWare NNS                             n/a

Communication Toolkits

     LAN WorkPlace Toolkit for DOS           4.01

NetWare System Interfaces

     NetWare C Interface for DOS             1.2
     NetWare System Calls for DOS            1.0
     NetWare System Interface
     Technical Overview                      1.2

Software Developer's Kits

     OS/2 Developer's Kit                    2.0
     NetWare C Interface for Windows         1.3
     NetWare C Interface for Macintosh       1.3
     NetWare Network Management Toolkit      1.1
     LAN WorkPlace Toolkit for OS/2          2.0
     Network C for NLMs                      2.0 (d)
     NetWare TIRPC for DOS and NLMs          1.0
     NetWare AppleTalk Interface for NLMs    1.0
     NetWare for SAA LU6.2 Tools             1.2
     NetWare 3270 Tools                      1.6
     NetWare Management System (Windows)     1.0

NetWare RPC

     NetWare RPC for DOS                     1.1
     NetWare RPC 386                         1.1

Compiler Toolkits

     Network C for DOS                       2.0

XQL

     XQL for DOS                             2.11
     XQL for OS/2                            2.11

NetWare SQL

     NetWare SQL (NLM)                       3.0
     NetWare SQL (VAP)                       2.11

Btrieve

     NetWare Btrieve (NLM)                   5.15
     NetWare Btrieve (VAP)                   5.15
     Btrieve for DOS                         5.10a
     Btrieve for OS/2                        5.10
     Btrieve for Windows                     5.10

Xtrieve PLUS

     Xtrieve PLUS for DOS                    4.10
     Xtrieve PLUS for OS/2                   4.01

Report Executive

     Report Executive for DOS                4.01a
     Report Executive for OS/2               4.01a

For a complete list of the Novell product line contact Novell
Austin or your local Novell Authorized dealer.




*********************************************
*********************************************
CURRENT REQUESTER VERSIONS
*********************************************
*********************************************

NetWare Btrieve v5.15

     Requester for DOS                       5.16
     Requester for OS/2                      5.17a
     Requester Interface for Windows 3.0     5.17a

NetWare SQL                                  VAP       NLM

     Requester for DOS                       2.12a     3.0
     Requester for OS/2                      2.11      3.0
     Requester Interface for Windows 3.0     2.13      3.0

NetWare Shells and Requesters

     DOS Shell                                    3.26
     IPX (DOS)                                    3.10
     VIPX.386                                     1.11
     NetWare Requester for OS/2                   2.0
     NETWARE.DRV (Windows)                        1.03.7
     VNETWARE.386 (Windows)                       1.03.2




*********************************************
*********************************************
CONTACTING NOVELL AUSTIN
*********************************************
*********************************************

To obtain technical support, call 1-800-NETWARE (1-800-638-9273),
or 1-801-429-5588. Be prepared to give the support operator your
open incident reference number. Technical support questions may
also be sent by FAX to 1-512-794-1775.

Many international distributors provide technical support. Please
contact your distributor or local Novell office (see list on back
cover) for more information on internation-al support options.

Software patches may be obtained from Novell's NetWire forum on
CompuServe (NOVLIB, LIB 7), or by contacting the Developer Support
Group and specifying the patches you need by product name.

Novell database and development products can be obtained through
Novell Authorized Resellers, or by calling 1-800-RED-WORD
(1-800-733-9673) or 1-512-794-1796.

Software Developer's Kits (SDKs) are available only through
Novell's Professional Developers' Program Call 1-800-RED-WORD
(1-800-733-9673) or 1-512-794-1796.

For more information on Novell's Professional Developers' Program
and Novell development products, call 1-800-RED-WORD
(1-800-733-9673), or 1-512-794-1796, FAX 1-512-794-1770, or contact
the nearest Novell office.




*********************************************
*********************************************
ACKNOWLEDGEMENTS
*********************************************
*********************************************

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

Contributors:  Gaurang Amin,
               Linda Anderson,
               Vitek Boruvka,
               Irit Diaz,
               Neda Eslami,
               Kumar Gaddam,
               David Harris,
               Sudz Khawaja,
               Ken Lowrie,
               Diane Klinetob,
               Nancy Kromar,
               Rudy McNeese,
               Chris Ojeda,
               Paige Parker,
               Jose Pruneda,
               Randy Reddy,
               Glenn Stephens,
               Brenda Wallace

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

(c) 1992 Novell, Inc. All rights reserved.

*********************************************

Novell, the N design, NetWare, Btrieve, XQL and LAN WorkPlace are
registered trademarks, NetWare Lite, 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, NetWare LU6.2,
Report Executive, and Professional Development Series (PDS) are
trademarks, and NetWire 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 and 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.

*********************************************

Developer Support:
1-800-NETWARE (1-800-638-9273)
Tel. (801) 429-5588
FAX  (512) 794-1775

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

*********************************************

Novell, Inc.
Corporate Headquarters
Brazil, India, Pakistan Sales Office
122 East 1700 South
Provo, Utah 84606 USA
Tel.  (801) 429-7000
FAX   (801) 429-3944

*********************************************

Novell International Headquarters
2180 Fortune Drive
San Jose, CA 95131 USA
Tel.  (408) 434-2300
FAX   (408) 434-8697

*********************************************

Novell Australia
Level 2
2 Help Street
Chatswood NSW 2067
AUSTRALIA
Tel.  61 (2) 413-3077
FAX   61 (2) 413-3116

*********************************************

Novell Benelux
Excelsiorlaan 13
1930 Zaventem
BELGIUM
Tel.  32 (2) 725-02-00
FAX   32 (2) 725-03-11

*********************************************

Novell France
Tour Anjou
33, Quai De Dion-Bouton
92814 Puteaux Cedex
FRANCE
Tel.  33 (1) 4775-0909
FAX   33 (1) 4778-9472

*********************************************

Novell Germany
Willsttter Strasse 13
4000 Dsseldorf 11
GERMANY
Tel.  49 (211) 5973-0
FAX   49 (211) 5973-250

*********************************************

Novell Hong Kong
China Resources Bldg.
26 Harbour Rd., Room 4601-5
Wanchai
HONG KONG
Tel.  852 8272223
FAX   852 8276555

*********************************************

Novell Latin America
890 Ross Drive
Sunnyvale, CA 94089
USA
Tel.  (408) 747-4000
FAX   (408) 747-4940

*********************************************

Novell Italy
Via San Vittore 40
20123 Milan
ITALY
Tel.  39-2-4801 3554
FAX   39-2-4801 3594

*********************************************

Novell Japan
Toei Mishuku Bldg.3F
1-13-1 Mishuku
Setagaya-ku, Tokyo 154
JAPAN
Tel.  81 (3) 5481-1161
FAX   81 (3) 5481-1855

*********************************************

Novell Spain
Paseo Castellana, 40bis
28046 Madrid
SPAIN
Tel.  34 (1) 577-4941
FAX   34 (1) 577-9053

*********************************************

Novell Sweden
Kottbyjatan 7
16475 Kista
SWEDEN
Tel.  46 (8)-703 2350
FAX   46 (8)-703 9434

*********************************************

Novell Switzerland
Bahnstrasse 102
8105 Regensdorf
SWITZERLAND
Tel.  41 (1) 870-0650
FAX   41 (1) 870-0628

*********************************************

Novell United Kingdom
Avon House, Sweetwell Road
Bracknell, Berkshire
RG12 1HH
UNITED KINGDOM
Tel.  44 (344) 860 400
FAX   44 (344) 860 353

*********************************************
Professional Development Series
B  U  L  L  E  T  S
JULY 1992
END OF FILE
*********************************************
