VC Mirror Driver显示虚拟驱动经典开发
一个简单的显示驱动实例
windows wdk 7600的 mirror(镜像) 显示驱动部分
基本流程:
Windows 2000 DDK包含了一个例子镜像驱动程序,在 上面3个目录中包括了组件源文件。
目录
包含的源文件
Video\displays\mirror\dll
镜像驱动程序
Video\miniport\mirror
微端口驱动程序
Video\displays\mirror\app
用户模式服务。也包含mirror.inf。
打开disp文件夹 C:\WinDDK\7600.16385.1\src\video\displays\mirror\disp// wdk 2000 要方便一些
修改sources文件 // 指定警告错误级别
MSC_WARNING_LEVEL=/W4 改为:MSC_WARNING_LEVEL=/W3
打开debug.c 日志打印级别为 ULONG DebugLevel = 4
一.在driver.h头文件中:
1.pdev结构体添加缓存区指针
typedef struct _PDEV
{
HANDLE hDriver; // Handle to \Device\Screen
HDEV hdevEng; // Engine's handle to PDEV
HSURF hsurfEng; // Engine's handle to surface
HPALETTE hpalDefault; // Handle to the default palette for device.
PBYTE pjScreen; // This is pointer to base screen address
ULONG cxScreen; // Visible screen width
ULONG cyScreen; // Visible screen height
POINTL ptlOrg; // Where this display is anchored in
// the virtual desktop.
ULONG ulMode; // Mode the mini-port driver is in.
LONG lDeltaScreen; // Distance from one scan to the next.
ULONG cScreenSize; // size of video memory, including
// offscreen memory.
PVOID pOffscreenList; // linked list of DCI offscreen surfaces.
FLONG flRed; // For bitfields device, Red Mask
FLONG flGreen; // For bitfields device, Green Mask
FLONG flBlue; // For bitfields device, Blue Mask
ULONG cPaletteShift; // number of bits the 8-8-8 palette must
// be shifted by to fit in the hardware
// palette.
ULONG ulBitCount; // # of bits per pel 8,16,24,32 are only supported.
POINTL ptlHotSpot; // adjustment for pointer hot spot
VIDEO_POINTER_CAPABILITIES PointerCapabilities; // HW pointer abilities
PVIDEO_POINTER_ATTRIBUTES pPointerAttributes; // hardware pointer attributes
DWORD cjPointerAttributes; // Size of buffer allocated
BOOL fHwCursorActive; // Are we currently using the hw cursor
PALETTEENTRY *pPal; // If this is pal managed, this is the pal
BOOL bSupportDCI; // Does the miniport support DCI?
PVOID pvTmpBuffer; // ptr to MIRRSURF bits for screen surface
/* Add a file buffer memory pointer */
//==================================
PVOID pVideoMemory;
ULONG_PTR hMem;
//==================================
} PDEV, *PPDEV;
2.创建缓存区. 在函数中DrvEnableSurface绘画 // 提供一个绘画表面
HSURF DrvEnableSurface(
DHPDEV dhpdev)
{
PPDEV ppdev;
HSURF hsurf;
SIZEL sizl;
ULONG ulBitmapType;
FLONG flHooks;
ULONG mirrorsize;
ULONG BitsPerPel;
MIRRSURF *mirrsurf;
DHSURF dhsurf;
// Create engine bitmap around frame buffer.
DISPDBG((0,"DrvEnableSurface:\n"));
ppdev = (PPDEV) dhpdev;
ppdev->ptlOrg.x = 0;
ppdev->ptlOrg.y = 0;
sizl.cx = ppdev->cxScreen;
sizl.cy = ppdev->cyScreen;
if (ppdev->ulBitCount == 16)
{
ulBitmapType = BMF_16BPP;
flHooks = HOOKS_BMF16BPP;
BitsPerPel = 2;
}
else if (ppdev->ulBitCount == 24)
{
ulBitmapType = BMF_24BPP;
flHooks = HOOKS_BMF24BPP;
BitsPerPel = 3;
}
else
{
ulBitmapType = BMF_32BPP;
flHooks = HOOKS_BMF32BPP;
BitsPerPel = 4;
}
flHooks |= flGlobalHooks;
mirrorsize = (ULONG)(ppdev->cxScreen * ppdev->cyScreen * BitsPerPel);
ppdev->pvTmpBuffer = EngMapFile( // Mapping file buffer memory to disk
L"\\??\\c:\\video.dat",
mirrorsize,
&ppdev->hMem);
hsurf = (HSURF) EngCreateBitmap(sizl,
ppdev->lDeltaScreen,
ulBitmapType,
0,
(PVOID)(ppdev->pvTmpBuffer));
if (hsurf == (HSURF) 0)
{
RIP("DISP DrvEnableSurface failed EngCreateBitmap\n");
return(FALSE);
}
if (!EngAssociateSurface(hsurf, ppdev->hdevEng, flHooks))
{
RIP("DISRP DrvEnableSurface failed EngAssociateSurface\n");
EngDeleteSurface(hsurf);
return(FALSE);
}
ppdev->hsurfEng = (HSURF) hsurf;
return(hsurf);
}
3.在函数中DrvDisableSurface // 清理表面
VOID DrvDisableSurface(
DHPDEV dhpdev)
{
PPDEV ppdev = (PPDEV) dhpdev;
DISPDBG((0,"DrvDisableSurface:\n"));
EngDeleteSurface( ppdev->hsurfEng );
}
4. 在函数中DrvDisablePDEV // 退出时要删的缓存区
VOID DrvDisablePDEV(
DHPDEV dhpdev)
{
PPDEV ppdev = (PPDEV) dhpdev;
EngDeletePalette(ppdev->hpalDefault);
EngFreeMem(dhpdev);
EngUnmapFile(ppdev->hMem);
EngDeleteFile(L"\\??\\c:\\video.dat");
}
5.修正调色板
打开screen.c 修改调色板 颜色为 R G B
BOOL bInitPDEV(
PPDEV ppdev,
DEVMODEW *pDevMode,
GDIINFO *pGdiInfo,
DEVINFO *pDevInfo)
{
ULONG red, green, blue;
INT i;
//
// Fill in the GDIINFO data structure with the information returned from
// the kernel driver.
//
ppdev->ulMode = 0;
ppdev->cxScreen = pDevMode->dmPelsWidth;
ppdev->cyScreen = pDevMode->dmPelsHeight;
ppdev->ulBitCount = pDevMode->dmBitsPerPel;
ppdev->lDeltaScreen = 0;
ppdev->flRed = 0x00FF0000;
ppdev->flGreen = 0x000FF00;
ppdev->flBlue = 0x00000FF;
......
*pDevInfo = gDevInfoFrameBuffer;
if (ppdev->ulBitCount == 16)
{
pDevInfo->iDitherFormat = BMF_16BPP;
// each word single pixel 5-5-5
pDevInfo->hpalDefault = ppdev->hpalDefault =
EngCreatePalette(PAL_BITFIELDS, 0,NULL,
0x7c00,0x03e0,0x001f);
}
else
{
if (ppdev->ulBitCount == 24)
{
pDevInfo->iDitherFormat = BMF_24BPP;
}
else
{
pDevInfo->iDitherFormat = BMF_32BPP;
}
pDevInfo->hpalDefault = ppdev->hpalDefault =
EngCreatePalette(PAL_BITFIELDS, 0,NULL,
ppdev->flRed,ppdev->flGreen,ppdev->flBlue);
}
return(TRUE);
}
6.根据Hook标志路径回调GDI图形引擎管理
如:<BitBlt>
BOOL DrvBitBlt(
IN SURFOBJ *psoDst,
IN SURFOBJ *psoSrc,
IN SURFOBJ *psoMask,
IN CLIPOBJ *pco,
IN XLATEOBJ *pxlo,
IN RECTL *prclDst,
IN POINTL *pptlSrc,
IN POINTL *pptlMask,
IN BRUSHOBJ *pbo,
IN POINTL *pptlBrush,
IN ROP4 rop4
)
{
DISPDBG((0,"DrvBitBlt:(%d,%d,%d,%d)\n", prclDst->bottom, prclDst->left,prclDst->right, prclDst->top));
return EngBitBlt(psoDst, psoSrc, psoMask, pco, pxlo, prclDst, pptlSrc, pptlMask, pbo, pptlBrush, rop4);
//return TRUE;
}
7.变化的矩形
由源表面到目标表面都会有相对的变化矩形
例:通过debug打印
DISPDBG((0,"DrvBitBlt:(%d,%d,%d,%d)\n", prclDst->bottom, prclDst->left,prclDst->right, prclDst->top));
应用程序的使用
文件内存映射
将建立的c:\\video.dat文件进行映射
CString ptr = L"C:\\video.dat";
hFile = CreateFile(ptr, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if(hFile && hFile != INVALID_HANDLE_VALUE)
{
hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
if(hMapFile && hMapFile != INVALID_HANDLE_VALUE)
{
pVideoMemory = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
CloseHandle(hMapFile);
}
CloseHandle(hFile);
}
pVideoMemeory为变化数据指针。
微端口(miniport):
镜像驱动程序在微端口驱动程序中的功能需求很小,从代码上可以比较出镱像驱动少了许多功能,唯一必须实现的函数是DriverEntry,它是由微端口驱动程序导出的,也可以由以下函数导出:
HwVidFindAdapter
HwVidInitialize
HwVidStartIo
既然没有物理的显示设备与一个镜像的表面相关联,这三个函数可以空执行并且总是返回成功。
使用net内核api头文件冲突问题:
net内核api在wdk 7600上使用时需要自建立一个头文件及源文件(如 :xxx1.c与xxx1.h),将(如:#include "xxx1.h")导入mirror.c的源文件中。
如:在微端口上使用api来映射内存,跟据系统环境配置相应的net内核api来实现。
这是一个入门例子用来了解体会windows图形显示驱动的一些windows图形体系结构等。
需要参照的代码示例。
XP SP3测试
————————————————
版权声明:本文为CSDN博主「qwer430401」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qwer430401/article/details/53047022
VC Mirror Driver显示虚拟驱动经典开发的更多相关文章
- vnc mirror driver
2012年4月,大二下学期,平静的课堂上老师通知了一个比赛...第一届大学生软件设计大赛!然后我选了第六题:windows屏幕录像.就这样我就开始了我的vc开发生涯. 之前学了c/c++作为基础,自认 ...
- S3C2440触摸屏驱动实例开发讲解
出处:http://www.embeddedlinux.org.cn/html/yingjianqudong/ 一.开发环境 主 机:VMWare--Fedora 9 开发板:Mini2440--6 ...
- Vs2010 配置驱动的开发环境
我已被用来VS2010开发环境,之前曾经与vs2010驱动的开发环境.重装系统,一次又一次的配置,找了好几篇文章,配置没有成功,在配置阶段突然成功了,直接把原来的驱动程序的配置文件将能够接管使用. 当 ...
- VC下载文件显示进度条
VC下载文件显示进度条 逗比汪星人2009-09-18上传 by Koma http://blog.csd.net/wangningyu http://download.csdn.net/deta ...
- 异常驱动的开发(Exception-Driven Development)
你的网站或应用程序存在哪些问题?如果你在等着用户来告诉你,那么你只能看到所有的问题中已经暴露的那极小的一部分.要知道,那只是"冰山一角"! 而且,如果你真的是在守株待兔,我不得不很 ...
- 通过虚拟驱动vivi分析摄像头驱动
Linux摄像头驱动学习之:(二)通过虚拟驱动vivi分析摄像头驱动 一.通过指令 "strace -o xawtv.log xawtv" 得到以下调用信息: // 1~7都是在v ...
- 关于测试驱动的开发模式以及实战部分,建议看《Python Web开发测试驱动方法》这本书
关于测试驱动的开发模式以及实战部分,建议看<Python Web开发测试驱动方法>这本书
- 初始v4l2(六)-------根据虚拟驱动vivi的使用彻底分析摄像头驱动
前面的几篇文章已经分析了v4l2的框架,对框架的分析是比较粗浅的,能基本清楚函数之间的调用过程.但是很多内容并没有分析,比如说里面有很多ioctl,并没有分析哪些ioctl是必须的,也没有分析如何从应 ...
- DDD(Domain Driver Designer) 领域驱动设计简介
领域驱动设计之领域模型 加一个导航,关于如何设计聚合的详细思考,见这篇文章. 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity i ...
随机推荐
- 数字逻辑实践5->Verilog语法 | wire 与 reg 的选择与特性
问题起因:最初学习数字逻辑设计理论的时候还没有注意到,在实验课上写代码的时候发现了一个问题: 对于源码模块的变量定义,何时定义为reg.何时定义为wire?它们各自又有什么特性和物理意义? 1. wi ...
- try catch引发的性能优化深度思考
关键代码拆解成如下图所示(无关部分已省略): 起初我认为可能是这个 getRowDataItemNumberFormat 函数里面某些方法执行太慢,从 formatData.replace 到 une ...
- Codeforces 891D - Sloth(换根 dp)
Codeforces 题面传送门 & 洛谷题面传送门 换根 dp 好题. 为啥没人做/yiw 首先 \(n\) 为奇数时答案显然为 \(0\),证明显然.接下来我们着重探讨 \(n\) 是偶数 ...
- 亿级Web系统搭建:单机到分布式集群
亿级Web系统搭建:单机到分布式集群 当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压 ...
- HDC2021技术分论坛:异构组网如何解决共享资源冲突?
作者:lijie,HarmonyOS软总线领域专家 相信大家对HarmonyOS的"超级终端"比较熟悉了.那么,您知道超级终端场景下的多种设备在不同环境下是如何组成一个网络的吗?这 ...
- 全网最详细的ReentrantReadWriteLock源码剖析(万字长文)
碎碎念) 花了两天时间,终于把ReentrantReadWriteLock(读写锁)解析做完了.之前钻研过AQS(AbstractQueuedSynchronizer)的源码,弄懂读写锁也没有想象中那 ...
- 1005.K次取反后最大化的数组和
1005.K次取反后最大化的数组和 目录 1005.K次取反后最大化的数组和 题目 题解 排序+维护最小值min 题目 给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 ...
- IT四大名著
标题耸人听闻,sorry. CPU.操作系统.编译器和数据库我都不会.我英语也不行,但我认识所有的字母.:-) 万一有人感兴趣呢?https://sqlite.org/doclist.htmlThe ...
- Flink(一)【基础入门,Yarn、Local模式】
目录 一.介绍 Spark | Flink 二.快速入门:WC案例 pom依赖 批处理 流处理 有界流 无界流(重要) 三.Yarn模式部署 安装 打包测试,命令行(无界流) Flink on Yar ...
- 一起手写吧!promise.all
Promise.all 接收一个 promise 对象的数组作为参数,当这个数组里的所有 promise 对象全部变为resolve或 有 reject 状态出现的时候,它才会去调用 .then 方法 ...