一个简单的显示驱动实例

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. 模仿UP主,用Python实现一个弹幕控制的直播间!

    灵感来源 之前在B站看到一个有意思的视频: [B站][亦]终极云游戏!五千人同开一辆车,复现经典群体智慧实验 大家可以看看,很有意思. up主通过代码实现了实时读取直播间里的弹幕内容,进而控制自己的电 ...

  2. Mysql的delimiter

    告诉MySQL解释器,该段命令是否已经结束了,mysql是否可以执行了.默认情况下,delimiter是分号;.在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令. 有时 ...

  3. 零基础学习java------day15--------collections用法,比较器,Set(TreeSet,TreeMap),异常

    1. Collections用法 Collections: 集合的工具类public static <T> void sort(List<T> list) 排序,升序publi ...

  4. win32汇编基础

    win32汇编基础知识 Debug 版本|Release 版本 Debug 是"调试"的意思,Debug 版本就是为调试而生的,编译器在生成 Debug 版本的程序时会加入调试辅助 ...

  5. 【leetcode】917. Reverse Only Letters(双指针)

    Given a string s, reverse the string according to the following rules: All the characters that are n ...

  6. linux添加用户、权限

    # useradd –d /usr/sam -m sam 此命令创建了一个用户sam,其中-d和-m选项用来为登录名sam产生一个主目录/usr/sam(/usr为默认的用户主目录所在的父目录). 假 ...

  7. 基本类型、引用类型NPE异常

    1.null是Java中的关键字,像public.static.final.它是大小写敏感的,你不能将null写成Null或NULL,编译器将不能识别它们然后报错. 2.就像每种原始类型都有默认值一样 ...

  8. my37_MGR流控对数据库性能的影响以及MGR与主从的性能对比

    mysql> show variables like 'group_replication_flow_control_applier_threshold'; +----------------- ...

  9. Project Reactor工厂方法和错误处理

    工厂方法创建流 Backpressure : the ability for the consumer to signal the producer that the rate of emission ...

  10. linux 磁盘满了,vim 编辑文件时无法保存

    早上来发现 redis 不能用,报 MISCONF Redis is configured to save RDB snapshots, but it is currently not able to ...