一个简单的显示驱动实例

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显示虚拟驱动经典开发的更多相关文章

  1. vnc mirror driver

    2012年4月,大二下学期,平静的课堂上老师通知了一个比赛...第一届大学生软件设计大赛!然后我选了第六题:windows屏幕录像.就这样我就开始了我的vc开发生涯. 之前学了c/c++作为基础,自认 ...

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

    出处:http://www.embeddedlinux.org.cn/html/yingjianqudong/ 一.开发环境 主  机:VMWare--Fedora 9 开发板:Mini2440--6 ...

  3. Vs2010 配置驱动的开发环境

    我已被用来VS2010开发环境,之前曾经与vs2010驱动的开发环境.重装系统,一次又一次的配置,找了好几篇文章,配置没有成功,在配置阶段突然成功了,直接把原来的驱动程序的配置文件将能够接管使用. 当 ...

  4. VC下载文件显示进度条

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

  5. 异常驱动的开发(Exception-Driven Development)

    你的网站或应用程序存在哪些问题?如果你在等着用户来告诉你,那么你只能看到所有的问题中已经暴露的那极小的一部分.要知道,那只是"冰山一角"! 而且,如果你真的是在守株待兔,我不得不很 ...

  6. 通过虚拟驱动vivi分析摄像头驱动

    Linux摄像头驱动学习之:(二)通过虚拟驱动vivi分析摄像头驱动 一.通过指令 "strace -o xawtv.log xawtv" 得到以下调用信息: // 1~7都是在v ...

  7. 关于测试驱动的开发模式以及实战部分,建议看《Python Web开发测试驱动方法》这本书

    关于测试驱动的开发模式以及实战部分,建议看<Python Web开发测试驱动方法>这本书

  8. 初始v4l2(六)-------根据虚拟驱动vivi的使用彻底分析摄像头驱动

    前面的几篇文章已经分析了v4l2的框架,对框架的分析是比较粗浅的,能基本清楚函数之间的调用过程.但是很多内容并没有分析,比如说里面有很多ioctl,并没有分析哪些ioctl是必须的,也没有分析如何从应 ...

  9. DDD(Domain Driver Designer) 领域驱动设计简介

    领域驱动设计之领域模型 加一个导航,关于如何设计聚合的详细思考,见这篇文章. 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity i ...

随机推荐

  1. C#中的异步

    什么是异步? 作为一名Web端的码农,第一次接触异步是Ajax. 异步请求后端获取数据源,js操作html的dom节点,而无需要渲染整个网页的操作. 页面上点击按钮,加载进度动画,同时发起Ajax请求 ...

  2. 『学了就忘』Linux权限管理 — 55、文件特殊权限

    目录 1.文件特殊权限说明 2.设置SetUID 3.检测SetUID的脚本 4.设置SetGID (1)针对文件的作用 (2)针对目录的作用 5.Sticky BIT 6.设定文件特殊权限 7.文件 ...

  3. 洛谷 P4516 [JSOI2018]潜入行动

    题面传送门 一眼树形 \(dp\) 本题有 \(2\) 大难点. 难点之一是状态的设计,这里需要四维状态,\(dp[i][j][0/1][0/1]\) 表示在以 \(i\) 为根的子树内放了 \(j\ ...

  4. SP20173 DIVCNT2 - Counting Divisors (square)

    Refer 主要思路参考了 Command_block 的题解. Description 给定 \(n\)(\(n\le 10^{10}\)),求 \[\sum_{i=1}^n\sigma_0(i^2 ...

  5. Perl语言入门10-13

    ----------第十章 其他控制结构---------------- unless结构 unless($fred =~ /\A[A-Z_\w*\z]/i){print "yes" ...

  6. 【数据库】本地KEGG数据库如何拆分子库?

    目录 KEGG本地库文件 按物种拆分KEGG数据库 1.获得物种分类信息 2.获得物种分类的序列信息并建库 3.获得物种分类的K-ko对应文件 根据相似性原理,序列相似,功能相似,所有功能注释无非是用 ...

  7. 汽车C2M模式综述

  8. typedef 的用法

    [2]typedef (1)在C语言中,允许使用关键字typedef定义新的数据类型 其语法如下: typedef <已有数据类型> <新数据类型>; 如: typedef i ...

  9. vc控制台程序关闭事件时的正确处理方式

    百度可以找到很多关于这个问题解决的方法 关键控制台API函数:SetConsoleCtrlHandler 在支持C++ 11以上的编译器中,你可以这么做. SetConsoleCtrlHandler( ...

  10. linux下定位异常消耗的线程实战分析

    前言: 之前分享过一篇Linux开发coredump文件分析实战分享 ,今天再来分享一篇实战文章. 在我们嵌入式linux开发过程中,开发过程中我们经常会使用多进程.多线程开发.那么多线程使用过程中, ...