3 * GDI Driver support routines
4 * (mostly swiped from Wine)
8 #undef WIN32_LEAN_AND_MEAN
11 #include <ddk/ntddk.h>
13 #include <win32k/driver.h>
14 #include <win32k/misc.h>
16 #include <ddk/winddi.h>
17 #include <ddk/ntddvid.h>
22 #define DRIVER_TAG TAG('G', 'D', 'R', 'V')
24 typedef struct _GRAPHICS_DRIVER
27 PGD_ENABLEDRIVER EnableDriver;
29 struct _GRAPHICS_DRIVER *Next;
30 } GRAPHICS_DRIVER, *PGRAPHICS_DRIVER;
32 static PGRAPHICS_DRIVER DriverList;
33 static PGRAPHICS_DRIVER GenericDriver = 0;
35 BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver)
37 PGRAPHICS_DRIVER Driver = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Driver), DRIVER_TAG);
38 DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
39 if (!Driver) return FALSE;
40 Driver->ReferenceCount = 0;
41 Driver->EnableDriver = EnableDriver;
44 Driver->Name = ExAllocatePoolWithTag(PagedPool,
45 (wcslen(Name) + 1) * sizeof(WCHAR),
47 wcscpy(Driver->Name, Name);
48 Driver->Next = DriverList;
53 if (GenericDriver != NULL)
59 GenericDriver = Driver;
63 PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name)
65 static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\";
66 static WCHAR DefaultExtension[] = L".DLL";
67 SYSTEM_LOAD_IMAGE GdiDriverInfo;
68 GRAPHICS_DRIVER *Driver = DriverList;
72 BOOL PathSeparatorFound;
77 PathSeparatorFound = FALSE;
81 if (L'\\' == *p || L'/' == *p)
83 PathSeparatorFound = TRUE;
93 Size = (wcslen(Name) + 1) * sizeof(WCHAR);
94 if (! PathSeparatorFound)
96 Size += sizeof(DefaultPath) - sizeof(WCHAR);
100 Size += sizeof(DefaultExtension) - sizeof(WCHAR);
102 FullName = ExAllocatePoolWithTag(PagedPool, Size, DRIVER_TAG);
103 if (NULL == FullName)
105 DPRINT1("Out of memory\n");
108 if (PathSeparatorFound)
114 wcscpy(FullName, DefaultPath);
116 wcscat(FullName, Name);
119 wcscat(FullName, DefaultExtension);
122 /* First see if the driver hasn't already been loaded */
123 while (Driver && FullName)
125 if (!_wcsicmp( Driver->Name, FullName))
127 return Driver->EnableDriver;
129 Driver = Driver->Next;
132 /* If not, then load it */
133 RtlInitUnicodeString (&GdiDriverInfo.ModuleName, (LPWSTR)FullName);
134 Status = ZwSetSystemInformation (SystemLoadImage, &GdiDriverInfo, sizeof(SYSTEM_LOAD_IMAGE));
135 ExFreePool(FullName);
136 if (!NT_SUCCESS(Status)) return NULL;
138 DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
139 return (PGD_ENABLEDRIVER)GdiDriverInfo.EntryPoint;
142 BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
143 PDRIVER_FUNCTIONS DF)
147 for (i=0; i<DED->c; i++)
149 if(DED->pdrvfn[i].iFunc == INDEX_DrvEnablePDEV) DF->EnablePDev = (PGD_ENABLEPDEV)DED->pdrvfn[i].pfn;
150 if(DED->pdrvfn[i].iFunc == INDEX_DrvCompletePDEV) DF->CompletePDev = (PGD_COMPLETEPDEV)DED->pdrvfn[i].pfn;
151 if(DED->pdrvfn[i].iFunc == INDEX_DrvDisablePDEV) DF->DisablePDev = (PGD_DISABLEPDEV)DED->pdrvfn[i].pfn;
152 if(DED->pdrvfn[i].iFunc == INDEX_DrvEnableSurface) DF->EnableSurface = (PGD_ENABLESURFACE)DED->pdrvfn[i].pfn;
153 if(DED->pdrvfn[i].iFunc == INDEX_DrvDisableSurface) DF->DisableSurface = (PGD_DISABLESURFACE)DED->pdrvfn[i].pfn;
154 if(DED->pdrvfn[i].iFunc == INDEX_DrvAssertMode) DF->AssertMode = (PGD_ASSERTMODE)DED->pdrvfn[i].pfn;
155 if(DED->pdrvfn[i].iFunc == INDEX_DrvResetPDEV) DF->ResetPDev = (PGD_RESETPDEV)DED->pdrvfn[i].pfn;
156 if(DED->pdrvfn[i].iFunc == INDEX_DrvCreateDeviceBitmap)
157 DF->CreateDeviceBitmap = (PGD_CREATEDEVICEBITMAP)DED->pdrvfn[i].pfn;
158 if(DED->pdrvfn[i].iFunc == INDEX_DrvDeleteDeviceBitmap)
159 DF->DeleteDeviceBitmap = (PGD_DELETEDEVICEBITMAP)DED->pdrvfn[i].pfn;
160 if(DED->pdrvfn[i].iFunc == INDEX_DrvRealizeBrush) DF->RealizeBrush = (PGD_REALIZEBRUSH)DED->pdrvfn[i].pfn;
161 if(DED->pdrvfn[i].iFunc == INDEX_DrvDitherColor) DF->DitherColor = (PGD_DITHERCOLOR)DED->pdrvfn[i].pfn;
162 if(DED->pdrvfn[i].iFunc == INDEX_DrvStrokePath) DF->StrokePath = (PGD_STROKEPATH)DED->pdrvfn[i].pfn;
163 if(DED->pdrvfn[i].iFunc == INDEX_DrvFillPath) DF->FillPath = (PGD_FILLPATH)DED->pdrvfn[i].pfn;
164 if(DED->pdrvfn[i].iFunc == INDEX_DrvStrokeAndFillPath)
165 DF->StrokeAndFillPath = (PGD_STROKEANDFILLPATH)DED->pdrvfn[i].pfn;
166 if(DED->pdrvfn[i].iFunc == INDEX_DrvPaint) DF->Paint = (PGD_PAINT)DED->pdrvfn[i].pfn;
167 if(DED->pdrvfn[i].iFunc == INDEX_DrvBitBlt) DF->BitBlt = (PGD_BITBLT)DED->pdrvfn[i].pfn;
168 if(DED->pdrvfn[i].iFunc == INDEX_DrvTransparentBlt) DF->TransparentBlt = (PGD_TRANSPARENTBLT)DED->pdrvfn[i].pfn;
169 if(DED->pdrvfn[i].iFunc == INDEX_DrvCopyBits) DF->CopyBits = (PGD_COPYBITS)DED->pdrvfn[i].pfn;
170 if(DED->pdrvfn[i].iFunc == INDEX_DrvStretchBlt) DF->StretchBlt = (PGD_STRETCHBLT)DED->pdrvfn[i].pfn;
171 if(DED->pdrvfn[i].iFunc == INDEX_DrvSetPalette) DF->SetPalette = (PGD_SETPALETTE)DED->pdrvfn[i].pfn;
172 if(DED->pdrvfn[i].iFunc == INDEX_DrvTextOut) DF->TextOut = (PGD_TEXTOUT)DED->pdrvfn[i].pfn;
173 if(DED->pdrvfn[i].iFunc == INDEX_DrvEscape) DF->Escape = (PGD_ESCAPE)DED->pdrvfn[i].pfn;
174 if(DED->pdrvfn[i].iFunc == INDEX_DrvDrawEscape) DF->DrawEscape = (PGD_DRAWESCAPE)DED->pdrvfn[i].pfn;
175 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryFont) DF->QueryFont = (PGD_QUERYFONT)DED->pdrvfn[i].pfn;
176 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryFontTree) DF->QueryFontTree = (PGD_QUERYFONTTREE)DED->pdrvfn[i].pfn;
177 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryFontData) DF->QueryFontData = (PGD_QUERYFONTDATA)DED->pdrvfn[i].pfn;
178 if(DED->pdrvfn[i].iFunc == INDEX_DrvSetPointerShape) DF->SetPointerShape = (PGD_SETPOINTERSHAPE)DED->pdrvfn[i].pfn;
179 if(DED->pdrvfn[i].iFunc == INDEX_DrvMovePointer) DF->MovePointer = (PGD_MOVEPOINTER)DED->pdrvfn[i].pfn;
180 if(DED->pdrvfn[i].iFunc == INDEX_DrvLineTo) DF->LineTo = (PGD_LINETO)DED->pdrvfn[i].pfn;
181 if(DED->pdrvfn[i].iFunc == INDEX_DrvSendPage) DF->SendPage = (PGD_SENDPAGE)DED->pdrvfn[i].pfn;
182 if(DED->pdrvfn[i].iFunc == INDEX_DrvStartPage) DF->StartPage = (PGD_STARTPAGE)DED->pdrvfn[i].pfn;
183 if(DED->pdrvfn[i].iFunc == INDEX_DrvEndDoc) DF->EndDoc = (PGD_ENDDOC)DED->pdrvfn[i].pfn;
184 if(DED->pdrvfn[i].iFunc == INDEX_DrvStartDoc) DF->StartDoc = (PGD_STARTDOC)DED->pdrvfn[i].pfn;
185 if(DED->pdrvfn[i].iFunc == INDEX_DrvGetGlyphMode) DF->GetGlyphMode = (PGD_GETGLYPHMODE)DED->pdrvfn[i].pfn;
186 if(DED->pdrvfn[i].iFunc == INDEX_DrvSynchronize) DF->Synchronize = (PGD_SYNCHRONIZE)DED->pdrvfn[i].pfn;
187 if(DED->pdrvfn[i].iFunc == INDEX_DrvSaveScreenBits) DF->SaveScreenBits = (PGD_SAVESCREENBITS)DED->pdrvfn[i].pfn;
188 if(DED->pdrvfn[i].iFunc == INDEX_DrvGetModes) DF->GetModes = (PGD_GETMODES)DED->pdrvfn[i].pfn;
189 if(DED->pdrvfn[i].iFunc == INDEX_DrvFree) DF->Free = (PGD_FREE)DED->pdrvfn[i].pfn;
190 if(DED->pdrvfn[i].iFunc == INDEX_DrvDestroyFont) DF->DestroyFont = (PGD_DESTROYFONT)DED->pdrvfn[i].pfn;
191 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryFontCaps) DF->QueryFontCaps = (PGD_QUERYFONTCAPS)DED->pdrvfn[i].pfn;
192 if(DED->pdrvfn[i].iFunc == INDEX_DrvLoadFontFile) DF->LoadFontFile = (PGD_LOADFONTFILE)DED->pdrvfn[i].pfn;
193 if(DED->pdrvfn[i].iFunc == INDEX_DrvUnloadFontFile) DF->UnloadFontFile = (PGD_UNLOADFONTFILE)DED->pdrvfn[i].pfn;
194 if(DED->pdrvfn[i].iFunc == INDEX_DrvFontManagement) DF->FontManagement = (PGD_FONTMANAGEMENT)DED->pdrvfn[i].pfn;
195 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryTrueTypeTable)
196 DF->QueryTrueTypeTable = (PGD_QUERYTRUETYPETABLE)DED->pdrvfn[i].pfn;
197 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryTrueTypeOutline)
198 DF->QueryTrueTypeOutline = (PGD_QUERYTRUETYPEOUTLINE)DED->pdrvfn[i].pfn;
199 if(DED->pdrvfn[i].iFunc == INDEX_DrvGetTrueTypeFile) DF->GetTrueTypeFile = (PGD_GETTRUETYPEFILE)DED->pdrvfn[i].pfn;
200 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryFontFile) DF->QueryFontFile = (PGD_QUERYFONTFILE)DED->pdrvfn[i].pfn;
201 if(DED->pdrvfn[i].iFunc == INDEX_DrvQueryAdvanceWidths)
202 DF->QueryAdvanceWidths = (PGD_QUERYADVANCEWIDTHS)DED->pdrvfn[i].pfn;
203 if(DED->pdrvfn[i].iFunc == INDEX_DrvSetPixelFormat) DF->SetPixelFormat = (PGD_SETPIXELFORMAT)DED->pdrvfn[i].pfn;
204 if(DED->pdrvfn[i].iFunc == INDEX_DrvDescribePixelFormat)
205 DF->DescribePixelFormat = (PGD_DESCRIBEPIXELFORMAT)DED->pdrvfn[i].pfn;
206 if(DED->pdrvfn[i].iFunc == INDEX_DrvSwapBuffers) DF->SwapBuffers = (PGD_SWAPBUFFERS)DED->pdrvfn[i].pfn;
207 if(DED->pdrvfn[i].iFunc == INDEX_DrvStartBanding) DF->StartBanding = (PGD_STARTBANDING)DED->pdrvfn[i].pfn;
208 if(DED->pdrvfn[i].iFunc == INDEX_DrvNextBand) DF->NextBand = (PGD_NEXTBAND)DED->pdrvfn[i].pfn;
210 if(DED->pdrvfn[i].iFunc == INDEX_DrvGetDirectDrawInfo) DF->GETDIRECTDRAWINFO = (PGD_)DED->pdrvfn[i].pfn;
211 if(DED->pdrvfn[i].iFunc == INDEX_DrvEnableDirectDraw) DF->ENABLEDIRECTDRAW = (PGD_)DED->pdrvfn[i].pfn;
212 if(DED->pdrvfn[i].iFunc == INDEX_DrvDisableDirectDraw) DF->DISABLEDIRECTDRAW = (PGD_)DED->pdrvfn[i].pfn;
214 if(DED->pdrvfn[i].iFunc == INDEX_DrvQuerySpoolType) DF->QuerySpoolType = (PGD_QUERYSPOOLTYPE)DED->pdrvfn[i].pfn;
220 typedef VP_STATUS (*PMP_DRIVERENTRY)(PVOID, PVOID);
222 HANDLE DRIVER_FindMPDriver(LPCWSTR Name)
224 OBJECT_ATTRIBUTES ObjectAttributes;
225 UNICODE_STRING DeviceName;
226 IO_STATUS_BLOCK Iosb;
227 HANDLE DisplayHandle;
230 /* Switch to process context in which handle is to be valid */
231 KeAttachProcess(W32kDeviceProcess);
233 RtlInitUnicodeStringFromLiteral(&DeviceName, L"\\??\\DISPLAY1");
234 InitializeObjectAttributes(&ObjectAttributes,
239 Status = ZwOpenFile(&DisplayHandle,
244 FILE_SYNCHRONOUS_IO_ALERT);
248 if (!NT_SUCCESS(Status))
250 DPRINT("ZwOpenFile() failed (Status %lx)\n", Status);
254 return(DisplayHandle);
258 BOOL DRIVER_UnregisterDriver(LPCWSTR Name)
260 PGRAPHICS_DRIVER Driver = NULL;
264 if (DriverList != NULL)
266 if (!_wcsicmp(DriverList->Name, Name))
269 DriverList = DriverList->Next;
274 while (Driver->Next && _wcsicmp(Driver->Name, Name))
276 Driver = Driver->Next;
283 if (GenericDriver != NULL)
285 Driver = GenericDriver;
286 GenericDriver = NULL;
292 ExFreePool(Driver->Name);
303 INT DRIVER_ReferenceDriver (LPCWSTR Name)
305 GRAPHICS_DRIVER *Driver = DriverList;
307 while (Driver && Name)
309 DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
310 if (!_wcsicmp( Driver->Name, Name))
312 return ++Driver->ReferenceCount;
314 Driver = Driver->Next;
316 DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
317 assert( GenericDriver != 0 );
318 return ++GenericDriver->ReferenceCount;
321 INT DRIVER_UnreferenceDriver (LPCWSTR Name)
323 GRAPHICS_DRIVER *Driver = DriverList;
325 while (Driver && Name)
327 DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
328 if (!_wcsicmp( Driver->Name, Name))
330 return --Driver->ReferenceCount;
332 Driver = Driver->Next;
334 DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
335 assert( GenericDriver != 0 );
336 return --GenericDriver->ReferenceCount;