BRUSHOBJ 为图形函数定义了画刷对象,输出直线、文本或填充 驱动程序能调用 BRUSHOBJ服务来实现画刷或找到GDI预先缓存的实现方 CLIPOBJ 为绘图或填充提供能访问裁剪区的驱动程序。这个区域能用一系列矩形计 算 FLOATOBJ 允许图形驱动程序模拟浮点操作。浮点操作不适用所有其他的核心模式驱 动程序。 FONTOBJ 使驱动程序访问字体的一个特别的实例(或实现)的信息。 PALOBJ 包含RGB调色板颜色的结构:通过 PALOBJ cGetColors和 DrySet palette 函数可以访问。 PATHOBJ 定义路径指定要绘制什么(直线或贝塞尔曲线)。 PATHOBJ结构传递给驱 动程序用以描述要绘制或填充的一系列直线和贝塞尔曲线。 STROBJ 为驱动程序计算轮廓处理和位置的列表,描述如何绘制文本字符串。 SURFOBJ 识别一个表面,它可以是GDI位图、设备相关位图或设备管理的表面。更 多的信息参见表面类型。 XFORMOBJ 描述一个任意的线性二维变换,如几何宽度直线( geometric wide line) XLATEOBJ 主义从源表面格式到目的表面格式转换像素所需要的变换 2.2.1.2GDI服务例程 GDI输出许多服务例程,其名字的形式是Engx。驱动程序动态地连接到win32k.sys 来直接访问这些例程。GDI服务例程包括表面管理、绘图模拟以及路径、调色板、字体和文 本服务。这些服务在CD支持的服务中详细讨论。 2.2.2PDEV协商 任何图形驱动程序的首要任务之一是在驱动程序初始化期间使PDV有效。PDEV是物 理设备的逻辑表现。这个表现由驱动程序定义,一般是私有的数据结构。启用PDEV的更多 的信息参考 Dry Enablepdev。 通过 DrvEnablepDev函数,驱动程序必须给GDI提供信息,描述请求的设备及其能力。 驱动程序给GDI的一条重要信息是 DEVINFO结构的f1 Graphics Caps和f1 Graphics Caps2成 员中的一组图形能力标志( GCAPS XXX和 GCAPS2Xxx标志)。 能力标志允许GDⅠ确定那些操作是PDE支持的。例如,GDI测试能力标志,指示在 GDI尝试用这些基本的类型调用 DryStrokePath函数来绘制路径之前,PDEV是否能处理贝塞 尔曲线和几何宽度直线。如果能力标志指示PDEV不能处理这些基本类型,GDI断开直线或 曲线,使GDI能简化对驱动程序的调用。 从驱动程序一侧来看,无论何时驱动程序从GDI获得一个高级的路径相关的调用,如 果路径或裁剪区对设备进行的处理过于复杂,它可返回 FALSE 当驱动程序处理一条装饰线( cosmetic line)时它不能从 DryStrokePath返回 FALSE 因为它必须为装饰线处理任意复杂的裁剪区或造型。然而,如果路径是贝塞尔曲线或几何直 线, DryStrokePath能够返回 FALSE。当这种情况出现时,GDI把调用分割成简单的调用 就像能力标志位没有置1一样。例如,如果当 DryStrokePath发送一个几何直线时返回 FALSE,GDI简化直线并调用 DryFillPath函数 如果 DryStrokePath被报告一个错误,它必须返回 DDI ERROR 6
6 BRUSHOBJ 为图形函数定义了画刷对象,输出直线、文本或填充。 驱动程序能调用 BRUSHOBJ 服务来实现画刷或找到 GDI 预先缓存的实现方 法。 CLIPOBJ 为绘图或填充提供能访问裁剪区的驱动程序。这个区域能用一系列矩形计 算。 FLOATOBJ 允许图形驱动程序模拟浮点操作。浮点操作不适用所有其他的核心模式驱 动程序。 FONTOBJ 使驱动程序访问字体的一个特别的实例(或实现)的信息。 PALOBJ 包含 RGB 调色板颜色的结构;通过 PALOBJ_cGetColors 和 DrvSetPalette 函数可以访问。 PATHOBJ 定义路径指定要绘制什么(直线或贝塞尔曲线)。PATHOBJ 结构传递给驱 动程序用以描述要绘制或填充的一系列直线和贝塞尔曲线。 STROBJ 为驱动程序计算轮廓处理和位置的列表,描述如何绘制文本字符串。 SURFOBJ 识别一个表面,它可以是 GDI 位图、设备相关位图或设备管理的表面。更 多的信息参见表面类型。 XFORMOBJ 描述一个任意的线性二维变换,如几何宽度直线(geometric wide line)。 XLATEOBJ 定义从源表面格式到目的表面格式转换像素所需要的变换。 2.2.1.2 GDI 服务例程 GDI 输出许多服务例程,其名字的形式是 EngXxx。驱动程序动态地连接到 win32k.sys 来直接访问这些例程。GDI 服务例程包括表面管理、绘图模拟以及路径、调色板、字体和文 本服务。这些服务在 GDI 支持的服务中详细讨论。 2.2.2 PDEV 协商 任何图形驱动程序的首要任务之一是在驱动程序初始化期间使 PDEV 有效。PDEV 是物 理设备的逻辑表现。这个表现由驱动程序定义,一般是私有的数据结构。启用 PDEV 的更多 的信息参考 DrvEnablePDEV。 通过 DrvEnablePDEV 函数,驱动程序必须给 GDI 提供信息,描述请求的设备及其能力。 驱动程序给 GDI 的一条重要信息是 DEVINFO 结构的 flGraphicsCaps 和 flGraphicsCaps2 成 员中的一组图形能力标志(GCAPS_Xxx 和 GCAPS2_Xxx 标志)。 能力标志允许 GDI 确定那些操作是 PDEV 支持的。例如,GDI 测试能力标志,指示在 GDI 尝试用这些基本的类型调用 DrvStrokePath 函数来绘制路径之前,PDEV 是否能处理贝塞 尔曲线和几何宽度直线。如果能力标志指示 PDEV 不能处理这些基本类型,GDI 断开直线或 曲线,使 GDI 能简化对驱动程序的调用。 从驱动程序一侧来看,无论何时驱动程序从 GDI 获得一个高级的路径相关的调用,如 果路径或裁剪区对设备进行的处理过于复杂,它可返回 FALSE。 当驱动程序处理一条装饰线(cosmetic line)时它不能从 DrvStrokePath 返回 FALSE, 因为它必须为装饰线处理任意复杂的裁剪区或造型。然而,如果路径是贝塞尔曲线或几何直 线,DrvStrokePath 能够返回 FALSE。当这种情况出现时,GDI 把调用分割成简单的调用。 就像能力标志位没有置 1 一样。例如,如果当 DrvStrokePath 发送一个几何直线时返回 FALSE,GDI 简化直线并调用 DrvFillPath 函数。 如果 DrvStrokePath 被报告一个错误,它必须返回 DDI_ERROR
在GDI和驱动程序之间的这种协商,对依赖于PDEV的函数,允许GDI和驱动程序产 生高质量的输出而无须过多的通信。 2.2.3表面协商 绘图和文本输出要求一个绘制的表面。这个表面由 Dry EnableSurface函数创建并称 作主表面( primary surface)。它也被称作屏幕上的表面(On- screen surface),因为它出 现在视频显示器上。每个PDEV只能启用一个主表面,尽管一个驱动程序能够支持几个PDEV 支持 DrvCreateDeviceBitmap函数的驱动程序能够创建和使用其他的表面。这些位图表面称 作次要表面( secondary surface)或屏慕外的表面(of- screen surface)。对任一种类型 的表面,驱动程序负责确定它支持的绘图操作的类型。 2.2.3.1表面坐标 设备表面是22*2像素数组的子集。这些像素是由一对28位的带符号数寻址的。设备 表面左上角的像素坐标是(0,0)。设备表面位于这个坐标空间的右下象限,两个坐标都是 非负的 2.2.3.2DC原点 应用程序要求在22*2像素的数组范围内保存其图形。设备空间在DDI级有其他的尺 寸,因为窗口管理器可能用一个带符号的27位的坐标即DC原点偏移应用程序的坐标。DC 原点对驱动程序是不可见的,驱动程序在偏移执行之后才识别图形坐标 2.2.3.3FIX坐标 DI使用分数坐标,能够在设备表面上1/16像素的范围内表示一个位置。(在矢量设 备上,分数坐标比设备分辨率精确16倍。)分数坐标用32位数字表示,是带符号的28.4 位FIX表示法。在这种表示法中,高28位表示坐标的整数部分,最低的4位表示分数部分 例如,0x000000C℃等于+3.7500,0 X FFFFFFE8等于-1.5000 FIX坐标表示直线和贝塞尔曲线的控制点。对某一对象,如矩形裁剪区,GDI用带符 号的32位整数表示坐标。因为坐标是28位数,整数坐标最高的5位或者全清0或者全置1。 2.2.3.4表面类型 表面类型在如何处理它们的上下文中可以看到。这些类型如下: 引擎管理的表面 设备管理的表面(标准格式位图) 设备管理的表面(非标准表面)
7 在 GDI 和驱动程序之间的这种协商,对依赖于 PDEV 的函数,允许 GDI 和驱动程序产 生高质量的输出而无须过多的通信。 2.2.3 表面协商 绘图和文本输出要求一个绘制的表面。这个表面由 DrvEnableSurface 函数创建并称 作主表面(primary surface)。它也被称作屏幕上的表面(on-screen surface),因为它出 现在视频显示器上。每个 PDEV 只能启用一个主表面,尽管一个驱动程序能够支持几个 PDEV。 支持 DrvCreateDeviceBitmap 函数的驱动程序能够创建和使用其他的表面。这些位图表面称 作次要表面(secondary surface)或屏幕外的表面(off-screen surface)。对任一种类型 的表面,驱动程序负责确定它支持的绘图操作的类型。 2.2.3.1 表面坐标 设备表面是 2 28*228 像素数组的子集。这些像素是由一对 28 位的带符号数寻址的。设备 表面左上角的像素坐标是(0,0)。设备表面位于这个坐标空间的右下象限,两个坐标都是 非负的。 2.2.3.2 DC 原点 应用程序要求在 2 27*227 像素的数组范围内保存其图形。设备空间在 DDI 级有其他的尺 寸,因为窗口管理器可能用一个带符号的 27 位的坐标即 DC 原点偏移应用程序的坐标。DC 原点对驱动程序是不可见的,驱动程序在偏移执行之后才识别图形坐标。 2.2.3.3 FIX 坐标 DDI 使用分数坐标,能够在设备表面上 1/16 像素的范围内表示一个位置。(在矢量设 备上,分数坐标比设备分辨率精确 16 倍。)分数坐标用 32 位数字表示,是带符号的 28.4 位 FIX 表示法。在这种表示法中,高 28 位表示坐标的整数部分,最低的 4 位表示分数部分。 例如,0x0000003C 等于+3.7500,0xFFFFFFE8 等于-1.5000。 FIX 坐标表示直线和贝塞尔曲线的控制点。对某一对象,如矩形裁剪区,GDI 用带符 号的 32 位整数表示坐标。因为坐标是 28 位数,整数坐标最高的 5 位或者全清 0 或者全置 1。 2.2.3.4 表面类型 表面类型在如何处理它们的上下文中可以看到。这些类型如下: ▪ 引擎管理的表面 ▪ 设备管理的表面(标准格式位图) ▪ 设备管理的表面(非标准表面)
引擎管理的表面 引擎管理的表面有以下特征: 由GDⅠ创建和管理 用一种标准的DIB格式作为DIB创建:从上至下,原点位于左上角,或者从底向 上,原点位于左下角 类型为 STYPE BITMAP 表面没有相应的设备句柄。 标准格式位图是单平面、压缩像素(每个像素的数据用连续的方式存储)格式的位图 位图的每条扫描线在4字节的边界排列 在 EngCreateBitmap函数中创建的位图是DB格式。为了使引擎能管理位图,必须是 DIB格式。 设备管理的表面(标准格式位图) 设备管理的表面有以下特征: 通过对设备驱动程序的 DrvCreateDeviceBitmap函数的调用创建。 有一个表面的相关设备句柄( DHSURF:参见在线 DDK Graphics Driver Reference 中的 SURFOBJ。) 可以是透明的或不透明的。 不透明的设备管理表面是一种GDI既没有任何有关位图格式的信息,也没有位图中位 的参考信息的表面。因为这些原因,驱动程序最少必须支持 DryBitBlt、 DryText0ut和 DryStockePath函数。这样的表面的类型是 STYPE DEVICE。 透明的设备管理表面是一种GDI含有有关位图格式的信息并知道位图中位的位置的表 面。因为这个原因,驱动程序不需要实现任何绘图操作,并使它们都服从GDI。这样的表面 的类型是 STYPE BITMAP。 驱动程序为了转换不透明的位图到透明的位图,它必须调用 EngModifySurface函数。 通过这一调用,驱动程序通知GDI位图格式和在存储器中位图的位置。 设备管理的DIB表面允许驱动程序回调GD使GD在表面绘图。管理其自身表面的驱 动程序,也能通过在其表面周围封装DIB(用 EngCreateBitmap创建)而引用到GDI的回调, 使用DB除外。 设备管理的表面(非标准格式位图) 通过调用 EngCreateDeviceSurface函数使GDI创建表面并返回一个句柄,驱动程序 可以启用一个设备管理的非DIB表面。GDⅠ依赖驱动程序访问和控制绘制到何处,并从设备 管理的表面读出。 设备相关位图(DDB),有时称作设备格式位图,是另一种类型的非DIB、设备管理的 表面。DDB支持某些驱动程序,如VGA驱动程序,实现快速的位图到屏幕的块传送。DDB也 允许驱动程序在屏幕外的显示存储器绘制非DIB位图。如果请求了DDB,驱动程序能支持 DrvCreateDeviceBitmap函数并调用 EngCreateDeviceBitmap函数使引擎返回一个到位图的 句柄 2.2.3.5GDI彩色空间转换
8 引擎管理的表面 引擎管理的表面有以下特征: ▪ 由 GDI 创建和管理。 ▪ 用一种标准的 DIB 格式作为 DIB 创建:从上至下,原点位于左上角,或者从底向 上,原点位于左下角。 ▪ 类型为 STYPE_BITMAP。 ▪ 表面没有相应的设备句柄。 标准格式位图是单平面、压缩像素(每个像素的数据用连续的方式存储)格式的位图。 位图的每条扫描线在 4 字节的边界排列。 在 EngCreateBitmap 函数中创建的位图是 DIB 格式。为了使引擎能管理位图,必须是 DIB 格式。 设备管理的表面(标准格式位图) 设备管理的表面有以下特征: ▪ 通过对设备驱动程序的 DrvCreateDeviceBitmap 函数的调用创建。 ▪ 有一个表面的相关设备句柄(DHSURF;参见在线 DDK Graphics Driver Reference 中的 SURFOBJ。) ▪ 可以是透明的或不透明的。 不透明的设备管理表面是一种 GDI 既没有任何有关位图格式的信息,也没有位图中位 的参考信息的表面。因为这些原因,驱动程序最少必须支持 DrvBitBlt、DrvTextOut 和 DrvStockePath 函数。这样的表面的类型是 STYPE_DEVICE。 透明的设备管理表面是一种 GDI 含有有关位图格式的信息并知道位图中位的位置的表 面。因为这个原因,驱动程序不需要实现任何绘图操作,并使它们都服从 GDI。这样的表面 的类型是 STYPE_BITMAP。 驱动程序为了转换不透明的位图到透明的位图,它必须调用 EngModifySurface 函数。 通过这一调用,驱动程序通知 GDI 位图格式和在存储器中位图的位置。 设备管理的 DIB 表面允许驱动程序回调 GDI 使 GDI 在表面绘图。管理其自身表面的驱 动程序,也能通过在其表面周围封装 DIB(用 EngCreateBitmap 创建)而引用到 GDI 的回调, 使用 DIB 除外。 设备管理的表面(非标准格式位图) 通过调用 EngCreateDeviceSurface 函数使 GDI 创建表面并返回一个句柄,驱动程序 可以启用一个设备管理的非 DIB 表面。GDI 依赖驱动程序访问和控制绘制到何处,并从设备 管理的表面读出。 设备相关位图(DDB),有时称作设备格式位图,是另一种类型的非 DIB、设备管理的 表面。DDB 支持某些驱动程序,如 VGA 驱动程序,实现快速的位图到屏幕的块传送。DDB 也 允许驱动程序在屏幕外的显示存储器绘制非 DIB 位图。如果请求了 DDB,驱动程序能支持 DrvCreateDeviceBitmap 函数并调用EngCreateDeviceBitmap 函数使引擎返回一个到位图的 句柄。 2.2.3.5 GDI 彩色空间转换
GDI使用三个RGB颜色空间描述它的位图。在每个颜色空间中,三个位域,或颜色通 道,在给定的颜色中分别用来指定红、绿、蓝使用的位的数量。为了能匹配GDI的位图能力, 显示器驱动程序必须能从一个RGB颜色空间转换到另一个。 GDI能识别下列的颜色空间。 5,5,5RGB:红、绿、蓝都是5位颜色通道。 5,6,5RGB:红色是5位颜色通道,绿色是6位颜色通道,蓝色是5位颜色通道。 8,8,8RGB:红、绿、蓝都是8位颜色通道 通常,当从一个多位的颜色通道向少位的颜色通道转换时,GDI丢弃掉低位。当从 个少位的颜色通道向多位的通道转换时,较小通道的所有位全部拷贝到较大的通道。为了填 充较大通道的剩余位,较小通道的某些位将再次拷贝到较大的通道。下表概述了GDI从一个 RGB颜色空间转换到另一个所使用的规则。在这个表中,转换过程中值发生改变的颜色通道 用黑体表示。 GDI颜色空间转换规则 From 规则 例子 5,5,55,6,5源的绿色通道的最高有效位(0x15,0x19,0x1D)变成 (MSB)加到目标的绿色通道(0x15,0x33,0x1D) 的低位最后 注意只有绿色通道改变。 源的5位通道的值是二进制 11001,转换成6位值, 110011 5,5,58,8,8对每个通道,源通道的3个(0x15,0x19,0x1D)变成 MSB加到目标通道的最低位的(0xAD,0xCE,0xEF 最后 在红色通道中,10101变成 10101101。类似的变化也出现 在绿色和蓝色通道。 5,5丢弃源绿色通道的最低有效(0x15,0x33,0x1D)变成 位(LSB)。 (0x15,0x19,0x1D)。 注意只有绿色通道改变。 丢弃110011的最低位,得到 5,6,58,8,8对源的5位通道(红色和蓝(0x15,0x33,0x1D)变成 色),从源通道拷贝3个MSB(0xAD,OxCE,OxEF) 加到目标通道的最低位的最在红色通道中 变成 后。对6位的绿色通道,从源10101101。在绿色通道中, 通道拷贝2个MSB加到目标通110011变成11001111蓝色 道的最低位的最后 通道的变化和红色通道类似 8,8,8 5,5丢弃源通道的3个最低有效(0xAB,0xCD,0xEF)变成 位(LSB)。 (0x15,0x19,0x1D)。 在红色通道中,10101101变 成10101。类似的变化也出现 在其他两个通道。 8,8,85,6,5丢弃红色和蓝色通道的3个(0xAB,0xCD,0xEF)变成 最低有效位(LSB)。丢弃绿色(0x15,0x33,0x1D) 通道的2个最低有效位在绿色通道中,11001101变 (LSB) 成110011。红色和蓝色通道 的变化与前面列出的变换相
9 GDI 使用三个 RGB 颜色空间描述它的位图。在每个颜色空间中,三个位域,或颜色通 道,在给定的颜色中分别用来指定红、绿、蓝使用的位的数量。为了能匹配 GDI 的位图能力, 显示器驱动程序必须能从一个 RGB 颜色空间转换到另一个。 GDI 能识别下列的颜色空间。 ▪ 5,5,5RGB:红、绿、蓝都是 5 位颜色通道。 ▪ 5,6,5RGB:红色是 5 位颜色通道,绿色是 6 位颜色通道,蓝色是 5 位颜色通道。 ▪ 8,8,8RGB:红、绿、蓝都是 8 位颜色通道。 通常,当从一个多位的颜色通道向少位的颜色通道转换时,GDI 丢弃掉低位。当从一 个少位的颜色通道向多位的通道转换时,较小通道的所有位全部拷贝到较大的通道。为了填 充较大通道的剩余位,较小通道的某些位将再次拷贝到较大的通道。下表概述了 GDI 从一个 RGB 颜色空间转换到另一个所使用的规则。在这个表中,转换过程中值发生改变的颜色通道 用黑体表示。 GDI 颜色空间转换规则 From To 规则 例子 5,5,5 5,6,5 源的绿色通道的最高有效位 (MSB)加到目标的绿色通道 的低位最后。 (0x15,0x19,0x1D)变成 (0x15,0x33,0x1D)。 注意只有绿色通道改变。 源的 5 位通道的值是二进制 11001 ,转换成 6 位值, 110011。 5,5,5 8,8,8 对每个通道,源通道的 3 个 MSB 加到目标通道的最低位的 最后。 (0x15,0x19,0x1D)变成 (0xAD,0xCE,0xEF)。 在红色通道中,10101 变成 10101101。类似的变化也出现 在绿色和蓝色通道。 5,6,5 5,5,5 丢弃源绿色通道的最低有效 位(LSB)。 (0x15,0x33,0x1D)变成 (0x15,0x19, 0x1D)。 注意只有绿色通道改变。 丢弃 110011 的最低位,得到 11001。 5,6,5 8,8,8 对源的 5 位通道(红色和蓝 色),从源通道拷贝 3 个 MSB 加到目标通道的最低位的最 后。对 6 位的绿色通道,从源 通道拷贝2个MSB加到目标通 道的最低位的最后。 (0x15,0x33,0x1D)变成 (0xAD,0xCE,0xEF)。 在红色通道中,10101 变成 10101101。在绿色通道中, 110011 变成 11001111。蓝色 通道的变化和红色通道类似。 8,8,8 5,5,5 丢弃源通道的 3 个最低有效 位(LSB)。 (0xAB,0xCD,0xEF)变成 (0x15,0x19,0x1D)。 在红色通道中,10101101 变 成 10101。类似的变化也出现 在其他两个通道。 8,8,8 5,6,5 丢弃红色和蓝色通道的 3 个 最低有效位(LSB)。丢弃绿色 通 道 的 2 个 最 低 有 效 位 (LSB)。 (0xAB,0xCD,0xEF)变成 (0x15,0x33,0x1D)。 在绿色通道中,11001101 变 成 110011。红色和蓝色通道 的变化与前面列出的变换相 同
2. 3. 6 Hooking A Punting 术语 poking和 Punting指的是驱动程序决定是否提供标准的位图绘画操作,或依赖 GDI提供这些操作。如果驱动程序实现了引擎管理的表面,GDI能处理所有的绘图操作。然 而,如果硬件能加速这些操作,驱动程序能提供一个或更多的绘图函数。通过实现,或 Hooking Drv Xxa函数来做到这一点 也许只想实现绘图操作的一个子集,实现一个特殊的DDI接口点。对它不支持的任何 操作,驱动程序能调用相应的GDI函数来实现。这称作 Punting到GDI。有一些情形是操作 必须在驱动程序内实现。例如,如果驱动程序实现了一个设备管理的表面,某些绘图函数必 须在显示器驱动程序内完成 ooking 缺省情况下,当绘图表面是引擎管理的表面时,ωDⅠ处理绘画(绘图)操作。驱动程 序利用硬件对一给定的表面,为一些或所有的绘图函数提供了加速,或者使用了特别的块传 送硬件,能够hook这些函数。对于hok调用,驱动程序把hook指定为 EngAssociateSurface 和 EngModifySurface函数 flOck参数的标记。 如果驱动程序指定了一个函数的hook标记,它必须提供在其支持DDI入口点的列表 中的函数。驱动程序能够优化具有硬件支持的操作。这样的驱动程序在一个hook调用中可 能只能处理某一种情况。例如,如果在一个hook调用中请求了复杂的图形,它可能还要更 有效地直接回调GDI,允许GDI处理操作 这里还有另一个例子,驱动程序选择是否处理hook调用。考虑应该支持硬件的驱动 程序,有能力用某些ROP处理位块传输调用。即使驱动程序能够独立地实现许多操作,其他 方面仅是一个缓冲区。这样的驱动程序将为帧缓冲区给位图表面返回一个句柄,就像为其 PDEV表面一样,但它将为自己 hook drybitblt调用。当GDI调用 DryBitblt时,驱动程序 能够检查R尸来看它是否是由硬件支持的一个函数。如果不是,驱动程序能通过对 Engbitblt 的一个调用把操作传递GDI。 支持设备管理表面的驱动程序必须向外hook一些绘图函数,名字是 DrvCopyBits、 DryTextout和 DryStrokepath。虽然GDI模拟能够处理其他绘图函数,因为性能上的原因推 荐这种类型的驱动程序hok其他函数,就像 DryBitB1t和 Drv Realizebrush函数,因为模 拟需要从或向表面绘图。 Punting Punting回调到GDI的意思是提交一个调用到相应的GDI模拟。通常,对每个Drvx 调用都有一个相应的 GDI Eng xx模拟调用,带有相同的参数。在驱动程序制作透明的位图 时,所有的参数都没有改变地传递到GDI模拟。对每个调用驱动程序punt回GDI,驱动程 序的大小缩减了(因为功能上的代码忽略了)。然而,因为引擎拥有调用,驱动程序在执行 速度上没有控制。对一些复杂的情况,在驱动程序中提供支持也许没有实际的优势 可以hook的GDI图形输出函数 驱动程序能够hook的图形输出函数和相应的GDI模拟在下表中列出 驱动程序图形输出函数 相应的GDI模拟 Drybitblt EngBitBlt DrvPlgblt EngPlgblt DryStretchBlt EngStretchBlt
10 2.2.3.6 Hooking 和 Punting 术语 Hooking 和 Punting 指的是驱动程序决定是否提供标准的位图绘画操作,或依赖 GDI 提供这些操作。如果驱动程序实现了引擎管理的表面,GDI 能处理所有的绘图操作。然 而,如果硬件能加速这些操作,驱动程序能提供一个或更多的绘图函数。通过实现,或 Hooking DrvXxx 函数来做到这一点。 也许只想实现绘图操作的一个子集,实现一个特殊的 DDI 接口点。对它不支持的任何 操作,驱动程序能调用相应的 GDI 函数来实现。这称作 Punting 到 GDI。有一些情形是操作 必须在驱动程序内实现。例如,如果驱动程序实现了一个设备管理的表面,某些绘图函数必 须在显示器驱动程序内完成。 Hooking 缺省情况下,当绘图表面是引擎管理的表面时,GDI 处理绘画(绘图)操作。驱动程 序利用硬件对一给定的表面,为一些或所有的绘图函数提供了加速,或者使用了特别的块传 送硬件,能够 hook 这些函数。对于 hook 调用,驱动程序把 hook 指定为 EngAssociateSurface 和 EngModifySurface 函数 flHook 参数的标记。 如果驱动程序指定了一个函数的 hook 标记,它必须提供在其支持 DDI 入口点的列表 中的函数。驱动程序能够优化具有硬件支持的操作。这样的驱动程序在一个 hook 调用中可 能只能处理某一种情况。例如,如果在一个 hook 调用中请求了复杂的图形,它可能还要更 有效地直接回调 GDI,允许 GDI 处理操作。 这里还有另一个例子,驱动程序选择是否处理 hook 调用。考虑应该支持硬件的驱动 程序,有能力用某些 ROP 处理位块传输调用。即使驱动程序能够独立地实现许多操作,其他 方面仅是一个缓冲区。这样的驱动程序将为帧缓冲区给位图表面返回一个句柄,就像为其 PDEV 表面一样,但它将为自己 hook DrvBitBlt 调用。当 GDI 调用 DrvBitBlt 时,驱动程序 能够检查 ROP 来看它是否是由硬件支持的一个函数。如果不是,驱动程序能通过对 EngBitBlt 的一个调用把操作传递 GDI。 支持设备管理表面的驱动程序必须向外 hook 一些绘图函数,名字是 DrvCopyBits、 DrvTextOut 和 DrvStrokePath。虽然 GDI 模拟能够处理其他绘图函数,因为性能上的原因推 荐这种类型的驱动程序 hook 其他函数,就像 DrvBitBlt 和 DrvRealizeBrush 函数,因为模 拟需要从或向表面绘图。 Punting Punting 回调到 GDI 的意思是提交一个调用到相应的 GDI 模拟。通常,对每个 DrvXxx 调用都有一个相应的 GDI EngXxx 模拟调用,带有相同的参数。在驱动程序制作透明的位图 时,所有的参数都没有改变地传递到 GDI 模拟。对每个调用驱动程序 punt 回 GDI,驱动程 序的大小缩减了(因为功能上的代码忽略了)。然而,因为引擎拥有调用,驱动程序在执行 速度上没有控制。对一些复杂的情况,在驱动程序中提供支持也许没有实际的优势。 可以 hook 的 GDI 图形输出函数 驱动程序能够 hook 的图形输出函数和相应的 GDI 模拟在下表中列出。 驱动程序图形输出函数 相应的 GDI 模拟 DrvBitBlt EngBitBlt DrvPlgBlt EngPlgBlt DrvStretchBlt EngStretchBlt