driver development part 6_ introduction to display drivers - codeproject.pdf

29
11,313,438 members ﴾10,880 online﴿ Sign in home quick answers discussions features community help Search for articles, questions, tips Articles » Platforms, Frameworks & Libraries » Win32/64 SDK & OS » Windows General Toby Opferman, 29 Jan 2006 Rate this: Driver Development Part 6: Introduction to Display Drivers Introduction to the Windows display driver model. Download source files ‐ 74.6 Kb Introduction It has been a while since I have updated this series and I have found some free time to write the next version. In this article, we will take a look at how to write a simple display driver. A display driver is a special type of driver which fits into a framework that is unlike what we have talked about so far in this series. The example driver for this article will show how to write a basic display driver which does not have any hardware associated with it. Instead this display driver will implement graphics to memory and an application will be used 4.94 ﴾79 votes﴿ articles

Upload: pmmanjesh

Post on 12-Dec-2015

234 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 1/29

11,313,438 members ﴾10,880 online﴿   

   

Sign in

home quick answers discussions features community help Search for articles, questions, tips

Articles » Platforms, Frameworks & Libraries » Win32/64 SDK & OS » Windows General 

Toby Opferman, 29 Jan 2006 Rate this:

Driver Development Part 6: Introduction to DisplayDrivers

Introduction to the Windows display driver model.

Download source files ‐ 74.6 Kb

IntroductionIt has been a while since I have updated this series and I have found some free time to write the next version. Inthis article, we will take a look at how to write a simple display driver. A display driver is a special type of driverwhich fits into a framework that is unlike what we have talked about so far in this series.

The example driver for this article will show how to write a basic display driver which does not have any hardwareassociated with it. Instead this display driver will implement graphics to memory and an application will be used

   4.94 ﴾79 votes﴿

articles

Page 2: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 2/29

to display those graphics. This method was demonstrated in an article I wrote for the C/C++ User's Journalhowever that article was about extending VMWare to support multiple monitors. This article will only be focusingon display drivers themselves and will not use VMWare but require just your local machine.

Display driver architectureThe first place to start is to show the display driver architecture as it is in Windows NT. I will make a commenthere that Windows Vista introduces a new display driver model known as LDDM. This is essential in supportingthe new Desktop Window Manager however Windows Vista still supports the old display driver model inconjunction with the old Window Manager. This article will not be covering LDDM.

The display driver model consists of two pieces, the miniport driver and the display driver. The miniport driver isloaded into system space and is responsible for enumerating devices and managing device resources. The displaydriver is loaded into session space and is responsible for implementing the actual GDI graphics calls. The driver isresponsible for implementing these calls however it wants which can be done in software or deferred to thegraphics card itself. The display driver has full control over how a line is drawn or how a transparency effect isimplemented.

The following diagram shows the Windows display driver architecture:

Page 3: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 3/29

The display miniport

The miniport driver is loaded into system space and is responsible for managing display device resources andenumerating devices. This driver however uses another driver as its framework which is VIDEOPRT.SYS. This driverexports APIs which your driver will link against and use. Surprised a driver can export APIs? Don't be. Drivers usethe PE format and have export and import tables. You can export APIs from your driver and allow other drivers tolink against them just like a DLL. In fact all the APIs you use you are just linking against the kernel and otherdrivers.

I will note there is a slight difference between linking against kernel and user mode drivers. If a driver linksagainst a driver that is not currently loaded into memory, that driver will become loaded into memory howeverthe DriverEntry for that driver will not be called. The DriverEntry itself is not called until the driver is directlyloaded using ZwLoadDriver, loaded by the system or with the service API as we were shown previously. In anycase you can export APIs from one driver and link against and use those APIs from another driver. There is no APIto "GetProcAddress" in the kernel so you would need to write one.

In any case, VideoPrt.SYS exports APIs which your miniport driver will call. This driver does a few things one ofwhich is to implement common code so that video driver writers do not need to rewrite the same code. This codeincludes video device enumeration between the WIN32 subsystem ﴾WIN32K.SYS﴿ and your miniport. TheVideoPrt.SYS will also create the device objects for the display and when you call the initialization routine it willthunk your driver object's entry points to point to VideoPrt.SYS!

The VideoPrt.SYS APIs all start with "VideoPort" and the first one you call is "VideoPortInitialize". If younotice the first two arguments are the ones passed into your DriverEntry routine however it simply calls them"Context1" and "Context2" as if your video miniport driver is "special". Don't be fooled, this driver entry is thesame as what we worked with before and the first "Context1" is actually your driver object. Once you pass yourdriver object to VideoPortInitialize all your entry points to your driver are thunked to point to VideoPrt.Sys.Instead you pass in different function pointers in "VIDEO_HW_INITIALIZATION_DATA" which VideoPrt.SYS willcall instead when it needs to.

This means that you do not need to directly deal with IRPs in a video miniport. The VideoPrt.SYS will insteadhandle them, break them down and then determine when you need to be informed about the data. Instead youdo deal with what they call "VRP" or "Video Request Packet". This is essentially a mild, broken down version ofthe IRP in a different data structure. You simply need to return there is no special handling of this data structureas there is with IRPs.

Page 4: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 4/29

The documentation specifies that you should only use the "VideoPort" APIs in a miniport however since this isalso just a regular system level driver you can still link against any kernel API you wish and I have done thisbefore. This is not the case with the display driver itself as we will see later.

Since we do not have any hardware our miniport driver will be pretty thin and easy. The following code showshow the video miniport DriverEntry is constructed:

Hide   Shrink   Copy Code

/********************************************************************** *  *  DriverEntry * *    This is the entry point for this video miniport driver * **********************************************************************/ULONG DriverEntry(PVOID pContext1, PVOID pContext2){    VIDEO_HW_INITIALIZATION_DATA hwInitData;    VP_STATUS vpStatus;    /*     * The Video Miniport is "technically" restricted to calling      * "Video*" APIs.     * There is a driver that encapsulates this driver by setting your      * driver's entry points to locations in itself. It will then      * handle your IRP's for you and determine which of the entry      * points (provided below) into your driver that should be called.     * This driver however does run in the context of system memory      * unlike the GDI component.     */    VideoPortZeroMemory(&hwInitData,                                 sizeof(VIDEO_HW_INITIALIZATION_DATA));    hwInitData.HwInitDataSize  = sizeof(VIDEO_HW_INITIALIZATION_DATA);    hwInitData.HwFindAdapter             = FakeGfxCard_FindAdapter;    hwInitData.HwInitialize              = FakeGfxCard_Initialize;    hwInitData.HwStartIO                 = FakeGfxCard_StartIO;    hwInitData.HwResetHw                 = FakeGfxCard_ResetHW;    hwInitData.HwInterrupt               = FakeGfxCard_VidInterrupt;    hwInitData.HwGetPowerState           = FakeGfxCard_GetPowerState;    hwInitData.HwSetPowerState           = FakeGfxCard_SetPowerState;    hwInitData.HwGetVideoChildDescriptor =                                       FakeGfxCard_GetChildDescriptor;    vpStatus = VideoPortInitialize(pContext1,                                       pContext2, &hwInitData, NULL);    return vpStatus;}

Page 5: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 5/29

Article

Browse Code

Stats

Revisions

Alternatives

Comments ﴾118﴿

Tagged as

Win2K

WinXP

I mentioned before you simply pass the DriverObject directly through to the VideoPrt.SYS driver as shownabove. You also fill in a data structure which contains entries into your driver which the VideoPrt.SYS driver willcall to perform various actions. The "HwStartIO" is where you would handle IOCTLs and you can use IOCTLsbetween the display driver and the Video Miniport. The display driver would simply call "EngDeviceIoControl"and this IOCTL will be handled in the miniport's HwStartIO.

The following shows how I have implemented the video miniport functions:

Hide   Shrink   Copy Code

/*#pragma alloc_text(PAGE, FakeGfxCard_ResetHW)       Cannot be Paged*//*#pragma alloc_text(PAGE, FakeGfxCard_VidInterrupt)  Cannot be Paged*/#pragma alloc_text(PAGE, FakeGfxCard_GetPowerState)#pragma alloc_text(PAGE, FakeGfxCard_SetPowerState)#pragma alloc_text(PAGE, FakeGfxCard_GetChildDescriptor)#pragma alloc_text(PAGE, FakeGfxCard_FindAdapter)#pragma alloc_text(PAGE, FakeGfxCard_Initialize)#pragma alloc_text(PAGE, FakeGfxCard_StartIO)/********************************************************************** *  *  FakeGfxCard_ResetHW * *     This routine would reset the hardware when a soft reboot is *     performed. Returning FALSE from this routine would force *     the HAL to perform an INT 10h and set Mode 3 (Text).  * *     We are not real hardware so we will just return TRUE so the HAL *     does nothing. * **********************************************************************/BOOLEAN FakeGfxCard_ResetHW(PVOID HwDeviceExtension,                                  ULONG Columns, ULONG Rows){   return TRUE;}/********************************************************************** *  *  FakeGfxCard_VidInterrupt * *     Checks if it's adapter generated an interrupt and dismisses it *     or returns FALSE if it did not. * **********************************************************************/BOOLEAN FakeGfxCard_VidInterrupt(PVOID HwDeviceExtension){   return FALSE;

Page 6: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 6/29

Related Articles

Driver DevelopmentPart 1: Introductionto Drivers

File System FilterDriver Tutorial

A simple demo forWDM Driverdevelopment

Raw Ethernet PacketSending

Driver Wizard

Win2003

Vista

C++

C

Visual‐Studio

Dev

ASM

Intermediate

Virtualization

}/********************************************************************** *  *  FakeGfxCard_GetPowerState * *         Queries if the device can support the requested power state. * **********************************************************************/VP_STATUS FakeGfxCard_GetPowerState(PVOID HwDeviceExtension,           ULONG HwId, PVIDEO_POWER_MANAGEMENT VideoPowerControl){   return NO_ERROR;}/********************************************************************** *  *  FakeGfxCard_SetPowerState * *         Sets the power state. * **********************************************************************/VP_STATUS FakeGfxCard_SetPowerState(PVOID HwDeviceExtension,           ULONG HwId, PVIDEO_POWER_MANAGEMENT VideoPowerControl){   return NO_ERROR;}/********************************************************************** *  *  FakeGfxCard_GetChildDescriptor * *        Returns an identifer for any child device supported  *        by the miniport. * **********************************************************************/ULONG FakeGfxCard_GetChildDescriptor (PVOID HwDeviceExtension,       PVIDEO_CHILD_ENUM_INFO ChildEnumInfo, PVIDEO_CHILD_TYPE pChildType,       PVOID pChildDescriptor, PULONG pUId, PULONG pUnused){   return ERROR_NO_MORE_DEVICES;}/********************************************************************** *  *  FakeGfxCard_FindAdapter * *        This function performs initialization specific to devices  *        maintained by this miniport driver. * **********************************************************************/VP_STATUS FakeGfxCard_FindAdapter(PVOID HwDeviceExtension, 

Page 7: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 7/29

            PVOID HwContext, PWSTR ArgumentString,             PVIDEO_PORT_CONFIG_INFO ConfigInfo, PUCHAR Again){   return NO_ERROR;}/********************************************************************** *  *  FakeGfxCard_Initialize * *      This initializes the device. * **********************************************************************/BOOLEAN FakeGfxCard_Initialize(PVOID HwDeviceExtension){   return TRUE;}/********************************************************************** *  *  FakeGfxCard_StartIO * *      This routine executes requests on behalf of the GDI Driver  *      and the system. The GDI driver is allowed to issue IOCTLs  *      which would then be sent to this routine to be performed  *      on it's behalf. * *      We can add our own proprietary IOCTLs here to be processed  *      from the GDI driver.  * **********************************************************************/BOOLEAN FakeGfxCard_StartIO(PVOID HwDeviceExtension,                 PVIDEO_REQUEST_PACKET RequestPacket){   RequestPacket‐>StatusBlock‐>Status      = 0;   RequestPacket‐>StatusBlock‐>Information = 0;   return TRUE;}

Since I don't have any hardware I simply implement enough of a miniport to make the system happy. The onlypossible API I would intend to use would be "StartIO" if I needed to access or perform an operation on thesystem that the display driver is not capable of doing with its limited API set. However in this implementationthere is nothing we need done. Remember, the main purpose of the miniport is to enumerate hardwaredevices/resources and manage them. If you don't have any then that removes everything but the necessary tokeep the driver model happy.

Page 8: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 8/29

The display driver

The display driver links against WIN32K.SYS and is only allowed to call Eng* APIs. These APIs are actually found inthe kernel and in user mode. Prior to NT4 the display drivers were in user mode. In any case the same API setused by display drivers is also used by printer drivers. Conforming to this API set also allows the display driver tobe movable to user or kernel with minimal work.

The display driver however is not loaded into system memory but instead session space. Session space is thekernel equivalent of process isolation. In user mode processes have their own virtual memory address space andin the kernel sessions have their own virtual memory address space. System space is the kernel memory which isglobal to all sessions.

A session is an instance of a logged on user which contains its own Window Manager, Desktop﴾s﴿, shell andapplications. This is most notable in Windows XP "Fast User Switching" in which you can log multiple users onto asingle machine. Each user is actually in a unique session with a unique range of kernel memory known as sessionspace.

This can be a problem when designing a video driver. It means you cannot simply pass random memory down toyour miniport if your miniport may process that memory outside the context of the current session. This is forexample passing this memory to be processed in another thread which could reside in the system process forexample.

If the system process is not associated with your session then you will be accessing a different memory rangethan you think. When this occurs you get the "A driver has not been correctly ported to Terminal Services" bluescreen.

The display driver is not anything like the drivers we have worked with so far. It is still in PE format but it is notlike the miniport which is a normal kernel driver linking against a different frame work. This driver cannot usekernel APIs by linking directly to them and should not use them for the exact reason specified above. If the APIpasses the memory outside of session space then you have a blue screen unless you ensure you only pass systemmemory. This is another reason to only use the Eng* API set however you could request a function pointer tablefrom the miniport driver; nothing actually prevents you from doing so.

In any case the display driver behaves more like a DLL than normal drivers do and it is essentially treated as one.This driver's framework is tied to WIN32K.SYS which implements the Window Manager as well as GDI. This driveris compiled using "‐entry:DrvEnableDriver@12 /SUBSYSTEM:NATIVE" where DrvEnableDriver is the

Page 9: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 9/29

entry point for the display driver.

DrvEnableDriver

This is the initial entry point for a display driver and it is not related to DriverEntry in any way. This API passesin a DRVENABLEDATA structure which is to be filled in with a table of functions which are the entries to the driver.The table contains a list which is an index value followed by the function pointer. The index value specifies thefunction type such as "INDEX_DrvCompletePDEV" which specifies that the function pointer is a pointer to theDrvCompletePDEV handler in the driver. Some APIs are optional and some are required.

This entry point is simply responsible for returning the list of your functions. You may also do any initializationyou may need to do here. The following is the code from the sample display driver in this article:

Hide   Shrink   Copy Code

/* * Display Drivers provide a list of function entry points for specific GDI * tasks. These are identified by providing a pre‐defined "INDEX" value (pre‐  * defined * by microsoft) followed by the function entry point. There are levels of  * flexibility * on which ones you are REQUIRED and which ones are technically OPTIONAL. * */                                            DRVFN g_DrvFunctions[] ={    {   INDEX_DrvAssertMode,         (PFN) GdiExample_DrvAssertMode         },    {   INDEX_DrvCompletePDEV,       (PFN) GdiExample_DrvCompletePDEV       },    {   INDEX_DrvCreateDeviceBitmap, (PFN) GdiExample_DrvCreateDeviceBitmap },    {   INDEX_DrvDeleteDeviceBitmap, (PFN) GdiExample_DrvDeleteDeviceBitmap },    {   INDEX_DrvDestroyFont,        (PFN) GdiExample_DrvDestroyFont        },    {   INDEX_DrvDisablePDEV,        (PFN) GdiExample_DrvDisablePDEV        },    {   INDEX_DrvDisableDriver,      (PFN) GdiExample_DrvDisableDriver      },    {   INDEX_DrvDisableSurface,     (PFN) GdiExample_DrvDisableSurface     },    {   INDEX_DrvSaveScreenBits,     (PFN) GdiExample_DrvSaveScreenBits     },    {   INDEX_DrvEnablePDEV,         (PFN) GdiExample_DrvEnablePDEV         },    {   INDEX_DrvEnableSurface,      (PFN) GdiExample_DrvEnableSurface      },    {   INDEX_DrvEscape,             (PFN) GdiExample_DrvEscape             },    {   INDEX_DrvGetModes,           (PFN) GdiExample_DrvGetModes           },    {   INDEX_DrvMovePointer,        (PFN) GdiExample_DrvMovePointer        },    {   INDEX_DrvNotify,             (PFN) GdiExample_DrvNotify             },  //  {   INDEX_DrvRealizeBrush,     (PFN) GdiExample_DrvRealizeBrush       },    {   INDEX_DrvResetPDEV,          (PFN) GdiExample_DrvResetPDEV          },

Page 10: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 10/29

    {   INDEX_DrvSetPalette,         (PFN) GdiExample_DrvSetPalette         },    {   INDEX_DrvSetPointerShape,    (PFN) GdiExample_DrvSetPointerShape    },    {   INDEX_DrvStretchBlt,         (PFN) GdiExample_DrvStretchBlt         },    {   INDEX_DrvSynchronizeSurface, (PFN) GdiExample_DrvSynchronizeSurface },    {   INDEX_DrvAlphaBlend,         (PFN) GdiExample_DrvAlphaBlend         },    {   INDEX_DrvBitBlt,             (PFN) GdiExample_DrvBitBlt             },    {   INDEX_DrvCopyBits,           (PFN) GdiExample_DrvCopyBits           },    {   INDEX_DrvFillPath,           (PFN) GdiExample_DrvFillPath           },    {   INDEX_DrvGradientFill,       (PFN) GdiExample_DrvGradientFill       },    {   INDEX_DrvLineTo,             (PFN) GdiExample_DrvLineTo             },    {   INDEX_DrvStrokePath,         (PFN) GdiExample_DrvStrokePath         },    {   INDEX_DrvTextOut,            (PFN) GdiExample_DrvTextOut            },    {   INDEX_DrvTransparentBlt,     (PFN) GdiExample_DrvTransparentBlt     },};                                            ULONG g_ulNumberOfFunctions = sizeof(g_DrvFunctions) / sizeof(DRVFN);/********************************************************************* * DrvEnableDriver * *   This is the initial driver entry point. This is the "DriverEntry"  *   equivlent for Display and Printer drivers. This function must  *   return a function table that represents all the supported entry  *   points into this driver. * *********************************************************************/BOOL DrvEnableDriver(ULONG ulEngineVersion,      ULONG ulDataSize, DRVENABLEDATA *pDrvEnableData){    BOOL bDriverEnabled = FALSE;    /*     * We only want to support versions > NT 4     *     */    if(HIWORD(ulEngineVersion) >= 0x3 &&        ulDataSize >= sizeof(DRVENABLEDATA))    {       pDrvEnableData‐>iDriverVersion = DDI_DRIVER_VERSION;       pDrvEnableData‐>pdrvfn         = g_DrvFunctions;       pDrvEnableData‐>c              = g_ulNumberOfFunctions;       bDriverEnabled                 = TRUE;    }    return bDriverEnabled;              }

DrvDisableDriver

Page 11: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 11/29

This function handler is called when the display driver is being unloaded. In this handler you can perform anyclean up necessary for what you have created in the DrvEnableDriver call. The following code is from thesample driver:

Hide   Copy Code

/********************************************************************* * GdiExample_DrvDisableDriver * *   This function is used to notify the driver when the driver is *   getting ready to be unloaded. * *********************************************************************/VOID GdiExample_DrvDisableDriver(VOID){    /*     *  No Clean up To Do     */}

DrvGetModes

The API called after the driver is loaded and enabled is DrvGetModes. This API is used to query the modessupported by the device. These modes are used to populate the "Settings" tab in the "Display Properties" dialog.The modes can be cached so the operating system does not think of them as being dynamic and changing. Theoperating system believes this to be a static list and while there are times and ways that this API may be calledmore than once for the most part it should not be considered dynamic.

The API is generally called twice the first time it simply asks for the size required to store the modes and thesecond time it calls with the correct size. The following code fragment is from the sample driver which onlysupports 640x480x32:

Hide   Shrink   Copy Code

/********************************************************************* * GdiExample_DrvGetModes * *    This API is used to enumerate display modes. * *    This driver only supports 640x480x32 * *********************************************************************/ULONG GdiExample_DrvGetModes(HANDLE hDriver, 

Page 12: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 12/29

                               ULONG cjSize, DEVMODEW *pdm){   ULONG ulBytesWritten = 0, ulBytesNeeded = sizeof(DEVMODEW);   ULONG ulReturnValue;   ENGDEBUGPRINT(0, "GdiExample_DrvGetModes\r\n", NULL);   if(pdm == NULL)   {       ulReturnValue =  ulBytesNeeded;   }   else   {              ulBytesWritten = sizeof(DEVMODEW);       memset(pdm, 0, sizeof(DEVMODEW));       memcpy(pdm‐>dmDeviceName, DLL_NAME, sizeof(DLL_NAME));       pdm‐>dmSpecVersion   = DM_SPECVERSION;       pdm‐>dmDriverVersion = DM_SPECVERSION;       pdm‐>dmDriverExtra      = 0;       pdm‐>dmSize             = sizeof(DEVMODEW);       pdm‐>dmBitsPerPel       = 32;       pdm‐>dmPelsWidth        = 640;       pdm‐>dmPelsHeight       = 480;       pdm‐>dmDisplayFrequency = 75;       pdm‐>dmDisplayFlags     = 0;              pdm‐>dmPanningWidth     = pdm‐>dmPelsWidth;       pdm‐>dmPanningHeight    = pdm‐>dmPelsHeight;       pdm‐>dmFields           = DM_BITSPERPEL | DM_PELSWIDTH |                                  DM_PELSHEIGHT | DM_DISPLAYFLAGS |                                  DM_DISPLAYFREQUENCY;       ulReturnValue = ulBytesWritten;   }   return ulReturnValue;}

DrvEnablePDEV

Once a mode is chosen this API is then called which will allow the driver to enable the "physical device". Thepurpose of this API is to allow the display driver to create its own private context which will be passed into theother display entry points. The reason for this private context is that a single display driver may handle multipledisplay devices and as such would need to distinguish one display device from another. The return value for thisAPI is a pointer to the context or instance of the supplied display device.

The selected display setting is passed into this API via the DEVMODE parameter however the sample driver does

Page 13: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 13/29

not use this method since it's hard coded to setup 800x600x32 mode only.

This API aside from creating an instance structure must also initialize the GDIINFO and DEVINFO data structuresat a minimum. These parameters are important as if you fill in supporting a certain feature and you really do notyou can have graphic corruption as a side effect or even blue screen. The next two parameters that I will mentionare the hDev and hDriver parameters. The hDriver parameter is actually the DEVICE_OBJECT for the displaydriver and can be used with APIs such as EngDeviceIoControl to communicate with the miniport driver.

The hDev is the handle to GDI however since the device is in the process of being created it is actually useless. Itis recommended that you wait until the DrvCompletePDEV call before saving and using this handle. Thefollowing code is from the sample driver's DrvEnablePDEV:

Hide   Shrink   Copy Code

/********************************************************************* * GdiExample_DrvEnablePDEV * *   This function will provide a description of the Physical Device.  *   The data returned is a user defined data context to be used as a  *   handle for this display device. * *   The hDriver is a handle to the miniport driver associated with  *   this display device. This handle can be used to communicate to  *   the miniport through APIs to send things like IOCTLs. * *********************************************************************/DHPDEV GdiExample_DrvEnablePDEV(DEVMODEW *pdm, PWSTR pwszLogAddr,        ULONG cPat, HSURF *phsurfPatterns, ULONG cjCaps,        GDIINFO *pGdiInfo, ULONG cjDevInfo, DEVINFO *pDevInfo,        HDEV hdev, PWSTR pwszDeviceName, HANDLE hDriver) {    PDEVICE_DATA pDeviceData = NULL;        ENGDEBUGPRINT(0, "GdiExample_DrvEnablePDEV Enter \r\n", NULL);    pDeviceData = (PDEVICE_DATA) EngAllocMem(0,                                sizeof(DEVICE_DATA), FAKE_GFX_TAG);    if(pDeviceData)    {        memset(pDeviceData, 0, sizeof(DEVICE_DATA));        memset(pGdiInfo, 0, cjCaps);        memset(pDevInfo, 0, cjDevInfo);        {            pGdiInfo‐>ulVersion    = 0x5000;            pGdiInfo‐>ulTechnology = DT_RASDISPLAY;            pGdiInfo‐>ulHorzSize   = 0;

Page 14: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 14/29

            pGdiInfo‐>ulVertSize   = 0;            pGdiInfo‐>ulHorzRes        = RESOLUTION_X;            pGdiInfo‐>ulVertRes        = RESOLUTION_Y;            pGdiInfo‐>ulPanningHorzRes = 0;            pGdiInfo‐>ulPanningVertRes = 0;            pGdiInfo‐>cBitsPixel       = 8;            pGdiInfo‐>cPlanes          = 4;            pGdiInfo‐>ulNumColors      = 20;            pGdiInfo‐>ulVRefresh       = 1;                   pGdiInfo‐>ulBltAlignment   = 1;                 pGdiInfo‐>ulLogPixelsX = 96;            pGdiInfo‐>ulLogPixelsY = 96;            pGdiInfo‐>flTextCaps   = TC_RA_ABLE;            pGdiInfo‐>flRaster     = 0;            pGdiInfo‐>ulDACRed     = 8;            pGdiInfo‐>ulDACGreen   = 8;            pGdiInfo‐>ulDACBlue    = 8;            pGdiInfo‐>ulAspectX    = 0x24;             pGdiInfo‐>ulNumPalReg  = 256;            pGdiInfo‐>ulAspectY    = 0x24;            pGdiInfo‐>ulAspectXY   = 0x33;            pGdiInfo‐>xStyleStep   = 1;                   pGdiInfo‐>yStyleStep   = 1;            pGdiInfo‐>denStyleStep = 3;            pGdiInfo‐>ptlPhysOffset.x = 0;            pGdiInfo‐>ptlPhysOffset.y = 0;            pGdiInfo‐>szlPhysSize.cx  = 0;            pGdiInfo‐>szlPhysSize.cy  = 0;            pGdiInfo‐>ciDevice.Red.x = 6700;            pGdiInfo‐>ciDevice.Red.y = 3300;            pGdiInfo‐>ciDevice.Red.Y = 0;            pGdiInfo‐>ciDevice.Green.x = 2100;            pGdiInfo‐>ciDevice.Green.y = 7100;            pGdiInfo‐>ciDevice.Green.Y = 0;            pGdiInfo‐>ciDevice.Blue.x = 1400;            pGdiInfo‐>ciDevice.Blue.y = 800;            pGdiInfo‐>ciDevice.Blue.Y = 0;            pGdiInfo‐>ciDevice.AlignmentWhite.x = 3127;            pGdiInfo‐>ciDevice.AlignmentWhite.y = 3290;            pGdiInfo‐>ciDevice.AlignmentWhite.Y = 0;            pGdiInfo‐>ciDevice.RedGamma = 20000;            pGdiInfo‐>ciDevice.GreenGamma = 20000;            pGdiInfo‐>ciDevice.BlueGamma = 20000;            pGdiInfo‐>ciDevice.Cyan.x = 1750;            pGdiInfo‐>ciDevice.Cyan.y = 3950;            pGdiInfo‐>ciDevice.Cyan.Y = 0;            pGdiInfo‐>ciDevice.Magenta.x = 4050;            pGdiInfo‐>ciDevice.Magenta.y = 2050;

Page 15: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 15/29

            pGdiInfo‐>ciDevice.Magenta.Y = 0;            pGdiInfo‐>ciDevice.Yellow.x = 4400;            pGdiInfo‐>ciDevice.Yellow.y = 5200;            pGdiInfo‐>ciDevice.Yellow.Y = 0;            pGdiInfo‐>ciDevice.MagentaInCyanDye = 0;            pGdiInfo‐>ciDevice.YellowInCyanDye = 0;            pGdiInfo‐>ciDevice.CyanInMagentaDye = 0;            pGdiInfo‐>ciDevice.YellowInMagentaDye = 0;            pGdiInfo‐>ciDevice.CyanInYellowDye = 0;            pGdiInfo‐>ciDevice.MagentaInYellowDye = 0;            pGdiInfo‐>ulDevicePelsDPI = 0;             pGdiInfo‐>ulPrimaryOrder = PRIMARY_ORDER_CBA;            pGdiInfo‐>ulHTPatternSize = HT_PATSIZE_4x4_M;            pGdiInfo‐>flHTFlags = HT_FLAG_ADDITIVE_PRIMS;            pGdiInfo‐>ulHTOutputFormat = HT_FORMAT_32BPP;                        *pDevInfo = gDevInfoFrameBuffer;            pDevInfo‐>iDitherFormat = BMF_32BPP;        }        pDeviceData‐>pVideoMemory = EngMapFile(L"\\??\\c:\\video.dat",               RESOLUTION_X*RESOLUTION_Y*4, &pDeviceData‐>pMappedFile);        pDeviceData‐>hDriver = hDriver;        pDevInfo‐>hpalDefault = EngCreatePalette(PAL_BITFIELDS,                0, NULL, 0xFF0000, 0xFF00, 0xFF);    }    ENGDEBUGPRINT(0, "GdiExample_DrvEnablePDEV Exit \r\n", NULL);    return (DHPDEV)pDeviceData;}

DrvCompletePDEV

This call is made after the enable to notify the display driver that the device object is now completed. The onlyparameters are the private data structure created in the enable call and the completed handle to the GDI device.Unless you have more initialization to do you generally can just save the GDI handle and move on. The followingis the code from the sample driver:

Hide   Copy Code

/********************************************************************* * GdiExample_DrvCompletePDEV * *   This is called to complete the process of enabling the device. *    * *********************************************************************/

Page 16: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 16/29

void GdiExample_DrvCompletePDEV(DHPDEV  dhpdev, HDEV  hdev){    PDEVICE_DATA pDeviceData = (PDEVICE_DATA)dhpdev;    ENGDEBUGPRINT(0, "GdiExample_DrvCompletePDEV Enter \r\n", NULL);    pDeviceData‐>hdev = hdev;    ENGDEBUGPRINT(0, "GdiExample_DrvCompletePDEV Exit \r\n", NULL);}

DrvDisablePDEV

This API is called when the PDEV is no longer needed and will be destroyed. This is called afterDrvDisableSurface if there is a surface enabled. Our implementation of this API is very simple and will justperform some clean up of what was created during the creation of the private PDEV structure:

Hide   Copy Code

/********************************************************************* * GdiExample_DrvDisablePDEV * *   This is called to disable the PDEV we created. *    * *********************************************************************/void GdiExample_DrvDisablePDEV(DHPDEV  dhpdev){    PDEVICE_DATA pDeviceData = (PDEVICE_DATA)dhpdev;    UINT dwBytesReturned = 0;    ENGDEBUGPRINT(0, "GdiExample_DrvDisablePDEV\r\n", NULL);    if(pDeviceData‐>pMappedFile)    {       EngUnmapFile(pDeviceData‐>pMappedFile);    }    EngFreeMem(dhpdev);}

DrvEnableSurface

This API is called after the PDEV has completed to ask the display driver to create a surface. Also as noted in thecomments below you have two choices when creating a surface. You can create a surface in which the displaydriver will manage it or you can create one in which GDI will manage for you. The following code chose theoption of managing its own device surface.

Page 17: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 17/29

The entire purpose is to define a drawing surface in which GDI will also be able to draw onto. Display drivers havetheir own device surfaces and thus will generally want to manage its surface. In doing this it must describe thesurface in a way which GDI can understand and be able to draw on it. This means defining the start address andeven the pitch as display drivers do not generally have linear buffers for all modes. In our case we use thememory mapped file we created to be our video memory:

Hide   Shrink   Copy Code

/********************************************************************* * GdiExample_DrvEnableSurface * *  This API is used to enable the physical device surface.  * *  You have two choices here. *      *     1. Driver Manages it's own surface *          EngCreateDeviceSurface ‐ Create the handle *          EngModifySurface ‐ Let GDI Know about the object. * *     2. GDI Manages the surface *          EngCreateBitmap ‐ Create a handle in a format that  *                            GDI Understands *          EngAssociateSurface ‐ Let GDI Know about the object. * * *********************************************************************/HSURF GdiExample_DrvEnableSurface(DHPDEV  dhpdev){    HSURF       hsurf;    SIZEL       sizl;    PDEVICE_DATA pDeviceData = (PDEVICE_DATA)dhpdev;        ENGDEBUGPRINT(0, "GdiExample_DrvEnableSurface\r\n", NULL);    pDeviceData‐>pDeviceSurface =       (PDEVICE_SURFACE)EngAllocMem(FL_ZERO_MEMORY,       sizeof(DEVICE_SURFACE), FAKE_GFX_TAG);    sizl.cx = 800;    sizl.cy = 600;    hsurf = (HSURF)EngCreateDeviceSurface(            (DHSURF)pDeviceData‐>pDeviceSurface, sizl, BMF_32BPP);        EngModifySurface(hsurf, pDeviceData‐>hdev,            HOOK_FILLPATH | HOOK_STROKEPATH | HOOK_LINETO |            HOOK_TEXTOUT | HOOK_BITBLT | HOOK_COPYBITS,            MS_NOTSYSTEMMEMORY, (DHSURF)pDeviceData‐>pDeviceSurface,            pDeviceData‐>pVideoMemory, 800*4, NULL);

Page 18: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 18/29

        return(hsurf);}

DrvDisableSurface

This API is called to destroy the drawing surface created in the DrvEnableSurface call. This is called beforedestroying the PDEV. The following is the code from the example program:

Hide   Copy Code

/********************************************************************* * GdiExample_DrvDisableSurface * *  This API is called to disable the GDI Surface. * * *********************************************************************/void GdiExample_DrvDisableSurface(DHPDEV  dhpdev){    PDEVICE_DATA pDeviceData = (PDEVICE_DATA)dhpdev;    ENGDEBUGPRINT(0, "GdiExample_DrvDisableSurface\r\n", NULL);    EngDeleteSurface(pDeviceData‐>hsurf);    pDeviceData‐>hsurf = NULL;    EngFreeMem(pDeviceData‐>pDeviceSurface);    pDeviceData‐>pDeviceSurface = NULL;}

Sequencing

So, let's go through this one more time for clarity.

DrvEnableDriver: The driver is loaded.DrvGetModes: Get the buffer size to hold all supported display modes.DrvGetModes: Get the display modes.DrvEnablePDEV: Inform the display driver to initialize to a mode selected in the DEVMODE data structureand return an instance handle.DrvCompletePDEV: Inform the driver that the device initialization is complete.DrvEnableSurface: Get the driver to supply a drawing surface.

Page 19: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 19/29

<GDI Calls>

DrvDisableSurface: Destroy the drawing surface.DrvDisablePDEV: Destroy the instance structure.DrvDisableDriver: Unload the display driver.

So how does the drawing work?

The "GDI Calls" are essentially handling things like "BitBlt" in your display driver which is actually inDrvBitBlt. You may notice that with our driver it doesn't implement any graphical commands itself. This isbecause we do not have hardware to accelerate drawing features and I decided that it's a lot less work to just callthe routines provided to you by Windows that already implement these features in software. As in the example,DrvBitBlt can simply be diverted to EngBitBlt. These will simply render directly to our video buffer which inour case is a memory mapped file.

You may be wondering "how do I get to my PDEV or my surface object from these Drv* calls". Well, the SURFOBJpassed into these APIs does contain a pointer to the surface object. These are found at the dhsurf and dhpdevmembers of the SURFOBJ structure. The dhsurf member is the handle the device created provided the SURFOBJrepresents a device managed surface. This can be determined by checking the STYPE_DEVICE flag set on theSURFOBJ.

Display driver escape codesIn my tutorials on device drivers we learned that it is possible to use "DeviceIoControl" from user mode toimplement and communicate our own commands between the application and the driver. This is also possiblewith display drivers however it is a little different and instead of being called "IOCTLs" they are called "EscapeCodes".

In user mode you can send "Escape Codes" to the display driver using one of two methods. The first isExtEscape which simply sends the data you provide to the driver. Your display driver would then handle this inits DrvEscape routine.

The second method is DrawEscape which can be handled in DrvDrawEscape in your driver. The difference isthat DrawEscape allows you to provide a Window DC with your data and the clipping for that window will be

Page 20: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 20/29

provided to your driver. This allows you to easily implement extended drawing commands which can behavecorrectly in the windowing environment as your driver will be informed of the proper clipping area.

OpenGL supportOpenGL support is done through the use of an "ICD" or "Installable Client Driver". This is a concept originallycreated by SGI to help improve the performance of OpenGL on Windows by letting the vendor implement thegraphics pipeline completely. When OpenGL32.DLL gets loaded it simply asks the video driver for it's ICD and ifthere is one it's loaded into the process space and OpenGL APIs are serviced by the ICD. The ICD is in full controlof the graphics pipeline and thus each vendor and driver version may have a different implementation.

The usual case is to buffer the OpenGL commands and flush them to the card using the ExtEscape API. The ICDkit is now maintained by Microsoft and it is not free if you wish to develop for it.

The other method of supporting OpenGL is through something called a "Mini Client Driver" or "MCD". This isMicrosoft's original method for OpenGL support and is similar to an ICD but the MCD lives in the kernel. Thismethod is not used by any driver vendor that I know of and is very slow which is the reason for the ICDimplementation.

DirectX supportIn XPDM, Direct Draw support is done in the GDI driver. This is through the DrvEnableDirectDraw interface.The user mode portion and some of the kernel for the DirectX graphics pipeline is implemented by Microsoftsupplied system components. The API will simply return back a list of callback interfaces the DirectDraw layer inthe kernel will use to perform specific actions in the hardware.

Direct3D is initialized through the DrvGetDirectDrawInfo in which the GDI driver will claim to supportDirect3D. The supplied callbacks will be called several times to get the appropriate interfaces into the driverwhich implement the various features of Direct3D. This is described on MSDN.

What is a mirror driver?

Page 21: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 21/29

A mirror driver is a not well documented feature in which you can load a video driver that will "mirror" anotherdisplay driver. That is they will receive the same calls as the display driver they are mirroring. A mirror driver isdocumented to not support DrvGetModes however if you do implement it the returned modes will be cachedand you cannot dynamically change the modes. Although I have heard that implementing DrvGetModes canhelp with loading and unloading the display driver on mode switches I was unable to get this to work.

To load a mirror driver the registry key for this device needs to set the "Attach.ToDesktop" value to 1 andthen you call ChangeDisplaySettingsEx with "CDS_UPDATEREGISTRY" on the mirror driver. You then set themode you wish to switch to and call ChangeDisplaySettingsEx again on the mirror driver.

The mirror driver does not properly unload at mode switch and generally if there are references to a drawingsurface the driver will not unload. So, in my experience to get a mirror driver to mode switch you need anapplication that will detect WM_DISPLAYCHANGE messages. You also need to set "Attach.ToDesktop" to 0 afteryou load the display driver. This will help unload the display driver and on WM_DISPLAYCHANGE you can then gothrough the procedure to unload the mirror driver.

If you wish to immediately unload the mirror driver without a display change you simply need to follow the samesteps as what loaded it. Set "Attach.ToDesktop" to 0 and then perform the "CDS_UPDATEREGISTRY". You canthen call "ChangeDisplaySettingsEx" again with no parameters to force unloading. Although this seems towork again everything is done by referencing the display surface so if there are outstanding references to thedisplay surface the driver will not be unloaded. The mirror driver sample in the DDK does not do all of this andhas some missing pieces such as not implementing the WM_DISPLAYCHANGE and not resetting the"Attach.ToDesktop" value after loading the mirror driver.

The exampleThe example driver in this article simply shares a memory mapped file between an application and the displaydriver. The display driver will write graphics commands to the memory mapped file and the application simplyacts as a monitor and will just refresh itself ~70 times a second. This is not efficient but it is just an example. Thedisplay driver is installed as a regular hardware driver and is seen just as an ATI or NVIDIA driver would be.

To install the example you will simply need to use the "Add New Hardware" wizard in the control panel. You mustselect "Hardware is already installed" and "Manually select hardware from a list". The following picture shows thelist of devices for which you scroll down to the bottom and select "Add a new hardware device":

Page 22: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 22/29

Then you simply want to select "Have Disk" and find the .INF file that is provided with this project. You will thenneed to scroll down this new list and find "Toby Opferman Sample Video Display" as shown in the followingpicture:

Page 23: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 23/29

You will see the following dialog when installing just select "Continue Anyway" unless you do not want to installthe driver. The next thing you do is just enable the second monitor using the display settings and the third tab.Run the application monitor program provided with this article and you will be shown the second monitor in thatapplication window:

Page 24: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 24/29

HomeworkReading and seeing is a good way to learn however I believe you learn more if you actually try and dosomething! What I want you to do is take my example and add more display modes! This will require changes tothe application and you can either attempt to make the application detect these display changes through variousmethods including WM_DISPLAYCHANGE or simply require the user to restart the application and prompt orenumerate devices to get the new display settings and adjust the window appropriately.

Here is a little hint. When a new mode is selected you do not always get a DrvDisableSurface,DrvDisablePDEV, then a DrvEnablePDEV on the new setting. You may instead get a DrvAssertMode. This iscalled to switch one PDEV to another as this API passes in a BOOL to inform the driver to enable or disable thesupplied PDEV.

Conclusion

Page 25: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 25/29

Toby OpfermanEngineer Intel United States

This article showed how to create a very basic display driver to handle GDI commands. The display driverarchitecture mentioned in the article only covered XPDM and not the new LDDM as found in Windows Vista. Thisis also essentially the extreme basics of "where to get started". Even so hopefully you have learned a littlesomething about display drivers and the Windows operating system.

LicenseThis article has no explicit license attached to it but may contain usage terms in the article text or the downloadfiles themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

EMAIL

Page 26: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 26/29

Toby Opferman has worked in just about all aspects of Windows development including applications, servicesand drivers. He has also played a variety of roles professionally on a wide range of projects. This has included pureresearching roles, architect roles and developer roles. He also was also solely responsible for debugging trapsand blue screens for a number of years. Previously of Citrix Systems he is very experienced in the area of Terminal Services. He currently works onOperating Systems and low level architecture at Intel.

Search Comments   Go

 

Comments and Discussions

You must Sign In to use this message board.

Profile popups    Spacing Relaxed   Noise Very High   Layout Normal   Per page 50     Update

First Prev Next

Gabriel Barros 8‐Sep‐14 12:20 

Jason Boggess 6‐Mar‐13 13:28 

Minho Hong 3‐Feb‐13 6:26 

Thanks

Can't compile

how can i change display settings in programmatically?

Page 27: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 27/29

Member 9067884 12‐Feb‐13 20:30 

Member 8266113 11‐Jan‐13 17:52 

Member 8266113 13‐Jan‐13 16:07 

Member 9067884 12‐Feb‐13 20:20 

irit 14‐Jun‐12 4:22 

sonrie69 19‐Oct‐11 7:16 

Anfet 14‐Aug‐11 9:32 

ishaq ibrahim 15‐May‐11 15:50 

Toby Opferman 21‐May‐11 19:01 

Jack Stephenson 6‐Mar‐11 10:26 

initialj 4‐Jun‐12 0:40 

Rafael Coradini Schwarz 4‐Aug‐10 5:22 

Member 4013784 18‐Jul‐10 21:07 

CzekoladowyArab 7‐Nov‐09 0:09 

javad_2005 16‐Oct‐09 22:51 

voguish.prince 25‐Sep‐09 0:20 

shigang.z 9‐Aug‐09 18:29 

proforov 12‐May‐10 2:36 

Re: how can i change display settings in programmatically?

Can this xddm model works on Windows7?

Re: Can this xddm model works on Windows7?

Re: Can this xddm model works on Windows7?

Copy Video Memory

video driver debug ‐

Mouse Emulation

Mouse and keyboard imputs

Re: Mouse and keyboard imputs

What chages are required to make this work in Win7???

Re: What chages are required to make this work in Win7???

Multiple head display driver

Some doubts related to your sample driver.

Screenshot

mirror Driver

Homogeneous Multi‐adapter video driver

Two bugs in the code

Re: Two bugs in the code

Page 28: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 28/29

Kyomster 6‐Jun‐09 14:13 

Minho Hong 16‐Nov‐13 15:47 

vikrant kpr 9‐May‐09 16:28 

binsa 29‐Dec‐08 7:01 

AllenZhang 15‐Mar‐09 21:06 

mwxkingboy 23‐Dec‐08 21:59 

Hyung Gak Kim 17‐Dec‐08 16:02 

mwxkingboy 21‐Dec‐08 20:30 

elo_gc 17‐Jan‐09 3:57 

Member 270529 10‐Nov‐08 8:35 

Cojocaru Sergiu 13‐Aug‐07 12:24 

prgmmer 3‐Aug‐07 10:44 

Superlexx 20‐Jun‐07 5:29 

nayanaps 22‐Apr‐07 21:59 

xinshou 20‐Mar‐07 19:08 

uday__m 14‐Mar‐07 3:05 

Sol_Ken 28‐Feb‐07 21:07 

Make it work on Windows Vista

Re: Make it work on Windows Vista

How does the concept filter driver fits in?

How can I build this sources in VS 2005?

Re: How can I build this sources in VS 2005?

how to dynamic change 800x600x32 mode to 1024*768*32mode in the gdi driver part

How can I build this?? [modified]

Re: How can I build this??

Re: How can I build this??

Citrix?

Mirror callback

Compiling fakemonitor.dll using WDK

supporting multiple resolution

Clone Mode

please give me some help!

Sychronizing of Application & Driver ‐ Regd

Problems in Compilation

Page 29: Driver Development Part 6_ Introduction to Display Drivers - CodeProject.pdf

3/21/2015 Driver Development Part 6: Introduction to Display Drivers ­ CodeProject

http://www.codeproject.com/Articles/12878/Driver­Development­Part­Introduction­to­Display 29/29

Permalink | Advertise | Privacy | Terms of Use | Mobile Web04 | 2.8.150312.1 | Last Updated 30 Jan 2006

Article Copyright 2006 by Toby OpfermanEverything else Copyright © CodeProject, 1999‐2015

Layout: fixed | fluid

bil_geo 30‐Jan‐07 4:06 

futingcchq dsaf 11‐Sep‐08 2:59 

AllenZhang 15‐Mar‐09 20:47 

sonuguec 28‐Nov‐06 20:37 

Toby Opferman 28‐Nov‐06 20:55 

sonuguec 28‐Nov‐06 22:00 

skadeateh 7‐Nov‐06 0:14 

Pepao 2‐Nov‐06 12:55 

Toby Opferman 2‐Nov‐06 17:41 

Pepao 3‐Nov‐06 14:15 

Toby Opferman 3‐Nov‐06 16:43 

vikas.gupta84 30‐Oct‐06 23:20 

Last Visit: 31‐Dec‐99 19:00     Last Update: 20‐Mar‐15 18:30 Refresh 1 2 3 Next »

General    News    Suggestion    Question    Bug    Answer    Joke    Rant    Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

multiple display monitor

Re: multiple display monitor

Re: multiple display monitor

Uninstallation ﴾Windows 2000﴿

Re: Uninstallation ﴾Windows 2000﴿

Re: Uninstallation ﴾Windows 2000﴿

how to build this driver??

XP Desktop Icons lose transparency after load driver

Re: XP Desktop Icons lose transparency after load driver

Re: XP Desktop Icons lose transparency after load driver

Re: XP Desktop Icons lose transparency after load driver

Compatibility of sample driver to win2k