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

posted @ 2019-12-10 18:25  CNHK19  阅读(1237)  评论(0编辑  收藏  举报