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

原文地址:https://www.cnblogs.com/cnhk19/p/12018365.html

时间: 2024-11-10 14:20:44

VC Mirror Driver显示虚拟驱动经典开发的相关文章

S3C2440触摸屏驱动实例开发讲解

出处:http://www.embeddedlinux.org.cn/html/yingjianqudong/ 一.开发环境 主  机:VMWare--Fedora 9 开发板:Mini2440--64MB Nand, Kernel:2.6.30.4 编译器:arm-linux-gcc-4.3.2 二.前提知识 1.Linux输入子系统(Input Subsystem): 在Linux中,输入子系统是由输入子系统设备驱动层.输入子系统核心层(Input Core)和输入子系统事件处理层(Even

VC++实现位图显示透明效果--实现原理

我们在进行程序的界面设计时,常常希望将位图的关键部分,也既是图像的前景显示在界面上,而将位图的背景隐藏起来,将位图与界面很自然的融合在一起,本文介绍了透明位图的制作知识,并将透明位图在一个对话框中显示了出来.本文所使用的原始位图及程序编译运行后的界面效果如下图所示: 图一.原始位图 图二.对话框界面上透明显示位图 一.实现方法 绘制"透明"位图是指绘制某一位图中除指定颜色外的其余部分,我们称这种颜色为"透明色".通过将位图的背景色指定为"透明色"

Vs2010 配置驱动的开发环境

我已被用来VS2010开发环境,之前曾经与vs2010驱动的开发环境.重装系统,一次又一次的配置,找了好几篇文章,配置没有成功,在配置阶段突然成功了,直接把原来的驱动程序的配置文件将能够接管使用. 当然首先: 打开(生成-->配置管理器) 并新建一个名称为"Dirver"的解决方式配置 从此处复制设置:debug. 此时会在project文件夹下成成一个配置文件. 将以下内容拷贝到配置文件里,关闭project又一次打开就可以. <?xml version="1.

领域驱动设计系列文章(1)——通过现实例子显示领域驱动设计的威力(转)

http://www.blogjava.net/johnnylzb/archive/2010/05/15/321057.html 领域驱动设计系列文章(1)——通过现实例子显示领域驱动设计的威力 曾经参与过系统维护或是在现有系统中进行迭代开发的软件工程师们,你们是否有过这样的痛苦经历:当需要修改一个Bug的时候,面对一个类中成百上千行的代码,没有注释,千奇百怪的方法和变量名字,层层嵌套的方法调用,混乱不堪的结构,不要说准确找到Bug所在的位置,就是要清晰知道一段代码究竟是做了什么也非常困难,最终

Linux驱动经典面试题目

1.  linux驱动分类 2.  信号量与自旋锁 3.  platform总线设备及总线设备如何编写 4.  kmalloc和vmalloc的区别 5.  module_init的级别 6.  添加驱动 7.  IIC原理,总线框架,设备编写方法,i2c_msg 8.  kernel panic 9.  USB总线,USB传输种类,urb等 10.android boot 流程 11.android init解析init.rcLinux驱动经典面试题目,布布扣,bubuko.com

VC下载文件显示进度条

VC下载文件显示进度条 逗比汪星人2009-09-18上传 by Koma http://blog.csd.net/wangningyu http://download.csdn.net/detail/wangningyu/1674247

javahost:使用虚拟DNS省掉开发环境配置hosts文件

javahost:使用虚拟DNS省掉开发环境配置hosts文件 学习如何使用java修改DNS解析记录,采用Properties文件替代hosts文件. 在不同运行环境访问不同将数据源服务器,为了方便切换是否使用域名替代IP? 如果使用域名的话,在开发环境就需要配置hosts文件 团队其他成员checkout代码是否需要文档告诉他怎么配置hosts文件? 您负责的项目很多怎么办?为了方便修改hots文件您是否会借助Win Hosts Manager之类的软件? 讨厌写文档吗?想团队其他成员che

机器学习实践 测试驱动的开发方法——互动出版网

这篇是计算机类的优质预售推荐>>>><机器学习实践 测试驱动的开发方法> 用测试驱动方法开发出可靠.稳定的机器学习算法. 编辑推荐 本书介绍在开发机器学习算法时如何运用测试驱动的方法,捕捉可能扰乱正常分析的错误.这本实践指南从测试驱动开发和机器学习的基本原理讲起,展示了如何将测试驱动开发运用于若干机器学习算法,包括朴素贝叶斯分类器和神经网络. 任何机器学习算法都有一些传统的测试方法,但它们通常都不会考虑编码中的人为错误.借助测试驱动的开发方法,你便不会像其他研究者那样盲

loadrunner虚拟用户脚本开发

一.loadrunner虚拟用户开发---变量详细解析 变量的定义 局部变量和全局变量 1.在init  action end中定义的变量就是局部变量 2.在gloabal中定义的变量是全局变量 3.什么时候定义全局变量? 整个过程中固定不变的,例如url地址,KEY 其他,需要定义成全局变量. 简单例子: 在action里,定义一个变量a,赋值10,然后打印a,可以看到结果打印出10. 可以看出,在LR中打印的时候,只需要用LR的函数lr_output_message就可以了,C语言的函数pr