ReactOS 0.4.15-dev-8241-g63935f8
device.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI Driver Device Functions
5 * FILE: win32ss/gdi/eng/device.c
6 * PROGRAMER: Jason Filby
7 * Timo Kreuzer
8 */
9
10#include <win32k.h>
11#include <ntddvdeo.h>
12
14
17
21static ULONG giDevNum = 1;
22
23CODE_SEG("INIT")
27{
31
32 return STATUS_SUCCESS;
33}
34
35static
38 _In_ PGRAPHICS_DEVICE pGraphicsDevice)
39{
40 WCHAR awcDeviceKey[256], awcServiceName[100];
41 PWSTR lastBkSlash;
43 ULONG cbValue;
44 HKEY hkey;
45
46 /* Open the key for the adapters */
47 Status = RegOpenKey(L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO", &hkey);
48 if (!NT_SUCCESS(Status))
49 {
50 ERR("Could not open HARDWARE\\DEVICEMAP\\VIDEO registry key: 0x%08lx\n", Status);
51 return FALSE;
52 }
53
54 /* Read the name of the device key */
55 cbValue = sizeof(awcDeviceKey);
56 Status = RegQueryValue(hkey, pGraphicsDevice->szNtDeviceName, REG_SZ, awcDeviceKey, &cbValue);
57 ZwClose(hkey);
58 if (!NT_SUCCESS(Status))
59 {
60 ERR("Could not read '%S' registry value: 0x%08lx\n", Status);
61 return FALSE;
62 }
63
64 /* Replace 'DeviceN' by 'Video' */
65 lastBkSlash = wcsrchr(awcDeviceKey, L'\\');
66 if (!lastBkSlash)
67 {
68 ERR("Invalid registry key '%S'\n", lastBkSlash);
69 return FALSE;
70 }
71 if (!NT_SUCCESS(RtlStringCchCopyW(lastBkSlash + 1,
72 ARRAYSIZE(awcDeviceKey) - (lastBkSlash + 1 - awcDeviceKey),
73 L"Video")))
74 {
75 ERR("Failed to add 'Video' to registry key '%S'\n", awcDeviceKey);
76 return FALSE;
77 }
78
79 /* Open device key */
80 Status = RegOpenKey(awcDeviceKey, &hkey);
81 if (!NT_SUCCESS(Status))
82 {
83 ERR("Could not open %S registry key: 0x%08lx\n", awcDeviceKey, Status);
84 return FALSE;
85 }
86
87 /* Read service name */
88 cbValue = sizeof(awcServiceName);
89 Status = RegQueryValue(hkey, L"Service", REG_SZ, awcServiceName, &cbValue);
90 ZwClose(hkey);
91 if (!NT_SUCCESS(Status))
92 {
93 ERR("Could not read Service registry value in %S: 0x%08lx\n", awcDeviceKey, Status);
94 return FALSE;
95 }
96
97 /* Device is using VGA driver if service name starts with 'VGA' (case insensitive) */
98 return (_wcsnicmp(awcServiceName, L"VGA", 3) == 0);
99}
100
101/*
102 * Add a device to gpGraphicsDeviceFirst/gpGraphicsDeviceLast list (if not already present).
103 */
105static
106VOID
107EngpLinkGraphicsDevice(
108 _In_ PGRAPHICS_DEVICE pToAdd)
109{
110 PGRAPHICS_DEVICE pGraphicsDevice;
111
112 TRACE("EngLinkGraphicsDevice(%p)\n", pToAdd);
113
114 /* Search if device is not already linked */
115 for (pGraphicsDevice = gpGraphicsDeviceFirst;
116 pGraphicsDevice;
117 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice)
118 {
119 if (pGraphicsDevice == pToAdd)
120 return;
121 }
122
123 pToAdd->pNextGraphicsDevice = NULL;
126 gpGraphicsDeviceLast = pToAdd;
128 gpGraphicsDeviceFirst = pToAdd;
129}
130
131/*
132 * Remove a device from gpGraphicsDeviceFirst/gpGraphicsDeviceLast list.
133 */
135static
136VOID
137EngpUnlinkGraphicsDevice(
138 _In_ PGRAPHICS_DEVICE pToDelete)
139{
140 PGRAPHICS_DEVICE pPrevGraphicsDevice = NULL;
141 PGRAPHICS_DEVICE pGraphicsDevice = gpGraphicsDeviceFirst;
142
143 TRACE("EngpUnlinkGraphicsDevice('%S')\n", pToDelete->szNtDeviceName);
144
145 while (pGraphicsDevice)
146 {
147 if (pGraphicsDevice != pToDelete)
148 {
149 /* Keep current device */
150 pPrevGraphicsDevice = pGraphicsDevice;
151 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice;
152 }
153 else
154 {
155 /* At first, link again associated VGA Device */
156 if (pGraphicsDevice->pVgaDevice)
157 EngpLinkGraphicsDevice(pGraphicsDevice->pVgaDevice);
158
159 /* We need to remove current device */
160 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice;
161
162 /* Unlink chain */
163 if (!pPrevGraphicsDevice)
165 else
166 pPrevGraphicsDevice->pNextGraphicsDevice = pToDelete->pNextGraphicsDevice;
167 if (gpGraphicsDeviceLast == pToDelete)
168 gpGraphicsDeviceLast = pPrevGraphicsDevice;
169 }
170 }
171}
172
175{
176 ULONG iDevNum, iVGACompatible = -1, ulMaxObjectNumber = 0;
177 WCHAR awcDeviceName[20], awcWinDeviceName[20];
178 UNICODE_STRING ustrDeviceName;
179 WCHAR awcBuffer[256];
181 PGRAPHICS_DEVICE pGraphicsDevice;
182 BOOLEAN bFoundNewDevice = FALSE;
183 ULONG cbValue;
184 HKEY hkey;
185
186 /* Open the key for the adapters */
187 Status = RegOpenKey(L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO", &hkey);
188 if (!NT_SUCCESS(Status))
189 {
190 ERR("Could not open HARDWARE\\DEVICEMAP\\VIDEO registry key:0x%lx\n", Status);
191 return Status;
192 }
193
194 /* Read the name of the VGA adapter */
195 cbValue = sizeof(awcDeviceName);
196 Status = RegQueryValue(hkey, L"VgaCompatible", REG_SZ, awcDeviceName, &cbValue);
197 if (NT_SUCCESS(Status))
198 {
199 iVGACompatible = _wtoi(&awcDeviceName[sizeof("\\Device\\Video")-1]);
200 ERR("VGA adapter = %lu\n", iVGACompatible);
201 }
202
203 /* Get the maximum number of adapters */
204 if (!RegReadDWORD(hkey, L"MaxObjectNumber", &ulMaxObjectNumber))
205 {
206 ERR("Could not read MaxObjectNumber, defaulting to 0.\n");
207 }
208
209 TRACE("Found %lu devices\n", ulMaxObjectNumber + 1);
210
211 /* Loop through all adapters */
212 for (iDevNum = 0; iDevNum <= ulMaxObjectNumber; iDevNum++)
213 {
214 /* Create the adapter's key name */
215 swprintf(awcDeviceName, L"\\Device\\Video%lu", iDevNum);
216
217 /* Create the display device name */
218 swprintf(awcWinDeviceName, L"\\\\.\\DISPLAY%lu", iDevNum + 1);
219 RtlInitUnicodeString(&ustrDeviceName, awcWinDeviceName);
220
221 /* Check if the device exists already */
222 pGraphicsDevice = EngpFindGraphicsDevice(&ustrDeviceName, iDevNum);
223 if (pGraphicsDevice != NULL)
224 {
225 continue;
226 }
227
228 /* Read the reg key name */
229 cbValue = sizeof(awcBuffer);
230 Status = RegQueryValue(hkey, awcDeviceName, REG_SZ, awcBuffer, &cbValue);
231 if (!NT_SUCCESS(Status))
232 {
233 ERR("failed to query the registry path:0x%lx\n", Status);
234 continue;
235 }
236
237 /* Initialize the driver for this device */
238 pGraphicsDevice = InitDisplayDriver(awcDeviceName, awcBuffer);
239 if (!pGraphicsDevice) continue;
240
241 /* Check if this is a VGA compatible adapter */
242 if (pGraphicsDevice->StateFlags & DISPLAY_DEVICE_VGA_COMPATIBLE)
243 {
244 /* Save this as the VGA adapter */
246 {
247 gpVgaGraphicsDevice = pGraphicsDevice;
248 TRACE("gpVgaGraphicsDevice = %p\n", gpVgaGraphicsDevice);
249 }
250 }
251 bFoundNewDevice = TRUE;
252
253 /* Set the first one as primary device */
255 {
256 gpPrimaryGraphicsDevice = pGraphicsDevice;
257 TRACE("gpPrimaryGraphicsDevice = %p\n", gpPrimaryGraphicsDevice);
258 }
259 }
260
261 /* Close the device map registry key */
262 ZwClose(hkey);
263
264 /* Can we link VGA device to primary device? */
269 {
270 /* Yes. Remove VGA device from global list, and attach it to primary device */
271 TRACE("Linking VGA device %S to primary device %S\n", gpVgaGraphicsDevice->szNtDeviceName, gpPrimaryGraphicsDevice->szNtDeviceName);
272 EngpUnlinkGraphicsDevice(gpVgaGraphicsDevice);
274 }
275
276 if (bFoundNewDevice && gbBaseVideo)
277 {
278 PGRAPHICS_DEVICE pToDelete;
279
280 /* Lock list */
282
283 /* Remove every device from linked list, except base-video one */
284 pGraphicsDevice = gpGraphicsDeviceFirst;
285 while (pGraphicsDevice)
286 {
287 if (!EngpHasVgaDriver(pGraphicsDevice))
288 {
289 /* Not base-video device. Remove it */
290 pToDelete = pGraphicsDevice;
291 TRACE("Removing non-base-video device %S (%S)\n", pToDelete->szWinDeviceName, pToDelete->szNtDeviceName);
292
293 EngpUnlinkGraphicsDevice(pGraphicsDevice);
294 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice;
295
296 /* Free memory */
299 }
300 else
301 {
302 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice;
303 }
304 }
305
306 /* Unlock list */
308 }
309
310 return STATUS_SUCCESS;
311}
312
313/* Open display settings registry key
314 * Returns NULL in case of error. */
315static HKEY
317 _In_ PGRAPHICS_DEVICE pGraphicsDevice)
318{
319 static const PWCHAR KEY_VIDEO = L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO";
320 HKEY hKey;
321 WCHAR szDeviceKey[256];
322 ULONG cbSize;
324
325 /* Open the device map registry key */
327 if (!NT_SUCCESS(Status))
328 {
329 ERR("Could not open HARDWARE\\DEVICEMAP\\VIDEO registry key: status 0x%08x\n", Status);
330 return NULL;
331 }
332
333 /* Query the registry path */
334 cbSize = sizeof(szDeviceKey);
336 pGraphicsDevice->szNtDeviceName,
337 REG_SZ,
338 szDeviceKey,
339 &cbSize);
340 ZwClose(hKey);
341
342 /* Open the registry key */
343 Status = RegOpenKey(szDeviceKey, &hKey);
344 if (!NT_SUCCESS(Status))
345 {
346 ERR("Could not open registry key '%S': status 0x%08x\n", szDeviceKey, Status);
347 return NULL;
348 }
349
350 return hKey;
351}
352
355 _In_ PGRAPHICS_DEVICE pGraphicsDevice,
356 _Out_ PDEVMODEW pdm)
357{
358 HKEY hKey;
360 RTL_QUERY_REGISTRY_TABLE DisplaySettingsTable[] =
361 {
362#define READ(field, str) \
363 { \
364 NULL, \
365 RTL_QUERY_REGISTRY_DIRECT, \
366 L ##str, \
367 &pdm->field, \
368 REG_NONE, NULL, 0 \
369 },
370 READ(dmBitsPerPel, "DefaultSettings.BitsPerPel")
371 READ(dmPelsWidth, "DefaultSettings.XResolution")
372 READ(dmPelsHeight, "DefaultSettings.YResolution")
373 READ(dmDisplayFlags, "DefaultSettings.Flags")
374 READ(dmDisplayFrequency, "DefaultSettings.VRefresh")
375 READ(dmPanningWidth, "DefaultSettings.XPanning")
376 READ(dmPanningHeight, "DefaultSettings.YPanning")
377 READ(dmDisplayOrientation, "DefaultSettings.Orientation")
378 READ(dmDisplayFixedOutput, "DefaultSettings.FixedOutput")
379 READ(dmPosition.x, "Attach.RelativeX")
380 READ(dmPosition.y, "Attach.RelativeY")
381#undef READ
382 {0}
383 };
384
385 hKey = EngpGetRegistryHandleFromDeviceMap(pGraphicsDevice);
386 if (!hKey)
387 return STATUS_UNSUCCESSFUL;
388
390 (PWSTR)hKey,
391 DisplaySettingsTable,
392 NULL,
393 NULL);
394
395 ZwClose(hKey);
396 return Status;
397}
398
399DWORD
401 _In_ PGRAPHICS_DEVICE pGraphicsDevice)
402{
403 HKEY hKey;
404 DWORD dwAccelerationLevel = 0;
405 RTL_QUERY_REGISTRY_TABLE DisplaySettingsTable[] =
406 {
407 {
408 NULL,
410 L"Acceleration.Level",
411 &dwAccelerationLevel,
412 REG_NONE, NULL, 0
413 },
414 {0}
415 };
416
417 hKey = EngpGetRegistryHandleFromDeviceMap(pGraphicsDevice);
418 if (!hKey)
419 return 0;
420
422 (PWSTR)hKey,
423 DisplaySettingsTable,
424 NULL,
425 NULL);
426 ZwClose(hKey);
427
428 return dwAccelerationLevel;
429}
430
431extern VOID
433
434// PVIDEO_WIN32K_CALLOUT
435VOID
436NTAPI
439{
440/*
441 * IMPORTANT NOTICE!! On Windows XP/2003 this function triggers the creation of
442 * a specific VideoPortCalloutThread() system thread using the same mechanism
443 * as the RIT/desktop/Ghost system threads.
444 */
445
447
448 TRACE("VideoPortCallout(0x%p, 0x%x)\n",
449 CallbackParams, CallbackParams ? CallbackParams->CalloutType : -1);
450
451 if (!CallbackParams)
452 return;
453
454 switch (CallbackParams->CalloutType)
455 {
457 {
458 TRACE("VideoPortCallout: VideoFindAdapterCallout called - Param = %s\n",
459 CallbackParams->Param ? "TRUE" : "FALSE");
460 if (CallbackParams->Param == TRUE)
461 {
462 /* Re-enable the display */
464 }
465 else
466 {
467 /* Disable the display */
468 NOTHING; // Nothing to do for the moment...
469 }
470
471 CallbackParams->Status = STATUS_SUCCESS;
472 break;
473 }
474
484 ERR("VideoPortCallout: CalloutType 0x%x is UNIMPLEMENTED!\n", CallbackParams->CalloutType);
485 CallbackParams->Status = STATUS_NOT_IMPLEMENTED;
486 break;
487
488 default:
489 ERR("VideoPortCallout: Unknown CalloutType 0x%x\n", CallbackParams->CalloutType);
490 CallbackParams->Status = STATUS_UNSUCCESSFUL;
491 break;
492 }
493}
494
496NTAPI
498 _In_ PUNICODE_STRING pustrDeviceName,
499 _In_ PUNICODE_STRING pustrDiplayDrivers,
500 _In_ PUNICODE_STRING pustrDescription)
501{
502 PGRAPHICS_DEVICE pGraphicsDevice;
504 PFILE_OBJECT pFileObject;
506 VIDEO_WIN32K_CALLBACKS Win32kCallbacks;
507 ULONG ulReturn;
508 PWSTR pwsz;
509 ULONG cj;
510
511 TRACE("EngpRegisterGraphicsDevice(%wZ)\n", pustrDeviceName);
512
513 /* Allocate a GRAPHICS_DEVICE structure */
514 pGraphicsDevice = ExAllocatePoolZero(PagedPool,
515 sizeof(GRAPHICS_DEVICE),
517 if (!pGraphicsDevice)
518 {
519 ERR("ExAllocatePoolWithTag failed\n");
520 return NULL;
521 }
522
523 /* Try to open and enable the device */
524 Status = IoGetDeviceObjectPointer(pustrDeviceName,
526 &pFileObject,
528 if (!NT_SUCCESS(Status))
529 {
530 ERR("Could not open device %wZ, 0x%lx\n", pustrDeviceName, Status);
531 ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
532 return NULL;
533 }
534
535 /* Copy the device and file object pointers */
536 pGraphicsDevice->DeviceObject = pDeviceObject;
537 pGraphicsDevice->FileObject = pFileObject;
538
539 /* Initialize and register the device with videoprt for Win32k callbacks */
540 Win32kCallbacks.PhysDisp = pGraphicsDevice;
541 Win32kCallbacks.Callout = VideoPortCallout;
542 // Reset the data being returned prior to the call.
543 Win32kCallbacks.bACPI = FALSE;
544 Win32kCallbacks.pPhysDeviceObject = NULL;
545 Win32kCallbacks.DualviewFlags = 0;
546 Status = (NTSTATUS)EngDeviceIoControl((HANDLE)pDeviceObject,
548 &Win32kCallbacks,
549 sizeof(Win32kCallbacks),
550 &Win32kCallbacks,
551 sizeof(Win32kCallbacks),
552 &ulReturn);
553 if (Status != ERROR_SUCCESS)
554 {
555 ERR("EngDeviceIoControl(0x%p, IOCTL_VIDEO_INIT_WIN32K_CALLBACKS) failed, Status 0x%lx\n",
557 }
558 // TODO: Set flags according to the results.
559 // if (Win32kCallbacks.bACPI)
560 // if (Win32kCallbacks.DualviewFlags & ???)
561 pGraphicsDevice->PhysDeviceHandle = Win32kCallbacks.pPhysDeviceObject;
562
563 /* FIXME: Enumerate children monitor devices for this video adapter
564 *
565 * - Force the adapter to re-enumerate its monitors:
566 * IoSynchronousInvalidateDeviceRelations(pdo, BusRelations)
567 *
568 * - Retrieve all monitor PDOs from VideoPrt:
569 * EngDeviceIoControl(0x%p, IOCTL_VIDEO_ENUM_MONITOR_PDO)
570 *
571 * - Initialize these fields and structures accordingly:
572 * pGraphicsDevice->dwMonCnt
573 * pGraphicsDevice->pvMonDev[0..dwMonCnt-1]
574 */
575
576 /* Copy the device name */
577 RtlStringCbCopyNW(pGraphicsDevice->szNtDeviceName,
578 sizeof(pGraphicsDevice->szNtDeviceName),
579 pustrDeviceName->Buffer,
580 pustrDeviceName->Length);
581
582 /* Create a Win32 device name (FIXME: virtual devices!) */
583 RtlStringCbPrintfW(pGraphicsDevice->szWinDeviceName,
584 sizeof(pGraphicsDevice->szWinDeviceName),
585 L"\\\\.\\DISPLAY%d",
586 (int)giDevNum);
587
588 /* Allocate a buffer for the strings */
589 cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR);
591 if (!pwsz)
592 {
593 ERR("Could not allocate string buffer\n");
594 ASSERT(FALSE); // FIXME
595 ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
596 return NULL;
597 }
598
599 /* Copy the display driver names */
600 pGraphicsDevice->pDiplayDrivers = pwsz;
601 RtlCopyMemory(pGraphicsDevice->pDiplayDrivers,
602 pustrDiplayDrivers->Buffer,
603 pustrDiplayDrivers->Length);
604
605 /* Copy the description */
606 pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR);
607 RtlCopyMemory(pGraphicsDevice->pwszDescription,
608 pustrDescription->Buffer,
609 pustrDescription->Length);
610 pGraphicsDevice->pwszDescription[pustrDescription->Length/sizeof(WCHAR)] = 0;
611
612 /* Lock loader */
614
615 /* Insert the device into the global list */
616 EngpLinkGraphicsDevice(pGraphicsDevice);
617
618 /* Increment the device number */
619 giDevNum++;
620
621 /* Unlock loader */
623 TRACE("Prepared %lu modes for %ls\n", pGraphicsDevice->cDevModes, pGraphicsDevice->pwszDescription);
624
625 /* HACK: already in graphic mode; display wallpaper on this new display */
627 {
628 UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
629 UNICODE_STRING DisplayName;
630 HDC hdc;
631 RtlInitUnicodeString(&DisplayName, pGraphicsDevice->szWinDeviceName);
632 hdc = IntGdiCreateDC(&DriverName, &DisplayName, NULL, NULL, FALSE);
634 }
635
636 return pGraphicsDevice;
637}
638
640NTAPI
642 _In_opt_ PUNICODE_STRING pustrDevice,
643 _In_ ULONG iDevNum)
644{
645 UNICODE_STRING ustrCurrent;
646 PGRAPHICS_DEVICE pGraphicsDevice;
647 ULONG i;
648 TRACE("EngpFindGraphicsDevice('%wZ', %lu)\n",
649 pustrDevice, iDevNum);
650
651 /* Lock list */
653
654 if (pustrDevice && pustrDevice->Buffer)
655 {
656 /* Find specified video adapter by name */
657 for (pGraphicsDevice = gpGraphicsDeviceFirst;
658 pGraphicsDevice;
659 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice)
660 {
661 /* Compare the device name */
662 RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
663 if (RtlEqualUnicodeString(&ustrCurrent, pustrDevice, FALSE))
664 {
665 break;
666 }
667 }
668
669 if (pGraphicsDevice)
670 {
671 /* Validate selected monitor number */
672#if 0
673 if (iDevNum >= pGraphicsDevice->dwMonCnt)
674 pGraphicsDevice = NULL;
675#else
676 /* FIXME: dwMonCnt not initialized, see EngpRegisterGraphicsDevice */
677#endif
678 }
679 }
680 else
681 {
682 /* Select video adapter by device number */
683 for (pGraphicsDevice = gpGraphicsDeviceFirst, i = 0;
684 pGraphicsDevice && i < iDevNum;
685 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice, i++);
686 }
687
688 /* Unlock list */
690
691 return pGraphicsDevice;
692}
693
694static
697 _In_ PFILE_OBJECT pFileObject,
698 _In_ ULONG ulMajorFunction,
699 _In_reads_(nBufferSize) PVOID lpBuffer,
700 _In_ SIZE_T nBufferSize,
701 _In_ ULONGLONG ullStartOffset,
702 _Out_ PULONG_PTR lpInformation)
703{
706 PIRP pIrp;
709 LARGE_INTEGER liStartOffset;
710
711 /* Get corresponding device object */
713 if (!pDeviceObject)
714 {
716 }
717
718 /* Initialize an event */
720
721 /* Build IRP */
722 liStartOffset.QuadPart = ullStartOffset;
723 pIrp = IoBuildSynchronousFsdRequest(ulMajorFunction,
725 lpBuffer,
726 (ULONG)nBufferSize,
727 &liStartOffset,
728 &Event,
729 &Iosb);
730 if (!pIrp)
731 {
733 }
734
735 /* Call the driver */
737
738 /* Wait if neccessary */
739 if (STATUS_PENDING == Status)
740 {
742 Status = Iosb.Status;
743 }
744
745 /* Return information to the caller about the operation. */
746 *lpInformation = Iosb.Information;
747
748 /* Return NTSTATUS */
749 return Status;
750}
751
752VOID
755 _In_ PFILE_OBJECT pFileObject,
758 _Out_ PSIZE_T lpBytesWritten)
759{
761
762 status = EngpFileIoRequest(pFileObject,
764 lpBuffer,
765 nLength,
766 0,
767 lpBytesWritten);
768 if (!NT_SUCCESS(status))
769 {
770 *lpBytesWritten = 0;
771 }
772}
773
774_Success_(return>=0)
777EngFileIoControl(
778 _In_ PFILE_OBJECT pFileObject,
780 _In_reads_(nInBufferSize) PVOID lpInBuffer,
781 _In_ SIZE_T nInBufferSize,
782 _Out_writes_(nOutBufferSize) PVOID lpOutBuffer,
783 _In_ SIZE_T nOutBufferSize,
784 _Out_ PULONG_PTR lpInformation)
785{
788 PIRP pIrp;
791
792 /* Get corresponding device object */
794 if (!pDeviceObject)
795 {
797 }
798
799 /* Initialize an event */
801
802 /* Build IO control IRP */
805 lpInBuffer,
806 (ULONG)nInBufferSize,
807 lpOutBuffer,
808 (ULONG)nOutBufferSize,
809 FALSE,
810 &Event,
811 &Iosb);
812 if (!pIrp)
813 {
815 }
816
817 /* Call the driver */
819
820 /* Wait if neccessary */
821 if (Status == STATUS_PENDING)
822 {
824 Status = Iosb.Status;
825 }
826
827 /* Return information to the caller about the operation. */
828 *lpInformation = Iosb.Information;
829
830 /* This function returns NTSTATUS */
831 return Status;
832}
833
834/*
835 * @implemented
836 */
837_Success_(return==0)
838DWORD
840EngDeviceIoControl(
841 _In_ HANDLE hDevice,
848{
849 PIRP Irp;
854
855 TRACE("EngDeviceIoControl() called\n");
856
857 if (!hDevice)
858 {
860 }
861
863
864 DeviceObject = (PDEVICE_OBJECT) hDevice;
865
868 lpInBuffer,
870 lpOutBuffer,
872 FALSE,
873 &Event,
874 &Iosb);
875 if (!Irp) return ERROR_NOT_ENOUGH_MEMORY;
876
878
879 if (Status == STATUS_PENDING)
880 {
882 Status = Iosb.Status;
883 }
884
885 TRACE("EngDeviceIoControl(): Returning %X/%X\n", Iosb.Status,
886 Iosb.Information);
887
888 /* Return information to the caller about the operation. */
889 *lpBytesReturned = (DWORD)Iosb.Information;
890
891 /* Convert NT status values to win32 error codes. */
892 switch (Status)
893 {
896
898 return ERROR_MORE_DATA;
899
902
905
908
910 return ERROR_DEV_NOT_EXIST;
911
912 case STATUS_PENDING:
913 return ERROR_IO_PENDING;
914 }
915
916 return Status;
917}
918
919/* EOF */
#define CODE_SEG(...)
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
DWORD_PTR HSEMAPHORE
Definition: axcore.idl:60
LONG NTSTATUS
Definition: precomp.h:26
#define ERR(fmt,...)
Definition: debug.h:113
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
#define _Requires_lock_held_(lock)
_In_ PIRP Irp
Definition: csq.h:116
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
HDC FASTCALL IntGdiCreateDC(PUNICODE_STRING Driver, PUNICODE_STRING pustrDevice, PVOID pUMdhpdev, CONST PDEVMODEW pdmInit, BOOL CreateAsIC)
Definition: dclife.c:1040
#define ERROR_DEV_NOT_EXIST
Definition: dderror.h:8
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_IO_PENDING
Definition: dderror.h:15
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define APIENTRY
Definition: api.h:79
#define NTSTATUS
Definition: precomp.h:21
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define wcsrchr
Definition: compat.h:16
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define swprintf
Definition: precomp.h:40
switch(r->id)
Definition: btrfs.c:3046
return Iosb
Definition: create.c:4402
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define PagedPool
Definition: env_spec_w32.h:308
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
FxIrp * pIrp
VOID WINAPI EngReleaseSemaphore(IN HSEMAPHORE hsem)
Definition: eng.c:235
HSEMAPHORE WINAPI EngCreateSemaphore(VOID)
Definition: eng.c:75
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ _CRTIMP int __cdecl _wtoi(_In_z_ const wchar_t *_Str)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define NOTHING
Definition: input_list.c:10
#define REG_SZ
Definition: layer.c:22
PMDEVOBJ gpmdev
Definition: mdevobj.c:14
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:92
#define _Success_(expr)
Definition: ms_sal.h:259
#define _Out_writes_(size)
Definition: ms_sal.h:348
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_reads_bytes_opt_(size)
Definition: ms_sal.h:322
#define _In_opt_
Definition: ms_sal.h:309
#define _Out_writes_bytes_opt_(size)
Definition: ms_sal.h:351
#define _In_reads_(size)
Definition: ms_sal.h:319
_In_ PNDIS_STRING _In_ PNDIS_STRING _Out_ PDEVICE_OBJECT * pDeviceObject
Definition: ndis.h:4679
#define KernelMode
Definition: asm.h:34
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define DWORD
Definition: nt_native.h:44
#define REG_NONE
Definition: nt_native.h:1492
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
@ VideoEnumChildPdoNotifyCallout
Definition: ntddvdeo.h:295
@ VideoPowerNotifyCallout
Definition: ntddvdeo.h:293
@ VideoDxgkFindAdapterTdrCallout
Definition: ntddvdeo.h:302
@ VideoDxgkMonitorEventCallout
Definition: ntddvdeo.h:301
@ VideoChangeDisplaySettingsCallout
Definition: ntddvdeo.h:298
@ VideoDisplaySwitchCallout
Definition: ntddvdeo.h:294
@ VideoPnpNotifyCallout
Definition: ntddvdeo.h:299
@ VideoDxgkDisplaySwitchCallout
Definition: ntddvdeo.h:300
@ VideoFindAdapterCallout
Definition: ntddvdeo.h:296
@ VideoWakeupCallout
Definition: ntddvdeo.h:297
struct _VIDEO_WIN32K_CALLBACKS_PARAMS * PVIDEO_WIN32K_CALLBACKS_PARAMS
#define IOCTL_VIDEO_INIT_WIN32K_CALLBACKS
Definition: ntddvdeo.h:131
@ SynchronizationEvent
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
NTSTRSAFEAPI RtlStringCbCopyNW(_Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc, _In_ size_t cbToCopy)
Definition: ntstrsafe.h:416
#define L(x)
Definition: ntvdm.h:50
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define TRACE(s)
Definition: solgame.cpp:4
DWORD StateFlags
Definition: pdevobj.h:66
struct _GRAPHICS_DEVICE * pVgaDevice
Definition: pdevobj.h:62
LPWSTR pDiplayDrivers
Definition: pdevobj.h:71
WCHAR szWinDeviceName[CCHDEVICENAME/2]
Definition: pdevobj.h:60
DWORD dwMonCnt
Definition: pdevobj.h:73
PFILE_OBJECT FileObject
Definition: pdevobj.h:75
WCHAR szNtDeviceName[CCHDEVICENAME/2]
Definition: pdevobj.h:59
LPWSTR pwszDescription
Definition: pdevobj.h:72
ULONG cDevModes
Definition: pdevobj.h:69
struct _GRAPHICS_DEVICE * pNextGraphicsDevice
Definition: pdevobj.h:61
PDEVICE_OBJECT DeviceObject
Definition: pdevobj.h:63
PDEVICE_OBJECT PhysDeviceHandle
Definition: pdevobj.h:64
PPDEVOBJ ppdevGlobal
Definition: mdevobj.h:16
VIDEO_WIN32K_CALLBACKS_PARAMS_TYPE CalloutType
Definition: ntddvdeo.h:319
OUT ULONG DualviewFlags
Definition: ntddvdeo.h:335
IN PVIDEO_WIN32K_CALLOUT Callout
Definition: ntddvdeo.h:332
OUT HANDLE pPhysDeviceObject
Definition: ntddvdeo.h:334
Definition: ps.c:97
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
static PGRAPHICS_DEVICE gpGraphicsDeviceLast
Definition: device.c:19
static ULONG giDevNum
Definition: device.c:21
PGRAPHICS_DEVICE NTAPI EngpRegisterGraphicsDevice(_In_ PUNICODE_STRING pustrDeviceName, _In_ PUNICODE_STRING pustrDiplayDrivers, _In_ PUNICODE_STRING pustrDescription)
Definition: device.c:497
NTSTATUS EngpGetDisplayDriverParameters(_In_ PGRAPHICS_DEVICE pGraphicsDevice, _Out_ PDEVMODEW pdm)
Definition: device.c:354
static HKEY EngpGetRegistryHandleFromDeviceMap(_In_ PGRAPHICS_DEVICE pGraphicsDevice)
Definition: device.c:316
static BOOLEAN EngpHasVgaDriver(_In_ PGRAPHICS_DEVICE pGraphicsDevice)
Definition: device.c:37
VOID UserRefreshDisplay(IN PPDEVOBJ ppdev)
Definition: display.c:193
DWORD EngpGetDisplayDriverAccelerationLevel(_In_ PGRAPHICS_DEVICE pGraphicsDevice)
Definition: device.c:400
VOID NTAPI VideoPortCallout(_In_ PVOID Params)
Definition: device.c:437
PGRAPHICS_DEVICE NTAPI EngpFindGraphicsDevice(_In_opt_ PUNICODE_STRING pustrDevice, _In_ ULONG iDevNum)
Definition: device.c:641
static NTSTATUS EngpFileIoRequest(_In_ PFILE_OBJECT pFileObject, _In_ ULONG ulMajorFunction, _In_reads_(nBufferSize) PVOID lpBuffer, _In_ SIZE_T nBufferSize, _In_ ULONGLONG ullStartOffset, _Out_ PULONG_PTR lpInformation)
Definition: device.c:696
static PGRAPHICS_DEVICE gpGraphicsDeviceFirst
Definition: device.c:18
NTSTATUS EngpUpdateGraphicsDeviceList(VOID)
Definition: device.c:174
#define READ(field, str)
VOID APIENTRY EngFileWrite(_In_ PFILE_OBJECT pFileObject, _In_reads_(nLength) PVOID lpBuffer, _In_ SIZE_T nLength, _Out_ PSIZE_T lpBytesWritten)
Definition: device.c:754
PGRAPHICS_DEVICE gpPrimaryGraphicsDevice
Definition: device.c:15
static HSEMAPHORE ghsemGraphicsDeviceList
Definition: device.c:20
NTSTATUS NTAPI InitDeviceImpl(VOID)
Definition: device.c:26
PGRAPHICS_DEVICE gpVgaGraphicsDevice
Definition: device.c:16
_In_ DWORD dwIoControlCode
Definition: device.c:779
BOOL NTAPI RegReadDWORD(HKEY hkey, PCWSTR pwszValue, PDWORD pdwData)
Definition: registry.c:149
HDC ScreenDeviceContext
Definition: desktop.c:36
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1835
BOOL gbBaseVideo
Definition: display.c:12
PGRAPHICS_DEVICE NTAPI InitDisplayDriver(IN PWSTR pwszDeviceName, IN PWSTR pwszRegKey)
Definition: display.c:66
static const PWCHAR KEY_VIDEO
Definition: display.c:15
#define GDITAG_DRVSUP
Definition: tags.h:77
#define GDITAG_GDEVICE
Definition: tags.h:99
_In_ DWORD nLength
Definition: wincon.h:473
_In_ DWORD _In_ DWORD _In_ DWORD cjOutBufferSize
Definition: winddi.h:1704
_In_ DWORD _In_ DWORD _In_ DWORD _Out_ LPDWORD lpBytesReturned
Definition: winddi.h:1705
ENGAPI VOID APIENTRY EngAcquireSemaphore(_Inout_ HSEMAPHORE hsem)
_In_ ULONG cj
Definition: winddi.h:3540
_In_ DWORD _In_ DWORD cjInBufferSize
Definition: winddi.h:1702
#define DISPLAY_DEVICE_VGA_COMPATIBLE
Definition: wingdi.h:1400
#define RegOpenKey
Definition: winreg.h:519
#define RegQueryValue
Definition: winreg.h:523
* PFILE_OBJECT
Definition: iotypes.h:1998
@ Executive
Definition: ketypes.h:415
__wchar_t WCHAR
Definition: xmlstorage.h:180