[Top] [Prev] [Next] [Bottom]

IntranetWare HostPrint Exit Routines


IntranetWare HostPrint includes an "exit routine" interface. This facility permits customized, nonstandard processing of the printer data stream after it has been processed by HostPrint but before it is sent to the NetWare print queue. A typical use of this facility would be to look for special, unusual sequences of printable characters and replace them with printer-specific control codes.

HostPrint includes two sample "exit routine" NLMs: HPESC and HPNIBBLE. This appendix documents these sample routines. You can find these NLMs, source code as well as executable code, in the \EXITNLMS directory on the HostPrint media.

Using IntranetWare HostPrint Exit Routines

Always load the exit routine NLM before loading the HostPrint NLM. HostPrint will not recognize or use the exit routines unless the exit routine NLM (in the case below, HPNIBBLE) is loaded first. For example,

load hpnibble

load hostprt

Only one exit routine NLM can be loaded. If you attempt to load a second exit routine NLM, it will fail to load (NetWare will report that it contains global symbols that have already been exported).

You can load and unload the HostPrint NLM while the exit routine NLM remains loaded. Think of the exit routine NLM as a "library NLM" (similar to CLIB.NLM). Leave the exit routine NLM loaded, and it will always be there when you need it.

How to Use the HPESC.NLM Sample Exit Routine

This sample exit routine NLM is designed to detect one or two special character strings in the ASCII output that is being sent to a printer and to replace them with a single ASCII "escape" code (hex 1B) wherever they occur.

HPESC.NLM has a number of command-line parameters that allow you to specify the special character strings and to control on which printer sessions the substitution will be performed. By default (that is, if no command-line parameters are entered), HPESC will look for the two strings ¬1B (see Note 1) and $£1B£ (see Note 2) and replace them with the "escape" code on all printer sessions.

1. All HostPrint exit routines operate on the data after it has been translated from EBCDIC to ASCII. In HPESC, the default string ¬1B has been encoded using ASCII code page 100, which is the ASCII code page that is normally configured for Hewlett-Packard LaserJet printers in the printer definitions supplied with HostPrint. (ASCII code page 100 is also known as "Roman-8" in Hewlett-Packard printer documentation and as the "ANSI character set" in Microsoft Windows documentation.)

If you re-enter this string from the NetWare console, using the /s1=1B command-line parameter, you will be entering it in the ASCII code page used by the PC BIOS, which is usually ASCII code page 437. This will not work correctly unless the printer definition customized for the target printer specifies a compatible ASCII code page (such as 437 or 850). If the target printer is customized for ASCII code page 100 and you wish to re-enter the ¬ character from the NetWare console, hold the <Alt> key and enter 172 from the numeric keypad (it will display as the ¼ character, but it will actually be the code for ¬ in ASCII code page 100).
2. In HPESC, the default string $£1B£ has been encoded using ASCII code page 100, the code page that is normally configured for Hewlett-Packard LaserJet printers used with HostPrint. If you re-enter this string from the NetWare console, using the /s2=$£1B£ command-line parameter, you will normally be entering it in ASCII code page 437. If the target printer is customized for ASCII code page 100 and you wish to re-enter the £ characters from the NetWare console, hold the <Alt> key and enter 163 from the numeric keypad (they will display as ú characters, but they will actually be the code for £ in ASCII code page 100).

The complete syntax for HPESC is

load hpesc [parameter-1] [parameter-2] ...

The optional parameters can be entered in any order. They can be any of the following:

/lu=*

indicates that both LU type 1 and LU type 3 printer sessions are to be processed by the exit routine NLM. This is the default.

/lu=1

indicates that only LU type 1 printer sessions are to be processed by the exit routine NLM.

/lu=3

indicates that only LU type 3 printer sessions are to be processed by the exit routine NLM.

/p=x

(where x is any string of 0 to 32 characters) indicates that the exit routine NLM is to process only printer sessions that match the printer device name x. A zero-length string (/p=) matches all printer device names; this is the default. Any other string is considered to match all printer device names that start with the specified string, regardless of case (uppercase, lowercase, or mixed).

If you want to match a printer device name that contains embedded blanks, you must enclose the entire parameter in a pair of double-quotation marks. For example: "/p=pcl custom".

/s1=x

(where x is any string of 0 to 7 characters) specifies a string of ASCII characters that are to be replaced by a single ASCII "escape" code. The default is /s1=¬1B (in ASCII code page 100). A zero-length string (/s1=) turns off the "string 1" replacement function.

ASCII characters with codes of 128 and above can be entered from the NetWare console by holding the <Alt> key and using the decimal digit keys on the numeric keypad.

Be sure to enter the decimal code that applies to the desired character in the code page used by the target printer, even though this code may display as a different character on the NetWare console screen. For example, Hewlett-Packard LaserJet printers are normally configured to use ASCII code page 100, but the NetWare console normally uses ASCII code page 437 to display characters on the screen. (ASCII code page 100 is also known as "Roman-8" in Hewlett-Packard printer documentation and as the "ANSI character set" in Microsoft Windows documentation, whereas ASCII code page 437 is the hardware or OEM character set used by IBM-compatible personal computers.)


/s2=x

(where x is any string of 0 to 7 characters) specifies a string of ASCII characters that are to be replaced by a single ASCII "escape" code. The default is /s2=$£1B£ (in ASCII code page 100). A zero-length string (/s2=) turns off the "string 2" replacement function.

How to Use the HPNIBBLE.NLM Sample Exit Routine

This sample exit routine NLM is designed to enter "nibblization mode" when it detects a specific character string in the ASCII output that is being sent to a printer. While in "nibblization mode," each pair of printable hexadecimal characters that is found in the ASCII output is replaced with a single ASCII code that has the hex value specified by the two printable characters. If the printable character pair 1B is found in the output, the two characters are replaced with a single ASCII "escape" code (hex 1B). "Nibblization mode" ends when a second (possibly identical) character string is encountered during the "nibblization mode" processing.

HPNIBBLE.NLM has a number of command-line parameters that allow you to specify the special character strings and to control on which printer sessions the substitution will be performed. By default (that is, if no command-line parameters are entered), HPNIBBLE will look for the string %% to both start and end the "nibblization mode" processing.

The syntax for the HPNIBBLE NLM is

load hpnibble [parameter-1] [parameter-2] ...

The optional parameters can be entered in any order. They can be any of the following:

/lu=*

indicates that both LU type 1 and LU type 3 printer sessions are to be processed by the exit routine NLM. This is the default.

/lu=1

indicates that only LU type 1 printer sessions are to be processed by the exit routine NLM.

/lu=3

indicates that only LU type 3 printer sessions are to be processed by the exit routine NLM.

/p=x

(where x is any string of 0 to 32 characters) indicates that the exit routine NLM is to process only printer sessions that match the printer device name x. A zero-length string (/p=) matches all printer device names; this is the default. Any other string is considered to match all printer device names that start with the specified string, regardless of case (uppercase, lowercase, or mixed).

If you want to match a printer device name that contains embedded blanks, you must enclose the entire parameter in a pair of double-quotation marks. For example: "/p=pcl custom".

/s=x

(where x is any string of 1 to 7 characters) specifies the string of ASCII characters that indicates the start and/or end of "nibblization mode." The default is /s=%%.

ASCII characters with codes of 128 and above can be entered from the NetWare console by holding the <Alt> key and using the decimal digit keys on the numeric keypad.

Be sure to enter the decimal code that applies to the desired character in the code page used by the target printer, even though this code may display as a different character on the NetWare console screen. For example, Hewlett-Packard LaserJet printers are normally configured to use ASCII code page 100, but the NetWare console normally uses ASCII code page 437 to display characters on the screen. (ASCII code page 100 is also known as "Roman-8" in Hewlett-Packard printer documentation and as the "ANSI character set" in Microsoft Windows documentation, whereas ASCII code page 437 is the hardware or OEM character set used by IBM-compatible personal computers.)

/s1=x

(where x is any string of 1 to 7 characters) specifies the string of ASCII characters that indicates the start of "nibblization mode." The default is /s1=%%.

/s2=x

(where x is any string of 1 to 7 characters) specifies the string of ASCII characters that indicates the end of "nibblization mode." The default is /s2=%%.

Coding IntranetWare HostPrint Exit Routines

The \EXITNLMS directory on the HostPrint product diskettes includes source code for the two sample exit routine NLMs. In addition, this directory contains .BAT files and .RSP files that can be used to compile and link the sample NLMs. These procedures use the C language compiler and the WLINK linker from the Novell NLM Software Developer's Kit (SDK). See Figure F-1 and Figure F-2.

Figure F-1
Compile Step for Exit Routine NLMs


COMPILE.BAT file:

rem drive "n:" is a network drive that has the NetWare NLM SDK

set inc386=n:\nwsdk\nlm\v3.0\novh;n:\compile\wcc\nlm\v9.01\h

n:\compile\wcc\nlm\v9.01\bin\wcc386p /3s /fpc %1


Before coding your own exit routine NLMs, you should study the source code for the two sample NLMs. You can also use the source code for the sample NLMs as a "starting point," adding whatever variations and modifications you require.

Figure F-2
Typical Link Step for Exit Routine NLMs


LINKESC.BAT file:

n:\compile\wcc\nlm\v9.01\binb\wlink @hpesc.rsp

HPESC.RSP file:

form novell nlm `IntranetWare HostPrint EXIT Routines'

name hpesc.nlm

file n:\nwsdk\nlm\v3.0\novi\prelude.obj

file hpesc.obj

debug novell

export HPStartOfJobExit, HPASCIIDataExit, HPEndOfJobExit

import @n:\nwsdk\nlm\v3.0\novi\clib.imp

option screenname `none'

option version=1.0

option copyright `Copyright (c) 1994, Novell, Inc.'

option map

option verbose

module clib.nlm


Exit Routine Interface Specifications

A HostPrint exit routine NLM must have a "main" function (to initialize the NLM-see the sample NLMs for details). Otherwise, an exit routine NLM is designed essentially as a "library" NLM (like CLIB.NLM), that is, the exit routine NLM implements one or more "exit functions" that are called at certain times by the regular HostPrint NLM.

Three exit functions are defined as the interface to the exit routine NLM. Most exit routine NLMs will implement all three of these functions; however, it is possible to implement only one or two of them. The regular HostPrint NLM will call only those exit functions that are actually present in the exit routine NLM.

So that the regular HostPrint NLM can find the exit functions, the exit function names must be exported when the exit routine NLM is linked. See Figure F-2.

Start of Job Exit Function

This function is called at the start of each new print job, before any data is output to the NetWare print queue. The main purpose of this function is to allow the exit routine NLM to allocate its own control block to be used for processing the job.

Your exit routine NLM will probably need to have its own control block, allocated on a "per session" basis, to keep track of the state of the data that is passed to the ASCII Data Exit function (see the next section for details). You can allocate such a block in this function and pass its address back to the regular HostPrint NLM; thereafter, the address of your control block will be passed by the regular HostPrint NLM on every call to an exit function for that session. You can free your control block in the End of Job Exit function (and allocate a new one the next time the Start of Job Exit function is called) or you can keep it around for the duration of the entire host session. When the regular HostPrint NLM is unloaded, it will free any exit routine NLM control blocks that are still allocated.

The function name is HPStartOfJobExit. The parameters are:

unsigned char lutype

1 - the session is currently bound as LU type 1

3 - the session is currently bound as LU type 3

char *PrintDefName

Pointer to a character string that contains the print device name currently being used for this session.

void **ExitBlockPtrPtr

Pointer to a memory location that contains a pointer to the exit routine NLM's own control block for this session.

If no such control block has previously been identified to HostPrint, the memory location pointed to by ExitBlockPtrPtr contains 0. In that case, the exit routine can store the address of its control block in the memory location pointed to by ExitBlockPtrPtr. For example:

if (!*ExitBlockPtrPtr)
*ExitBlockPtrPtr = calloc(1, ...);

ASCII Data Exit Function

This function is called whenever a buffer full of ASCII data is ready to be sent to the NetWare print queue. All data, including the job initialization control code sequence (if any), is passed to this function. The only exception is the job termination control code sequence (if any), which is passed to the End of Job Exit function.

This function performs the principal processing of the exit routine NLM. The typical activity performed by this function is to examine the ASCII data buffer for specific character strings and to replace them with special control codes whenever they occur. If the string is more than one character in length, this exit function must be prepared to handle strings that start in one buffer and end in another (on the next call to this exit function). This exit function must also be able to "back off" from processing a sequence if it starts out matching the special sequence but later turns out to be different. These requirements mean that the exit functions must keep track of the character string in a control block that is allocated on a "per session" basis (see "Start of Job Exit Function" on page F-8).

The function name is HPASCIIDataExit. The parameters are:

unsigned char lutype

1 - the session is currently bound as LU type 1

3 - the session is currently bound as LU type 3

char *PrintDefName

Pointer to a character string that contains the print device name currently being used for this session.

void **ExitBlockPtrPtr

Pointer to a memory location that contains a pointer to the exit routine NLM's own control block for this session.

unsigned char **DataPtrPtr

Pointer to a memory location that contains a pointer to the ASCII data buffer that is ready to be printed.

The exit routine can modify the data in the buffer pointed to by *DataPtrPtr, but the length of this buffer cannot be increased. If the exit routine needs to expand the data, it must allocate its own buffer and place the address of the new buffer in the memory location pointed to by DataPtrPtr. For example,

original_ptr = *DataPtrPtr;
*DataPtrPtr = calloc(1, *LengthPtr + ...);

The exit routine must not free the original buffer; HostPrint will take care of freeing both the original buffer and any new buffer that may be allocated by the exit routine.

unsigned int *LengthPtr

Pointer to a memory location that contains the length of the data in the ASCII data buffer that is ready to be printed.

If the exit routine increases or decreases the length of the data to be printed, the new length must be set in the memory location pointed to by LengthPtr. For example,

*LengthPtr = ...;

End of Job Exit Function

This function is called at the end of each new print job, at the time that the job termination control code sequence (if any) is output to the NetWare print queue (but after all other data has been output). The main purpose of this function is to allow the exit routine NLM to "clean up." For example, if a part of a character string was detected at the end of the previous call to the ASCII Data Exit function, the NLM would abandon the sequence, output the partial sequence as ordinary ASCII data, and reset the state to "normal" in the exit routine control block (or free the control block altogether-if your strategy is to allocate a new control block at the start of each job-in the Start of Job Exit function).

The function name is HPEndOfJobExit. The parameters are:

unsigned char lutype

1 - the session is currently bound as LU type 1

3 - the session is currently bound as LU type 3

char *PrintDefName

Pointer to a character string that contains the print device name currently being used for this session.

void **ExitBlockPtrPtr

Pointer to a memory location that contains a pointer to the exit routine NLM's own control block for this session.

If the exit routine frees its own control block prior to returning to HostPrint, the exit routine must store zero in the memory location pointed to by ExitBlockPtrPtr. For example,

*ExitBlockPtrPtr = 0;
unsigned char **DataPtrPtr

Pointer to a memory location that contains a pointer to the job termination control code sequence that is ready to be printed.

The exit routine must not modify the data in the buffer pointed to by *DataPtrPtr. If the exit routine needs to change this data in any way, it must allocate its own buffer and place the address of the new buffer in the memory location pointed to by DataPtrPtr. For example,

original_ptr = *DataPtrPtr;
*DataPtrPtr = calloc(1, *LengthPtr + ...);

The exit routine must not free the job termination control code sequence buffer; HostPrint will take care of freeing any new buffer that may be allocated by the exit routine.

unsigned int *LengthPtr

Pointer to a memory location that contains the length of the data in the ASCII data buffer that is ready to be printed.

If there is no job termination control code sequence, *LengthPtr will be zero. If the exit routine increases or decreases the length of the data to be printed, the new length must be set in the memory location pointed to by LengthPtr. For example,

*LengthPtr = ...;


[Top] [Prev] [Next] [Bottom]

usib2hpd@vnet.ibm.com
Copyright © Novell, Inc. and International Business Machines Corporation 1998. All rights reserved.