1.介绍

1.1 官方文档

Windows 开发人员文档 – Windows drivers | Microsoft Docs

打印设备 – Windows drivers | Microsoft Docs

Wine Developer’s Guide/Architecture Overview – WineHQ Wiki

Introduction to Print Providers – Windows drivers | Microsoft Docs

1.2 打印流程

应用程序打印流程

Introduction to Spooler Components – Windows drivers | Microsoft Docs

应用

打印应用程序通过调用 GDI 函数创建打印作业。

GDI

图形设备接口 (GDI) 包括用户模式和内核模式组件。 需要图形支持的 Win32 应用程序使用用户模式组件 Microsoft Win32 GDI。 内核模式组件 graphics engine(or graphics rendering engine) 导出图形设备驱动程序可以使用的服务和函数。

Winspool.drv

Winspool.drv 是后台处理程序spooler的客户端接口。 它导出组成后台处理程序的 Win32 API 的函数,并提供用于访问服务器的 RPC stubs。 (GDI 是主要客户端,但应用程序也会调用其一些 Win32 functions.)

Spoolsv.exe

Spoolsv.exe是后台处理程序spooler的 API 服务器。 它作为 Windows 2000 (或更高版本) 服务实现,该服务在操作系统启动时启动。 此模块是将 RPC 接口导出到后台处理程序 Win32 API 的服务器端。 Spoolsv.exe客户端包括本地 Winspool.drv 以及远程Win32spl.dll 。 该模块实现一些 API 函数,但大多数函数调用通过Router (Spoolss.dll) 传递给打印提供程序。

Router

路由器Spoolss.dll根据每个函数调用提供的打印机名称或句柄确定要调用的打印提供程序,并将函数调用传递给正确的提供程序。

Print Provider

支持指定打印设备的打印提供程序。

Print Monitor

Windows XP 支持两种类型的打印监视器:语言监视器和端口监视器。

Print Provider

打印提供程序简介 – Windows drivers | Microsoft Docs

Print Provider 负责将打印作业定向到本地或远程打印设备。 它们还负责打印队列管理操作,例如启动、停止和枚举服务器的打印队列。 打印提供程序定义打印服务器与计算机无关的高级操作系统视图。

所有 Print Provider 都实现一组通用的打印提供程序功能。 这些功能由一组 API 函数定义,这些函数由后台处理程序的路由器 (Spoolss.dll) 调用。

由 Print Provider 定义的大多数函数都需要打印机句柄作为输入。 Print Provider 客户端通过调用 Microsoft Windows SDK 文档) Winspool.drv 中所述的OpenPrinter(来获取打印机句柄,该文档调用 API 服务器 (Spoolsv.exe) 。 后台处理程序的路由器 (Spoolss.dll) 调用每个打印提供程序的OpenPrinter函数,直到其中一个提供打印机句柄和一个返回值,指示打印提供程序识别指定的打印机名称。 然后,路由器将自己的句柄返回到 API 服务器。 路由器的句柄包括打印机句柄和提供程序句柄。 此句柄将返回到应用程序,以便可以将来自应用程序的后续调用定向到正确的提供程序和打印机。

通过支持预定义的 API 函数集,Microsoft Windows 2000 及更高版本的 Print Provider 可以提供以下功能:

  • 打印队列管理添加、删除、打开、关闭、枚举和设置打印队列的参数。 此外,提供打印队列状态更改的通知。
  • 打印机驱动程序管理添加、删除、枚举和指定打印机驱动程序的目录。
  • 打印作业创建启动和结束文档、开始和结束文档页、将作业的数据流写入端口、读取打印机状态信息。
  • 打印作业计划计划、枚举和设置打印作业的参数。
  • 窗体管理添加、删除、枚举和设置打印窗体的参数。
  • 打印处理器管理添加、删除、枚举、指定 的目录以及打印处理器支持的数据类型。
  • 打印监视器管理添加、删除和枚举打印监视器。
  • 端口管理添加、删除、配置、枚举和设置打印机端口的参数。
  • 注册表管理创建、删除和枚举与打印提供程序关联的注册表项和值。
  • 其他功能显示消息框、关闭打印提供程序、读取内存映射的后台文件,在端口监视器 UI DLL 和端口监视器服务器 DLL 之间提供通信路径。

这些功能作为一组由打印提供程序定义的函数实现。

系统自带的 Print Provider

Microsoft 提供以下打印提供程序,Windows 2000 及更高版本:

  • Localspl.dll

本地打印提供程序。 处理定向到从本地服务器管理的打印机的所有打印作业。

  • Win32spl.dll

Windows网络打印提供程序。 处理定向到远程 Win32 (基于 NT 的操作系统或工作组) 服务器的Windows的打印作业。 当作业到达远程服务器时,它将传递到服务器的本地打印提供程序。

  • Nwprovau.dll

Novell NetWare 打印提供程序。 处理定向到 Novell NetWare 打印服务器的打印作业。

  • Inetpp.dll

HTTP 打印提供程序。 处理发送到 URL 的打印作业。

Localspl.dll

本地打印提供程序 – Windows drivers | Microsoft Docs

警告从Windows 10开始,支持第三方打印提供程序的 API 已弃用。 Microsoft 不建议对第三方打印提供商进行任何投资。 此外,在 v4 打印驱动程序模型的Windows 8和较新版本的产品上,第三方打印提供程序可能无法创建或管理使用 v4 打印驱动程序的队列。

Microsoft Windows 2000 及更高版本的本地打印提供程序为所有通过本地打印提供商的端口监视器访问的打印机提供作业控制和打印机管理功能。 (客户端管理员在使用“添加打印机向导”时选择“本地打印机”选项设置对此类打印机的访问权限。) 此类打印机包括连接到本地系统的串行和并行端口的打印机。 它们还可以包括连接到其他 I/O 通道的设备,例如 SCSI 端口,以及连接到远程非 NT 操作系统服务器的打印机。

本地打印提供程序实现由打印提供程序定义的整个函数集。 它还提供以下功能:

  • 打印作业后台处理程序,其中对定向到本地可访问的打印队列的作业进行反池处理。
  • 支持 Windows 2000 及更高版本的操作系统版本的打印机驱动程序体系结构,并调用本地打印机接口 DLL。
  • 对供应商提供的打印处理器的支持 (请参阅编写打印处理器) 。
  • 对供应商提供的打印监视器的支持 (请参阅编写打印监视器) 。

下图提供了一个 (一些简化的) 视图控制流在本地打印机提供程序的组件之间,当应用程序创建打印作业时。

如图所示,应用程序通过调用图形驱动程序接口 (GDI) 来创建打印作业。 无论打印作业的初始输出格式是否为 EMF,本地打印提供程序的作业创建 API 都会创建后台处理程序文件。 稍后,当计划作业时,将读取后台处理程序文件,并且,如果格式是增强型图元文件 (EMF),则 EMF 打印处理器(winprint.dll)会将作业发送回 GDI 以转换为 RAW 格式,并借助打印机驱动的打印机图形 DLL。 然后,可以通过本地打印提供程序将转换后的数据流发回打印机 (而无需重新打印) 。

打印机图形 DLL(驱动)

打印机图形 DLL – Windows drivers | Microsoft Docs

打印机图形 DLL 实现使用图形 DDI中所述的 Drv 前缀图形 DDI 函数。 这些 DLL 具有以下两个职责:

  • 协助 GDI rendering 打印作业:打印机图形 DLL 可以提供图形 DDI 绘图函数来处理必须以设备特定的方式执行的绘图操作,因此不能由 GDI 的r endering engine 单独处理。
  • 将 rendered的数据流传送到后台处理程序 spooler:打印机图形 DLL 通常生成 spooler 可以通过打印监视器发送到打印机硬件的RAW 数据类型 输出流(包括命令序列) ,。

打印机图形DLL必须提供的渲染辅助取决于打印机类型,具体取决于硬件的绘图能力,包括以下场景:

  • GDI rendering engine 使用 GDI-managed surface 执行所有渲染。 图形 DLL 不提供任何 DDI 绘图函数。
  • 图形 DLL 提供了一些图形 DDI 绘图函数与 GDI 的 rendering engine 结合使用,并使用 GDI-managed surface。图形DLL提供的图形DDI绘图功能可以选择性地回调GDI rendering engine 的GDI 支持服务。
  • 图形 DLL 通过提供图形 DDI 绘图函数和使用GDI-managed surface 执行所有渲染。

例如,Microsoft 通用打印机驱动程序(Unidrv) 使用 GDI-managed surface 并提供一些图形 DDI 绘图功能,而Microsoft PostScript打印机驱动程序使用 device-managed surface.。

有关在图形驱动程序中提供 rendering 帮助的详细信息,请参阅Surface Types和Using the Graphics DDI。

下图说明了应用程序使用 GDI 创建打印作业时发生的数据流与EMF 录制和播放组合在一起。

请注意,在这些关系图中,如果 GDI 的输出格式增强 (EMF) ,则在 EMF打印处理器播放 EMF 记录之前,打印机图形 DLL 不会接收作业。 另请注意,EMF 打印处理器将输出格式更改为非 EMF。

此图演示了完全本地环境。 如果打印机连接到服务器,则 EMF 记录通常由客户端的 GDI 呈现引擎副本生成, (GRE) ,然后后台处理程序到发送到服务器的本地文件。 服务器后台处理程序的副本读取文件,并将记录发送到服务器的 EMF 打印处理器,服务器 GRE 的副本调用服务器的打印机图形 DLL。

用户模式打印机图形 DLL

注意在 Windows Vista 打印机图形 DLL 中,只能在用户模式下执行。 有关详细信息,请参阅选择用户模式或内核模式。

内核模式打印机图形 DLL

1.3 其他文档

Windows打印体系结构之打印假脱机(Print Spooler)

打印机驱动程序的基础知识 – 豆丁网 (docin.com)

1.4 DDK

下载 Windows 驱动程序工具包 (WDK) – Windows drivers | Microsoft Docs

2. GDI 打印机驱动

所有 Windows 2000 及更高版本的打印机驱动程序都由以下组件组成:

  • 一种打印机图形 DLL,可帮助 GDI 呈现打印作业,并将呈现的数据流发送到打印后台处理程序。
  • 一个打印机接口 DLL,该 DLL 提供驱动程序配置参数的用户界面,以及后台处理程序可以调用的接口来通知驱动程序与打印相关的系统事件。

此外,Microsoft 提供的打印机驱动程序使用打印机数据文件。

  • Microsoft 通用打印机驱动程序介绍(GPD) 文件的一般打印机说明。
  • Microsoft PostScript 打印机驱动程序介绍(PPD) 文件 PostScript 打印机说明。
  • Microsoft 绘图仪驱动程序介绍(PCD) 文件的绘图仪特性数据。

2.1 打印机图形函数

打印机图形 DLL 定义的函数 – Windows drivers | Microsoft Docs

打印机图形 DLL 实现使用图形 DDI中所述的 Drv 前缀图形 DDI 函数。 这些 DLL 具有以下两个职责:

  • 协助 GDI 呈现打印作业。打印机图形 DLL 可以提供图形 DDI 绘图函数来处理必须以设备特定的方式执行的绘图操作,因此不能由 GDI 的呈现引擎独占处理。
  • 将呈现的数据流传送到后台处理程序。打印机图形 DLL 通常在RAW 数据类型中生成输出流, (包括命令序列) 后台处理程序可以通过打印监视器发送到打印机硬件。

与所有图形驱动程序一样,打印机图形 Dll 负责定义以下图形 DDI 函数。 按照DrvEnableDriver,初始驱动程序入口点,其余函数按字母顺序列出。 GDI 通过DrvEnableDriver返回的函数指针数组调用所有其他显示驱动程序函数。

打印机图形 DLL 定义的函数

函数名称

说明

DrvEnableDriver

允许驱动程序自行初始化并返回指向支持的图形 DDI 函数的指针。

DrvCompletePDEV

向设备实例提供具有 GDI 句柄的驱动程序。

DrvDisableDriver

(可选的) 允许驱动程序在卸载之前执行清理操作。

DrvDisablePDEV

允许驱动程序删除特定于设备实例的信息。

DrvDisableSurface

允许驱动程序删除绘图图面。

DrvEnablePDEV

允许驱动程序提供具有物理设备特征的 GDI,并初始化特定于设备实例的信息。

DrvEnableSurface

允许驱动程序创建绘图图面。

DrvQueryDeviceSupport

(可选) 返回请求的特定于设备的信息。

DrvQueryDriverInfo

(可选) 返回请求的特定于驱动程序的信息。

打印机图形 Dll 还负责定义下列打印特定图形 DDI 函数,这些函数在呈现打印作业的过程中的特定点调用。

函数

调用时

DrvEndDoc

当 GDI 完成将文档发送到要呈现的驱动程序时。

DrvNextBand

当 GDI 完成为物理页面绘制带区时, (可选) ,以便驱动程序可以将带区发送到打印机。

DrvQueryPerBandInfo

在 GDI 开始为物理页面绘制带区之前, (可选) ,因此驱动程序可以向 GDI 提供特定于波段的信息。

DrvSendPage

当 GDI 完成了物理页的绘制时,因此驱动程序可以将页发送到打印机。

DrvStartBanding

当 GDI 准备好开始向要呈现的驱动程序中发送物理页面带区时, (可选) 。

DrvStartDoc

当 GDI 准备好开始向驱动程序发送文档以供呈现时使用。

DrvStartPage

当 GDI 准备好开始向要呈现的驱动程序发送文档页面时。

通常,打印机图形 DLL 还会定义完成打印作业呈现所需的任何其他图形 DDI 函数。 定义的函数的数量和类型取决于:

  • 驱动程序是否支持使用 GDI 托管或设备托管的绘图图面的 (或二者) 。 有关详细信息,请参阅表面类型。
  • GDI 操作可由 GDI 处理的范围,而不是由驱动程序本身来执行。 有关详细信息,请参阅使用图形 DDI。

打印机图形 Dll 定义的所有函数都是通过 GDI 的内核模式图形呈现引擎( (GRE) )调用的。

DrvEnableDriver和DrvQueryDriverInfo函数由图形 DLL 导出。 所有其他受支持的图形 DDI 函数的地址都放置在DrvEnableDriver函数返回的表中。

2.2 打印机接口函数

按打印机接口 DLL 定义的函数 – Windows drivers | Microsoft Docs

打印机通常为用户提供大量可修改的配置选项,可以针对打印的每个文档更改这些选项。 必须通过可由应用程序调用的用户界面访问纸张、托盘和字体选择等选项,以及图像分辨率、大小、颜色等。

打印机驱动程序的 打印机接口 DLL在用户模式下执行,负责将用户界面导出到打印机的配置选项。 提供此接口涉及为打印机创建属性表页。 打印 (文件夹) 等应用程序通过调用打印后台处理程序导出的 Win32 函数来显示接口,而后台处理程序则调用打印机接口DLL定义的函数。

为配置选项提供用户界面并不是打印机接口 DLL 的唯一责任。 DLL 还导出后台处理程序可以调用的函数,以通知驱动程序与打印相关的系统事件,例如驱动程序安装和升级,或者打印机添加和连接。

界面部分的功能为用户提供用户界面,用户可以根据自己的需要通过该界面设置不同打印机参数,同时提供一个spooler为通知驱动打印相关的系统事件而能够调用的接口。

打印机接口 Dll 导出下表中列出的函数。

函数

用途

DllEntryPoint

初始 DLL 入口点通常称为 DLLMain (Microsoft Windows SDK 文档) 中所述。

DrvConvertDevMode

将指定的DEVMODEW结构从一个版本转换到另一个版本。

DrvDeviceCapabilities

返回有关打印机功能的请求信息。

DrvDevicePropertySheets

调用CPSUI创建描述打印机属性的属性表页。

DrvDocumentEvent

(可选) 允许打印机接口 DLL 指定与打印文档将处理的文档相关联的事件。

DrvDriverEvent

(可选) 允许打印机接口 DLL 响应来自特定于特定驱动程序事件的后台处理程序的通知。

DrvDocumentPropertySheets

调用 CPSUI 创建描述打印文档属性的属性表页。

DrvPrinterEvent

允许打印机接口 DLL 响应来自特定于打印机的事件已发生的后台处理程序的通知。

DrvQueryColorProfile

(可选) 允许打印机接口 DLL 指定用于颜色管理的 ICC 配置文件。

DrvQueryJobAttributes

(可选) 使打印机接口 DLL 能够指定支持在物理页面上打印多个文档页面的功能, ( “N 向上” 打印) ,打印每个页面的多个副本,以及对页面进行分页。

DevQueryPrintEx

确定是否可以使用打印机的当前配置打印打印作业。

DrvSplDeviceCaps

返回有关打印机功能的请求信息。

DrvUpgradePrinter

(可选) 在将新版本的驱动程序添加到系统时更新打印机的注册表设置。