*********************************************
*********************************************
Professional Development Series
B  U  L  L  E  T  S
*********************************************
August/September 1992
Volume 4, Number 8
*********************************************
*********************************************


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

Hello and welcome to the August/September 1992 issue of Bullets!


It is my belief that the Novell developer is breaking away
--breaking away from the single-platform application. More and more
developers are expanding applications to include more than one
platform of choice. Two years ago, how many developers were
seriously writing to DOS and the Windows, OS/2 or NetWare Server
(NLM) platforms? From watching the class and type of logged new
incident calls to Developer Support, I see this trend becoming the
norm.

I'm sure you have noticed the survey encasing this month's Bullets.
In the next couple of months you may receive multiple surveys from
Novell. Some of the questions may seem esoteric in nature, but
we're looking to our customers for insight for planning our budgets
and strategic commitments for Fiscal Year 1993.

If you have ever heard Ray Norda speak, somewhere in his message
were the words "Customer driven and loving it" --a powerful message
and directive for Novell Support/Services. A colleague from
Sunnyvale, Kraig Ellis, recently added the twist: "Customer loving
and driving it." As a support provider, Kraig knows that
implementation is nine-tenths of the directive. Every member of the
Novell Support/Services organization is now driving this directive,
breaking-away to keep our support teams on the developing edge.

Happy_Programming!

Mad Poarch
Director
Developer Support/Service


*********************************************
*********************************************
ARTICLE:
NLMs: From "Hello World" to World-Class Computing (Part III)
*********************************************
*********************************************

In the April 1992 issue of Bullets, "NLMs: From 'Hello World' to
World-Class Computing (Part I)", Bullets investigated the design
and function of the communication protocol (CP) layer of a
distributed application. Part II of this article (Bullets, May
1992) examined the three remaining software components of a
distributed application: the distributed application protocol (DAP)
layer, and the client and server portions of the distributed
application (Figure 1 contains an illustration of these four
components). To illustrate optimal distributed application design,
Part I and II examined the design of a sample distributed
application called DAX, an example built upon the IPX protocol. The
latest version of the DAX example program is available on NetWire,
Novell's CompuServe forum (NOVLIB, LIB 1, DAX1.ZIP).

*********************************************
Figure 1: Components of a Distributed Application

         SERVER                             CLIENT
____________________________________________________________
   Server Application                 Client Application
           |                                  |
 Distributed Application            Distributed Application
      Protocol (DAP)                     Protocol (DAP)
           |                                  |
 Communication Protocol             Communication Protocol
           |                                  |
   Communication Media                Communication Media
____________________________________________________________

End of Figure 1
*********************************************

This month, Part III will examine the procedure for porting client
code to a different platform, specifically the Microsoft Windows
environment. Part III will discuss the programming tools needed for
the port, look at the changes that must be made for the DAX example
program to support the Windows environment, and outline all of the
components needed to create NetWare-Aware applications for the
Windows v3.0 and v3.1 platforms.


Required Novell Programming Components

The Novell programming components you need to write NetWare-Aware
Windows applications are:

*    The NetWare C Interface for Windows v1.22 or later (v1.3 if you
     are using Windows v3.1)

*    Novell's Windows Workstation Kit, which contains all the
     components you need to run a Windows workstation on NetWare.

See the sidebar on commonly asked questions for more information
on required components.

*********************************************
SIDEBAR:
Windows Application Development:
Common Questions

-----------------------------------------------------------

Q:   What version of IPX and the SHELL should I use?

A:   IPX.COM v3.10 or higher; NETX.COM v3.26 or higher;
     IPXODI.COM v1.20 or higher. Download DOSUP5.ZIP from
     NOVLIB LIB 5 to get these files.

-----------------------------------------------------------

Q:   Where do I get the latest versions of VNETWARE.386,
     NETWARE.DRV and VIPX.386?

A:   For Windows v3.1, use the drivers that came with Windows v3.1.
     The drivers for Windows v3.0 are available on NetWire in
     either WINUP6.ZIP (NOVLIB, LIB 5) or W30DRV.ZIP (NOVDEV, LIB
     10).

-----------------------------------------------------------

Q:   What do I need to run in Enhanced mode?

A:   Windows will load the VIPX.386 in your SYSTEM.INI under the
     section [386Enh]. Make sure that you use the latest version
     of VIPX.386.

-----------------------------------------------------------

Q:   What is the difference between VNETWARE.386 and VIPX.386?

A:   VIPX.386 is the enhanced mode, virtual IPX driver.
     VNETWARE.386 is the enhanced mode, virtual NetWare Shell
     driver.

-----------------------------------------------------------

Q:   What DLLs should I use?

A:   The NetWare C Interface for Windows v1.22 DLLs may not
     support Windows v3.1. For compatibility with both Windows
     v3.0 and Windows v3.1, use the DLLs that come with the
     NetWare C Interface for Windows v1.3.

-----------------------------------------------------------

Q:   I don't have a CompuServe account, and I need the latest
     NetWare shells and drivers for Windows. Where can I get them?


A:   Contact your local Novell office or, in the US, call
     1-800-UPDATE1 to order the documentation and disks.

-----------------------------------------------------------

Q:   What should I do with an old program built with the NetWare
     C Interface for Windows SDK 1.22?

A:   You may need to rebuild these programs and give your
     clients new copies of the applications and v1.3 of
     Novell's Windows DLLs. Most applications will only need
     to be relinked.

-----------------------------------------------------------

Q:   When running Windows v3.0a, I get the message "Can't find
     NETWARE.DLL". How can I obtain this driver?

A:   NETWARE.DLL is the same thing as NETWARE.DRV. Place
     NETWARE.DRV in the proper path and Windows will find it.

-----------------------------------------------------------

END OF SIDEBAR
*********************************************

Other Programming Tools

Creating Windows applications requires a compiler and linker that
support the Windows environment and the Microsoft Windows Software
Developer's Kit (SDK). The DAX example was compiled with Borland's
C++ v3.0 compiler, because this compiler has everything you need
to build Windows applications, including the necessary components
of the Microsoft Windows SDK. Since the DAX client code is not GUI
(Graphic User Interface) compatible, the EasyWin library support
for STDIO and CONIO APIs in the Borland C++ compiler simplifies
porting the application to Windows. EasyWin maps library functions
such as printf() and scanf() to Windows GUI calls. This library
frees you from having to use the Windows GUI API.


Porting the DAX Code

When you have all of the programming components needed to write/run
NetWare-Aware applications under Windows, you are ready to modify
the DAX example and port it to the Windows environment. DAX, by
design, is very modular, minimizing the changes required to each
software layer for the port. The communication protocol layer
requires the most extensive changes, followed by the DAP Layer.
Barring a change in the user interface, the client application
should not require any modifications at all. Finally, the engine
won't require any changes to support the new client.

Remember that the DAX client application is made up of three
separate components:

*    CP.LIB - library of Communication Protocol APIs

*    DAP.LIB - library of Distributed Application Protocol APIs

*    xxx.OBJ - client application object modules (e.g., STRESS.OBJ,
     INOUT.OBJ)

The libraries will be created using the command line compiler (as
opposed to Borland's Integrated Development Environment (IDE)). To
maintain compatibility with the DOS and NLM client code, use the
WATCOM WMAKE MAKEFILE format to create both the CP and DAP static
libraries.

To set up your environment to run Borland's C++ command line
compiler, you will need a TURBOC.CFG file that contains the INCLUDE
and LIBRARY paths needed for compiling. This file is created from
within the MAKEFILE to ensure that the correct system paths are
used (see the README.1ST file included with the DAXn.ZIP file for
a discussion on MAKEINIT). For the client software, you can use
Borland's IDE to create the application. The project and desktop
files have been included in the corresponding WIN directories to
simplify the setup process.


Porting the CP Layer

A quick review of the code in the client portion of the CP layer
reveals that you will need to make the following changes to port
the source code to the Windows v3.0 or v3.1 environment:

*    Define a Manifest Constant

*    Generate a Windows version of HELPER.H header file

*    Include the WINDOWS.H header file

*    Add a parameter called TASKID to all IPX APIs

To begin, you need a manifest constant that will be used to isolate
the code that is specific to Windows. In this example, the constant
WINCLIENT was chosen to maintain consistency with the other
environments. As in the DOS and NLM environments, you define the
WINCLIENT constant in the header file, "HELPER.H." Review current
platform specific code within the source to locate the code
fragments that need to be specific to Windows. In other words,
search for all occurrences of DOSCLIENT or NLMCLIENT, then make the
determination which code fragment is correct for Windows. If
neither code fragment is correct, then a Windows specific fragment
will be required.

For example, the module CPSEND.C contains an API, CPInitSendPacket,
which contains some platform specific code for DOS and NLMs.

#if defined(DOSCLIENT)
    packet->destination =
    *destination;
#elif defined(NLMCLIENT)
    *(IPXAddress *)&packet->destNet
    = *destination;
#endif

If you examine this code, you will see that the Windows environment
will require the same statement needed for the DOS environment, so
the following change was made:

#if defined(DOSCLIENT) ||
    defined(WINCLIENT)
    packet->destination =
    *destination;
#elif defined(NLMCLIENT)
    *(IPXAddress *)&packet->destNet
    = *destination;
#endif

You must also include the WINDOWS.H header file. To do this, add
the code to a common header file (or the source file if the common
header file is not specifically referenced) using the following
code fragment:

#if defined(WINCLIENT)
    #include <windows.h>
#endif

This "include" statement will include the necessary information for
building a Windows application. WINDOWS.H is normally supplied with
the Windows SDK, but some compilers which support Windows
development include this header file as part of their environment.
For example, Borland C++ includes the WINDOWS.H header file. For
the CP Layer, add this code fragment to the CPC.H header file.
CPC.H is included by all of the modules that make up the client
portion of the CP layer.

Supporting IPX under Windows is similar to supporting IPX in the
DOS environment; there are only a few minor coding differences.
First, an additional parameter, TASKID, is required for each of the
APIs. TASKID contains a virtualized identifier that the NetWare
DLLs use to track resources in use by a given IPX application. The
TASKID parameter is returned by the initialization API called
IpxInitialize(), and is subsequently used on all API calls to IPX.
Using HELPER.H and macros for the IPX APIs, you can completely hide
the TASKID parameter from the example program (See Figure 4 below).


The second requirement that is unique to the Windows environment
is a special API named IPXDeInitialize that must be called prior
to terminating the Windows client application (see Figure 2). This
API frees the resources allocated to the client when
IPXInitialize() is called. Again, this concept is unique to
Windows, and is not required for either the DOS or NLM
environments.

*********************************************
Figure 2: Deinitializing IPX in Windows

void    CPDeInitialize(CPDATA *CPid)
{
    if( CPid ){
        if( CPid->skt ) IPXCloseSocket(CPid->skt);
        CPDeInitializeRecvLogic(CPid);   // Clean up receive logic

        CPDeInitializeSendLogic(CPid);   // Clean up send logic
        CPDeInitializeConnLogic(CPid);   // Tear down the conn.
        memset(CPid,NULL,sizeof *CPid);
        #if defined(WINCLIENT)           // Only Windows clients

            IPXDeInitialize();           //   need to shutdown IPX

        #endif                           //
        #if defined(DYNAMICMEM)
            free(CPid);                  // Free client memory
        #endif
    }
}

End of Figure 2
*********************************************

So far, we have been very successful hiding platform specific
differences of the IPX API set in the file HELPER.H, and this
difference should not be an exception. IPXDeInitialize should be
written as a macro which expands to nothing in both the DOS and NLM
versions of HELPER.H. Figure 3 shows the final version of the
CPDeInitialize API. Figure 4 contains the macro definition of
IPXDeInitialize for Windows.

*********************************************
Figure 3: Hiding the IPXDeInitialize API

void    CPDeInitialize(CPDATA *CPid)
{
  if( CPid ){
      if( CPid->skt ) IPXCloseSocket(CPid->skt);
      CPDeInitializeRecvLogic(CPid);
      CPDeInitializeSendLogic(CPid);
      CPDeInitializeConnLogic(CPid);
      memset(CPid,NULL,sizeof *CPid);
      IPXDeInitialize();      // only calls shutdown if WIN client

      #if defined(DYNAMICMEM) // expands only for WIN clients
            free(CPid);
        #endif
    }
}

End of Figure 3
*********************************************

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

Figure 4: Windows version of the HELPER.H header file

#include <nxt.h>
#include <nit.h>

#define  WINCLIENT
#define  LONG_LIVED      (0xFF)
#define  SHORT_LIVED     LONG_LIVED

#define  ECBISINUSE(ecbp)         ((ecbp)->inUseFlag)
#define  INUSEFLAG(ecbp)          ((ecbp)->inUseFlag)
#define  COMPLETIONCODE(ecbp)     ((ecbp)->completionCode)
#define  ECBSOCKET(ecbp)          ((ecbp)->socketNumber)
#define  ECBFRAGCOUNT(ecbp)       ((ecbp)->fragmentCount)
#define  ECBFRAGADDR(ecbp,x)
((ecbp)->fragmentDescriptor[x].address)
#define  ECBFRAGSIZE(ecbp,x)      ((ecbp)->fragmentDescriptor[x].size)
#define  IPXDESTNETP(ipxp)        ((ipxp).network)
#define  IPXDESTNODEP(ipxp)       ((ipxp).node)
#define  IPXDESTSOCKETP(ipxp)     ((ipxp).socket)

extern   DWORD   _TASKID;
#define  MAXECBS     10
#define  MAXSIZE     576

#define  IPXReceive(ecbp)         IPXListenForPacket(_TASKID,ecbp)
#define  IPXSend(ecbp)            IPXSendPacket(_TASKID,ecbp)
#define  IPXInitialize()
(IPXInitialize)(&_TASKID,MAXECBS,MAXSIZE)
#define  IPXOpenSocket(skt,typ)   (IPXOpenSocket)(_TASKID,(WORD
*)skt,type)
#define  IPXCloseSocket(skt)      (IPXCloseSocket)(_TASKID,skt)
define   IPXCancelEvent(ecb)      (IPXCancelEvent)(_TASKID,ecb)
#define  IPXGetIntervalMarker()   (IPXGetIntervalMarker)(_TASKID)
#define  IPXGetLocalTarget(x,y,z) (IPXGetLocalTarget)(_TASKID,x,y,z)
#define  IPXDeInitialize()        (IPXSPXDeinit)(_TASKID)

End of Figure 4
*********************************************

No other changes to the CP layer are required to support Windows. Most
of the modifications can be hidden from the source code using  macros
defined in the HELPER.H macro file. This method keeps the source code
relatively clean and easy to read.


DAP Port

The changes to the DAP layer are very minimal, since this code simply
defines and implements the protocol between the client and server
applications. When porting this type of code between client platforms,
differences between items such as data type sizes (i.e., DOS "int" size
vs. Windows "int" size) must be resolved to maintain consistency. As
described in Part I and Part II of this article, the DAX example was
written to allow portability, so it already contains design provisions
for issues of this kind in the source code. When examining the code,
notice that data type sizes have been masked with typedefs like UINT16
and UINT32 for unsigned integer 16 bits and unsigned integer 32 bits,
respectively.

One change required to port the DAP layer to Windows is the inclusion
of the WINDOWS.H header file. For this layer, you can include this file
from DAPSYS.H, a header file included by all modules in the DAP Layer.


Finally, an API called delay() has been added to the module DAPSEND.C,
since there is no corresponding Windows API available in the Borland
environment. In this implementation, you do not need to be too concerned
over the accuracy of delay() (i.e., it does not need to delay for
exactly the number of milliseconds specified). This API is used by the
DAPSendRequest API while waiting for the application server to finish
servicing its request. You may notice that the example uses IPXYield()
rather than IPXRelinquishControl( ); IPXYield( ) truly yields control
back to Windows while IPXRelinquishControl( ) yields to the LAN driver.
You will find IPXYield( ) in the NetWare C Interface for Windows SDK
v1.3 in IPXYIELD.C.


The Client Application

Porting the client application requires very few changes to the client
code. As previously mentioned, with Borland's EasyWin library, no
Windows-specific code is required (i.e., you can use the printf()
version of the client code). Once again, you must include the header
file, WINDOWS.H, and since you are using Borland's IDE, you should
create a project file for each client example. Next, create a module
definition file for the linker. This file defines the requirements of
your Windows application. In the example, you might notice that both the
CODE and DATA segments are marked as "fixed;" they cannot be moved
around in memory.

As described here, porting the DAX example program to the Windows
environment is very straightforward, since no complicated user interface
is required. As with any GUI environment, the user interface is always
a primary consideration in an application porting process. After
examining the changes made to support the Windows environment, you
should be able to port the DAX example and other distributed
applications which follow a similar design philosophy to other
environments with a minimum of difficulty.



*********************************************
*********************************************
TECHNICAL INSIGHTS:
Multiple VIEW.DDFs
NetWare SQL v3.0
*********************************************
*********************************************

In the past, some NetWare SQL users set up multiple VIEW.DDF files for
a set of DDF files, so that each user could have their own views stored
exclusive of other users. With the introduction of named databases in
NetWare SQL v3.0, you can no longer create multiple VIEW.DDF files for
a set of dictionaries.

When you create a named database with NDBSETUP, only one path can be
specified for a set of DDF files. Therefore, it is not possible to
specify multiple paths for different VIEW.DDF files relating to the
field, file, and index DDFs for the named database.



*********************************************
*********************************************
TECHNICAL INSIGHTS:
NetWare SQL Documentation Correction
NetWare SQL v3.0
*********************************************
*********************************************

XQLLOCAL.DLL provides local processing for a small set of NetWare SQL
data conversion functions that can be performed either at the client or
the server. When the DLL is available, these functions can be performed
at the client, improving processing performance. If XQLLOCAL.DLL is not
available, the data conversion requests will be performed at the server
instead. The application will see no difference in functionality, only
performance. This relationship is similar to that of the two NetWare SQL
requesters available for DOS clients: NSREQ.EXE and NSREQS.EXE.

The NetWare SQL v3.0 Installation and Operation manual incorrectly
describes the use of the XQLLOCAL.DLL file for OS/2 workstations. On
page 2-44, the manual states:

     "XQLLOCAL.DLL provides support for data that resides on the local
     hard drive. An application at an OS/2 workstation cannot access
     local files using the requester alone."

A NetWare SQL application can not access files located on a local hard
drive. Since NetWare SQL utilizes NetWare Btrieve, the server-based
version of the Btrieve record manager, for all file I/O, the data files
must be located on the server for NetWare Btrieve to access them.



*********************************************
*********************************************
TECHNICAL INSIGHTS:
Extended Attributes Return Values Not Documented
Network C for NLMs v2.0(b)
*********************************************
*********************************************

The advanced services functions which deal with extended attributes
(EnumerateEA(), for example) can return values that are not documented.
The possible return values are shown in Figure 5.

*********************************************
Figure 5: Possible return codes for extended attribute functions

ERR_MISSING_EA_KEY                 200
ERR_EA_NOT_FOUND                   201
ERR_INVALID_EA_HANDLE_TYPE         202
ERR_EA_NO_KEY_NO_DATA              203
ERR_EA_NUMBER_MISMATCH             204
ERR_EXTENT_NUMBER_OUT_OF_RANGE     205
ERR_EA_BAD_DIR_NUM                 206
ERR_INVALID_EA_HANDLE              207
ERR_EA_POSITION_OUT_OF_RANGE       208
ERR_EA_ACCESS_DENIED               209
ERR_DATA_PAGE_ODD_SIZE             210
ERR_EA_VOLUME_NOT_MOUNTED          211
ERR_BAD_PAGE_BOUNDARY              212
ERR_INSPECT_FAILURE                213
ERR_EA_ALREADY_CLAIMED             214
ERR_ODD_BUFFER_SIZE                215
ERR_NO_SCORECARDS                  216
ERR_BAD_EDS_SIGNATURE              217
ERR_EA_SPACE_LIMIT                 218
ERR_EA_KEY_CORRUPT                 219
ERR_EA_KEY_LIMIT                   220
ERR_TALLY_CORRUPT                  221

End of Figure 5
*********************************************



*********************************************
*********************************************
TECHNICAL INSIGHTS:
Status 84 and Insert Operations
NetWare Btrieve (NLM) v6.0
*********************************************
*********************************************

A status 84 (Record in Use) is a valid status code on an Insert
operation. Insert operations occasionally return this status code when
a stress test is conducted with several PCs. NetWare Btrieve returns
this status code because it is locking the key page for a brief period
of time to update key information. At this time, if a user tries to
insert records that are indirectly accessing the key page, the Insert
operation will result in a status 84.

To avoid this situation, design your applications to trap for status 84s
and retry the Insert operation.



*********************************************
*********************************************
TECHNICAL INSIGHTS:
Print Server Printer Status Codes
NetWare C Interface for DOS v1.2
*********************************************
*********************************************

The NetWare C Interface for DOS v1.2 does not document the meaning of
the states of the status byte returned by PSGetPrinterStatus. The values
for these states are defined in the NPT.H header file. The meaning of
each state is defined below.

*    PSTAT_WAITING_FOR_JOB indicates that the printer is available and
     ready for a print job.

*    PSTAT_WAITING_FOR_FORM indicates that the printer is waiting for
     a new form to be mounted.

*    PSTAT_PRINTING_JOB indicates that the printer is currently printing
     a print job.

*    PSTAT_PAUSED indicates that the printer has been paused and
     will continue to print the active job when started.

*    PSTAT_STOPPED indicates that the printer has been stopped and the
     current job aborted. When the printer is started it will begin to
     look for another job to print.

*    PSTAT_MARK_EJECT indicates that someone has paused or stopped
     the printer and sent a mark top of form or a page eject. The
     print is in the state of executing the request.

*    PSTAT_READY_TO_GO_DOWN does indicate that the printer has
     finished printing any currently active job and is ready to go
     down.

*    PSTAT_NOT_CONNECTED indicates the printer is not currently
     connected to the print server.

*    PSTAT_PRIVATE indicates that a remote printer is not currently
     available as a network printer. This happens when a command
     is sent to the print server telling it to release the printer.




*********************************************
*********************************************
TECHNICAL INSIGHTS:
Diagnostic Functions Not Returning Data
NetWare C Interface for Windows v1.3
*********************************************
*********************************************

Diagnostic functions that use the NWmemmove function in the module
NWSTRING.C do not return all of the data expected within the structure.
To ensure that all expected data is updated in the structures, make the
source code changes outlined in Figure 6. Then, recreate the DLL with
the .OBJ files and MAKEFILE provided with the NetWare C Interface for
Windows.

*********************************************
Figure 6: Modifications to NetWare C Interface for DOS

~
~
~
void FAR * FAR PASCAL NWMemmove( char far *toBlock,
                                 char far *fromBlock,
                                 unsigned int len )
   {
   WORD  i;                            // This was a BYTE.

   if( fromBlock == toBlock )
      {
      return( toBlock );
      }
   for( i = 0; i < len; i++ )          // len was cast to a BYTE
      *(toBlock + i) = *(fromBlock + i);

   return( toBlock );
   }
~
~
~
End of Figure 6
*********************************************



*********************************************
*********************************************
TECHNICAL INSIGHTS:
Storing and Recalling Views
NetWare SQL v3.0
*********************************************
*********************************************

If a view is stored in Xtrieve PLUS v4.11, a component of NetWare SQL
v3.0, it cannot be recalled using XQLP v2.11 or NetWare SQL v2.11. If
you attempt to do so, Xtrieve PLUS will return a status 253 (incorrect
version of view definition). However, NetWare SQL v3.0 is able to recall
views that are stored by XQL/NetWare SQL v2.11.



*********************************************
*********************************************
TECHNICAL INSIGHTS:
NetWare Runtime, NetWare SQL v3.0 & Applications
NetWare SQL v3.0
*********************************************
*********************************************

NetWare Runtime allows you to run NetWare SQL applications in a
dedicated database environment. It is provided with every copy of
NetWare SQL v3.0 with a user count of 20 or above. NetWare Runtime only
allows one NetWare connection/login to the server. This connection is
intended for administrative purposes, and is generally used by the
supervisor in order to perform maintenance on the server. Since NetWare
SQL does not require users to have a NetWare connection to the server
to access NetWare SQL, this environment can be used for multiuser access
to NetWare SQL applications.

Two restrictions for running database applications on a NetWare Runtime
server are briefly described in the NetWare SQL v3.0 Installation and
Operation manual on page 2-38.

First, a NetWare Runtime server can not accept direct Btrieve calls from
an application. Although NetWare SQL does not require a NetWare
connection, NetWare Btrieve does. Therefore, an application which makes
only Btrieve calls, or makes both Btrieve and NetWare SQL calls can not
be run against files on a NetWare Runtime server.

The second restriction is that the application must use a named
database. Since users do not have a connection, they cannot access data
dictionaries and data files via drive mappings. A named database must
be defined on the NetWare Runtime server using the NetWare SQL Setup
Utility, thus indicating which directories contain the database files
and dictionaries. The application can then use this database name to
login to NetWare SQL and access the data files.

If the application or the data dictionary contains references to drive
mappings, a NetWare SQL Requester Configuration File can be defined to
indicate what directories on the NetWare Runtime server should be used
whenever a particular drive mapping is encountered by the application.
This is described in more detail in the same manual on pages 2-47 and
2-48.



*********************************************
*********************************************
TECHNICAL INSIGHTS:
SubmitAccountCharge API Truncates Comment
NetWare C Interface for DOS v1.2
*********************************************
*********************************************

The SubmitAccountCharge API expects the comment parameter to be a null
terminated string, so it truncates binary data when there is a zero byte
in the buffer. To prevent truncation, change the source code for this
API (in SBTACTCH.C) to accept an 8th parameter (BYTE CommentLen) and
delete the following two lines from within the function:

  BYTE CommentLen;
  .
  .
  .
  CommentLen = MIN(
   (BYTE)(strlen(comment)), 255 );

This change is not necessary for standard accounting charges because
they do not contain binary data. However, custom service types may
require binary data in the comment field.



*********************************************
*********************************************
TECHNICAL INSIGHTS:
Active Named Databases
NetWare SQL v3.0
*********************************************
*********************************************

After you define a named database through NDBSETUP.NLM, NSSPXCOM.NLM may
not advertise that name on the network immediately. NSSPXCOM
periodically checks for changes in DBNAMES.CFG, the file where the
database names are stored. When NSSPXCOM is unloaded and reloaded, it
will immediately begin advertising all defined database names that are
not already being advertised on the network from another server.



*********************************************
*********************************************
TECHNICAL INSIGHTS:
ReturnSpaceRestrictionForDirectory API Returns -1
Network C for NLMs v2.0(c)
*********************************************
*********************************************

The ReturnSpaceRestrictionForDirectory API returns a -1 when used
against a directory which is a subdirectory of a parent on which
restrictions are enforced. The call should return the amount of the
restriction remaining for the directory. Currently, the only workaround
is to scan all levels of a directory tree when searching for
restrictions.



*********************************************
*********************************************
TECHNICAL INSIGHTS:
QueryServices API Returns Invalid Node Address
NetWare C Interface for Windows v1.3
*********************************************
*********************************************

The NetWare C Interface for Windows v1.22 returned the network, node,
and socket in lo-hi format, rather than hi-lo. The correction for this
situation was to reswap the values before passing them to other
functions. Version 1.3 returns the node address in an order that is more
unusual: after swapping to hi-lo order, the last two bytes of the
address (4 and 5) are at the beginning instead of the end. For example,
the following node address,

  00 11 22 33 44 55

would normally be stored in memory in the same byte order. Instead, it
is stored as,

  44 55 00 11 22 33

To correct this situation, add the function below.

  BYTE *FixNode(BYTE *node)
  {
     BYTE temp[2];

     temp[0] = node[5];
     temp[1] = node[4];
     node[5] = node[3];
     node[4] = node[2];
     node[3] = node[1];
     node[2] = node[0];
     node[1] = temp[0];
     node[0] = temp[1];
     return node;
  }

Then, use the following function call:

  FixNode(sapBuffer.Node);

The problem in the source code for QueryServices( ) can also be
corrected by removing the swaps of the network, node, and socket.
However, there is no easy way to replace a single module in a DLL, so
the solution above is preferable.



*********************************************
*********************************************
TECHNICAL INSIGHTS:
Disappearing Attributes
Xtrieve PLUS for DOS v4.10
*********************************************
*********************************************

If several views are active at the same time, XQLP may run out of
buffers and attributes defined in the dictionary may not appear on the
Edit screen. To prevent attributes from disappearing, release any active
views not currently needed, or load XQLP with a larger /b parameter. The
maximum /b value for XQLP v2.11a is 36.



*********************************************
*********************************************
NIBBLES & BITS:
Fast answers to common questions
*********************************************
*********************************************

NetWare SQL

Editor's  In the June issue of Bullets, "Nibbles & Bits" ("NetWare
Note      SQL" heading) incorrectly stated that, with NetWare
          SQL, "there is no quick way to disable Referential
          Integrity (RI)." The original answer should have
          been,

          "There is no quick way to remove RI. Deleting
          RELATE.DDF will not remove RI because there will
          still be an entry in FILE.DDF and the table
          definitions will still contain referential
          constraints. Also, you cannot drop x$Relate from the
          dictionaries.To successfully remove RI, you must
          alter all table definitions."

          There is a fast way to disable Referential
          Integrity. In theNDBSETUP utility the switch,
          "Enable/Disable RI," toggles to set a flag that
          enables or disables RI. Since RI is enforced at the
          NetWare Btrieve level, NetWare Btrieve v6.0 (a
          component of NetWare SQL v3.0) checks this flag
          before doing anything else. When the flag is set to
          "Disable," NetWare Btrieve will not enforce RI, even
          though the constraints still exist.

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

General

     TIP: When compiling an application on NetWare using the
          Microsoft v7.0 C/C++ compiler, set up your search mapping
          to point to the appropriate compiler files, as shown
          below:

          MAP ROOT INS S16:=
          SERVER\VOLUME:C7\BIN

          Without the ROOT keyword, "S16:" will be interpreted by the
          NMAKE utility as "S16:\." The ROOT keyword sets the directory
          as the root, so "S16:" is interpreted as the correct
          directory.

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

NetWare System Calls for DOS

     Q:   How can I increase the maximum number of NetBIOS  names for
          a workstation?

     A:   You can increase the maximum number of NetBIOS names for a
          workstation by using an undocumented SHELL/NET.CFG parameter.
          The syntax is outlined below:

          NETBIOS NAMES=<Number>

          A maximum of 250 names per workstation are possible.

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

NetWare C Interface for DOS

     Q:   I have deleted a file and now I want to determine its size.
          Is there an API that I can call to obtain this information?

     A:   The ScanSalvagableFiles() function returns the size of a
          deleted file in the dataForkSize field. Although this field
          is documented as being for the Macintosh, the size of any file
          can be returned in this field.

     Q:   Why can't I initialize SPX under NetWare Lite?

     A:   By default, NetWare Lite disables SPX and diagnostic
          capabilities of IPXODI. This makes it impossible to run SPX
          and diagnostic applications. To enable these applications,
          remove /A parameter from the IPXODI load line.

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

NetWare C Interface for Windows

     Q:   What are the ordinal numbers for the NetWare APIs?

     A:   When the NetWare C Interface for Windows v1.3 SDK was
          introduced and the DLLs were restructured, the ordinal numbers
          no longer matched those listed in the documentation. You will
          find the correct ordinal numbers in the .DEF files on the
          distribution disks under the \SRC directories. The files are
          NWIPXSPX.DEF (communications, diagnostics and SAP),
          NWNETAPI.DEF (all noncommunication services), and NWPSREV.DEF
          (print server services).

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

Network C for NLMs

     Q:   Does the NLM environment support Named Pipes?

     A:   No. Named Pipes is currently supported on DOS, OS/2 and
          Windows clients only.

     Q:   I opened a file with the name "log," and CLib
          returned a handle, but when I call read( ) with that
          handle, the function blocks and never returns. Why
          is this happening?

     A:   STREAMS is returning the file handle when you pass it this
          filename. CLib calls the STREAMS open API first, and when
          STREAMS returns the handle, CLib links it into your open file
          list and returns it to you. In this situation, you have two
          options.

          *    Avoid passing in lower case names to CLib (i.e., call
               strupr( ) first)

          *    Pass full volume path specifications
               instead (i.e., SYS:LOG)

          Other circumstances may cause similar situations. For example,
          if you pass in "log" with one or more digits after it
          ("log123"), the same thing will occur.

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

NetWare OS/2 Requester

     Q:   Under OS/2, can I have more than eight connections to a file
          server?

     A:   Yes. In the NET.CFG file, you will find a parameter
          called "sessions." If you set this parameter to a
          number between eight and twenty, NetWare will
          support that number of sessions.

     Q:   Can I load NetBIOS if I am using a virtual DOS box under the
          NetWare OS/2 requester v2.0?

     A:   Yes, but only if the NBDAEMON is not loaded in the OS/2
          machine's CONFIG.SYS file. Either load the DOS version or the
          OS/2 version, but never load both versions.

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

Btrieve

     Q:   When I run Btrieve applications in multiple DOS
          sessions from Windows, if I terminate a DOS session
          while Brequest is still loaded, the workstation
          hangs. What should I do?

     A:   This situation is caused by a current limitation of SPX. To
          avoid the problem affecting Brequest, unload Brequest before
          terminating a DOS session.

     Q:   Can BREBUILD rebuild Btrieve files created in the Btrieve v3.x
          format, or do you need to run another upgrade utility first?

     A:   You should be able to rebuild Btrieve v3.x files
          using BREBUILD, unless they have been extended
          across a volume. If the files have been extended,
          you should run CONVERT4 to translate the Btrieve
          v3.x file into v4.x format, then run BREBUILD. Any
          Btrieve v4.x and v5.x files can be rebuilt using
          BREBUILD.

     Q:   Will Brequest work in an OS/2 v2.0 DOS Box?

     A:   Brequest v5.16 and NetWare Btrieve (NLM) v5.15 will not run
          properly in multiple private DOS boxes. The system halts.
          Brequest v5.16 and NetWare Btrieve (NLM) v5.15 do not work in
          a global DOS box either. Trap D occurs when Btrieve calls are
          made. Both of these situations have been reported to Novell
          Development.

     Q:   Why is the NetWare Btrieve NLM returning a status 18 (Disk
          Full) when I still have plenty of disk space left?

     A:   The NetWare Btrieve NLM is attempting to expand a
          file and the file does not have an owner name. This
          normally occurs when the user (bindery object) who
          created the file is deleted from the bindery.

          Use NDIR to determine which files do not have owner
          names. Then, use the NetWare FILER utility to assign
          an owner name to these files.




*********************************************
*********************************************
PATCH LISTINGS:
Btrieve for DOS v5.10 Patches
*********************************************
*********************************************

For a description of patches 1 through 115, refer to earlier issues of
Bullets.

116. Btrieve (DOS)

     In situations where,

     *    Patch #79 has been applied,

     *    Btrieve operates on a NetWare Lite network,

     *    The .TRN file is redirected over the network and is
          used by another instance of Btrieve,

     a simple series of operations will either fail or hang the
     workstation, depending on which version of NetWare Lite you are
     using. This patch corrects the situation. (This patch also resolves
     problems fixed in patch 79.)

Grow Patch (DOS, Windows, OS/2)

     This patch allocates a new patch area, to be used by subsequent
     patches. It increases the size of BTRIEVE.EXE, WBTRCALL.DLL and
     BTRCALLS.DLL by 512 bytes, and causes Btrieve to use an additional
     512 bytes of RAM.

117. Btrieve (DOS, Windows, OS/2, VAP)

     This patch resolves a problem introduced by patch 112. Both patches
     should be applied to correct the original situation mentioned at
     patch 112.




*********************************************
*********************************************
PATCH LISTINGS:
NetWare Btrieve (VAP, NLM) v5.15 Patches
*********************************************
*********************************************

For a description of patches 1 through 63, refer to earlier issues of
Bullets.

64.  (BTRIEVE.NLM)

     Get Greater Than (8) or Get Less Than (10) operations do not work
     as expected with key-only files if the key value specified for the
     operation exists in the file. It may return the wrong record or an
     erroneous status 9 (End of File) or status 19 (Unrecoverable
     Error), or it may cause the server to hang, depending on the file
     and the key value. This patch ensures that the operations are
     successful.

65.  (BTRIEVE.NLM)

     Within a transaction, if:

     *    The first operation is an Insert (2)

     *    The record has a duplicate key, and

     *    Logging is active for the file,

     Btrieve erroneously makes a second BEGIN_TRANSACTION entry in
     the log file. This second entry causes a status 37
     (Transaction is Active) when you perform a "roll-forward"
     operation on the file. This patch prevents Btrieve from
     logging the same Begin Transaction (19) operation twice.



*********************************************
*********************************************
NOVELL EDUCATION:
Course Update
*********************************************
*********************************************

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


904: Btrieve: An Overview

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


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


907: Xtrieve PLUS

     This course has been updated to include new features
     introduced with NetWare SQL v3.0. Teaches 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.


911: NetWare Database Administrator

     This new course gives a complete, hands-on look at installing
     and configuring NetWare SQL and NetWare Btrieve. Covers the
     basics of ANSI Standard Structured Query Language (SQL),
     focusing on NetWare SQL and key database features like
     security, referential integrity (RI), database design, data
     normalization and performance.


912: Programming with NetWare SQL

     This new course is designed for developers and experienced network
     and database administrators who will be developing NetWare SQL
     applications or enhancing existing Btrieve applications with
     NetWare SQL. Provides an in-depth look at the functionality of
     NetWare SQL and discusses optimizing database systems for
     development of efficient applications using Novell database tools.


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.


To obtain information on pricing, location, scheduling, & course content
for classes held in the US, call 1-800-233-3382, 1-801-429-5508 or
1-800-NETWARE. Customers oustide of the US should call 1-801-429-5508.
For information on availability, location, and prices of classes outside
of the US, contact your local Novell office.



*********************************************
*********************************************
FUN & FACTS:
Developer Trivia
*********************************************
*********************************************

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

1.   What key is used to bring up the Remote Console "Available Options"
     menu ?
     A.   <*> on the number pad
     B.   Shift <*>
     C.   Alt + Esc
     D.   <+> on the number pad

2.   What status code will be returned if you try to access a
     NetWare Btrieve v6.0 file with NetWare Btrieve v5.x?
     A.   2 (I/O Error)
     B.   3 (File Not Open)
     C.   0 (Successful Operation)

3.   What are the names of two modes of services provided by the
     Transport Layer Interface (TLI)?
     A.   Connection mode & Connectionless mode
     B.   Real mode & Standard mode
     C.   Connect mode & Disconnect mode

4.   The command file used for NSUTIL, RIUTIL or BUTIL cannot
     contain lines that are longer than ________.
     A.   80 characters
     B.   130 characters
     C.   1024 characters

5.   What is the difference between BUTIL.NLM v5.x Recover option
     and the BUTIL.NLM v6.x Recover option (shipped with NetWare
     SQL v3.0)?
     A.   BUTIL v6.0 is faster
     B.   BUTIL v6.x uses Get operations, but BUTIL v6.x uses Step
          operations
     C.   BUTIL v6.x checks the Page Allocation Table (PAT) pages and
          reconstructs them if necessary.

6.   The Btrieve requester (BREQUEST.EXE) will not run in an OS/2
     v1.3 DOS Box.
     A.   True
     B.   False

7.   What new data type has been introduced in NetWare SQL v3.0?
     A.   NumericSTS
     B.   Byte
     C.   None

8.   How many simultaneous Named Pipes connections does the OS/2
     Requester v1.3 support?
     A.   245
     B.   250
     C.   255



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

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



*********************************************
*********************************************
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
     NetWare NNS


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

     NetWare 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


Communication Toolkits

     LAN WorkPlace Toolkit for DOS                     4.01


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.



*********************************************
*********************************************
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:  Linda Anderson
               Vitek Boruvka
               Steve Cannon
               Michael Eisa
               Neda Eslami
               Kumar Gaddam
               David Harris
               Laura Heater
               Ken Lowrie
               Diane Klinetob
               Nancy Kromar
               Clint McVey
               Paige Parker
               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. Borland is a registered trademark of Borland
International, 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
122 East 1700 South
P.O. Box 5900
Provo, Utah 84606
USA
Tel.  (801) 429-7000

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

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

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

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) 47.75.09.09
FAX   33 (1) 47.78.94.72

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

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

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

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

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

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, 40 bis
28046 Madrid
Spain
Tel.  34 (1) 577-4941
FAX   34 (1) 577-9053

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

Novell Sweden
Kottbyjatan 7
16475 Kista
Sweden
Tel.  46 (8)-7032350
FAX   46 (8)-7039434

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

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
August/September 1992
End of File
*********************************************
