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 ...
随机推荐
- Hive处理Json数据
Json 格式的数据处理 Json 数据格式是我们比较常用的的一种数据格式,例如埋点数据.业务端的数据.前后端调用都采用的是这种数据格式,所以我们很有必要学习一下这种数据格式的处理方法 准备数据 ca ...
- CF1540B Tree Array
先写一下自己想到的部分: 考虑枚举一个根. 计算一个点对出现的概率. 对于我这种期望概率基本不会的人,差点就把这题切了. 自己想到的部分都没有假. 问题在于: 如何计算一个点对出现的概率. 考虑和这两 ...
- UOJ #228 - 基础数据结构练习题(势能线段树+复杂度分析)
题面传送门 神仙题. 乍一看和经典题 花神游历各国有一点像,只不过多了一个区间加操作.不过多了这个区间加操作就无法再像花神游历各国那样暴力开根直到最小值为 \(1\) 为止的做法了,稍微感性理解一下即 ...
- C语言小练习 微型学生管理系统
很简陋,没有做输入校验,以写出来为第一目的,中间出了不少问题,尤其是结构体内字符串赋值的时候(理解不透彻),字符串比较用strcmp不能直接==判定,逻辑也很重要,不然会出现莫名其妙的问题. 涉及知识 ...
- 非标准的xml解析器的C++实现:三、解析器的初步实现
如同我之前的一篇文章说的那样,我没有支持DTD与命名空间, 当前实现出来的解析器,只能与xmlhttp对比,因为chrome浏览器解析大文档有bug,至于其他人实现的,我就不一一测试了,既然都决定自己 ...
- 工作学习2-gcc升级引发的崩溃
分享一下调查gcc 8.0下,函数漏写返回值崩溃问题,调查记录. 现在新的硬件,基本操作系统都是redhat 8.0,升级后测试时,发现了一个崩溃问题,记录一下. ================== ...
- 详解 Rainbond Ingress 泛解析域名机制
Rainbond 作为一款云原生应用管理平台,天生带有引导南北向网络流量的分布式网关 rbd-gateway.区别于一般的 Ingress 配置中,用户需要自行定义域名的使用体验,Rainbond 的 ...
- MapReduce03 框架原理InputFormat数据输入
目录 1 InputFormat数据输入 1.1 切片与MapTask并行度决定机制 问题引出 MapTask并行度决定机制 Job提交流程源码 切片源码 1.2 FileInputFormat切片机 ...
- acute, adapt
acute In Euclidean [欧几里得] geometry, an angle is the figure [图形] formed by two rays, called the sides ...
- 【XSS】再谈CSP内容安全策略
再谈CSP内容安全策略 之前每次都是想的很浅,或者只是个理论派,事实证明就是得动手实践 参考 CSP的用法 官方文档 通过设置属性来告诉浏览器允许加载的资源数据来源.可通过Response响应头来设置 ...