Does this site look plain?

This site uses advanced css techniques

In the process of developing a Windows printer driver, we created this winprinfo tool to allow us to query the printer system from the point of view of an application: there are several APIs that permit a wide range of query. This tool exercises them all and proved to be indispensible in our development.

Table of Contents

IMPORTANT - We don't mind providing support for the tool itself, but explaining what the output means or assisting in driver/application debugging is substantially beyond the scope of this free tool. The Microsoft MSDN documentation is pretty good at explaining what all these things mean, and we encourage you to Google for the names of the API functions in question for more information.

NOTE - this is a console-mode tool: it must be run in an MS-DOS/command window. If you try to run it from Explorer, it will flash a window and exit. This is not a GUI tool.

Download / Build

Both source and binary are available:

We promise that the binary was built from this source and that it performs no shenanigans. We don't promise that it has no bugs. Use at your own risk.

This code was built with Microsoft Visual C++, but strictly in the command-line mode, not using the IDE. In addition, the makefile requires GNU Make (gmake.exe) because we simply cannot stand Microsoft's NMAKE. You can get a GNU Make executable for Win32 here.

We built this to run strictly on NT/Win2000/XP platforms: if it works at all on Win95/98/ME, we'd be very surprised.


Once a printer has been opened, there are several Win32 API calls that can be used to query the device. These are DeviceCapabilities(), GetDeviceCaps, and EnumForms() (there may be more, but we'll add them as we discover them.

Driver Info / GetPrinterDriver()
By fetching a DRIVER_INFO_4 object for this printer, we're able to show the version (kernel or user), as well as the paths used for all the support files (driver and UI DLLs, plus the dependent files).
DEVMODE / DeviceCapabilities()
A central data structure involved in printing is the DEVMODE, which is a collection of settings that apply to a printjob. Each printer has a group of default settings that are used in the absense of any user input on the subject, and they are managed with the printer's setup GUI.
Using the DeviceCapabilities() API function, we are able to extract a number of individual parameters from the DEVMODE and report them.
Since a printer is a "graphics device", there are some kinds of parameters that are in common with other devices such as video displays. The GetDeviceCaps() call returns a small set of numeric parameters, many of which have no real interest to printer developers.
The NT print spooler supports the notion of "forms", which is simply a way of attaching a name to a specifically-sized piece of output media. There are built-in sizes such as Letter and Legal, but there are at least a hundreds defined for oddball paper sizes all over the world. A print driver can define additional forms as well, though the interaction between the central forms database and the driver is still a little unclear.

The output is quite verbose, and this shows part of the results for the HP LaserJet 4200 named "Upstairs LaserJet" (run on Win2000):

C> winprinfo --printer="Upstairs LaserJet"
winprinfo 1.0.1 - 2003-10-02 -

Querying printer "Upstairs LaserJet" via port ""
Printer Upstairs LaserJet is open
fetched DEVMODE, 4360 bytes
  Numeric parameters:
    DC_COLLATE         1
    DC_COPIES          9999
    DC_DRIVER          1280
    DC_DUPLEX          0
    DC_EXTRA           4140
    DC_FIELDS          0x781ff43
    DC_MINEXTENT       w=  98.4 h= 190.5 mm
    DC_MAXEXTENT       w= 297.0 h= 431.8 mm

The full output can be found HERE.

Command Line Parameters

When winprinfo is run without command-line arguments, it reports a short "help" listing that summarizes the options available, which are expanded.

Show a brief help listing, then exit.
Show the program's version information, then exit.
Show the current default printer, then exit.
C> winprinfo --default
Default = "HP4200 PS"
Query printer name "P", which must be enclosed in quotes if it contains spaces. Example: --printer="Upstairs LaserJet". Case does not seem to be significant in the printer name.
This allows providing the name of the "port", the channel through with the print data is sent to the device, but this is not usually required. Ports can be things like "COM3:" or "LPT1:", but the default of the empty string seems to be sufficient.
Internally, all measurements are maintained and displayed in millimeters, but they can also be shown in inches.
As above, but also show PostScript "points" (1/72nd of an inch units).
Disable the EnumForms step.
Enumerate all the printers on the local system. It's used to find out the proper printer names for use with the --printer=P parameter, and it overrides all the other parameters.
Enumerate all the Print Providers on the current system:
C> winprinfo --enumproviders
[0] name    = "Windows NT Local Print Providor"
    comment = "Locally connected Printers"
    descr   = "Windows NT Local Printers"

[1] name    = "Windows NT Remote Printers"
    comment = "Remote Printers"
    descr   = "Microsoft Windows Network"

[2] name    = "Windows NT Internet Provider"
    comment = "Internet URL Printers"
    descr   = "Windows NT Internet Printing"
Enumerate all the Print Processors on the current system, along with the directory where the processors are found (which is associated with the current environment).
C> winprinfo --enumprocessors
Print processor dir:

[0] Processor = "ModiPrint"
    Datatype  = "RAW"
    Datatype  = "NT EMF 1.006"
    Datatype  = "NT EMF 1.007"
    Datatype  = "NT EMF 1.008"
    Datatype  = "TEXT"

[1] Processor = "HPPRN05"
    Datatype  = "RAW"
    Datatype  = "RAW [FF appended]"
    Datatype  = "RAW [FF auto]"
    Datatype  = "NT EMF 1.003"
    Datatype  = "NT EMF 1.006"
    Datatype  = "NT EMF 1.007"
    Datatype  = "NT EMF 1.008"
    Datatype  = "TEXT"

[2] Processor = "WinPrint"
    Datatype  = "RAW"
    Datatype  = "RAW [FF appended]"
    Datatype  = "RAW [FF auto]"
    Datatype  = "NT EMF 1.003"
    Datatype  = "NT EMF 1.006"
    Datatype  = "NT EMF 1.007"
    Datatype  = "NT EMF 1.008"
    Datatype  = "TEXT"

Version history

This is a simple mirror of the revision log in our development environment, but it might lag a bit behind the version of the executable actually found on the web.

2006-07-22 1.1.0
--- Added enumeration of driver configuration

2005-05-24 1.0.9
--- Added --default

2005-05-04 1.0.8
--- Added --enumproviders & --enumprocessors

2005-02-15 1.0.7
--- Added PRINTER_INFO_2 data

2004-07-28 1.0.6
-- Minor packaging updates

2003-10-13 1.0.5
-- Lots of PC-Lint-suggested cleanups

2003-10-10 1.0.4
-- Added remote-server support

2003-10-10 1.0.3
-- Fixed error message when --printer option omitted

Thu Oct  9 20:44:21 PDT 2003 -- version 1.0.2
-- Added the "--enum" parameter

Thu Oct  2 13:22:20 PDT 2003 -- version 1.0.1
-- Initial release