How Windows 3.11 Routed Custom Printer Driver Data

In Microsoft Windows 3.11, printing relied on a modular 16-bit architecture that bridged hardware-independent applications with physical hardware through the Graphics Device Interface (GDI) and custom printer drivers. Rather than requiring individual programs to generate device-specific control codes, Windows 3.11 routed high-level drawing commands from applications through GDI.EXE, which interacted directly with a designated driver (.DRV) file. This driver transformed generic graphics primitives into device-specific data streams, such as PostScript, PCL, or proprietary raster signals, before handing the processed output to the Windows Print Manager or directly to local system ports.

The Role of GDI and the Device Driver Interface (DDI)

The printing pipeline began inside an application using standard GDI drawing functions. When an application initiated a print job:

  1. The program obtained a printer Device Context (DC) associated with the targeted output device.
  2. The application issued standard graphics calls—such as TextOut, LineTo, and BitBlt—enclosed within StartDoc and EndDoc calls.
  3. GDI.EXE processed these commands and compared them against the capabilities reported by the active printer driver.

The communication between the GDI and the custom printer driver occurred through the 16-bit Device Driver Interface (DDI). The custom driver exported a mandatory set of entry points, chief among them being Control (used for escape sequences), Enable (to initialize and define the hardware environment), and rendering functions that matched the GDI primitives the device supported.

Custom Printer Drivers as 16-bit DLLs

In Windows 3.11, a custom printer driver was essentially a 16-bit Windows Dynamic Link Library (DLL) with a .DRV file extension. The driver was responsible for advertising its rendering abilities via a device descriptor block (GDIINFO).

If a printer possessed a native hardware-level capability—such as scalable font generation or vector curve rendering—the custom driver handled the GDI call directly and converted the instructions into the printer's native page description language (such as PostScript or HP PCL).

If the hardware lacked native processing capabilities (as was common with budget dot-matrix or ink-jet printers), the custom driver leveraged GDI's internal banding engine. In a banded configuration:

  • The custom driver divided the page into smaller horizontal rectangular bands to conserve conventional memory.
  • GDI rasterized each band into a monochrome or color bitmap in memory.
  • The custom driver extracted the raster bitmap and serialized it into raw, device-specific dot patterns and pin-firing escape codes.

Escape Sequences and ExtEscape

For operations that GDI did not natively encapsulate—such as paper-bin selection, duplexing, draft mode toggles, or direct device-specific configuration—Windows 3.11 used the Control function (historically invoked via the Escape or ExtEscape API).

When an application called an escape function, GDI passed the request, input buffer, and output buffer straight to the driver’s exported Control routine. Custom drivers evaluated these codes to alter their internal state, append specific hardware escape sequences to the print stream, or return device status queries back to the software.

Data Handoff: Print Manager vs. Direct Port I/O

Once the custom driver converted the GDI commands into the final printer language, the resulting byte stream was transferred out of the driver using Windows 3.11's spooling subsystem:

  • Spooling to Print Manager: By default, the driver did not talk directly to physical hardware. Instead, it sent the formatted byte stream through GDI's spooler functions (OpenJob, WriteJob, and CloseJob). These functions wrote the output to a temporary .SPL file on disk. The Windows Print Manager (PRINTMAN.EXE) operated as a background task, reading the .SPL file and sending chunks of data to the designated port.
  • Fast Printing Direct to Port: If spooling was disabled or the "Fast Printing Direct to Port" option was enabled in the Control Panel, the data bypassed disk creation. The output routines bypassed Print Manager and directly transmitted the driver’s data stream to standard MS-DOS communication channels—typically local parallel ports (LPT1 through LPT3) or serial ports (COM1 through COM4).

Hardware Transmission via DOS and BIOS

At the lowest level of the Windows 3.11 print path, data routed to a parallel port reached the hardware through one of two methods:

  1. Virtual Device Drivers (VxDs): In 386 Enhanced Mode, VPICD (Virtual Programmable Interrupt Controller Device) and VPD (Virtual Printer Device) trapped hardware interrupts and managed access to parallel port registers (0x378, 0x278), preventing conflicts between DOS applications and Windows processes.
  2. DOS/BIOS Calls: For standard printing pathways where VxD hardware virtualization was bypassed, Windows issued standard software interrupts (INT 17h for BIOS printer services or INT 21h Function 40h for DOS file/device handles) to write the custom driver's generated byte stream directly across the physical hardware interface.