MARCH 1992 VOLUME 4 NUMBER 3
INDEX
Hello and welcome to the March 1992 issue of Bullets!
As you will very quickly notice, in this issue of Bullets,we have included a four-page technical
marketing supplement.
This supplement provides our existing database programmers a quick look at the new
functionality that is available in NWSQL v.3.0, as well as the enhancements and features added
to version 6.0 of Btrieve. For those of you that are not currently using our database tools, we
hope that these new features will entice you, too.
The excitement here at Novell Austin increased as NetWare SQL v3.0 neared completion and the
scheduled release date inched closer and closer. The level of activity and teamwork also
increased as each department prepared for the release. For the past three months, we have been
involved in intensified in-house technical classes and presentations, marketing reseller
seminars, software engineer training and long hours of coding and testing.
These activities have demonstrated our entire site's commitment to the success of NetWare SQL
v3.0. All of our efforts will be worth it if you, the Novell developer, are satisfied with the final
product. Let us know what you think!
Happy_Programming!
Mad Poarch
Director
Developer Support/Service
Capturing with the NetWare Print Services
One of the most commonly asked questions regarding the use of the NetWare C Interface
for DOS APIs is, "How can I duplicate the functionality of the CAPTURE.EXE program?" The
NetWare Print Services APIs are very useful for developers who need to control the printing
capabilities of other applications. Applications can also use these services to handle their own
printing needs, but may be better served by writing directly to print queues using Queue
Services.
This article describes how to use the various NetWare Print Services APIs to control capturing of
printed output and redirect it to a print queue or file on a NetWare file server. The code examples
in this article are excerpts from a program called CAPIT. C, which reproduces much of the
functionality of CAPTURE.EXE. Because of space limitations, the entire source code for
CAPIT.EXE cannot be printed in this publication. Both the source code and the executable itself
are available in Novell's CompuServe forum, NetWire (see details at end of article).
The CAPTURE.EXE program included with NetWare provides some additional capabilities over
CAPIT.EXE. For example, it can retrieve default capture flags defined by PRINTCON in the
file, PRINTCON.DAT. The format of the information in PRINTCON.DAT is proprietary to
Novell and is subject to change without notice. If you need a mechanism to store or retrieve these
default values, you should develop your own. This article will demonstrate how to
"carry-forward" existing capture flags.
CAPIT.EXE uses "default" capture functions whenever they are available. This design simplifies
the code for choosing the local printer to which printer output will be directed. These functions
act on the printer port being captured, which is set by the function SetDefaultLocalPrinter().
There are also "specific" functions that act upon a specified local printer on each call. These
functions are similar to their "default" counterparts, but include an extra parameter specifying the
local printer.
The Capturing Process
The capturing process requires four basic operations:
- End any existing capture
- Set the capture print queue
- Set the capture flags
- Start the capture
To correctly capture printer ports, perform each of these operations in the sequence shown
above.
Ending Existing Captures
To begin capturing, a program should first end any existing capture. Ending a capture
clears existing capture flags and makes them irretrievable. So, CAPIT.EXE first saves the
existing capture flags by calling the GetDefaultCaptureFlags() API. If a capture is still in
progress, this API returns a number of valid flags that can be used when setting up the next
capture. If no capture is active, these flags should be reset to their defaults, using the procedure
shown in Figure 1.
FIGURE 1: Resetting capture flags to default values
SetDefaultLocalPrinter(localPrinterToCaptureTo);
GetDefaultCaptureFlags(&setCaptureFlags);
retCode = GetLPTCaptureStatus(&serverNumber);
if (retCode == 0) // Reset flags if not now captured
{
setCaptureFlags.status = 0x00;
setCaptureFlags.flags = 0x00;
setCaptureFlags.tabSize = 0x08;
setCaptureFlags.serverPrinter = 0x00;
setCaptureFlags.numberOfCopies = 0x01;
setCaptureFlags.formType = 0x00;
setCaptureFlags.localLPTDevice = 0x00;
setCaptureFlags.flushCaptureOnDeviceClose = FALSE;
setCaptureFlags.flushCaptureTimeoutCount = 0x00;
setCaptureFlags.maxLines = 66;
setCaptureFlags.maxChars = 132;
setCaptureFlags.formName[0] = NULL;
setCaptureFlags.LPTCaptureFlag = FALSE;
setCaptureFlags.fileCaptureFlag = FALSE;
setCaptureFlags.printQueueFlag = FALSE;
setCaptureFlags.printQueueID = 0x00;
}
End of Figure 1
After resetting the flags to default values, you can end the capture by calling the
EndLPTCapture() API. CAPIT.EXE then parses the command line and determines which flags
must change for the next capture. The flags will be covered in more detail in the section entitled
"Setting Capture Flags."
The documentation for SetDefaultCaptureFlags() and SetSpecificCaptureFlags() incorrectly
states that the parameter passed to each function should be a pointer to a structure of type,
SET_CAPTURE_FLAGS. Although the function's prototype expects this type of pointer,
additional flags in the CAPTURE_FLAGS structure are required. These functions should be
passed the same structure that is passed to the appropriate GET functions, and cast to the
expected structure. For example:
This is why the code required to get and clear the flags (shown in Figure 1) uses setCaptureFlags.
The functions to set the flags require the entire structure as defined by CAPTURE_FLAGS, not
the shortened version defined by SET_CAPTURE_FLAGS.
Capturing to a File or Print Queue
Next, define either a file or a print queue to which printer output will be directed. To
define a file, set the preferred connection ID for the file server where the file is located, and call:
specifyCaptureFile(directoryHandle, path);
The directory handle can be zero if the path is a fully qualified volume path (e.g., path =
"SYS:USERS\GUEST \CAPTURE.TXT"). Otherwise, the directory handle and the path must
make up a full path (e.g., handle = 1 and points to "SYS:USERS\GUEST" and path =
"CAPTURE.TXT"). If capturing to a print queue, make the calls in Figure 2.
FIGURE 2: Calls necessary to capture to print queue
SetPreferredConnectionID(printServerConnectionID);
retCode = GetBinderyObjectID(queueName,
OT_PRINT_QUEUE,
&queueID);
if (retCode != 0)
{
// Queue may not exist on server handle the error
}
setCaptureFlags.LPTCaptureFlag = FALSE;
retCode = SetCapturePrintQueue(localPrinterToCaptureTo,
printServerConnectionID,
queueID);
End of Figure 2
The CAPTURE_FLAGS structure member LPTCaptureFlag must be set to zero to inform the
shell that a new queue has been specified, otherwise the queue/server association will not be
handled correctly. Although it is cleared by ending the capture, the flags in this structure are
acquired before ending the capture.
Setting Capture Flags
The capture flags must be set after designating a queue and before beginning the capture.
To set the flags, call SetDefaultCaptureFlags() or SetSpecificCaptureFlags() and pass in a pointer
to a CAPTURE_FLAGS structure (not the SET_CAPTURE_FLAGS structure). Most of these
flags are clearly documented in the NetWare C Interface for DOS v1.2. A few of these flags are
defined more clearly here. The flags field defaults to all bits turned off. The bits are defined in
Figure 3.
FIGURE 3: Flags field of CAPTURE_FLAGS structure
Flag Definition
----------------------------------------------------------
0x01 Undefined
0x02 Undefined
0x04 If set, jobs get printed if workstation loses connection during capture
0x08 If set, form feeds will not be sent at the end of each job
0x10 If set, the user is notified when the job has printed
0x20 Undefined
0x40 If set, tabs are converted to spaces
0x80 If set, a banner page is printed before the print job
End of Figure 3
Bit position 0x04 is currently not set by CAPTURE.EXE or CAPIT.EXE. If bit position
0x80 is set, the banner that is printed consists of what is stored in bannerText and the user name
stored by the function SetBannerUserName(). If bit position 0x40 is set, tabs are converted to the
amount of spaces defined in tabSize. If bit position 0x10 is set, the user will be notified via a
broadcast message when the job has printed.
The printerSetupBuffer and printerResetBuffer fields are used for placing printer controls before
and after a print job. They are far pointers to the buffers created by the NetWare shell. The first
word (not byte) in each buffer defines the size of the buffer. The second word defines the length
of the printer control (how many bytes to send to the printer). The remaining bytes are sent to the
printer.
The size of these buffers is determined by the PRINT HEADER= and PRINT TAIL= parameters
inside the shell.cfg or net.cfg file. If these parameters are not set within these files, default sizes
are used: 64 bytes for the printerSetupBuffer and 16 bytes for the printerResetBuffer.
Unless you need to modify the values inside these buffers, you only need to know how to treat
the pointers to the buffers under various versions of the shell. With versions of NetWare shell
before v3.00, the address of the buffers was returned long-swapped (i.e. in "hi-lo" or non-Intel
format), but with v3.00 and above, the addresses are no longer swapped (they are returned in
lo-hi, or Intel-readable, format).
The NetWare C Interface for DOS (v1.2 and earlier) swapped these bytes to compensate for the
swapping performed with pre-v3.00 shells, but the interface does not check for the shell version
before doing so. Therefore, if your application is running under shell versions 3.00 and above
you must swap these values. Swapping can be performed with the code displayed in Figure 4.
FIGURE 4: Calls needed to manage differences between v2.x & v3.x shells
retCode = GetNetWareShellVersion(&majorVersion,
&minorVersion,
&revisionLevel);
if (retCode == 0)
{
printf("Shell version too old\n");
exit(1);
}
if (majorVersion > 2)
{
setCaptureFlags.printerSetupBuffer =
(char far *)LongSwap((long)setCaptureFlags.printerSetupBuffer);
setCaptureFlags.printerResetBuffer =
(char far *)LongSwap((long)setCaptureFlags.printerResetBuffer);
}
End of Figure 4
The flag used to enable/disable auto endcap is flushCaptureOnDeviceClose. This flag should be
set to TRUE to disable auto endcap. The flushCaptureTimeoutCount flag defines the number of
ticks to wait without any printing before the job is queued for printing.
The only remaining step is to start the capture, either with StartLPTCapture() or
StartSpecificLPTCapture().
Capturing data intended for a printer and redirecting it to a file or print queue is a fairly simple
matter. A few situations require special handling, but once these are resolved, applications that
are not NetWare-Aware can be made to print to NetWare print servers or files. An alternative to
capturing printer output is to write data directly to NetWare print queues.
The source code to CAPIT.EXE and the executable can be downloaded from NetWire (NOVLIB
section, LIB 14, under filename CAPITx.ZIP, where "x" is the revision number if any). If you
have additional questions on capturing with the NetWare Print Services, or if you need technical
assistance, please contact the Developer Support Group at Novell Austin (See "Contacting
Novell Austin" at the end of this issue).
NetWare SQL New & Enhanced Features
NetWare SQL v3.0 offers new and enhanced features that improve performance and
increase database integrity.
Even a novice database administrator will be able to install and use NetWare SQL v3.0 due to the
new, simple Install utility We have improved the performance of many join and fetch functions
at the NetWare SQL level and enhanced loading of large files. The documentation has been
reorganized to better accommodate different expertise in the SQL level functions or relational
primitives. Convenient quick reference cards provide easy access to SQL statements and status
codes.
Cursor Stability, the ability to lock the page containing the record to which the cursor is currently
pointing, has been added. Cursor stability ensures that the data each user reads remains stable,
while still allowing other users access to other pages within the same data files. The cursor
stability isolation level generally permits greater concurrency for all users on a network by
limiting the number of records each user locks at any one time. This allows other network users
to access more pages of the data file.
Btrieve Enhancements
Many enhancements of NetWare SQL v3.0 occur at the Btrieve v6.0 record manager level.
The Btrieve file structure has been modified to support Referential Integrity, online backup, new
caching algorithms, page allocation tables, and passive control. Since Btrieve v6.0 file structure
has changed significantly, it is necessary to convert any existing Btrieve data to the new Btrieve
v6.0 format. A utility is included to perform the conversion. If users choose not to take advantage
of the new features and increased performance, the previous Btrieve v5.x files are still
compatible.
Referential Integrity (RI) constraints ensure that cross references between tables are always valid.
A Database Administrator can define RI restrictions with SQL statements. NetWare SQL
enforces these constraints across all applications at the Btrieve level. Since these RI restrictions
are enforced at the data dictionary level, developers are freed from having to include RI
restrictions directly in their applications.
Online Backup or continuous operations allows users to backup the database currently in use at
any time without closing the files. Online backup is implemented with a NetWare SQL utility
which opens the original file in a read only mode. Btrieve backs up a "snapshot" of the file and
creates a "Delta" file for operations occurring during the backup process. After turning off the
backup utility, Btrieve issues a "commit" transaction.
New caching algorithms have been developed to provide hashing search methods for improved
access, concurrent sharing of a single cache, and persistence of the cache across operations. The
speed of building and loading supplemental indexes for large data files has been improved with
merge sorts.
Page Allocation Tables (PATs) contain information about the file, such as file size and page size,
as well as information about other current pages. PATs represent a departure from Btrieve's
previous pre-imaging method. Btrieve's previous pre-imaging is the process of storing the image
of a file page before a record on the page is updated. In the alternative, PATs are updates to the
page or pages written into unused or "recycled" pages in the Btrieve file. During the commit, the
PAT is updated to reflect any activity. This enhances performance because a pre-imaging file
does not need to be maintained.
Because of the shift to PATs, a "roll-back" command is no longer necessary. The user is working
with a "virtual" copy of the file. The file is always valid and internally consistent except during a
controlled commit period.
Passive Control allows applications to expect the update or delete operation to complete
successfully. Rather than requiring an application to lock a record before updating it, Btrieve
returns a "conflict" status at update time if an application attempts to update a record that has
been changed since the application last read it. Passive control supports updates of one record at
a time outside of a transaction.
Passive control allows a single user application to run on the network without implementing
locking. However, passive control is most effective when an application is operating in a lightly
utilized network environment or on files in which the data is fairly static.
Packaging and Upgrades
NetWare SQL v3.0 is now user-count stratified exactly the same as NetWare v3.11. The
20, 50, 100, and 250 user versions include the NetWare Runtime components. Customers do not
need to match NetWare and NetWare SQL user count versions. The user count of NetWare SQL
is limited to the number of NetWare SQL logins not NetWare logins.
The NetWare SQL Developer's Kit will be offered concurrently (as a separate product) with the
release of NetWare SQL v3.0. The developer's kit documents the NetWare SQL APIs and SQL
statements. It also provides a comprehensive overview for new NetWare SQL developers who
start writing applications for NetWare SQL. The language interfaces and embedded SQL
preprocessor for DOS and libraries for OS/2 are a part of the kit.
Upgrades are offered from NetWare SQL 386 2.11 (NLM) and NetWare SQL 2.11 (VAP) for a
limited time.
For more information about NetWare SQL v3.0, contact your local Novell reseller, or call
1-800-477-9139 (FAX 512-345-9509). Customers outside the USA, please contact your local
Novell office or call 512-795-8094.
CLib API Update: GetVolumeNumber( ) (Network C for NLMs v2.0b)
With the Network C for NLMs SDK, if you call GetVolumeNumber() to get the number
of a volume on a remote server, the function appears to returns incorrect information for the
volume number. Actually, the volume number is retuned in the first byte. The remainder of the
"int," however, is not cleared, and contains the information that it held before the call. For
example:
Source:
int volNumber = 0xFFFFFFFF;
GetVolumeNumber("SYS", &volNumber);
printf("0x%X\n", volNumber);
Output:
0xFFFFFF00
To avoid confusion, clear the volume number to zeros before making the call.
Patches for 3270 LAN Workstation for DOS (3270 LAN Workstation for DOS v2.0)
The newly released patch file, PTF-283, fixes the following problems in the 3270 LAN
Workstation for DOS v2.0:
- Cursor movement problems on Printer Control Panel.
- "No Resources Available" when WSLAN is configured for multiple gateways.
- Incompatible keyboard BIOS problem with new IBM PS/2 model 35 and 40.
PTF-283 supercedes PTF-269, PTF-270, and PTF-273, and can be downloaded from
NetWire (NOVLIB section, LIB 9). To apply PTF-283, copy all of the files into the current
working directory.
Internals of the XQL Data Segment (XQL for DOS v2.11)
When XQL loads, it allocates a 64K data segment in which it stores all of its local
variables when executing the functions requested by an application. Within this 64K data
segment, a fixed amount of memory is filled with global data and data that is allocated at
loadtime. The remaining memory is divided up according to the specified loadtime parameters.
Figure 5 shows how this 64K buffer is divided.
FIGURE 5: Makeup of 64K XQL data segment
BYTES DESCRIPTION
------------------------------------------------------
13856 XQL's global data
980 Memory allocated to hold info about active dictionary
539 Current Session data structure
867 Current View data structure
1400 Join List data structures
2267 Data buffer (allocated at load-time) used for swapping data structures to disk
2062 Memory used for extended Btrieve operations
896 Dictionary position blocks
817 Misc. key buffer, currency addresses, etc.
------------------------------------------------------
23684 This is the fixed size of data that resides in XQL's 64K data segment. There is 41852
bytes of data left for the load-time parameters. Space will be allocated in the data segment for
the /w, /t and /b parameters as follows:
w Fetch buffer. w = value in /w: parameter
t * 130 Trans. processing. t = value in /t: parameter.
Defaults to 12.
b * 1024 Heap buffer. b = value in /b: parameter
------------------------------------------------------
65536 If this number is exceeded XQL will display an "insufficient memory" error and fail to
load.
End of Figure 5
For example, the following load parameters would require too much memory:
xql /t:12 /v:8 /w:8000 /b:32 /e
23684
(12 * 130)
8000
+ (32 * 1024)
-------------
66012
Reducing the /t parameter to eight will enable XQL to load.
xql /t:8 /v:8 /w:8000 /b:32 /e
23684
(8 * 130)
8000
+ (32 * 1024)
-------------
65492
Whether or not you use expanded memory, this information will not change. Expanded memory
simply provides you with more free memory on your system after XQL is loaded.
SPXEstablishConnection( ) Uses "bp" Register (NetWare System Calls for DOS v1.0)
With the NetWare System Calls, the function, SPXEstablishConnection(), uses the "bp"
register. Calling SPXEstablishConnection() requires that you "push" the "bp" register before the
call and that you "pop" it after the call. Otherwise, some of the variables on the stack may be
overwritten.
This requirement is undocumented in the current NetWare System Calls manual.
MapDrive & Search Drives (NetWare C Interface for DOS v1.2)
When you attempt to delete search drives with the MapDrive function, a number of
situations may arise which prevent the deletion. The MapDrive function can successfully delete
mapped search drives, but you must meet a few undocumented requirements. Figure 6 contains
example code which demonstrates the steps needed to delete a mapped search drive.
FIGURE 6: Deleting mapped search drive with MapDrive function
GetSearchDriveVector(vectorBuffer);
for(i=0;i<16;i++)
if(vectorBuffer[i] == driveLetter - 'A') break;
if(i == 16) i=0;
else i++; /* Search Drives are */
/* relative to 1, not 0. */
cCode=MapDrive(connectionID, /* Server Connection ID */
NO_BASE_DRIVE, /* No Relative drv Mapping */
"", /* No Path Required */
DRIVE_DELETE, /* Delete This Drive */
i, /* Number Of Search Drive */
&driveLetter); /* Drive To Be Deleted*/
End of Figure 6
The two most common mistakes when deleting a search drive with the Map Drive
function are using the wrong connectionID and passing in an incorrect search drive number. The
connectionID is the file server to which the drive is mapped. The search drive number is a
number from one to sixteen which inidicates the order of the search drive in the search drive
vector table.
PUBLIC User in Xtrieve PLUS v4.10 (Xtrieve Plus v4.10)
In version 4.10, Xtrieve PLUS introduced a user called PUBLIC to its security
implementation. PUBLIC is not a username and cannot be used to access a dictionary that has
security installed. PUBLIC also has no password.
PUBLIC functions like a group (as in NetWare, where there can be individual users and groups).
The Master user can assign rights to PUBLIC. Then, as individual users are added, the Master
user does not need to redefined each users rights individually; users can be assigned the rights
that have been given to PUBLIC (this design is similar to security equivalences in NetWare).
GetBinderyObjectDiskSpaceLeft( ) Problem (NetWare C Interface for DOS v1.20)
When you call the GetBinderyObjectDiskSpaceLeft API, the value returned in
"UnusedDiskBlocks" is the value for the used disk blocks of the specified object, not the unused
disk blocks. The returned value also includes the used disk blocks for all the volumes on the
specified server. This situation occurs with NetWare v3.11 servers and has been reported. There
is no workaround at this time.
Calling GlobalAlloc( ) from Windows DLLs (Network C for Windows v1.22)
When allocating Event Control Blocks (ECBs) dynamically using GlobalAlloc(), specify
the following flags:
- GMEM_DDESHARE
- GMEM_FIXED
- GMEM_NOT_BANKED
You must then call GlobalLock() or GlobalWire(), and then GlobalPageLock().
GlobalPageLock() informs the Windows Kernel not to swap memory where the ECBs are
located. This is very important when using Event Service Routines (ESRs). In most cases, you
should lock the memory allocated to ECBs in the data segment. To do this, declare the data
segment containing the ECBs and packet fragments to be "fixed" in the program's .DEF file.
ScanDirEntry Sequence Number (NetWare C Interface for DOS v1.2)
When using the NetWare C Interface for DOS API, ScanDirEntry, on a 286 server, only
one or two files are returned. The sequence number is not updated by this function whenever a
286 server is detected. To obtain a valid sequence number, either modify the source code to
update the sequence number, or use the sequence number returned by the DirStructure API.
Key Position & Create Operation (Btrieve (all versions))
When creating a Btrieve file, you must specify a Key Position for each key segment. The
Key Position is the starting position of the segment within the data record. If you specify a Key
Position of zero, Btrieve will return a status 27 (Invalid Key Position).
The Key Position must be set to a value between one and the specified record length. This
requirement also applies with BUTIL -CREATE operations and any application that performs a
Btrieve Create (14) operation.
CLib Rename API & Directories on NetWare 2.x Servers (Network C for NLMs v2.0b)
The Rename function supplied with CLib malfunctions when applied to directories located
on NetWare 2.x file servers. The Rename function requires both an old name and a new name.
Whenever you need to change the name of a directory on a NetWare 2.x file server, enter a full
path for the old name and just the new directory name (no path) for the new name.
Btrieve Pascal Examples (Btrieve for DOS v5.10a)
The sample Pascal programs in the Btrieve Programmer's Manual (April 1990 edition)
were written with Microsoft Pascal. Turbo Pascal programmers cannot use these example
programs without modification because of differences in the way the two languages manage
"string" variables. In Turbo Pascal, a variable declared as "string[4]" is actually five bytes long,
because it includes a length byte indicating the significant amount of data in the remaining four
bytes. Btrieve does not expect a length byte, and interprets it as a general data byte.
For instance, the Btrieve Create example in Appendix D results in a status 25 (Create I/O Error),
a status 27 (Invalid Key Position) or possibly other errors if used in a Turbo Pascal program. The
following changes should be made in order for the Btrieve Create example program to function
properly:
- The key specification must include a four-byte "Not used" field. In the sample program,
this field is declared as "NOT_USED : string[4];" which is actually a five-byte field. This will
cause a status 27 to be returned on the Btrieve Create call. Change this variable to "NOT_USED
: ARRAY [1..4] OF char;"
- Similarly, the file specification includes a four-byte "Not used" field, as well as a
two-byte "Reserved" field. The sample program declares the fields as "NOT_USED : string[4];"
and "RESERVED : string[2];" respectively. These may also produce a status 27 on the Btrieve
Create call. Change the data type of these fields to ARRAY [1..x] OF char.
- The KeyBuffer parameter passed on the Btrieve Create call must contain the name of the
file to be created. The example uses a variable declared as: "FILE_NAME : string[17];" and then
calls Btrieve with this variable as the key buffer (fifth) parameter. When Btrieve reads
FILE_NAME, it reads the length byte first, which usually is not a legal character for a DOS file
name, and a status 25 will be returned.
To avoid problems, either declare this parameter as an "ARRAY [1..x] OF char" or pass it
to Btrieve with a [1] subscript. For example:
STATUS := BTRV (B_CREATE,
POS_BLK,
DATA_BUF,
DATA_LEN,
FILE_NAME[1],
0);
Many of the sample Pascal programs in the Btrieve Programmer's Manual also define the
data buffer with a variant record. This is not necessary in Turbo Pascal. For example, when
converting the Pascal Get First example from Appendix D (see Figure 7) to Turbo Pascal, you
can use a simple record type, as shown in Figure 8. Then, specify DATA_BUF as the third
parameter.
FIGURE 7: Excerpt from Pascal Get First example in Btrieve manual
type
EMP_REC = record
case integer of
1: (NAME : string(20);
AGE : string(2);
HIRE_DATE : string(6));
2: (ENTIRE : string(28));
end;
var
DATA_BUF : EMP_REC;
...
begin
...
STATUS := BTRV(B_GET_FIRST, POS_BLK, DATA_BUF.ENTIRE,
DATA_LEN, KEY_BUF, 2);
End of Figure 7
FIGURE 8: Turbo Pascal modifications to Get First example
type
EMP_REC = record
NAME : string[20];
AGE : string[2];
HIRE_DATE : string[6]
end;
...
STATUS := BTRV( B_GET_FIRST,
POS_BLK,
DATA_BUF, {Use "DATA_BUF" as 3rd parameter}
DATA_LEN,
KEY_BUF,
2);
End of Figure 8
Preventing NLMs from Unloading (Network C for NLMs SDK v2.0b)
If you want to prevent an NetWare Loadable Module (NLM) from unloading, here is one
possible approach:
- Specify the CHECK option in your LNK file, giving it the name of a function that
will be called on an unload attempt. The prompt from the loader will expect a "Yes/No"
response. Forcing a "No" response and an "n" will prevent the NLM from unloading. For
example:
option check=NWNoUnload
- Insert the routine listed in Figure 9 into your code. This routine will "push"
characters to the console screen using "ungetch" ("n").
- The routine in Figure 9 prevents NLMs from unloading, so you must provide an alternate
method. Register a command processor using the RegisterConsoleCommand API.
FIGURE 9: Routine to prevent NLMs from unloading
#include
#include
#include
int NWNoUnload()
{
LONG OldScrID = GetCurrentScreen();
LONG NewScrID = CreateScreen("System Console",0);
if( OldScrID != NewScrID) SetCurrentScreen(NewScrID);
ungetch('n');
if( OldScrID != NewScrID) SetCurrentScreen(OldScrID);
return 1; // ask NetWare to send a warning message
}
End of Figure 9
NetWare System Calls Clarification (NetWare System Calls v1.0)
The documentation for the Change Process VAP system call should state that only register
DS is preserved when the call returns. All other registers are destroyed.
Stack Corruption on Paths Larger than 255 Bytes (Network C for NLMs SDK v2.0b)
Several CLib functions declare a local stack variable for paths that are 255 bytes long.
However, if a path is larger than 255 bytes, the path parser will overwrite the stack. Functions
exhibiting this behavior include __open() and opendir(). The __open function is the internal
function used by all CLib file open APIs. To avoid this situation, do not use paths larger than 255
bytes.
WLINK & Redefining Imported Symbols (Network C for NLMs SDK v2.0b)
If you redefine any imported symbol in your NLM, WLINK always resolves any
references to that symbol made by your NLM to the imported symbol. This WATCOM problem
initially appeared in the Network C for NLMs SDK v2.0a, and was repaired. It subsequently
reappeared in version 2.0b To avoid this situation, either remove the symbol you wish to redefine
from the import file or symbol list, or rename the symbol.
IPXGetInternetworkAddress API Problem (Network C for Windows v1.22)
The IPXGetinternetworkAddress API returns garbage if IPX/SPX is initialized with zero
maxECB's (meaning that the application will control its ECBs directly -not relaying the
NWIPXSPX.DLL or VIPX.386). The API functions correctly if the IPX/SPX is initialize with
any number of maxECB's other than zero. There is no workaround for this situation at this time.
EMSNETX Bug (EMSNETX v3.22)
Under certain conditions, file writes using EMSNETX v3.22 can become corrupted.
Specifically, corruption occurs when the buffer being read or written and the buffers the shell is
using are in EMS memory. The error does not usually occur immediately, but instead occurs
within one or two hours, with one to six bytes typically being corrupted each time. To avoid this
situation, either set CACHE BUFFERS=0 in NET.CFG or SHELL.CFG, or avoid using the EMS
shell.
CLib Addition Error (Network C for NLMs SDK v2.0b)
If you compile with /FPC, and try to add the numbers 31.09 and 1.91, the internal CLib
helper function, __FDA, will incorrectly yield 16.0. Currently, there is no workaround for this
error.
Fast Answers to Common Questions
NetWare C Interface for DOS v1.2
Q - Why doesn't LoginToFileServer() from the NetWare C Interface for DOS run the
login script?
A - There is no API to execute the login script.
NETX v3.22
Q - Under NETX v3.22, when I use the Borland Make utility to invoke BCCX v2.0,
the system halts with an expanded memory error 12 or the machine reboots. Why does this
occur?
A - Borland's Make utility has an option (-S) that allows you to swap the make utility
out of memory while it compiles or links. Errors occur when the Make utility tries to reload itself
into memory. Borland's C++ Compiler v3.0 does not include a BCCX file and functions
correctly. Earlier shells seem to work properly; the problem seems to only occur when you use
BCCX v2.0 with netx v3.22.
Network C for NLMs v2.0b
Q - Where can I find the tutorial examples in the Network C for NLM's SDK v2.0b?
The documentation says it is on the "tutorial diskette," but I did not receive such a disk.
A - If you install Network C for NLMs according to Novell's installation defaults, the
installation process places these tutorial examples in \WATCOM\NOVX\CS.
Q - When I use the AIOCOMX driver at high speeds, it frequently loses characters.
What should I do?
A - The COMX driver does not guarantee that all characters will be received, because
the LAN and disk drivers disable interrupts for too long. Drivers like the ARTIC driver and the
WNIM driver will produce better results since they have their own CPU on the board.
NetWare C Interface for Windows v1.22
Q - While running my Windows application, an error pops up that says
NETWARE.DLL cannot be found. What should I do?
A - Make sure that NETWARE.DRV is in the search path, or is located in the
directory from which Windows is running. When Windows cannot find NETWARE.DRV, it
returns the error message that it cannot find NETWARE.DLL.
Q - When using the DLLs provided with the NetWare C Interface for Windows SDK
v1.22, what is maximum packet size that NetWare supports under Windows Standard mode?
A - The maximum packet size is 512 bytes, including the header.
DR DOS v6.0
Q - Have any patches been released for DR DOS v6.0? How can I obtain these
patches?
A - A number of patches have been released for DR DOS v6.0 and can be acquired in
several ways:
- From the Digital Research CompuServe forum, DRFORUM.
- Directly from Digital Research by calling 408-646-6464.
- From Digital Research by faxing your request to 408-649-8209.
NetWare OS/2 Developer's Kit v1.3a
Q - What additional programs and libraries do I need to write Windows applications
for Named Pipes with the NetWare OS/2 SDK v1.3a?
A - You will need the DOSNP TSR that is provided with the NetWare OS/2 SDK and
the specific libraries that are also available with that SDK.
Q - The Named Pipe status codes are not defined in the DOS Named Pipe headers in
the NetWare OS/2 SDK v1.3. How can I check the status of a pipe without reading the data?
A - When you issue a DosPeekNamePipe API call while writing a DOS Named Pipe
application, you will notice that some of the status return codes are not defined, and that they
generate compiler warnings. The status codes describe the status of the Named Pipe. In the
NetWare OS/2 SDK, there is also a NMPIPE header file under the WINNP directory for
Windows and Named Pipes. If you need to use this API call, copy over the predefined status
codes to the DOS NMPIPE header file.
Btrieve
Q - How can I obtain UPPER.ALT, the file containing the alternate collating
sequence that sorts all characters as upper case? It was not shipped with Btrieve for Windows
v5.10 and Btrieve for OS/2v5.10.
A - You can download this file from NetWire (NOVLIB, LIB1, filename:
UPPER.ZIP).
Q - How can I define a C long integer as a key in Btrieve, when there is no long data
type?
A - To define a C long integer in Btrieve, specify the key as an integer with a length
of four bytes.
Patches can be downloaded from NetWire, or obtained from the Developer Support Group at no
charge. (See "Contacting Novell Austin" at the end of this issue).
NetWare Btrieve (VAP, NLM) v5.15 Patches
For a description of patches 1 through 50, refer to earlier issues of Bullets.
- 51. (BTRIEVE.NLM) This patch corrects the following situation involving
two workstations: the first workstation performs an Update (3) operation, but a status 80
(Conflict error) is returned because a second workstation updated the record after the first
workstation read the record. If the first workstation then performs a Get Position (22) operation
before rereading the record, an erroneous status 8 (Invalid Positioning) is returned. This patch
allows the Get Position operation to succeed.
- 52. (BTRIEVE.NLM) When you build a supplemental index, server utilization goes
to 100% and any other stations making Btrieve calls "time out," receiving status 95 (Session No
Longer Valid) errors. This patch corrects the situation by decreasing the time slice used by
Btrieve while sorting the keys.
NetWare SQL/XQL v2.11 Patches
For a description of patches 1 through 66, refer to earlier issues of Bullets.
Xtrieve PLUS for DOS v4.10 Patches
For a description of patches 1 through 9, refer to earlier issues of Bullets.
10. When a title field is defined and you edit or modify the view, if you escape and
then select CONTINUE, the data for the title field (or fields) will not show on the screen. The
refresh key will redisplay the data, but it removes the heading for the title field(s). This patch
corrects the situation.
11. When editing a string field, the data for the string field does not appear on the
screen after pressing ENTER, but the data is inserted or modified correctly. This patch ensures
that the string field is properly displayed.
12. This patch corrects the following situations:
If you 1) create a view, 2) create and store a report based on that view (without storing and
recalling the view first), and 3) store the view, then Xtrieve PLUS returns an error message when
you try to recall the report.
Also, if you 1) create, store and recall a view, 2) create and store a report, and 3) in a later
session, recreate the view (without storing and recalling it first), then Xtrieve PLUS returns an
error message when you try to recall the report.
13. If you place "@esc" in a report (or "@hexXX," where "XX" represents
non-printable characters), Xtrieve PLUS will not place the ESC character (or the unprintable XX
character) in the report output. This patch ensures that these characters are included.
14. Xtrieve PLUS does not detect duplicate field names with different cases until you
try to complete the file definition (with "Finished-Create" or "Finished-Don't Create"). This
patch corrects situation and returns the error, "Field names must be unique," when the field is
entered.
15. If you have a very large number of users (255 to 500) in your dictionary, then
Xtrieve PLUS may experience problems when showing, modifying, or removing a user. This
patch ensures that user information is displayed and utilized correctly.
Novell Education offers classes for many of the Development Products including Btrieve,
XQL/NetWare SQL, Xtrieve PLUS and the NetWare Client APIs. These classes are designed to
introduce participants to the powerful features of Novell's development tools, database products,
and NetWare services. Nearly 50% of class time is devoted to hands-on activities.
- 901 Programming with NetWare Client APIs
Mar. 16-18Austin, TX
Apr. 8-10 Washington, DC
- 905 Programming with Btrieve
May 12-14 Austin, TX
- 906 Programming with Btrieve: Advanced Features
Mar. 10-12Chicago, IL
- 907 Xtrieve PLUS
Mar. 17-18Washington, DC
May 20-21 Sunnyvale, CA
- 910 Programming with XQL
Apr. 14-16Chicago, IL
- 920 Programming with Network Communication Services
Mar. 19-20Austin, TX
Apr. 13-14Washington, DC
- 930 Developing NetWare Loadable Modules (NLMs)
Mar. 10-12Austin, TX
Apr. 14-16Austin, TX
May 13-15 Sunnyvale, CA
To register or obtain information on pricing, location and course content for classes held in the
US, call 1-800-233-3382, 1-801-429-5508 or 1-800-NET-WARE. International customers should
call 1-801-537-8850. All courses are subject to cancellation or rescheduling within two weeks of
the scheduled date, depending on enrollment.
For information on availability, location, and prices of international classes, contact your local
Novell office.
Test your "developing" skills with the various Professional Development Series products by
taking our Fun & Facts quiz. Have fun and good luck! (See the end of this issue for answers.)
1. In XQL, if you have a BOOLEAN field, and you specify an EDIT mask of "-NO,"
how would the value "false" be represented?
A. NO
B. (blank space)
C. FALSE
2. In XQL, if you have a BOOLEAN field, and you specify an EDIT mask of "-NO," how
would the value "true" be represented?
A. Yes
B. (blank space)
C. TRUE
3. In XQL, what environment variable tells XQLI where the dictionaries are located?
A. XQLIDD
B. XQLIDDF
C. XQLIDICT
4. What status code does Btrieve return when there is a CREATE I/O ERROR?
A. 2
B. 14
C. 25
5. When using data compression in Btrieve, can the record be of variable length?
A. Yes
B. No
6. In Xtrieve PLUS, what is the key sequence used to chain command files?
A. Alt-F8
B. Shift-F6
C. Shift-F7
7. Name the three queues within the Netware Operating System.
A. Print Server Queue, Object IDs Queue, and Supervisor's Queue
B. Job Queue, Print Queue, Users Queue
C. Run Queue, Sleep Queue, Semaphore Queue
8. What is the maximum size of an SPX packet in OS/2?
A. 576 bytes
B. 534 bytes
C. 540 bytes
9. What .OBJ file initializes all the CLIB.NLM data structures?
A. Startup.OBJ
B. Prelude.OBJ
C. Init.OBJ
10. In the NetWare 2.x environment, what two files make up the bindery?
A. Net$Bind.Sys and Net$Prop.Sys
B. Net$Bind.Sys and Net$Obj.Sys
C. Net$Bind.Sys and Net$Bval.Sys
11. What option in WDISASM will generate the .ASM format from a .OBJ file?
A. /a
B. /asm
C. /80x86
FUN & FACTS ANSWERS
1. A
2. B
3. A
4. C
5. A
6. C
7. C
8. A
9. B
10. C
11. A
Developer Support
Developers in the U.S. and Canada may contact Novell Developer Support via telephone, fax,
BBS or electronic mail via CompuServe, MHS or the Internet.
Voice
For both presales and postsales support, call Novell Developer Support between 8:00 a.m. and
5:00 p.m. Mountain Time at 1-801-429-5588. Many calls to Novell Developer Support are
passed to a software support engineer immediately. Calls to Novell Developer Support generally
will be acknowledged or answered within four hours.
Fax
If you prefer, you may contact Novell Developer Support via fax at 1-801-429-2990. Faxed
questions are acknowledged or answered within 24 hours.
Developer BBS
If you do not have access to either CompuServe or the Internet, send test cases to our BBS. Set
your communication software to N-8-1 and call 1-801-429-5836.
E-mail: CompuServe
Post your messages in the appropriate section addressed to Novell at 76701,171. These messages
will receive a response within 24 hours.
E-mail: MHS
You may direct your questions and comments to Novell Developer Support via Novell's Message
Handling Service E-mail facility. Address your messages to devsup@novell. These messages
will receive a response within 24 hours.
E-mail: Internet (SMTP)
An alternative method of contacting Novell Developer Support is through the Internet E-mail
system. Send your messages to devsup@novell.com. These messages will receive a response
within 24 hours.
NetWire on CompuServe
Novell's NetWire forum is open to all registered CompuServe subscribers. Through the
NDEVSUP forum, professional developers writing applications with Novell development tools
can gain access to information specific to Novell development. Support, patches, periodicals and
product information, as well as information on all of the programs and services provided for
Novell developers are accessible through this forum. Post your messages in the appropriate
section addressed to Novell at 76701,171. Technical questions will be acknowledged or
answered by Novell Developer Support within 24 hours.
Novell Products and SDKs
Novell products on the "Currently Shipping Developer Products" list (see page 15 of this
issue), including the Red Box Products, are available to Novell Professional Developer's
Program members. Call 1-800-RED-WORD (1-800-733-9673) or 1-303-894-4135 to order these
products or to receive additional information. To order other Red Box Products not listed,
contact your local Novell office or Novell Authorized Reseller.
DeveloperNet Labs
For information on DeveloperNet Labs development tools, education classes and product certification,
in the U.S. and Canada call 1-800-453-1267 ext. 5544 or 1-801-429-5544, or call your local
Novell office (see back cover of this issue).
Novell Developer Relations
Novell Professional Developers or those wishing to become members may contact Novell
Developer Relations via telephone, fax, or electronic mail via Compuserve, MHS or the Internet.
Voice
For general information or questions on Novell Developer Relations programs, in the U.S.
or Canada call 1-800-RED-WORD (1-800-733-9673). All others call 1-801-429-5281.
Fax
If you prefer, you may contact Novell Developer Relations via fax at 1-801-429-7207.
NetWire on CompuServe
Novell's NetWire forum is open to all registered Compuserve subscribers. Through the
NDEVREL forum, Novell Professional Developer's Program-related issues or general questions
may be posted. Through the NDEVINFO forum, customers who do not have products may post
pre-sales product information questions on all Novell SDKs.
E-mail: MHS or Internet (SMTP)
You may direct your questions and comments to Novell Developer Relations via Novell's
Message Handling Service E-mail facility. Address your messages to devprog@novell.com. Use
the same address when going through the Internet E-mail system.
Publisher: Mad Poarch
Editor: Kirk Humphries
Design: Creative Services, Provo
Contributing authors:
Linda Anderson, Vitek Boruvka, Michael Eisa, David Harris, Sudz Khawaja, Ken Lowrie, Rudy
McNeese, Clint McVey, Paige Parker, Randy Reddy, Carol Rylander, Glenn Stephens, Aslam
Tejani, Maggie Walczynski
Special thanks to the Developer Support, Development, Developer Relations, Product Marketing,
and Marketing Communications staff who contributed time and valuable input.
Novell, the N design, NetWare, Btrieve, XQL and LAN WorkPlace are registered trademarks,
NetWare System Calls for DOS, NetWare Loadable Module (NLM), NetWare SQL, NetWare
Btrieve, Xtrieve PLUS, NetWare C Interface for DOS, NetWare System Interface Technical
Overview, NetWare RPC, NetWare RPC 386, TCPort, TTS, NetWare LU6.2, Report Executive,
and Professional Development Series (PDS) are trademarks, and Professional Developers' Forum
(PDF), NetWire, Direct Connect and Professional Developers' Program (PDP) are servicemarks
of Novell, Inc. Apple, Macintosh, AppleTalk and HyperCard are registered trademarks of Apple
Computer, Inc. CompuServe is registered trademark of CompuServe Corporation. Microsoft is a
registered trademark, and Windows, Excel and Visual Basic are trademarks of Microsoft, Inc.
IBM and OS/2 are registered trademarks, and SAA is a trademark of International Business
Machines Corporation. Sun Microsystems and NFS are registered trademarks of Sun
Microsystems, Inc. WATCOM is a trademark of WATCOM Systems, Inc.
International Customers please contact your local Novell authorized dealer or nearest Novell
office.
|