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 ...
随机推荐
- 模仿UP主,用Python实现一个弹幕控制的直播间!
灵感来源 之前在B站看到一个有意思的视频: [B站][亦]终极云游戏!五千人同开一辆车,复现经典群体智慧实验 大家可以看看,很有意思. up主通过代码实现了实时读取直播间里的弹幕内容,进而控制自己的电 ...
- Mysql的delimiter
告诉MySQL解释器,该段命令是否已经结束了,mysql是否可以执行了.默认情况下,delimiter是分号;.在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令. 有时 ...
- 零基础学习java------day15--------collections用法,比较器,Set(TreeSet,TreeMap),异常
1. Collections用法 Collections: 集合的工具类public static <T> void sort(List<T> list) 排序,升序publi ...
- win32汇编基础
win32汇编基础知识 Debug 版本|Release 版本 Debug 是"调试"的意思,Debug 版本就是为调试而生的,编译器在生成 Debug 版本的程序时会加入调试辅助 ...
- 【leetcode】917. Reverse Only Letters(双指针)
Given a string s, reverse the string according to the following rules: All the characters that are n ...
- linux添加用户、权限
# useradd –d /usr/sam -m sam 此命令创建了一个用户sam,其中-d和-m选项用来为登录名sam产生一个主目录/usr/sam(/usr为默认的用户主目录所在的父目录). 假 ...
- 基本类型、引用类型NPE异常
1.null是Java中的关键字,像public.static.final.它是大小写敏感的,你不能将null写成Null或NULL,编译器将不能识别它们然后报错. 2.就像每种原始类型都有默认值一样 ...
- my37_MGR流控对数据库性能的影响以及MGR与主从的性能对比
mysql> show variables like 'group_replication_flow_control_applier_threshold'; +----------------- ...
- Project Reactor工厂方法和错误处理
工厂方法创建流 Backpressure : the ability for the consumer to signal the producer that the rate of emission ...
- linux 磁盘满了,vim 编辑文件时无法保存
早上来发现 redis 不能用,报 MISCONF Redis is configured to save RDB snapshots, but it is currently not able to ...