zoukankan      html  css  js  c++  java
  • VC Mirror Driver显示虚拟驱动经典开发

    一个简单的显示驱动实例

    windows wdk 7600的 mirror(镜像) 显示驱动部分

    基本流程:

    Windows 2000 DDK包含了一个例子镜像驱动程序,在 上面3个目录中包括了组件源文件。

    目录
        

    包含的源文件

    Videodisplaysmirrordll
        

    镜像驱动程序

    Videominiportmirror
        

    微端口驱动程序

    Videodisplaysmirrorapp
        

    用户模式服务。也包含mirror.inf。

    打开disp文件夹 C:WinDDK7600.16385.1srcvideodisplaysmirrordisp// 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 DeviceScreen
            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: "));
         
            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 ");
                return(FALSE);
            }
         
            if (!EngAssociateSurface(hsurf, ppdev->hdevEng, flHooks))
            {
                RIP("DISRP DrvEnableSurface failed EngAssociateSurface ");
                EngDeleteSurface(hsurf);
                return(FALSE);
            }
         
            ppdev->hsurfEng = (HSURF) hsurf;
            
            return(hsurf);
        }

    3.在函数中DrvDisableSurface // 清理表面

        VOID DrvDisableSurface(
        DHPDEV dhpdev)
        {
            PPDEV ppdev = (PPDEV) dhpdev;
         
            DISPDBG((0,"DrvDisableSurface: "));
         
            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) ", 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) ", 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

  • 相关阅读:
    数据管理(五)
    (译文)Gentoo的前世今生 part3 (完成版※)
    数据管理(三)
    数据管理(一)
    数据管理(七)
    (译文)Gentoo的前世今生 PART 1(完成版)
    数据管理(六)
    数据管理(四)
    SQL Server补丁版本的检查和安装过程中常见问题
    3938 Portal(离线型的并查集)
  • 原文地址:https://www.cnblogs.com/cnhk19/p/12018365.html
Copyright © 2011-2022 走看看