Driver Initialization and Cleanup

While the device driver may implement several or many functions, it exports only two of them to GDI; DrvEnableDriver, and DrvDisableDriver. The driver exposes its other supported functions through a function table. The first call GDI makes to a device driver is DrvEnableDriver. At this time, the driver fills in the passed-in DRVENABLEDATA structure so that GDI can determine which other DrvXxx functions are supported and where they are located. The driver supplies the following information in DRVENABLEDATA:

·The DDI version number of GDI. This constant in defined as DDI_DRIVER_VERSION in winddi.h.

·A pointer to an array of DRVFN structures that lists the supported functions their indexes.

·The number of DRVFN structures in the array.

For GDI to call a function other than the driver's enable and disable functions, the function's name and location must be made available to GDI. The following is an example array of DRVFN structures for a display driver that handles many of the drawing operations and supports a hardware pointer:

DRVFN gadrvfn[] = {

{ INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV },

{ INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV },

{ INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV },

{ INDEX_DrvEnableSurface, (PFN) DrvEnableSurface },

{ INDEX_DrvDisableSurface, (PFN) DrvDisableSurface },

{ INDEX_DrvAssertMode, (PFN) DrvAssertMode },

{ INDEX_DrvGetModes, (PFN) DrvGetModes },

{ INDEX_DrvDitherColor, (PFN) DrvDitherColor },

{ INDEX_DrvSetPalette, (PFN) DrvSetPalette },

{ INDEX_DrvCopyBits, (PFN) DrvCopyBits },

{ INDEX_DrvSetPointerShape,(PFN) DrvSetPointerShape },

{ INDEX_DrvMovePointer (PFN) DrvMovePointer },

{ INDEX_DrvBitBlt, (PFN) DrvBitBlt },

{ INDEX_DrvTextOut, (PFN) DrvTextOut },

{ INDEX_DrvStrokePath, (PFN) DrvStrokePath },

{ INDEX_DrvFillPath, (PFN) DrvFillPath },

{ INDEX_DrvRealizeBrush, (PFN) DrvRealizeBrush },

{ INDEX_DrvStretchBlt, (PFN) DrvStretchBlt },

{ INDEX_DrvPaint, (PFN) DrvPaint }

};

While DrvEnableDriver can also perform one-time initializations, such as the allocation of semaphores, a driver should not actually enable the hardware during DrvEnableDriver. Hardware initialization should occur in a driver's DrvEnablePDEV routine. Likewise, a driver should enable the surface in DrvEnableSurface.

GDI calls DrvDisableDriver to notify the driver that it is about to be unloaded. In response to this call, the driver should free all resources and memory still allocated by the driver at this point. Finally, if the hardware needs to be reset, the driver will be called with DrvAssertMode.