Windows内核原理与实现之 GDI (图形设备接口)

article/2025/10/5 16:43:58

文章摘录自《Windows内核原理与实现》一书。

图形用户界面是  Windows 操作系统的重要特色,这也是在 Windows 子系统中提供的。概括而言,Windows 的图形系统有两方面特点:首先,它提供了一套与设备无关的编程接口,即 GDI,这使得应用程序可以适应各种底层显示设备的差异;其次,应用程序与图形设备驱动程序之间的通信足够高效,从而使在频繁输出和刷新图形元素的情况下,Windows也能够为用户提供良好的视觉效果。

Windows子系统定义了一个稳定的图形体系结构,以便第三方的图形设备硬件厂商可以方便地将他们的视频显示器和打印设备集成到Windows 中。图 9.12 显示了 Windows 子系统的图形部分的体系结构(适用于Windows2000 以后的系统)。

 

在 Windows NT 4以前,图形显示是在子系统的用户模式进程(即 csrss.exe)中被处理的,从而 Windows NT 4开始,这部分功能转移到了内核中,允许应用程序的图形请求被直接通过显示驱动程序转发到视频适配器。在图 9.12中,子系统 DLL被动态链接到应用程序进程中,它们接收应用程序的图形请求,并将其转发到内核模式下的图形引擎中。

内核模式的图形引擎(即Windows 子系统的 GDI)位于 win32k.sys 中,其职责是接受来自用户模式的图形请求,并且完成通用的、不涉及硬件的图形绘制功能,而把涉及硬件的或者需要特殊支持的图形功能交给显示驱动程序或者转发给视频端口驱动程序来完成。图形引擎在一个标准格式的位图(单个平面的plane),像素可以是1,2,4,8,16或32位,每行上的像素连续存放,并且每行数据以 4 字节为对齐边界上执行各种绘制操作。

如有必要,则通过 DDI (Device Driver Interface,设备驱动程序接口) 调用显示驱动程序来完成相应的功能,图形 DDI 函数的名称都以 "Drv" 为前缀,例如显示驱动程序的入口例程,即初始化例程,为 DrvEnableDriver。

虽然显示驱动程序也被称为驱动程序,但是它并不遵守 I/O 管理器定义的接口标准,图形引擎与显示驱动程序之间的通信并没有采用 IoCallDriver 的调用方式。显示驱动程序本质上是一个动态链接库,它暴露了一组 DDI 函数,供图形引擎调用其功能;而图形引擎也暴露了一组 ENG函数给显示驱动,从而使显示驱动程序可以调用图形引擎的功能。显示驱动程序支持的 DDI 函数都通过其入口函数(即 DrvEnableDriver)的输出参数(一个函数数组)被传递给图形引擎。关于 DDI 和 ENG 函数用法的一个典型例子是:图形引擎调用显示驱动程序的 DrvBitBlt 函数。将标准格式位图中的矩形块拷贝到显示器设备的图形表面(surface)中;显示驱动程序调用 EngBitBlt 函数,将它管理的图形表面拷贝到 GDI 管理的标准格式位图中。

图形引擎和显示驱动程序之间建立联系的初始化过程是这样来完成的:

● 在一个会话中,当 GDI 被第一次调用来创建一个设备环境 (device context)时,图形引擎调用显示驱动程序的入口函数 DrvEnableDriver,从而获得显示驱动程序的版本,以及它所支持的  DDI 函数。

● 图形引擎接着调用 DrvEnableDriver,以获得关于该驱动程序的物理设备的一个特征描述。对于 GDI,显示驱动程序代表了一个逻辑设备,它可以管理多个物理设备,每个物理设备有它自己的硬件类型、逻辑地址和图形表面(surface)。对于每个物理设备,显示驱动程序可以管理多个内存表示,即 PDEV 数据结构,这些内存标识描述了此设备的状态以及它的图形能力。在同一个物理设备的多个 PDEV 中,同一时刻只能使用一个。当图形引擎调用 DrvEnableDriver 时,显示驱动程序根据指定的设备模式创建一个 PDEV。

● 当物理设备的 PDEV 被创建以后,图形引擎调用 DrvCompletePDEV,把它为该 PDEV生成的一个句柄告诉显示驱动程序,以便将来显示驱动程序调用 ENG 接口函数时指定此 PDEV。

● 最后,图形引擎调用 DrvEnableSurface,让显示驱动程序为该物理设备创建一个图形表面,已代表最终的图形输出硬件。显示驱动程序可以有两种不同的方法来建立图形表面:

    1,自己管理图形表面。

    2,完全由图形引擎来管理图形表面(即设备无关的位图)。

显示驱动程序配合图形引擎来实现图形绘制功能,图形引擎已经实现了在标准格式位图上的各种绘制能力。显示驱动程序可以把性能要求不高的位图操作,或者图形适配器不支持的复杂操作,交给子系统的图形引擎来完成;然而,如果图形适配器支持一些特殊的加速操作,那么,显示驱动程序可以选择只实现跟这些加速操作相关的图形功能,而其他的都转交给图形引擎来完成。简而言之,图形引擎完成了在标准格式位图上的所有图形操作,而显示驱动程序则往往有选择地实现部分图形操作,它的代码尺寸相对比较小。

在Windows 子系统的图形结构中,显示驱动程序与视频小端口驱动程序是成对出现的,也就是说,对于一个视频适配器,硬件厂商除了要提供一个显示驱动程序之外,还需要提供一个配套的视频小端口驱动程序。图 9.12 中的视频端口驱动程序是由 Windows 操作系统本身提供的,在Windows Server 2003 中视频端口驱动程序为 videoprt.sys, 该文件实际上并非一个驱动程序,而是一个动态链接库。然而,视频小端口驱动程序是正真的驱动程序,而且往往是即插即用驱动程序,所以,它们由即插即用管理器在系统引导时加载到系统中。视频端口驱动程序暴露一组以“VideoPort” 为前缀的函数,而视频小端口驱动程序则以回调函数的形式暴露了一组以“HwVid” 为前缀的函数。例如,VideoPortMapMemory 函数将视频存储区的一段物理地址范围映射到系统地址空间或者进程地址空间中;HwVidInitialize 函数执行适配器的初始化工作。

显示驱动程序不能处理设备中断。只有小端口驱动程序才能配置视频适配器的存储区,并且将存储区映射到显示驱动程序可以访问的虚拟地址空间中。总体上,视频小端口驱动程序负责直接的硬件资源管理和控制,例如注册中断服务例程、定时器例程、DPC例程,管理电源状态以及 DMA 传输等;视频端口驱动程序负责与图形处理有关的各种事项,包括缓存区管理、设备内存区管理与映射、端口驱动程序负责与图形处理有关的各种事项,包括缓存区管理、设备内存区管理与映射、读写 I/O 寄存器等,它也为小端口驱动程序提供一个与系统内核和执行体打交道的环境。

GDI或显示驱动程序调用图形引擎的 EngDeviceIoControl 函数来跟视频小端口驱动程序进行通信。虽然视频小端口驱动程序是一个真正的设备驱动程序,但它的大部分功能逻辑是由视频端口驱动程序来完成的。至于创建设备对象、I/O 请求分发等设备驱动程序的常规逻辑,均由视频端口驱动程序代劳。小端口驱动程序链接到视频端口驱动程序上,它除了暴露一个入口函数作为初始化例程以外,其他所有的接口函数均以函数指针的形式告诉视频端口驱动程序。

视频端口驱动程序是一个动态链接库,它不仅提供了控制视频适配器所需要的大部分功能,而且会将视频小端口驱动程序包装成一个真正的 I/O 设备驱动程序。小端口驱动程序除了在入口函数中调用 VideoPortInitialize 函数外,只需要提供一组回调函数即可。

在Windows子系统的显示驱动程序模型中,除了 GDI 部分,它提供了对 Microsoft DirectX 的显示支持,允许像游戏、多媒体播放器等应用软件直接操纵显示器硬件,绕过前面所提到的 GDI 图形引擎,从而获得更快的显示速度,并且避免屏幕抖动。Windows子系统的 NtGdiDd<Xxx> 和 NtGdiD3d<Xxx> 系统服务正是为了这类应用软件提供的 DirectDraw 和 Direct3D 支持。

DirectDraw 是  DirectX 中的显示部分,是一套与Windows 子系统 GDI 平行的图形编程接口。由于 DirectDraw 驱动程序充分发挥了硬件的图形加速能力,所以,DirectDraw 在快速运行和持续屏幕变化等图形特性方面比 GDI 有更强的处理能力和执行效率。我们认为 DirectDraw 是 GDI 的一个增强,更加适用于像场景游戏和多媒体播放器这样的应用软件。在Windows 2000 及以后的系统上,DirectDraw  包含以下组件:

●  用户模式 DirectDraw,是一个动态链接库(ddraw.dll),它提供了硬件仿真、管理各种 DirectDraw 对象、管理显示存储区和显示器硬件的服务。DirectDraw 为应用程序提供了基于 COM(Component Object Model) 的接口,所以,使用 DirectDraw 的软件必须是一个 COM 应用。

●  内核模式 DirectDraw,如同 GDI 一样,他也是 Windows 子系统的 win32k.sys 中的一部分。内核模式 DirectDraw 的职责是,检查 DirectDraw 系统调用的参数的有效性,并且负责与 GDI 的同步,以及维护各种跨进程的状态。它提供的系统服务以 “NtGdiDd” 和 “NtGdiDvp” 为前缀。

●  DirectDraw 驱动程序,这是由图形硬件厂商提供的软件组件。从形式来看,它既可以是显示驱动程序中的一个组成部分,也可以是一个独立的驱动程序。DirectDraw 驱动程序的核心是利用硬件的能力来提供更快、更强的图形显示功能。它提供各种回调函数供子系统调用,这组回调函数涉及图形表面(surface)、颜色控制和调色板、运动补偿(motion compensation)、视频端口,以及驱动程序内部的数据对象管理等。在Windows DDK 文档中这些回调函数的前缀为 “Dd” ,例如 DdCreateSurface。

DirectDraw 驱动程序的结构与显示驱动程序很相似,他并非 I/O 设备驱动程序,而是一个动态链接库,其初始化函数 DrvEnableDirectDraw 负责硬件初始化。Windows 子系统对 DirectDraw 的支持实际上也是 GDI 的一个扩展或延伸,DirectDraw 驱动程序是显示驱动程序的扩展。

DirectX 中也包含了对于三维图形的支持,称为 Direct3D。Windows子系统也支持 Direct3D。Windows 子系统通过 DirectDraw 函数 DdGetDriverInfo 来获得 Direct3D 的回调函数,因此,Direct3D 也可以看做是 DirectDraw 的一个自然扩展。


http://chatgpt.dhexx.cn/article/mNUgK1mL.shtml

相关文章

windows 驱动与内核调试 学习

概述 本文讲述笔者在学习内核和驱动开发的笔记。 驱动概述 一般驱动需要运行内核权限下运行(因为涉及硬件读取)&#xff0c;比如Intel下的ring 0 权限下。在windwos大量病毒和杀软为了特殊目的往往都是通过将自身升级为内核驱动方式进行运作。如果病毒程序首先进入ring 0理论…

Windows内核--CPU和内核(1.7)

Windows内核支援哪些CPU? Intel x86/x86_64 IA64已不再支持. AMD amd64 ARM (Windows On Arm: WOA) ARM具备低功耗优势, 除了高通, 还有Broadcom/NXP等都支援ARM架构. 苹果自研M系列开了头&#xff0c;ARM不仅有低功耗&#xff0c;同样有性能&#xff0c;Windows也想分一杯羹…

windows内核驱动

内核&驱动基础 WDK(Windows Driver Kit) 内核编程需要使用WDK WDK 下载 windows xp wdk 下载地址 WDK 安装 勾选所有的安装项,避免错过一些例子 默认安装目录: C:\WinDDKfirst驱动开发 源码 first.c #include <ntddk.h>#define DEBUG/** 卸载函数*/ VOID Driver…

Windows 内核会换为 Linux 吗?

关注、星标公众号&#xff0c;不错过精彩内容 来源&#xff1a;网络 编辑整理&#xff1a;strongerHuang 如果装个纯linux&#xff0c;则一些windows软件没法用。如果用windows然后装个虚拟机&#xff0c;在虚拟机上安装linux&#xff0c;又感觉麻烦而且占用电脑资源。 现在win…

Windows内核之系统架构

一.架构概述 下图显示了Windows的基本结构。Windows采用双模式来保护操作系统本身&#xff0c;以避免被应用程序的错误所波及。操作系统核心运行在内核模式下&#xff0c;应用程序的代码运行在用户模式下。每当应用程序需要用到系统内核或内核的扩展模块&#xff08;内核驱动程…

Windows内核原理与实现之Windows设备驱动程序

文章摘录自《Windows内核原理与实现》一书。 设备驱动程序是操纵设备的内核模块&#xff0c;I/O 管理器、即插即用管理器和电源管理器都需要与设备的驱动程序打交道。 在Windows I/O 系统中&#xff0c;设备驱动程序不仅为操作系统提供了支持各种 I/O 设备的能力&#xff0c;…

Windows内核的基本概念

Windows内核的基本概念 1 处理器模式 Windows使用 0 和3 两种特权级。0 表示CPU处于内核模式(kernel mode)&#xff1b;3 表示用户模式(user mode)。 1.1 内存管理 Windows 将32位虚拟内存空间按照0~4 GB的线性地址空间看待。其中2~4GB是所有进程共享的&#xff0c;为系…

Windows内核--源代码在哪里?(1.1)

大部分人能看到这篇帖子, 想必已经用过Windows系统多年了... 微软官方并不完全公开源代码 想清楚Windows技术内幕&#xff0c;就需要逆向工具。幸运的是: WRK源代码(Windows Research Kernel) (XP/Server 2003)Windows 2000源代码(Kernel和用户层) 深入解析Windows操作系统(最…

windows内核驱动开发(WDK环境搭建)

去官网下载WDK安装包和Visual Studio 下载 Windows 驱动程序工具包 (WDK) - Windows drivers | Microsoft Docs 首先安装Visual Studio 这个就不用我介绍了怎么安装了。 下面直接下载步骤二和步骤三的SDK和WDK。 SDK下载地址 WDK下载地址 注意下载的SDK和WDK版本需要统…

Windows内核--子系统(3.5)

到底什么是子系统? 子系统是用户层概念。在Windows内核之上&#xff0c;如果想要执行类UNIX应用程序&#xff0c;就是POSIX子系统&#xff0c;如果要类似OS/2环境&#xff0c;就是OS/2子系统。 如何能模拟出不同子系统呢? 一般需要子系统用户态应用程序和相关DLL支援。 对于W…

无法正常进入Windows也能开启Windows内核调试

1 背景 Windows的启动的早期阶段&#xff0c;大致分为3步&#xff1a;bootmgr&#xff0c;winload&#xff0c;nt内核加载。 下图是Winload阶段的一个报错。 如果出现Windowslogo&#xff0c;一般就是进入nt内核加载了。 我们经常开的调试功能是nt内核加载后的调试。无法调试…

windows内核开发学习笔记二十四:windows内核架构

从上图上可以看出&#xff0c;windows内核主要层次划分为三个层次&#xff0c;以及windows子系统、文件系统、网络、设备驱动程序等几个部分。 硬件抽象层&#xff08;Hardware Abstraction Layer&#xff0c;简称HAL&#xff09;&#xff1a;主要是把所有与硬件相关联的代码隔…

Windows内核--内核空间和用户空间(3.6)

内核喜欢抽象出句柄给用户空间 句柄, Handle, 表达处理、控制之意。内核不会直接暴露指针给用户空间&#xff0c;这样会增大内核风险。相反&#xff0c;内核抽象出Handle给用户态&#xff0c;不管是文件、进程、线程等对象&#xff0c;通过Handle可以隐藏内核细节&#xff0c;统…

Windows内核基础之权限级别

权限级别是CPU中的一个概念&#xff0c;CPU中包含4个权限级别&#xff0c;分别是0环&#xff0c;1环&#xff0c;2环&#xff0c;3环&#xff0c;CPU设计制造商最初希望0环用于运行内核&#xff0c;1环和2环运行设备驱动&#xff0c;3环运行应用程序&#xff0c;但是系统设计者…

Windows内核--调试内核源代码(1.5)

Kernel编译和普通应用程序编译有差异吗&#xff1f; 最终Kernel二进制档是给CPU执行的&#xff0c;只要用普通的C编译器能正常编译出给CPU执行的二进制程序即可&#xff0c;从编译角度&#xff0c;内核和应用程序无差别。Windows内核是exe文件。 内核与用户应用程序运行环境有…

Windows内核驱动Hook入门

文章目录 Hook框架选择基于微软规范的框架微软规范以外的框架简单介绍一下InfinityHook 获取内核中的函数地址内核中导出的函数内核未导出的函数获取 SSDT ShadowSSDT 地址获取系统服务号手动获取获取并判断系统版本 代码自动获取 获取GUI相关的函数地址&#xff0c;还需附加GU…

Windows内核编程(二)-第一个内核程序

第一个内核程序 通过 Visual Studio新建工程 注意事项&#xff1a; 大部分widnows驱动程序都是内核驱动(Kernel Driver)&#xff0c;所以本笔记不分"驱动程序"与"内核编程"&#xff0c;也不区分"内核模块"(Kernel Module)、“驱动程序”(Drive…

Windows内核原理与实现之Windows研究内核(WRK)

Windows并非一个开放源码的操作系统&#xff0c;但正如上一章所提&#xff0c;Microsoft开放了一份以Windows XP x64和Windows Server 2003 SP1为基础的内核源代码&#xff0c;它可以编译和运行&#xff0c;作为教育科研机构的教学实践和研究的平台使用&#xff0c;称为WRK&…

Windows内核结构

Windows内核结构 第一篇博客&#xff0c;随便写下练练手:) Windows内核总共分为三层&#xff1a; 与硬件直接打交道的这一层叫做硬件抽象层简称HAL&#xff0c;这一层的用意就是把所有与硬件相关联的代码逻辑隔离到一个专门的模块中&#xff0c;从而做到尽可能的独立于硬件平…

WINDOWS内核对象及其理解

一&#xff0e;前言 Windows中有很多像进程对象、线程对象、文件对象等等这样的对象&#xff0c;我们称之为Windows内核对象。内核对象是系统地址空间中的一个内存块&#xff0c;由系统创建并维护&#xff0c;这个内存对象是一个数据结构&#xff0c;维护着与对象相关的信息&a…