ReactOS 0.4.16-dev-1172-g2041f3c
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 is 'VGASave' (case insensitive) */
98 return (_wcsicmp(awcServiceName, L"VGASave") == 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
173/* Goal of this function is to:
174 * - detect new graphic devices (from registry) and initialize them
175 * - link primary device and VGA device (if available) using pVgaDevice field
176 * - handle gbBaseVideo global flag
177 * - set DISPLAY_DEVICE_PRIMARY_DEVICE on at least one device
178 * - set gpPrimaryGraphicsDevice
179 * - set gpVgaGraphicsDevice
180 */
183{
184 ULONG iDevNum, ulMaxObjectNumber = 0;
185 WCHAR awcDeviceName[20], awcWinDeviceName[20];
186 UNICODE_STRING ustrDeviceName;
187 WCHAR awcBuffer[256];
189 PGRAPHICS_DEVICE pGraphicsDevice, pNewPrimaryGraphicsDevice = NULL;
190 ULONG cbValue;
191 HKEY hkey;
192
193 /* Open the key for the adapters */
194 Status = RegOpenKey(L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO", &hkey);
195 if (!NT_SUCCESS(Status))
196 {
197 ERR("Could not open HARDWARE\\DEVICEMAP\\VIDEO registry key:0x%lx\n", Status);
198 return Status;
199 }
200
201 /* Get the maximum number of adapters */
202 if (!RegReadDWORD(hkey, L"MaxObjectNumber", &ulMaxObjectNumber))
203 {
204 ERR("Could not read MaxObjectNumber, defaulting to 0.\n");
205 }
206
207 TRACE("Found %lu devices\n", ulMaxObjectNumber + 1);
208
209 /* Loop through all adapters, to detect new ones */
210 for (iDevNum = 0; iDevNum <= ulMaxObjectNumber; iDevNum++)
211 {
212 /* Create the adapter's key name */
213 swprintf(awcDeviceName, L"\\Device\\Video%lu", iDevNum);
214
215 /* Create the display device name */
216 swprintf(awcWinDeviceName, L"\\\\.\\DISPLAY%lu", iDevNum + 1);
217 RtlInitUnicodeString(&ustrDeviceName, awcWinDeviceName);
218
219 /* Check if the device exists already */
220 pGraphicsDevice = EngpFindGraphicsDevice(&ustrDeviceName, iDevNum);
221 if (pGraphicsDevice != NULL)
222 {
223 continue;
224 }
225
226 /* Read the reg key name */
227 cbValue = sizeof(awcBuffer);
228 Status = RegQueryValue(hkey, awcDeviceName, REG_SZ, awcBuffer, &cbValue);
229 if (!NT_SUCCESS(Status))
230 {
231 ERR("failed to query the registry path:0x%lx\n", Status);
232 continue;
233 }
234
235 /* Initialize the driver for this device */
236 pGraphicsDevice = InitDisplayDriver(awcDeviceName, awcBuffer);
237 if (!pGraphicsDevice) continue;
238 }
239
240 /* Close the device map registry key */
241 ZwClose(hkey);
242
243 /* Choose a VGA device */
244 /* Try a device with DISPLAY_DEVICE_VGA_COMPATIBLE flag. If not found,
245 * fall back to current VGA device */
246 for (pGraphicsDevice = gpGraphicsDeviceFirst;
247 pGraphicsDevice;
248 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice)
249 {
250 if (pGraphicsDevice == gpVgaGraphicsDevice)
251 continue;
252 if (pGraphicsDevice->StateFlags & DISPLAY_DEVICE_VGA_COMPATIBLE && EngpHasVgaDriver(pGraphicsDevice))
253 {
254 gpVgaGraphicsDevice = pGraphicsDevice;
255 break;
256 }
257 }
258
259 /* Handle gbBaseVideo */
260 if (gbBaseVideo)
261 {
262 PGRAPHICS_DEVICE pToDelete;
263
264 /* Lock list */
266
267 /* Remove every device from linked list, except base-video one */
268 pGraphicsDevice = gpGraphicsDeviceFirst;
269 while (pGraphicsDevice)
270 {
271 if (!EngpHasVgaDriver(pGraphicsDevice))
272 {
273 /* Not base-video device. Remove it */
274 pToDelete = pGraphicsDevice;
275 TRACE("Removing non-base-video device %S (%S)\n", pToDelete->szWinDeviceName, pToDelete->szNtDeviceName);
276
277 EngpUnlinkGraphicsDevice(pGraphicsDevice);
278 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice;
279
280 /* Free memory */
283 }
284 else
285 {
286 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice;
287 }
288 }
289
290 /* Unlock list */
292 }
293
294 /* Choose a primary device (if none already exists) */
296 {
297 for (pGraphicsDevice = gpGraphicsDeviceFirst;
298 pGraphicsDevice;
299 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice)
300 {
301 if (!EngpHasVgaDriver(pGraphicsDevice))
302 {
303 pNewPrimaryGraphicsDevice = pGraphicsDevice;
304 break;
305 }
306 }
307 if (!pNewPrimaryGraphicsDevice)
308 pNewPrimaryGraphicsDevice = gpGraphicsDeviceFirst;
309 if (pNewPrimaryGraphicsDevice)
310 {
311 pNewPrimaryGraphicsDevice->StateFlags |= DISPLAY_DEVICE_PRIMARY_DEVICE;
312 gpPrimaryGraphicsDevice = pNewPrimaryGraphicsDevice;
313 }
314 }
315
316 /* Can we link VGA device to primary device? */
321 {
322 /* Yes. Remove VGA device from global list, and attach it to primary device */
323 TRACE("Linking VGA device %S to primary device %S\n", gpVgaGraphicsDevice->szNtDeviceName, gpPrimaryGraphicsDevice->szNtDeviceName);
325 EngpUnlinkGraphicsDevice(gpVgaGraphicsDevice);
328 }
329
330 return STATUS_SUCCESS;
331}
332
333/* Open display settings registry key
334 * Returns NULL in case of error. */
335static HKEY
337 _In_ PGRAPHICS_DEVICE pGraphicsDevice)
338{
339 static const PWCHAR KEY_VIDEO = L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO";
340 HKEY hKey;
341 WCHAR szDeviceKey[256];
342 ULONG cbSize;
344
345 /* Open the device map registry key */
347 if (!NT_SUCCESS(Status))
348 {
349 ERR("Could not open HARDWARE\\DEVICEMAP\\VIDEO registry key: status 0x%08x\n", Status);
350 return NULL;
351 }
352
353 /* Query the registry path */
354 cbSize = sizeof(szDeviceKey);
356 pGraphicsDevice->szNtDeviceName,
357 REG_SZ,
358 szDeviceKey,
359 &cbSize);
360 ZwClose(hKey);
361
362 /* Open the registry key */
363 Status = RegOpenKey(szDeviceKey, &hKey);
364 if (!NT_SUCCESS(Status))
365 {
366 ERR("Could not open registry key '%S': status 0x%08x\n", szDeviceKey, Status);
367 return NULL;
368 }
369
370 return hKey;
371}
372
375 _In_ PGRAPHICS_DEVICE pGraphicsDevice,
376 _Out_ PDEVMODEW pdm)
377{
378 HKEY hKey;
380 RTL_QUERY_REGISTRY_TABLE DisplaySettingsTable[] =
381 {
382#define READ(field, str) \
383 { \
384 NULL, \
385 RTL_QUERY_REGISTRY_DIRECT, \
386 L ##str, \
387 &pdm->field, \
388 REG_NONE, NULL, 0 \
389 },
390 READ(dmBitsPerPel, "DefaultSettings.BitsPerPel")
391 READ(dmPelsWidth, "DefaultSettings.XResolution")
392 READ(dmPelsHeight, "DefaultSettings.YResolution")
393 READ(dmDisplayFlags, "DefaultSettings.Flags")
394 READ(dmDisplayFrequency, "DefaultSettings.VRefresh")
395 READ(dmPanningWidth, "DefaultSettings.XPanning")
396 READ(dmPanningHeight, "DefaultSettings.YPanning")
397 READ(dmDisplayOrientation, "DefaultSettings.Orientation")
398 READ(dmDisplayFixedOutput, "DefaultSettings.FixedOutput")
399 READ(dmPosition.x, "Attach.RelativeX")
400 READ(dmPosition.y, "Attach.RelativeY")
401#undef READ
402 {0}
403 };
404
405 hKey = EngpGetRegistryHandleFromDeviceMap(pGraphicsDevice);
406 if (!hKey)
407 return STATUS_UNSUCCESSFUL;
408
410 (PWSTR)hKey,
411 DisplaySettingsTable,
412 NULL,
413 NULL);
414
415 ZwClose(hKey);
416 return Status;
417}
418
419DWORD
421 _In_ PGRAPHICS_DEVICE pGraphicsDevice)
422{
423 HKEY hKey;
424 DWORD dwAccelerationLevel = 0;
425 RTL_QUERY_REGISTRY_TABLE DisplaySettingsTable[] =
426 {
427 {
428 NULL,
430 L"Acceleration.Level",
431 &dwAccelerationLevel,
432 REG_NONE, NULL, 0
433 },
434 {0}
435 };
436
437 hKey = EngpGetRegistryHandleFromDeviceMap(pGraphicsDevice);
438 if (!hKey)
439 return 0;
440
442 (PWSTR)hKey,
443 DisplaySettingsTable,
444 NULL,
445 NULL);
446 ZwClose(hKey);
447
448 return dwAccelerationLevel;
449}
450
451extern VOID
453
454// PVIDEO_WIN32K_CALLOUT
455VOID
456NTAPI
459{
460/*
461 * IMPORTANT NOTICE!! On Windows XP/2003 this function triggers the creation of
462 * a specific VideoPortCalloutThread() system thread using the same mechanism
463 * as the RIT/desktop/Ghost system threads.
464 */
465
467
468 TRACE("VideoPortCallout(0x%p, 0x%x)\n",
469 CallbackParams, CallbackParams ? CallbackParams->CalloutType : -1);
470
471 if (!CallbackParams)
472 return;
473
474 switch (CallbackParams->CalloutType)
475 {
477 {
478 TRACE("VideoPortCallout: VideoFindAdapterCallout called - Param = %s\n",
479 CallbackParams->Param ? "TRUE" : "FALSE");
480 if (CallbackParams->Param == TRUE)
481 {
482 /* Re-enable the display */
484 }
485 else
486 {
487 /* Disable the display */
488 NOTHING; // Nothing to do for the moment...
489 }
490
491 CallbackParams->Status = STATUS_SUCCESS;
492 break;
493 }
494
504 ERR("VideoPortCallout: CalloutType 0x%x is UNIMPLEMENTED!\n", CallbackParams->CalloutType);
505 CallbackParams->Status = STATUS_NOT_IMPLEMENTED;
506 break;
507
508 default:
509 ERR("VideoPortCallout: Unknown CalloutType 0x%x\n", CallbackParams->CalloutType);
510 CallbackParams->Status = STATUS_UNSUCCESSFUL;
511 break;
512 }
513}
514
516NTAPI
518 _In_ PUNICODE_STRING pustrDeviceName,
519 _In_ PUNICODE_STRING pustrDiplayDrivers,
520 _In_ PUNICODE_STRING pustrDescription)
521{
522 PGRAPHICS_DEVICE pGraphicsDevice;
524 PFILE_OBJECT pFileObject;
526 VIDEO_WIN32K_CALLBACKS Win32kCallbacks;
527 ULONG ulReturn;
528 PWSTR pwsz;
529 ULONG cj;
530
531 TRACE("EngpRegisterGraphicsDevice(%wZ)\n", pustrDeviceName);
532
533 /* Allocate a GRAPHICS_DEVICE structure */
534 pGraphicsDevice = ExAllocatePoolZero(PagedPool,
535 sizeof(GRAPHICS_DEVICE),
537 if (!pGraphicsDevice)
538 {
539 ERR("ExAllocatePoolWithTag failed\n");
540 return NULL;
541 }
542
543 /* Try to open and enable the device */
544 Status = IoGetDeviceObjectPointer(pustrDeviceName,
546 &pFileObject,
548 if (!NT_SUCCESS(Status))
549 {
550 ERR("Could not open device %wZ, 0x%lx\n", pustrDeviceName, Status);
551 ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
552 return NULL;
553 }
554
555 /* Copy the device and file object pointers */
556 pGraphicsDevice->DeviceObject = pDeviceObject;
557 pGraphicsDevice->FileObject = pFileObject;
558
559 /* Initialize and register the device with videoprt for Win32k callbacks */
560 Win32kCallbacks.PhysDisp = pGraphicsDevice;
561 Win32kCallbacks.Callout = VideoPortCallout;
562 // Reset the data being returned prior to the call.
563 Win32kCallbacks.bACPI = FALSE;
564 Win32kCallbacks.pPhysDeviceObject = NULL;
565 Win32kCallbacks.DualviewFlags = 0;
566 Status = (NTSTATUS)EngDeviceIoControl((HANDLE)pDeviceObject,
568 &Win32kCallbacks,
569 sizeof(Win32kCallbacks),
570 &Win32kCallbacks,
571 sizeof(Win32kCallbacks),
572 &ulReturn);
573 if (Status != ERROR_SUCCESS)
574 {
575 ERR("EngDeviceIoControl(0x%p, IOCTL_VIDEO_INIT_WIN32K_CALLBACKS) failed, Status 0x%lx\n",
577 }
578 // TODO: Set flags according to the results.
579 // if (Win32kCallbacks.bACPI)
580 // if (Win32kCallbacks.DualviewFlags & ???)
581 pGraphicsDevice->PhysDeviceHandle = Win32kCallbacks.pPhysDeviceObject;
582
583 /* FIXME: Enumerate children monitor devices for this video adapter
584 *
585 * - Force the adapter to re-enumerate its monitors:
586 * IoSynchronousInvalidateDeviceRelations(pdo, BusRelations)
587 *
588 * - Retrieve all monitor PDOs from VideoPrt:
589 * EngDeviceIoControl(0x%p, IOCTL_VIDEO_ENUM_MONITOR_PDO)
590 *
591 * - Initialize these fields and structures accordingly:
592 * pGraphicsDevice->dwMonCnt
593 * pGraphicsDevice->pvMonDev[0..dwMonCnt-1]
594 */
595
596 /* Copy the device name */
597 RtlStringCbCopyNW(pGraphicsDevice->szNtDeviceName,
598 sizeof(pGraphicsDevice->szNtDeviceName),
599 pustrDeviceName->Buffer,
600 pustrDeviceName->Length);
601
602 /* Create a Win32 device name (FIXME: virtual devices!) */
603 RtlStringCbPrintfW(pGraphicsDevice->szWinDeviceName,
604 sizeof(pGraphicsDevice->szWinDeviceName),
605 L"\\\\.\\DISPLAY%d",
606 (int)giDevNum);
607
608 /* Allocate a buffer for the strings */
609 cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR);
611 if (!pwsz)
612 {
613 ERR("Could not allocate string buffer\n");
614 ASSERT(FALSE); // FIXME
615 ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
616 return NULL;
617 }
618
619 /* Copy the display driver names */
620 pGraphicsDevice->pDiplayDrivers = pwsz;
621 RtlCopyMemory(pGraphicsDevice->pDiplayDrivers,
622 pustrDiplayDrivers->Buffer,
623 pustrDiplayDrivers->Length);
624
625 /* Copy the description */
626 pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR);
627 RtlCopyMemory(pGraphicsDevice->pwszDescription,
628 pustrDescription->Buffer,
629 pustrDescription->Length);
630 pGraphicsDevice->pwszDescription[pustrDescription->Length/sizeof(WCHAR)] = 0;
631
632 /* Lock loader */
634
635 /* Insert the device into the global list */
636 EngpLinkGraphicsDevice(pGraphicsDevice);
637
638 /* Increment the device number */
639 giDevNum++;
640
641 /* Unlock loader */
643
644 /* HACK: already in graphic mode; display wallpaper on this new display */
646 {
647 UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
648 UNICODE_STRING DisplayName;
649 HDC hdc;
650 RtlInitUnicodeString(&DisplayName, pGraphicsDevice->szWinDeviceName);
651 hdc = IntGdiCreateDC(&DriverName, &DisplayName, NULL, NULL, FALSE);
653 }
654
655 return pGraphicsDevice;
656}
657
659NTAPI
661 _In_opt_ PUNICODE_STRING pustrDevice,
662 _In_ ULONG iDevNum)
663{
664 UNICODE_STRING ustrCurrent;
665 PGRAPHICS_DEVICE pGraphicsDevice;
666 ULONG i;
667 TRACE("EngpFindGraphicsDevice('%wZ', %lu)\n",
668 pustrDevice, iDevNum);
669
670 /* Lock list */
672
673 if (pustrDevice && pustrDevice->Buffer)
674 {
675 /* Find specified video adapter by name */
676 for (pGraphicsDevice = gpGraphicsDeviceFirst;
677 pGraphicsDevice;
678 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice)
679 {
680 /* Compare the device name */
681 RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
682 if (RtlEqualUnicodeString(&ustrCurrent, pustrDevice, FALSE))
683 {
684 break;
685 }
686 }
687
688 if (pGraphicsDevice)
689 {
690 /* Validate selected monitor number */
691#if 0
692 if (iDevNum >= pGraphicsDevice->dwMonCnt)
693 pGraphicsDevice = NULL;
694#else
695 /* FIXME: dwMonCnt not initialized, see EngpRegisterGraphicsDevice */
696#endif
697 }
698 }
699 else
700 {
701 /* Select video adapter by device number */
702 for (pGraphicsDevice = gpGraphicsDeviceFirst, i = 0;
703 pGraphicsDevice && i < iDevNum;
704 pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice, i++);
705 }
706
707 /* Unlock list */
709
710 return pGraphicsDevice;
711}
712
713static
716 _In_ PFILE_OBJECT pFileObject,
717 _In_ ULONG ulMajorFunction,
718 _In_reads_(nBufferSize) PVOID lpBuffer,
719 _In_ SIZE_T nBufferSize,
720 _In_ ULONGLONG ullStartOffset,
721 _Out_ PULONG_PTR lpInformation)
722{
725 PIRP pIrp;
728 LARGE_INTEGER liStartOffset;
729
730 /* Get corresponding device object */
732 if (!pDeviceObject)
733 {
735 }
736
737 /* Initialize an event */
739
740 /* Build IRP */
741 liStartOffset.QuadPart = ullStartOffset;
742 pIrp = IoBuildSynchronousFsdRequest(ulMajorFunction,
744 lpBuffer,
745 (ULONG)nBufferSize,
746 &liStartOffset,
747 &Event,
748 &Iosb);
749 if (!pIrp)
750 {
752 }
753
754 /* Call the driver */
756
757 /* Wait if neccessary */
758 if (STATUS_PENDING == Status)
759 {
761 Status = Iosb.Status;
762 }
763
764 /* Return information to the caller about the operation. */
765 *lpInformation = Iosb.Information;
766
767 /* Return NTSTATUS */
768 return Status;
769}
770
771VOID
774 _In_ PFILE_OBJECT pFileObject,
777 _Out_ PSIZE_T lpBytesWritten)
778{
780
781 status = EngpFileIoRequest(pFileObject,
783 lpBuffer,
784 nLength,
785 0,
786 lpBytesWritten);
787 if (!NT_SUCCESS(status))
788 {
789 *lpBytesWritten = 0;
790 }
791}
792
793_Success_(return>=0)
796EngFileIoControl(
797 _In_ PFILE_OBJECT pFileObject,
799 _In_reads_(nInBufferSize) PVOID lpInBuffer,
800 _In_ SIZE_T nInBufferSize,
801 _Out_writes_(nOutBufferSize) PVOID lpOutBuffer,
802 _In_ SIZE_T nOutBufferSize,
803 _Out_ PULONG_PTR lpInformation)
804{
807 PIRP pIrp;
810
811 /* Get corresponding device object */
813 if (!pDeviceObject)
814 {
816 }
817
818 /* Initialize an event */
820
821 /* Build IO control IRP */
824 lpInBuffer,
825 (ULONG)nInBufferSize,
826 lpOutBuffer,
827 (ULONG)nOutBufferSize,
828 FALSE,
829 &Event,
830 &Iosb);
831 if (!pIrp)
832 {
834 }
835
836 /* Call the driver */
838
839 /* Wait if neccessary */
840 if (Status == STATUS_PENDING)
841 {
843 Status = Iosb.Status;
844 }
845
846 /* Return information to the caller about the operation. */
847 *lpInformation = Iosb.Information;
848
849 /* This function returns NTSTATUS */
850 return Status;
851}
852
853/*
854 * @implemented
855 */
856_Success_(return==0)
857DWORD
859EngDeviceIoControl(
860 _In_ HANDLE hDevice,
867{
868 PIRP Irp;
873
874 TRACE("EngDeviceIoControl() called\n");
875
876 if (!hDevice)
877 {
879 }
880
882
883 DeviceObject = (PDEVICE_OBJECT) hDevice;
884
887 lpInBuffer,
889 lpOutBuffer,
891 FALSE,
892 &Event,
893 &Iosb);
894 if (!Irp) return ERROR_NOT_ENOUGH_MEMORY;
895
897
898 if (Status == STATUS_PENDING)
899 {
901 Status = Iosb.Status;
902 }
903
904 TRACE("EngDeviceIoControl(): Returning %X/%X\n", Iosb.Status,
905 Iosb.Information);
906
907 /* Return information to the caller about the operation. */
908 *lpBytesReturned = (DWORD)Iosb.Information;
909
910 /* Convert NT status values to win32 error codes. */
911 switch (Status)
912 {
915
917 return ERROR_MORE_DATA;
918
921
924
927
929 return ERROR_DEV_NOT_EXIST;
930
931 case STATUS_PENDING:
932 return ERROR_IO_PENDING;
933 }
934
935 return Status;
936}
937
938/* 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: precomp.h:57
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
#define _Requires_lock_held_(lock)
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
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:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define APIENTRY
Definition: api.h:79
#define NTSTATUS
Definition: precomp.h:19
#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:4403
#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
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
FORCEINLINE PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
static HDC
Definition: imagelist.c:88
_In_ PNDIS_STRING _In_ PNDIS_STRING _Out_ PDEVICE_OBJECT * pDeviceObject
Definition: ndis.h:4679
#define KernelMode
Definition: asm.h:38
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Success_(c)
Definition: no_sal2.h:84
#define _Out_writes_bytes_opt_(s)
Definition: no_sal2.h:228
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _In_reads_bytes_opt_(s)
Definition: no_sal2.h:224
#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_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 _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#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
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:517
NTSTATUS EngpGetDisplayDriverParameters(_In_ PGRAPHICS_DEVICE pGraphicsDevice, _Out_ PDEVMODEW pdm)
Definition: device.c:374
static HKEY EngpGetRegistryHandleFromDeviceMap(_In_ PGRAPHICS_DEVICE pGraphicsDevice)
Definition: device.c:336
static BOOLEAN EngpHasVgaDriver(_In_ PGRAPHICS_DEVICE pGraphicsDevice)
Definition: device.c:37
VOID UserRefreshDisplay(IN PPDEVOBJ ppdev)
Definition: display.c:177
DWORD EngpGetDisplayDriverAccelerationLevel(_In_ PGRAPHICS_DEVICE pGraphicsDevice)
Definition: device.c:420
VOID NTAPI VideoPortCallout(_In_ PVOID Params)
Definition: device.c:457
PGRAPHICS_DEVICE NTAPI EngpFindGraphicsDevice(_In_opt_ PUNICODE_STRING pustrDevice, _In_ ULONG iDevNum)
Definition: device.c:660
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:715
static PGRAPHICS_DEVICE gpGraphicsDeviceFirst
Definition: device.c:18
NTSTATUS EngpUpdateGraphicsDeviceList(VOID)
Definition: device.c:182
#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:773
static PGRAPHICS_DEVICE gpPrimaryGraphicsDevice
Definition: device.c:15
static HSEMAPHORE ghsemGraphicsDeviceList
Definition: device.c:20
NTSTATUS NTAPI InitDeviceImpl(VOID)
Definition: device.c:26
static PGRAPHICS_DEVICE gpVgaGraphicsDevice
Definition: device.c:16
_In_ DWORD dwIoControlCode
Definition: device.c:798
BOOL NTAPI RegReadDWORD(HKEY hkey, PCWSTR pwszValue, PDWORD pdwData)
Definition: registry.c:149
HDC ScreenDeviceContext
Definition: desktop.c:53
BOOL FASTCALL IntPaintDesktop(HDC hDC)
Definition: desktop.c:1854
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 DISPLAY_DEVICE_PRIMARY_DEVICE
Definition: wingdi.h:1398
#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