sync to trunk head (37853) (except rbuild changes)
[reactos.git] / reactos / subsystems / win32 / win32k / misc / driver.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$
20 *
21 * GDI Driver support routines
22 * (mostly swiped from Wine)
23 *
24 */
25
26 #include <w32k.h>
27
28 #define NDEBUG
29 #include <debug.h>
30
31 /* #define TRACE_DRV_CALLS to get a log of all calls into the display driver. */
32 #undef TRACE_DRV_CALLS
33
34
35 typedef struct _GRAPHICS_DRIVER
36 {
37 PWSTR Name;
38 PGD_ENABLEDRIVER EnableDriver;
39 int ReferenceCount;
40 struct _GRAPHICS_DRIVER *Next;
41 } GRAPHICS_DRIVER, *PGRAPHICS_DRIVER;
42
43 static PGRAPHICS_DRIVER DriverList;
44 static PGRAPHICS_DRIVER GenericDriver = NULL;
45
46 BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver)
47 {
48 PGRAPHICS_DRIVER Driver;
49
50 DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name );
51
52 if (GenericDriver != NULL)
53 {
54 return FALSE;
55 }
56 Driver = ExAllocatePoolWithTag(PagedPool, sizeof(*Driver), TAG_DRIVER);
57 if (!Driver) return FALSE;
58 Driver->ReferenceCount = 0;
59 Driver->EnableDriver = EnableDriver;
60 if (Name)
61 {
62 Driver->Name = ExAllocatePoolWithTag(PagedPool,
63 (wcslen(Name) + 1) * sizeof(WCHAR),
64 TAG_DRIVER);
65 if (Driver->Name == NULL)
66 {
67 DPRINT1("Out of memory\n");
68 ExFreePoolWithTag(Driver, TAG_DRIVER);
69 return FALSE;
70 }
71
72 wcscpy(Driver->Name, Name);
73 Driver->Next = DriverList;
74 DriverList = Driver;
75 return TRUE;
76 }
77
78 GenericDriver = Driver;
79 return TRUE;
80 }
81
82 PGD_ENABLEDRIVER DRIVER_FindExistingDDIDriver(LPCWSTR Name)
83 {
84 GRAPHICS_DRIVER *Driver = DriverList;
85 while (Driver && Name)
86 {
87 if (!_wcsicmp(Driver->Name, Name))
88 {
89 return Driver->EnableDriver;
90 }
91 Driver = Driver->Next;
92 }
93
94 return NULL;
95 }
96
97 PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name)
98 {
99 static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\";
100 static WCHAR DefaultExtension[] = L".DLL";
101 PGD_ENABLEDRIVER ExistingDriver;
102 SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
103 NTSTATUS Status;
104 LPWSTR FullName;
105 LPCWSTR p;
106 BOOL PathSeparatorFound;
107 BOOL DotFound;
108 UINT Size;
109
110 DotFound = FALSE;
111 PathSeparatorFound = FALSE;
112 p = Name;
113 while (L'\0' != *p)
114 {
115 if (L'\\' == *p || L'/' == *p)
116 {
117 PathSeparatorFound = TRUE;
118 DotFound = FALSE;
119 }
120 else if (L'.' == *p)
121 {
122 DotFound = TRUE;
123 }
124 p++;
125 }
126
127 Size = (wcslen(Name) + 1) * sizeof(WCHAR);
128 if (! PathSeparatorFound)
129 {
130 Size += sizeof(DefaultPath) - sizeof(WCHAR);
131 }
132 if (! DotFound)
133 {
134 Size += sizeof(DefaultExtension) - sizeof(WCHAR);
135 }
136 FullName = ExAllocatePoolWithTag(PagedPool, Size, TAG_DRIVER);
137 if (NULL == FullName)
138 {
139 DPRINT1("Out of memory\n");
140 return NULL;
141 }
142 if (PathSeparatorFound)
143 {
144 FullName[0] = L'\0';
145 }
146 else
147 {
148 wcscpy(FullName, DefaultPath);
149 }
150 wcscat(FullName, Name);
151 if (! DotFound)
152 {
153 wcscat(FullName, DefaultExtension);
154 }
155
156 /* First see if the driver hasn't already been loaded */
157 ExistingDriver = DRIVER_FindExistingDDIDriver(FullName);
158 if (ExistingDriver)
159 {
160 ExFreePoolWithTag(FullName, TAG_DRIVER);
161 return ExistingDriver;
162 }
163
164 /* If not, then load it */
165 RtlInitUnicodeString (&GdiDriverInfo.DriverName, FullName);
166 Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION));
167
168 if (!NT_SUCCESS(Status))
169 {
170 ExFreePool(FullName);
171 return NULL;
172 }
173
174 DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint);
175 DRIVER_RegisterDriver( FullName, GdiDriverInfo.EntryPoint);
176 ExFreePoolWithTag(FullName, TAG_DRIVER);
177 return (PGD_ENABLEDRIVER)GdiDriverInfo.EntryPoint;
178 }
179
180 #define BEGIN_FUNCTION_MAP() \
181 ULONG i; \
182 for (i = 0; i < DED->c; i++) \
183 { \
184 switch(DED->pdrvfn[i].iFunc) \
185 {
186
187 #define END_FUNCTION_MAP() \
188 default: \
189 DPRINT1("Unsupported DDI function 0x%x\n", DED->pdrvfn[i].iFunc); \
190 break; \
191 } \
192 }
193
194 #ifdef TRACE_DRV_CALLS
195
196 typedef struct _TRACEDRVINFO
197 {
198 unsigned Index;
199 char *Name;
200 PVOID DrvRoutine;
201 }
202 TRACEDRVINFO, *PTRACEDRVINFO;
203
204 __asm__(
205 " .text\n"
206 "TraceDrv:\n"
207 " pushl %eax\n"
208 " call _FindTraceInfo\n"
209 " add $4,%esp\n"
210 " pushl %eax\n"
211 " pushl 4(%eax)\n"
212 " call _DbgPrint\n"
213 " addl $4,%esp\n"
214 " popl %eax\n"
215 " mov 8(%eax),%eax\n"
216 " jmp *%eax\n"
217 );
218
219 #define TRACEDRV_ROUTINE(function) \
220 unsigned TraceDrvIndex##function = INDEX_Drv##function; \
221 __asm__ ( \
222 " .text\n" \
223 "_Trace" #function ":\n" \
224 " movl _TraceDrvIndex" #function ",%eax\n" \
225 " jmp TraceDrv\n" \
226 ); \
227 extern PVOID Trace##function;
228
229 TRACEDRV_ROUTINE(EnablePDEV)
230 TRACEDRV_ROUTINE(CompletePDEV)
231 TRACEDRV_ROUTINE(DisablePDEV)
232 TRACEDRV_ROUTINE(EnableSurface)
233 TRACEDRV_ROUTINE(DisableSurface)
234 TRACEDRV_ROUTINE(AssertMode)
235 TRACEDRV_ROUTINE(Offset)
236 TRACEDRV_ROUTINE(ResetPDEV)
237 TRACEDRV_ROUTINE(DisableDriver)
238 TRACEDRV_ROUTINE(CreateDeviceBitmap)
239 TRACEDRV_ROUTINE(DeleteDeviceBitmap)
240 TRACEDRV_ROUTINE(RealizeBrush)
241 TRACEDRV_ROUTINE(DitherColor)
242 TRACEDRV_ROUTINE(StrokePath)
243 TRACEDRV_ROUTINE(FillPath)
244 TRACEDRV_ROUTINE(StrokeAndFillPath)
245 TRACEDRV_ROUTINE(Paint)
246 TRACEDRV_ROUTINE(BitBlt)
247 TRACEDRV_ROUTINE(TransparentBlt)
248 TRACEDRV_ROUTINE(CopyBits)
249 TRACEDRV_ROUTINE(StretchBlt)
250 TRACEDRV_ROUTINE(StretchBltROP)
251 TRACEDRV_ROUTINE(SetPalette)
252 TRACEDRV_ROUTINE(TextOut)
253 TRACEDRV_ROUTINE(Escape)
254 TRACEDRV_ROUTINE(DrawEscape)
255 TRACEDRV_ROUTINE(QueryFont)
256 TRACEDRV_ROUTINE(QueryFontTree)
257 TRACEDRV_ROUTINE(QueryFontData)
258 TRACEDRV_ROUTINE(SetPointerShape)
259 TRACEDRV_ROUTINE(MovePointer)
260 TRACEDRV_ROUTINE(LineTo)
261 TRACEDRV_ROUTINE(SendPage)
262 TRACEDRV_ROUTINE(StartPage)
263 TRACEDRV_ROUTINE(EndDoc)
264 TRACEDRV_ROUTINE(StartDoc)
265 TRACEDRV_ROUTINE(GetGlyphMode)
266 TRACEDRV_ROUTINE(Synchronize)
267 TRACEDRV_ROUTINE(SaveScreenBits)
268 TRACEDRV_ROUTINE(GetModes)
269 TRACEDRV_ROUTINE(Free)
270 TRACEDRV_ROUTINE(DestroyFont)
271 TRACEDRV_ROUTINE(QueryFontCaps)
272 TRACEDRV_ROUTINE(LoadFontFile)
273 TRACEDRV_ROUTINE(UnloadFontFile)
274 TRACEDRV_ROUTINE(FontManagement)
275 TRACEDRV_ROUTINE(QueryTrueTypeTable)
276 TRACEDRV_ROUTINE(QueryTrueTypeOutline)
277 TRACEDRV_ROUTINE(GetTrueTypeFile)
278 TRACEDRV_ROUTINE(QueryFontFile)
279 TRACEDRV_ROUTINE(QueryAdvanceWidths)
280 TRACEDRV_ROUTINE(SetPixelFormat)
281 TRACEDRV_ROUTINE(DescribePixelFormat)
282 TRACEDRV_ROUTINE(SwapBuffers)
283 TRACEDRV_ROUTINE(StartBanding)
284 TRACEDRV_ROUTINE(NextBand)
285 TRACEDRV_ROUTINE(GetDirectDrawInfo)
286 TRACEDRV_ROUTINE(EnableDirectDraw)
287 TRACEDRV_ROUTINE(DisableDirectDraw)
288 TRACEDRV_ROUTINE(QuerySpoolType)
289 TRACEDRV_ROUTINE(IcmSetDeviceGammaRamp)
290 TRACEDRV_ROUTINE(GradientFill)
291 TRACEDRV_ROUTINE(SynchronizeSurface)
292 TRACEDRV_ROUTINE(AlphaBlend)
293
294 #define TRACEDRVINFO_ENTRY(function) \
295 { INDEX_Drv##function, "Drv" #function "\n", NULL }
296 static TRACEDRVINFO TraceDrvInfo[] =
297 {
298 TRACEDRVINFO_ENTRY(EnablePDEV),
299 TRACEDRVINFO_ENTRY(CompletePDEV),
300 TRACEDRVINFO_ENTRY(DisablePDEV),
301 TRACEDRVINFO_ENTRY(EnableSurface),
302 TRACEDRVINFO_ENTRY(DisableSurface),
303 TRACEDRVINFO_ENTRY(AssertMode),
304 TRACEDRVINFO_ENTRY(Offset),
305 TRACEDRVINFO_ENTRY(ResetPDEV),
306 TRACEDRVINFO_ENTRY(DisableDriver),
307 TRACEDRVINFO_ENTRY(CreateDeviceBitmap),
308 TRACEDRVINFO_ENTRY(DeleteDeviceBitmap),
309 TRACEDRVINFO_ENTRY(RealizeBrush),
310 TRACEDRVINFO_ENTRY(DitherColor),
311 TRACEDRVINFO_ENTRY(StrokePath),
312 TRACEDRVINFO_ENTRY(FillPath),
313 TRACEDRVINFO_ENTRY(StrokeAndFillPath),
314 TRACEDRVINFO_ENTRY(Paint),
315 TRACEDRVINFO_ENTRY(BitBlt),
316 TRACEDRVINFO_ENTRY(TransparentBlt),
317 TRACEDRVINFO_ENTRY(CopyBits),
318 TRACEDRVINFO_ENTRY(StretchBlt),
319 TRACEDRVINFO_ENTRY(StretchBltROP),
320 TRACEDRVINFO_ENTRY(SetPalette),
321 TRACEDRVINFO_ENTRY(TextOut),
322 TRACEDRVINFO_ENTRY(Escape),
323 TRACEDRVINFO_ENTRY(DrawEscape),
324 TRACEDRVINFO_ENTRY(QueryFont),
325 TRACEDRVINFO_ENTRY(QueryFontTree),
326 TRACEDRVINFO_ENTRY(QueryFontData),
327 TRACEDRVINFO_ENTRY(SetPointerShape),
328 TRACEDRVINFO_ENTRY(MovePointer),
329 TRACEDRVINFO_ENTRY(LineTo),
330 TRACEDRVINFO_ENTRY(SendPage),
331 TRACEDRVINFO_ENTRY(StartPage),
332 TRACEDRVINFO_ENTRY(EndDoc),
333 TRACEDRVINFO_ENTRY(StartDoc),
334 TRACEDRVINFO_ENTRY(GetGlyphMode),
335 TRACEDRVINFO_ENTRY(Synchronize),
336 TRACEDRVINFO_ENTRY(SaveScreenBits),
337 TRACEDRVINFO_ENTRY(GetModes),
338 TRACEDRVINFO_ENTRY(Free),
339 TRACEDRVINFO_ENTRY(DestroyFont),
340 TRACEDRVINFO_ENTRY(QueryFontCaps),
341 TRACEDRVINFO_ENTRY(LoadFontFile),
342 TRACEDRVINFO_ENTRY(UnloadFontFile),
343 TRACEDRVINFO_ENTRY(FontManagement),
344 TRACEDRVINFO_ENTRY(QueryTrueTypeTable),
345 TRACEDRVINFO_ENTRY(QueryTrueTypeOutline),
346 TRACEDRVINFO_ENTRY(GetTrueTypeFile),
347 TRACEDRVINFO_ENTRY(QueryFontFile),
348 TRACEDRVINFO_ENTRY(QueryAdvanceWidths),
349 TRACEDRVINFO_ENTRY(SetPixelFormat),
350 TRACEDRVINFO_ENTRY(DescribePixelFormat),
351 TRACEDRVINFO_ENTRY(SwapBuffers),
352 TRACEDRVINFO_ENTRY(StartBanding),
353 TRACEDRVINFO_ENTRY(NextBand),
354 TRACEDRVINFO_ENTRY(GetDirectDrawInfo),
355 TRACEDRVINFO_ENTRY(EnableDirectDraw),
356 TRACEDRVINFO_ENTRY(DisableDirectDraw),
357 TRACEDRVINFO_ENTRY(QuerySpoolType),
358 TRACEDRVINFO_ENTRY(IcmSetDeviceGammaRamp),
359 TRACEDRVINFO_ENTRY(GradientFill),
360 TRACEDRVINFO_ENTRY(SynchronizeSurface),
361 TRACEDRVINFO_ENTRY(AlphaBlend)
362 };
363
364 PTRACEDRVINFO
365 FindTraceInfo(unsigned Index)
366 {
367 unsigned i;
368
369 for (i = 0; i < sizeof(TraceDrvInfo) / sizeof(TRACEDRVINFO); i++)
370 {
371 if (TraceDrvInfo[i].Index == Index)
372 {
373 return TraceDrvInfo + i;
374 }
375 }
376
377 return NULL;
378 }
379
380 #define DRIVER_FUNCTION(function) \
381 case INDEX_Drv##function: \
382 FindTraceInfo(INDEX_Drv##function)->DrvRoutine = DED->pdrvfn[i].pfn; \
383 *(PVOID*)&DF->function = &Trace##function; \
384 break
385 #else
386 #define DRIVER_FUNCTION(function) \
387 case INDEX_Drv##function: \
388 *(PVOID*)&DF->function = DED->pdrvfn[i].pfn; \
389 break
390 #endif
391
392 BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
393 PDRIVER_FUNCTIONS DF)
394 {
395 BEGIN_FUNCTION_MAP();
396 DRIVER_FUNCTION(EnablePDEV);
397 DRIVER_FUNCTION(CompletePDEV);
398 DRIVER_FUNCTION(DisablePDEV);
399 DRIVER_FUNCTION(EnableSurface);
400 DRIVER_FUNCTION(DisableSurface);
401 DRIVER_FUNCTION(AssertMode);
402 DRIVER_FUNCTION(Offset);
403 DRIVER_FUNCTION(ResetPDEV);
404 DRIVER_FUNCTION(DisableDriver);
405 DRIVER_FUNCTION(Unknown1);
406 DRIVER_FUNCTION(CreateDeviceBitmap);
407 DRIVER_FUNCTION(DeleteDeviceBitmap);
408 DRIVER_FUNCTION(RealizeBrush);
409 DRIVER_FUNCTION(DitherColor);
410 DRIVER_FUNCTION(StrokePath);
411 DRIVER_FUNCTION(FillPath);
412 DRIVER_FUNCTION(StrokeAndFillPath);
413 DRIVER_FUNCTION(Paint);
414 DRIVER_FUNCTION(BitBlt);
415 DRIVER_FUNCTION(CopyBits);
416 DRIVER_FUNCTION(StretchBlt);
417 DRIVER_FUNCTION(Unknown2);
418 DRIVER_FUNCTION(SetPalette);
419 DRIVER_FUNCTION(TextOut);
420 DRIVER_FUNCTION(Escape);
421 DRIVER_FUNCTION(DrawEscape);
422 DRIVER_FUNCTION(QueryFont);
423 DRIVER_FUNCTION(QueryFontTree);
424 DRIVER_FUNCTION(QueryFontData);
425 DRIVER_FUNCTION(SetPointerShape);
426 DRIVER_FUNCTION(MovePointer);
427 DRIVER_FUNCTION(LineTo);
428 DRIVER_FUNCTION(SendPage);
429 DRIVER_FUNCTION(StartPage);
430 DRIVER_FUNCTION(EndDoc);
431 DRIVER_FUNCTION(StartDoc);
432 DRIVER_FUNCTION(Unknown3);
433 DRIVER_FUNCTION(GetGlyphMode);
434 DRIVER_FUNCTION(Synchronize);
435 DRIVER_FUNCTION(Unknown4);
436 DRIVER_FUNCTION(SaveScreenBits);
437 DRIVER_FUNCTION(GetModes);
438 DRIVER_FUNCTION(Free);
439 DRIVER_FUNCTION(DestroyFont);
440 DRIVER_FUNCTION(QueryFontCaps);
441 DRIVER_FUNCTION(LoadFontFile);
442 DRIVER_FUNCTION(UnloadFontFile);
443 DRIVER_FUNCTION(FontManagement);
444 DRIVER_FUNCTION(QueryTrueTypeTable);
445 DRIVER_FUNCTION(QueryTrueTypeOutline);
446 DRIVER_FUNCTION(GetTrueTypeFile);
447 DRIVER_FUNCTION(QueryFontFile);
448 DRIVER_FUNCTION(QueryAdvanceWidths);
449 DRIVER_FUNCTION(SetPixelFormat);
450 DRIVER_FUNCTION(DescribePixelFormat);
451 DRIVER_FUNCTION(SwapBuffers);
452 DRIVER_FUNCTION(StartBanding);
453 DRIVER_FUNCTION(NextBand);
454 DRIVER_FUNCTION(GetDirectDrawInfo);
455 DRIVER_FUNCTION(EnableDirectDraw);
456 DRIVER_FUNCTION(DisableDirectDraw);
457 DRIVER_FUNCTION(QuerySpoolType);
458 DRIVER_FUNCTION(Unknown5);
459 DRIVER_FUNCTION(IcmCreateColorTransform);
460 DRIVER_FUNCTION(IcmDeleteColorTransform);
461 DRIVER_FUNCTION(IcmCheckBitmapBits);
462 DRIVER_FUNCTION(IcmSetDeviceGammaRamp);
463 DRIVER_FUNCTION(GradientFill);
464 DRIVER_FUNCTION(StretchBltROP);
465 DRIVER_FUNCTION(PlgBlt);
466 DRIVER_FUNCTION(AlphaBlend);
467 DRIVER_FUNCTION(SynthesizeFont);
468 DRIVER_FUNCTION(GetSynthesizedFontFiles);
469 DRIVER_FUNCTION(TransparentBlt);
470 DRIVER_FUNCTION(QueryPerBandInfo);
471 DRIVER_FUNCTION(QueryDeviceSupport);
472 DRIVER_FUNCTION(Reserved1);
473 DRIVER_FUNCTION(Reserved2);
474 DRIVER_FUNCTION(Reserved3);
475 DRIVER_FUNCTION(Reserved4);
476 DRIVER_FUNCTION(Reserved5);
477 DRIVER_FUNCTION(Reserved6);
478 DRIVER_FUNCTION(Reserved7);
479 DRIVER_FUNCTION(Reserved8);
480 DRIVER_FUNCTION(DeriveSurface);
481 DRIVER_FUNCTION(QueryGlyphAttrs);
482 DRIVER_FUNCTION(Notify);
483 DRIVER_FUNCTION(SynchronizeSurface);
484 DRIVER_FUNCTION(ResetDevice);
485 DRIVER_FUNCTION(Reserved9);
486 DRIVER_FUNCTION(Reserved10);
487 DRIVER_FUNCTION(Reserved11);
488 END_FUNCTION_MAP();
489
490 return TRUE;
491 }
492
493 typedef LONG VP_STATUS;
494 typedef VP_STATUS (APIENTRY *PMP_DRIVERENTRY)(PVOID, PVOID);
495
496 PFILE_OBJECT DRIVER_FindMPDriver(ULONG DisplayNumber)
497 {
498 OBJECT_ATTRIBUTES ObjectAttributes;
499 WCHAR DeviceNameBuffer[20];
500 UNICODE_STRING DeviceName;
501 IO_STATUS_BLOCK Iosb;
502 HANDLE DisplayHandle;
503 NTSTATUS Status;
504 PFILE_OBJECT VideoFileObject;
505
506 swprintf(DeviceNameBuffer, L"\\??\\DISPLAY%d", DisplayNumber + 1);
507 RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
508 InitializeObjectAttributes(&ObjectAttributes,
509 &DeviceName,
510 0,
511 NULL,
512 NULL);
513 Status = ZwOpenFile(&DisplayHandle,
514 FILE_ALL_ACCESS,
515 &ObjectAttributes,
516 &Iosb,
517 0,
518 FILE_SYNCHRONOUS_IO_ALERT);
519 if (NT_SUCCESS(Status))
520 {
521 Status = ObReferenceObjectByHandle(DisplayHandle,
522 FILE_READ_DATA | FILE_WRITE_DATA,
523 IoFileObjectType,
524 KernelMode,
525 (PVOID *)&VideoFileObject,
526 NULL);
527 ZwClose(DisplayHandle);
528 }
529
530 if (!NT_SUCCESS(Status))
531 {
532 DPRINT1("Unable to connect to miniport (Status %lx)\n", Status);
533 DPRINT1("Perhaps the miniport wasn't loaded?\n");
534 return(NULL);
535 }
536
537 return VideoFileObject;
538 }
539
540
541 BOOL DRIVER_UnregisterDriver(LPCWSTR Name)
542 {
543 PGRAPHICS_DRIVER Driver = NULL;
544
545 if (Name)
546 {
547 if (DriverList != NULL)
548 {
549 if (!_wcsicmp(DriverList->Name, Name))
550 {
551 Driver = DriverList;
552 DriverList = DriverList->Next;
553 }
554 else
555 {
556 Driver = DriverList;
557 while (Driver->Next && _wcsicmp(Driver->Name, Name))
558 {
559 Driver = Driver->Next;
560 }
561 }
562 }
563 }
564 else
565 {
566 if (GenericDriver != NULL)
567 {
568 Driver = GenericDriver;
569 GenericDriver = NULL;
570 }
571 }
572
573 if (Driver != NULL)
574 {
575 ExFreePool(Driver->Name);
576 ExFreePool(Driver);
577
578 return TRUE;
579 }
580 else
581 {
582 return FALSE;
583 }
584 }
585
586 INT DRIVER_ReferenceDriver (LPCWSTR Name)
587 {
588 GRAPHICS_DRIVER *Driver = DriverList;
589
590 while (Driver && Name)
591 {
592 DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
593 if (!_wcsicmp( Driver->Name, Name))
594 {
595 return ++Driver->ReferenceCount;
596 }
597 Driver = Driver->Next;
598 }
599 DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
600 assert( GenericDriver != 0 );
601 return ++GenericDriver->ReferenceCount;
602 }
603
604 INT DRIVER_UnreferenceDriver (LPCWSTR Name)
605 {
606 GRAPHICS_DRIVER *Driver = DriverList;
607
608 while (Driver && Name)
609 {
610 DPRINT( "Comparing %S to %S\n", Driver->Name, Name );
611 if (!_wcsicmp( Driver->Name, Name))
612 {
613 return --Driver->ReferenceCount;
614 }
615 Driver = Driver->Next;
616 }
617 DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount );
618 assert( GenericDriver != 0 );
619 return --GenericDriver->ReferenceCount;
620 }
621 /* EOF */