选择用户模式或内核模式

重要

建议使用 Microsoft 的 IPP 收件箱类驱动程序以及打印支持应用 (PSA) ,自定义 Windows 10 和 11 中的打印体验,以便进行打印机设备开发。

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

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

  • 无限的堆栈空间。

  • 访问 Win32 API。

  • 导致系统崩溃的可能性较小。

  • 使用用户模式调试器,更易于调试。

  • 更好的浮点功能,因为不需要使用图形 DDI 浮点函数。

  • 能够调用任何不属于所述 Microsoft Windows 2000 及更高版本打印机驱动程序体系结构的自定义、供应商提供的用户模式 DLL

在 Windows Vista 中,无法安装内核模式打印机驱动程序。 如果应用程序尝试这样做, (Windows SDK 文档中所述的 AddPrinterDriver 和 AddprinterDriverEx 函数) 将失败,错误代码ERROR_KM_DRIVER_BLOCKED。

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

操作系统版本 打印机图形 DLL 的允许执行模式
Windows NT 4.0 内核 (kernel)
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 转换为用户模式执行。 若要转换,请将 DrvQueryDriverInfo 函数添加到 DLL,然后遵循 用于生成打印机图形 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 数据类型,而不是将图形 DDI 函数用于 GDI Floating-Point 服务