选择用户模式或内核模式

重要

新式打印平台是 Windows 与打印机通信的首选方式。 建议使用 Microsoft 的 IPP 收件箱类驱动程序以及打印支持应用 (PSA) 来自定义 Windows 10 和 11 中的打印体验,以便进行打印机设备开发。

有关详细信息,请参阅新式打印平台打印支持应用设计指南

与内核模式执行相比,用户模式执行打印机图形 DLL 具有以下优势:

  • 无限制的堆栈空间。

  • 访问 Win32 API。

  • 降低导致系统崩溃的可能性。

  • 使用用户模式调试器更轻松地进行调试。

  • 由于不需要使用图形 DDI 浮点函数,因此具有更好的浮点运算能力。

  • 调用任何定制的、供应商提供的用户模式 DLL 的能力,这些 DLL 不属于所述 Microsoft Windows 2000 及更高版本打印机驱动程序架构的一部分

在 Windows Vista 中,无法安装内核模式打印机驱动程序。 如果应用程序尝试执行该操作,则 AddPrinterDriver 和 AddprinterDriverEx 函数(在 Windows SDK 文档中介绍)将会失败,同时显示错误代码 ERROR_KM_DRIVER_BLOCKED。

下表显示了允许的打印机驱动程序执行模式:

操作系统版本 打印机图形 DLL 允许的执行模式
Windows NT 4.0 内核
Windows 2000 用户或内核
Windows XP 和 Server 2003 现有打印机可使用内核模式;安装新打印机需要使用用户模式
Windows Vista user

在用户模式下使用图形 DDI

用户模式打印机图形 DLL 并不局限于调用 GDI 支持服务和其他 Eng 前缀的图形 DDI 回调函数。 但有些规则必须遵守:

  • 与内核模式图形 DLL 一样,用户模式图形 DLL 也必须调用图形 DDI 来创建或修改绘图图面。 这些回调函数是 GDI 支持服务,不允许调用这些绘图函数的 Win32 对应函数。

    对于用户模式 DLL,对这些绘图回调函数的调用会被用户模式 GDI 客户端拦截,然后将调用传递给 GDI 的内核模式图形呈现引擎 (GRE)。

  • 用户模式 DLL 不能调用下列由 Eng 前缀的图形 DDI 函数:

    EngCreatePath

    EngGetType1FontList

    EngMapModule

    EngDebugBreak

  • 用户模式打印机图形 DLL 可以继续使用图形 DDI 函数来提供 GDI 浮点服务

将现有打印机图形 DLL 转换为用户模式

如果以前开发的打印机图形 DLL 在内核模式下执行,则可以将 DLL 转换为用户模式执行。 要进行转换,请在 DLL 中添加 DrvQueryDriverInfo 函数,然后遵循生成打印机图形 DLL 的规则。

在用户模式下创建新的打印机图形 DLL

要开发在用户模式下执行的新打印机图形 DLL,可以继续使用内核模式 DLL 使用的所有图形 DDI 函数。 但也可使用以下选项:

  • 对于与 Win32 完全对应的 Eng 前缀函数,建议调用 Win32 函数。 下表列出了这些 Eng 前缀函数及其 Win32 对应函数。

    Eng 前缀函数 Win32 等效项
    EngAllocMem HeapAlloc
    EngAllocUserMem HeapAlloc
    EngEnumForms EnumForms
    EngFreeMem HeapFree
    EngFreeUserMem HeapFree
    EngFindImageProcAddress GetProcAddress
    EngGetForm GetForm
    EngGetLastError GetLastError
    EngGetPrinter GetPrinter
    EngGetPrinterData GetPrinterData
    EngGetPrinterDriver GetPrinterDriver
    EngLoadImage LoadLibrary
    EngMulDiv MulDiv
    EngSetLastError SetLastError
    EngSetPrinterData SetPrinterData
    EngUnloadImage FreeLibrary
    EngWritePrinter WritePrinter
  • 对于与具有类似功能的 Win32 函数相对应的 Eng 前缀函数,也建议调用 Win32 函数。 下表列出了这些 Eng 前缀函数及其 Win32 对应函数。

    Eng 前缀函数 Win32 等效项
    EngAcquireSemaphore EnterCriticalSection
    EngCreateSemaphore 分配一个 CRITICAL_SECTION 对象,并通过调用 Win32 InitializeCriticalSection 函数对其进行初始化。
    EngDeleteSemaphore DeleteCriticalSection
    EngFindResource FindResource
    EngFreeModule FreeLibrary
    EngLoadModule LoadLibrary
    EngMultiByteToWideChar MultiByteToWideChar
    EngQueryLocalTime GetLocalTime
    EngReleaseSemaphore ReleaseSemaphore
    EngWideCharToMultiByte WideCharToMultiByte
  • 对于创建或修改绘图服务的函数,新驱动程序必须继续调用 GDI 支持服务,而不是其 Win32 对应服务。

  • 可以使用 FLOAT 数据类型,而不是使用 GDI 浮点服务的图形 DDI 函数。