Opening and Closing a Port

The OpenPort function acquires the specified port and returns a handle to it. The spooler uses this handle to print a job with subsequent calls to StartDocPort, WritePort, ReadPort, and EndDocPort.

For best performance, a port monitor’s implementation of OpenPort should perform all one-time port initializations. For example, localmon’s OpenPort function determines whether the logical port is a file, or a serial or parallel port, and then acquires and/or sets the port’s state as needed in order to print to it. If the port is a serial port, localmon acquires and stores its current control settings and its time-out parameters for later read and write operations by calling the Win32 GetCommState and GetCommTimeouts functions.

If necessary, the monitor should lock down the specified port so that other processes cannot use it.

Port names are unique on a per machine basis, and only one monitor can have a port at any time. For this reason, the spooler never makes two back-to-back OpenPort/OpenPortEx calls on a port with which two logical printers are associated. If the spooler needs to send a print job through the monitor that doesn’t hold the port, and if the port is not being used by the monitor that holds it, the spooler calls ClosePort on the holding monitor before calling OpenPort/OpenPortEx on the needed monitor. This would be true, for example, when a physical printer receives PostScript jobs through one monitor and PCL jobs through a different monitor.

The spooler calls ClosePort when a print job needs to be printed through a different language monitor, when a printer is is no longer associated with the port, and at spooler shutdown. ClosePort should release the port handle and clean up any resources associated with the closed port, such as memory that the monitor allocated for data structures.

OpenPortEx

Language monitors and LMPMs implement OpenPortEx. The spooler passes two additional parameters to this routine: the port monitor’s function pointers and the printer name. A language monitor should validate the port monitor by checking the function pointers for all the port monitor routines it requires. A language monitor acquires a handle to the port monitor when its OpenPortEx routine calls the OpenPort function of the specified port monitor.