Print monitor that prints into a directory

Environment: Visual C++ 6.0, Windows NT 4.0 / Windows2000

Recently we had to do some printing on our IIS-Server. Printing on a physically existing printer was no problem. But after that we tried to print into files and send the files to the appropriate user.
Printing to “FILE:”-port caused the spooler-service to ask for a destination file, which you had to type in manually. Of course this was not the right approach for our IIS-server.

After studying the MSDN I found “The Print Monitor API” (refer to this for further information) which explains how to implement a print monitor. A print monitor is a DLL that exports some specific functions to enable the print spooler to do customized tasks–for example to print not to a printer but into a directory.

I used the print monitor example from the Microsoft DDK as a template to implement this print monitor. The example in the DDK was very complicated and did more than I wanted it to do (it should just redirect the print jobs into appropriate files).

Notice that the file WINSPLP.H was shipped with the Microsoft Windows NT 4.0 DDK.


PORTLIST.CPP:

The heart of the our monitor is the CPortList class. It…
…stores all ports in the registry.
…loads the ports from the registry at start-up of the spooler-service.
…holds all handles to opened files.
…supplies a list of all known ports to MyEnumPorts.

Refer to source code for detailed information.


MONITOR.CPP:

It supplies all functions that are exported from the DLL:

InitializePrintMonitor
Called by the spooler-service to obtain pointers to all the other functions, and to do some init tasks, of course.

MyEnumPorts
Called by the spooler-service to obtain a list of the ports of our print monitor

MyOpenPort
Called by the spooler-service to open the port

MyStartDocPort
Called by the spooler-service to start the printing of a print job. This will create a new file in the ports output directory and keep a handle to the opened file.

MyWritePort
Called by the spooler-service to write to the port. This will write some data to the file. Will be called more than once.

MyReadPort
Supplied, but not implemented (no need for)

MyEndDocPort
Called by the spooler-service to write to the port. Called after all the data is written to the file. This will close the file.

MyClosePort
Called by the spooler-service to close the port

MyAddPort
Called by the spooler service to add a new port. The user has to specify the output directory.

MyAddPortEx
supplied, but not implemented (no need for)

WaitForOutput
I added this function to give any application the possibility to wait for finishing a print job. This function expects as a parameter the complete path of the file you are waiting for. This function will return when the file has been completely written.

Notice that the path consists of one byte characters, to simplify interaction with Visual Basic.


INSTALLATION:

To install the DLL just…
1. Copy the DLL to the System32-Directory.
2. Add following entries to the registry:
New key:
“HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlPrintMonitorsLocal Directory Port”
New value:
“HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlPrintMonitorsLocal Directory PortDriver” = “dirport.dll”
3. Restart your Spooler-Service

Thank you for reading this.
Any comments appreciated.

Bye
Peter

Downloads

Download demo project – 23 Kb

Download source – 12 Kb

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read