4 * Copyright (C) 2002, 2003, 2004 ReactOS Team
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 /* GLOBAL VARIABLES ***********************************************************/
26 PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension
= NULL
;
27 PVIDEO_WIN32K_CALLOUT Win32kCallout
;
29 /* PRIVATE FUNCTIONS **********************************************************/
32 * Reset display to blue screen
36 IntVideoPortResetDisplayParameters(ULONG Columns
, ULONG Rows
)
38 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
40 if (ResetDisplayParametersDeviceExtension
== NULL
)
43 DriverExtension
= ResetDisplayParametersDeviceExtension
->DriverExtension
;
45 if (DriverExtension
->InitializationData
.HwResetHw
!= NULL
)
47 if (DriverExtension
->InitializationData
.HwResetHw(
48 &ResetDisplayParametersDeviceExtension
->MiniPortDeviceExtension
,
51 ResetDisplayParametersDeviceExtension
= NULL
;
56 ResetDisplayParametersDeviceExtension
= NULL
;
62 IntVideoPortAddDevice(
63 IN PDRIVER_OBJECT DriverObject
,
64 IN PDEVICE_OBJECT PhysicalDeviceObject
)
66 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
67 PDEVICE_OBJECT DeviceObject
;
70 /* Get the initialization data we saved in VideoPortInitialize. */
71 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
73 /* Create adapter device object. */
74 Status
= IntVideoPortCreateAdapterDeviceObject(DriverObject
,
78 if (NT_SUCCESS(Status
))
79 VideoPortDeviceNumber
++;
85 * IntVideoPortDispatchOpen
87 * Answer requests for Open calls.
94 IntVideoPortDispatchOpen(
95 IN PDEVICE_OBJECT DeviceObject
,
98 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
99 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
101 TRACE_(VIDEOPRT
, "IntVideoPortDispatchOpen\n");
103 if (CsrssInitialized
== FALSE
)
106 * We know the first open call will be from the CSRSS process
107 * to let us know its handle.
110 INFO_(VIDEOPRT
, "Referencing CSRSS\n");
111 Csrss
= (PKPROCESS
)PsGetCurrentProcess();
112 INFO_(VIDEOPRT
, "Csrss %p\n", Csrss
);
114 IntInitializeVideoAddressSpace();
116 CsrssInitialized
= TRUE
;
119 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
120 DriverExtension
= DeviceExtension
->DriverExtension
;
122 if (DriverExtension
->InitializationData
.HwInitialize(&DeviceExtension
->MiniPortDeviceExtension
))
124 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
125 InterlockedIncrement((PLONG
)&DeviceExtension
->DeviceOpened
);
129 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
132 Irp
->IoStatus
.Information
= FILE_OPENED
;
133 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
135 return STATUS_SUCCESS
;
139 * IntVideoPortDispatchClose
141 * Answer requests for Close calls.
148 IntVideoPortDispatchClose(
149 IN PDEVICE_OBJECT DeviceObject
,
152 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
154 TRACE_(VIDEOPRT
, "IntVideoPortDispatchClose\n");
156 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
157 if ((DeviceExtension
->DeviceOpened
>= 1) &&
158 (InterlockedDecrement((PLONG
)&DeviceExtension
->DeviceOpened
) == 0))
160 ResetDisplayParametersDeviceExtension
= NULL
;
161 InbvNotifyDisplayOwnershipLost(NULL
);
162 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
163 IntVideoPortResetDisplayParameters(80, 50);
166 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
167 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
169 return STATUS_SUCCESS
;
173 IoctlName(ULONG Ioctl
)
177 case IOCTL_VIDEO_ENABLE_VDM
:
178 return "IOCTL_VIDEO_ENABLE_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS)
179 case IOCTL_VIDEO_DISABLE_VDM
:
180 return "IOCTL_VIDEO_DISABLE_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
181 case IOCTL_VIDEO_REGISTER_VDM
:
182 return "IOCTL_VIDEO_REGISTER_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
183 case IOCTL_VIDEO_SET_OUTPUT_DEVICE_POWER_STATE
:
184 return "IOCTL_VIDEO_SET_OUTPUT_DEVICE_POWER_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
185 case IOCTL_VIDEO_GET_OUTPUT_DEVICE_POWER_STATE
:
186 return "IOCTL_VIDEO_GET_OUTPUT_DEVICE_POWER_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
187 case IOCTL_VIDEO_MONITOR_DEVICE
:
188 return "IOCTL_VIDEO_MONITOR_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS)
189 case IOCTL_VIDEO_ENUM_MONITOR_PDO
:
190 return "IOCTL_VIDEO_ENUM_MONITOR_PDO"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS)
191 case IOCTL_VIDEO_INIT_WIN32K_CALLBACKS
:
192 return "IOCTL_VIDEO_INIT_WIN32K_CALLBACKS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS)
193 case IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS
:
194 return "IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS)
195 case IOCTL_VIDEO_IS_VGA_DEVICE
:
196 return "IOCTL_VIDEO_IS_VGA_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS)
197 case IOCTL_VIDEO_USE_DEVICE_IN_SESSION
:
198 return "IOCTL_VIDEO_USE_DEVICE_IN_SESSION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x0a, METHOD_BUFFERED, FILE_ANY_ACCESS)
199 case IOCTL_VIDEO_PREPARE_FOR_EARECOVERY
:
200 return "IOCTL_VIDEO_PREPARE_FOR_EARECOVERY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x0b, METHOD_BUFFERED, FILE_ANY_ACCESS)
201 case IOCTL_VIDEO_SAVE_HARDWARE_STATE
:
202 return "IOCTL_VIDEO_SAVE_HARDWARE_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x80, METHOD_BUFFERED, FILE_ANY_ACCESS)
203 case IOCTL_VIDEO_RESTORE_HARDWARE_STATE
:
204 return "IOCTL_VIDEO_RESTORE_HARDWARE_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x81, METHOD_BUFFERED, FILE_ANY_ACCESS)
205 case IOCTL_VIDEO_QUERY_AVAIL_MODES
:
206 return "IOCTL_VIDEO_QUERY_AVAIL_MODES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x100, METHOD_BUFFERED, FILE_ANY_ACCESS)
207 case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
:
208 return "IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x101, METHOD_BUFFERED, FILE_ANY_ACCESS)
209 case IOCTL_VIDEO_QUERY_CURRENT_MODE
:
210 return "IOCTL_VIDEO_QUERY_CURRENT_MODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x102, METHOD_BUFFERED, FILE_ANY_ACCESS)
211 case IOCTL_VIDEO_SET_CURRENT_MODE
:
212 return "IOCTL_VIDEO_SET_CURRENT_MODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x103, METHOD_BUFFERED, FILE_ANY_ACCESS)
213 case IOCTL_VIDEO_RESET_DEVICE
:
214 return "IOCTL_VIDEO_RESET_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x104, METHOD_BUFFERED, FILE_ANY_ACCESS)
215 case IOCTL_VIDEO_LOAD_AND_SET_FONT
:
216 return "IOCTL_VIDEO_LOAD_AND_SET_FONT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x105, METHOD_BUFFERED, FILE_ANY_ACCESS)
217 case IOCTL_VIDEO_SET_PALETTE_REGISTERS
:
218 return "IOCTL_VIDEO_SET_PALETTE_REGISTERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x106, METHOD_BUFFERED, FILE_ANY_ACCESS)
219 case IOCTL_VIDEO_SET_COLOR_REGISTERS
:
220 return "IOCTL_VIDEO_SET_COLOR_REGISTERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x107, METHOD_BUFFERED, FILE_ANY_ACCESS)
221 case IOCTL_VIDEO_ENABLE_CURSOR
:
222 return "IOCTL_VIDEO_ENABLE_CURSOR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x108, METHOD_BUFFERED, FILE_ANY_ACCESS)
223 case IOCTL_VIDEO_DISABLE_CURSOR
:
224 return "IOCTL_VIDEO_DISABLE_CURSOR"; // CTL_CODE (FILE_DEVICE_VIDEO, 0x109, METHOD_BUFFERED, FILE_ANY_ACCESS)
225 case IOCTL_VIDEO_SET_CURSOR_ATTR
:
226 return "IOCTL_VIDEO_SET_CURSOR_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10a, METHOD_BUFFERED, FILE_ANY_ACCESS)
227 case IOCTL_VIDEO_QUERY_CURSOR_ATTR
:
228 return "IOCTL_VIDEO_QUERY_CURSOR_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10b, METHOD_BUFFERED, FILE_ANY_ACCESS)
229 case IOCTL_VIDEO_SET_CURSOR_POSITION
:
230 return "IOCTL_VIDEO_SET_CURSOR_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10c, METHOD_BUFFERED, FILE_ANY_ACCESS)
231 case IOCTL_VIDEO_QUERY_CURSOR_POSITION
:
232 return "IOCTL_VIDEO_QUERY_CURSOR_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10d, METHOD_BUFFERED, FILE_ANY_ACCESS)
233 case IOCTL_VIDEO_ENABLE_POINTER
:
234 return "IOCTL_VIDEO_ENABLE_POINTER"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10e, METHOD_BUFFERED, FILE_ANY_ACCESS)
235 case IOCTL_VIDEO_DISABLE_POINTER
:
236 return "IOCTL_VIDEO_DISABLE_POINTER"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10f, METHOD_BUFFERED, FILE_ANY_ACCESS)
237 case IOCTL_VIDEO_SET_POINTER_ATTR
:
238 return "IOCTL_VIDEO_SET_POINTER_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x110, METHOD_BUFFERED, FILE_ANY_ACCESS)
239 case IOCTL_VIDEO_QUERY_POINTER_ATTR
:
240 return "IOCTL_VIDEO_QUERY_POINTER_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x111, METHOD_BUFFERED, FILE_ANY_ACCESS)
241 case IOCTL_VIDEO_SET_POINTER_POSITION
:
242 return "IOCTL_VIDEO_SET_POINTER_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x112, METHOD_BUFFERED, FILE_ANY_ACCESS)
243 case IOCTL_VIDEO_QUERY_POINTER_POSITION
:
244 return "IOCTL_VIDEO_QUERY_POINTER_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x113, METHOD_BUFFERED, FILE_ANY_ACCESS)
245 case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES
:
246 return "IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x114, METHOD_BUFFERED, FILE_ANY_ACCESS)
247 case IOCTL_VIDEO_GET_BANK_SELECT_CODE
:
248 return "IOCTL_VIDEO_GET_BANK_SELECT_CODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x115, METHOD_BUFFERED, FILE_ANY_ACCESS)
249 case IOCTL_VIDEO_MAP_VIDEO_MEMORY
:
250 return "IOCTL_VIDEO_MAP_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x116, METHOD_BUFFERED, FILE_ANY_ACCESS)
251 case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
:
252 return "IOCTL_VIDEO_UNMAP_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x117, METHOD_BUFFERED, FILE_ANY_ACCESS)
253 case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES
:
254 return "IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x118, METHOD_BUFFERED, FILE_ANY_ACCESS)
255 case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES
:
256 return "IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x119, METHOD_BUFFERED, FILE_ANY_ACCESS)
257 case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES
:
258 return "IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11a, METHOD_BUFFERED, FILE_ANY_ACCESS)
259 case IOCTL_VIDEO_SET_POWER_MANAGEMENT
:
260 return "IOCTL_VIDEO_SET_POWER_MANAGEMENT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11b, METHOD_BUFFERED, FILE_ANY_ACCESS)
261 case IOCTL_VIDEO_GET_POWER_MANAGEMENT
:
262 return "IOCTL_VIDEO_GET_POWER_MANAGEMENT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11c, METHOD_BUFFERED, FILE_ANY_ACCESS)
263 case IOCTL_VIDEO_SHARE_VIDEO_MEMORY
:
264 return "IOCTL_VIDEO_SHARE_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11d, METHOD_BUFFERED, FILE_ANY_ACCESS)
265 case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY
:
266 return "IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11e, METHOD_BUFFERED, FILE_ANY_ACCESS)
267 case IOCTL_VIDEO_SET_COLOR_LUT_DATA
:
268 return "IOCTL_VIDEO_SET_COLOR_LUT_DATA"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11f, METHOD_BUFFERED, FILE_ANY_ACCESS)
269 case IOCTL_VIDEO_GET_CHILD_STATE
:
270 return "IOCTL_VIDEO_GET_CHILD_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x120, METHOD_BUFFERED, FILE_ANY_ACCESS)
271 case IOCTL_VIDEO_VALIDATE_CHILD_STATE_CONFIGURATION
:
272 return "IOCTL_VIDEO_VALIDATE_CHILD_STATE_CONFIGURATION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x121, METHOD_BUFFERED, FILE_ANY_ACCESS)
273 case IOCTL_VIDEO_SET_CHILD_STATE_CONFIGURATION
:
274 return "IOCTL_VIDEO_SET_CHILD_STATE_CONFIGURATION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x122, METHOD_BUFFERED, FILE_ANY_ACCESS)
275 case IOCTL_VIDEO_SWITCH_DUALVIEW
:
276 return "IOCTL_VIDEO_SWITCH_DUALVIEW"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x123, METHOD_BUFFERED, FILE_ANY_ACCESS)
277 case IOCTL_VIDEO_SET_BANK_POSITION
:
278 return "IOCTL_VIDEO_SET_BANK_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x124, METHOD_BUFFERED, FILE_ANY_ACCESS)
279 case IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS
:
280 return "IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x125, METHOD_BUFFERED, FILE_ANY_ACCESS)
281 case IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS
:
282 return "IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x126, METHOD_BUFFERED, FILE_ANY_ACCESS)
283 case IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS
:
284 return "IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x127, METHOD_BUFFERED, FILE_ANY_ACCESS)
287 return "<unknown ioctl code";
292 VideoPortUseDeviceInSesion(
293 _Inout_ PDEVICE_OBJECT DeviceObject
,
294 _Inout_ PVIDEO_DEVICE_SESSION_STATUS SessionState
,
295 _In_ ULONG BufferLength
,
296 _Out_ PULONG_PTR Information
)
298 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
300 /* Check buffer size */
301 *Information
= sizeof(VIDEO_DEVICE_SESSION_STATUS
);
302 if (BufferLength
< sizeof(VIDEO_DEVICE_SESSION_STATUS
))
304 ERR_(VIDEOPRT
, "Buffer too small for VIDEO_DEVICE_SESSION_STATUS: %lx\n",
306 return STATUS_BUFFER_TOO_SMALL
;
309 /* Get the device extension */
310 DeviceExtension
= DeviceObject
->DeviceExtension
;
312 /* Shall we enable the session? */
313 if (SessionState
->bEnable
)
315 /* Check if we have no session yet */
316 if (DeviceExtension
->SessionId
== -1)
318 /* Use this session and return success */
319 DeviceExtension
->SessionId
= PsGetCurrentProcessSessionId();
320 SessionState
->bSuccess
= TRUE
;
324 ERR_(VIDEOPRT
, "Requested to set session, but session is already set to: 0x%lx",
325 DeviceExtension
->SessionId
);
326 SessionState
->bSuccess
= FALSE
;
331 /* Check if we belong to the current session */
332 if (DeviceExtension
->SessionId
== PsGetCurrentProcessSessionId())
334 /* Reset the session and return success */
335 DeviceExtension
->SessionId
= -1;
336 SessionState
->bSuccess
= TRUE
;
340 ERR_(VIDEOPRT
, "Requested to reset session, but session is not set\n");
341 SessionState
->bSuccess
= FALSE
;
345 return STATUS_SUCCESS
;
350 VideoPortInitWin32kCallbacks(
351 _In_ PDEVICE_OBJECT DeviceObject
,
352 _Inout_ PVIDEO_WIN32K_CALLBACKS Win32kCallbacks
,
353 _In_ ULONG BufferLength
,
354 _Out_ PULONG_PTR Information
)
356 *Information
= sizeof(VIDEO_WIN32K_CALLBACKS
);
357 if (BufferLength
< sizeof(VIDEO_WIN32K_CALLBACKS
))
359 ERR_(VIDEOPRT
, "Buffer too small for VIDEO_WIN32K_CALLBACKS: %lx\n",
361 return STATUS_BUFFER_TOO_SMALL
;
364 /* Save the callout function globally */
365 Win32kCallout
= Win32kCallbacks
->Callout
;
367 /* Return reasonable values to win32k */
368 Win32kCallbacks
->bACPI
= FALSE
;
369 Win32kCallbacks
->pPhysDeviceObject
= DeviceObject
;
370 Win32kCallbacks
->DualviewFlags
= 0;
372 return STATUS_SUCCESS
;
377 VideoPortForwardDeviceControl(
378 IN PDEVICE_OBJECT DeviceObject
,
381 PIO_STACK_LOCATION IrpStack
;
382 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
383 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
384 VIDEO_REQUEST_PACKET vrp
;
386 TRACE_(VIDEOPRT
, "VideoPortForwardDeviceControl\n");
388 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
389 DeviceExtension
= DeviceObject
->DeviceExtension
;
390 DriverExtension
= DeviceExtension
->DriverExtension
;
392 /* Translate the IRP to a VRP */
393 vrp
.StatusBlock
= (PSTATUS_BLOCK
)&Irp
->IoStatus
;
394 vrp
.IoControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
396 INFO_(VIDEOPRT
, "- IoControlCode: %x\n", vrp
.IoControlCode
);
398 /* We're assuming METHOD_BUFFERED */
399 vrp
.InputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
400 vrp
.InputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
401 vrp
.OutputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
402 vrp
.OutputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
404 /* Call the Miniport Driver with the VRP */
405 DriverExtension
->InitializationData
.HwStartIO(&DeviceExtension
->MiniPortDeviceExtension
,
408 INFO_(VIDEOPRT
, "- Returned status: %x\n", Irp
->IoStatus
.Status
);
410 /* Map from win32 error codes to NT status values. */
411 switch (Irp
->IoStatus
.Status
)
414 return STATUS_SUCCESS
;
415 case ERROR_NOT_ENOUGH_MEMORY
:
416 return STATUS_INSUFFICIENT_RESOURCES
;
417 case ERROR_MORE_DATA
:
418 return STATUS_BUFFER_OVERFLOW
;
419 case ERROR_INVALID_FUNCTION
:
420 return STATUS_NOT_IMPLEMENTED
;
421 case ERROR_INVALID_PARAMETER
:
422 return STATUS_INVALID_PARAMETER
;
423 case ERROR_INSUFFICIENT_BUFFER
:
424 return STATUS_BUFFER_TOO_SMALL
;
425 case ERROR_DEV_NOT_EXIST
:
426 return STATUS_DEVICE_DOES_NOT_EXIST
;
427 case ERROR_IO_PENDING
:
428 return STATUS_PENDING
;
430 return STATUS_UNSUCCESSFUL
;
435 * IntVideoPortDispatchDeviceControl
437 * Answer requests for device control calls.
444 IntVideoPortDispatchDeviceControl(
445 IN PDEVICE_OBJECT DeviceObject
,
448 PIO_STACK_LOCATION IrpStack
;
452 TRACE_(VIDEOPRT
, "IntVideoPortDispatchDeviceControl\n");
454 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
456 IoControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
458 INFO_(VIDEOPRT
, "- IoControlCode: %x: %s\n", IoControlCode
, IoctlName(IoControlCode
));
460 switch(IoControlCode
)
462 case IOCTL_VIDEO_INIT_WIN32K_CALLBACKS
:
463 INFO_(VIDEOPRT
, "- IOCTL_VIDEO_INIT_WIN32K_CALLBACKS\n");
464 Status
= VideoPortInitWin32kCallbacks(DeviceObject
,
465 Irp
->AssociatedIrp
.SystemBuffer
,
466 IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
,
467 &Irp
->IoStatus
.Information
);
470 case IOCTL_VIDEO_USE_DEVICE_IN_SESSION
:
471 INFO_(VIDEOPRT
, "- IOCTL_VIDEO_USE_DEVICE_IN_SESSION\n");
472 Status
= VideoPortUseDeviceInSesion(DeviceObject
,
473 Irp
->AssociatedIrp
.SystemBuffer
,
474 IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
,
475 &Irp
->IoStatus
.Information
);
479 /* Forward to the Miniport Driver */
480 Status
= VideoPortForwardDeviceControl(DeviceObject
, Irp
);
484 INFO_(VIDEOPRT
, "- Returned status: %x\n", Irp
->IoStatus
.Status
);
486 Irp
->IoStatus
.Status
= Status
;
487 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
495 * This is a bit of a hack. We want to take ownership of the display as late
496 * as possible, just before the switch to graphics mode. Win32k knows when
497 * this happens, we don't. So we need Win32k to inform us. This could be done
498 * using an IOCTL, but there's no way of knowing which IOCTL codes are unused
499 * in the communication between GDI driver and miniport driver. So we use
500 * IRP_MJ_WRITE as the signal that win32k is ready to switch to graphics mode,
501 * since we know for certain that there is no read/write activity going on
502 * between GDI and miniport drivers.
503 * We don't actually need the data that is passed, we just trigger on the fact
504 * that an IRP_MJ_WRITE was sent.
511 IntVideoPortDispatchWrite(
512 IN PDEVICE_OBJECT DeviceObject
,
515 PIO_STACK_LOCATION piosStack
= IoGetCurrentIrpStackLocation(Irp
);
516 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
519 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
522 * Storing the device extension pointer in a static variable is an
523 * ugly hack. Unfortunately, we need it in IntVideoPortResetDisplayParameters
524 * and InbvNotifyDisplayOwnershipLost doesn't allow us to pass a userdata
525 * parameter. On the bright side, the DISPLAY device is opened
526 * exclusively, so there can be only one device extension active at
529 * FIXME: We should process all opened display devices in
530 * IntVideoPortResetDisplayParameters.
532 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
533 InbvNotifyDisplayOwnershipLost(IntVideoPortResetDisplayParameters
);
535 nErrCode
= STATUS_SUCCESS
;
536 Irp
->IoStatus
.Information
= piosStack
->Parameters
.Write
.Length
;
537 Irp
->IoStatus
.Status
= nErrCode
;
538 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
545 IntVideoPortPnPStartDevice(
546 IN PDEVICE_OBJECT DeviceObject
,
549 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
550 PDRIVER_OBJECT DriverObject
;
551 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
552 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
553 PCM_RESOURCE_LIST AllocatedResources
;
555 /* Get the initialization data we saved in VideoPortInitialize.*/
556 DriverObject
= DeviceObject
->DriverObject
;
557 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
558 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
560 /* Store some resources in the DeviceExtension. */
561 AllocatedResources
= Stack
->Parameters
.StartDevice
.AllocatedResources
;
562 if (AllocatedResources
!= NULL
)
564 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
565 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
567 ULONG ResourceListSize
;
569 /* Save the resource list */
570 ResourceCount
= AllocatedResources
->List
[0].PartialResourceList
.Count
;
572 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
573 PartialDescriptors
[ResourceCount
]);
574 DeviceExtension
->AllocatedResources
= ExAllocatePool(PagedPool
, ResourceListSize
);
575 if (DeviceExtension
->AllocatedResources
== NULL
)
577 return STATUS_INSUFFICIENT_RESOURCES
;
580 RtlCopyMemory(DeviceExtension
->AllocatedResources
,
584 /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
585 for (FullList
= AllocatedResources
->List
;
586 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
589 INFO_(VIDEOPRT
, "InterfaceType %u BusNumber List %u Device BusNumber %u Version %u Revision %u\n",
590 FullList
->InterfaceType
, FullList
->BusNumber
, DeviceExtension
->SystemIoBusNumber
, FullList
->PartialResourceList
.Version
, FullList
->PartialResourceList
.Revision
);
592 /* FIXME: Is this ASSERT ok for resources from the PNP manager? */
593 ASSERT(FullList
->InterfaceType
== PCIBus
);
594 ASSERT(FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
);
595 ASSERT(1 == FullList
->PartialResourceList
.Version
);
596 ASSERT(1 == FullList
->PartialResourceList
.Revision
);
597 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
598 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
601 if (Descriptor
->Type
== CmResourceTypeInterrupt
)
603 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
604 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
605 if (Descriptor
->ShareDisposition
== CmResourceShareShared
)
606 DeviceExtension
->InterruptShared
= TRUE
;
608 DeviceExtension
->InterruptShared
= FALSE
;
614 INFO_(VIDEOPRT
, "Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
615 DeviceExtension
->InterruptLevel
,
616 DeviceExtension
->InterruptVector
);
618 /* Create adapter device object. */
619 return IntVideoPortFindAdapter(DriverObject
,
627 IntVideoPortForwardIrpAndWaitCompletionRoutine(
632 PKEVENT Event
= Context
;
634 if (Irp
->PendingReturned
)
635 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
637 return STATUS_MORE_PROCESSING_REQUIRED
;
642 IntVideoPortQueryBusRelations(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
644 PDEVICE_RELATIONS DeviceRelations
;
645 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
646 PVIDEO_PORT_CHILD_EXTENSION ChildExtension
;
648 PLIST_ENTRY CurrentEntry
;
650 /* Count the children */
652 CurrentEntry
= DeviceExtension
->ChildDeviceList
.Flink
;
653 while (CurrentEntry
!= &DeviceExtension
->ChildDeviceList
)
656 CurrentEntry
= CurrentEntry
->Flink
;
660 return Irp
->IoStatus
.Status
;
662 DeviceRelations
= ExAllocatePool(PagedPool
,
663 sizeof(DEVICE_RELATIONS
) + ((i
- 1) * sizeof(PVOID
)));
664 if (!DeviceRelations
) return STATUS_NO_MEMORY
;
666 DeviceRelations
->Count
= i
;
668 /* Add the children */
670 CurrentEntry
= DeviceExtension
->ChildDeviceList
.Flink
;
671 while (CurrentEntry
!= &DeviceExtension
->ChildDeviceList
)
673 ChildExtension
= CONTAINING_RECORD(CurrentEntry
, VIDEO_PORT_CHILD_EXTENSION
, ListEntry
);
675 ObReferenceObject(ChildExtension
->PhysicalDeviceObject
);
676 DeviceRelations
->Objects
[i
] = ChildExtension
->PhysicalDeviceObject
;
679 CurrentEntry
= CurrentEntry
->Flink
;
682 INFO_(VIDEOPRT
, "Reported %d PDOs\n", i
);
683 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
685 return STATUS_SUCCESS
;
690 IntVideoPortForwardIrpAndWait(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
694 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
=
695 (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
697 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
698 IoCopyCurrentIrpStackLocationToNext(Irp
);
699 IoSetCompletionRoutine(Irp
,
700 IntVideoPortForwardIrpAndWaitCompletionRoutine
,
706 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
707 if (Status
== STATUS_PENDING
)
709 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
710 Status
= Irp
->IoStatus
.Status
;
718 IntVideoPortDispatchFdoPnp(
719 IN PDEVICE_OBJECT DeviceObject
,
722 PIO_STACK_LOCATION IrpSp
;
724 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
726 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
728 switch (IrpSp
->MinorFunction
)
730 case IRP_MN_START_DEVICE
:
731 Status
= IntVideoPortForwardIrpAndWait(DeviceObject
, Irp
);
732 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
733 Status
= IntVideoPortPnPStartDevice(DeviceObject
, Irp
);
734 Irp
->IoStatus
.Status
= Status
;
735 Irp
->IoStatus
.Information
= 0;
736 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
739 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
740 Status
= IntVideoPortForwardIrpAndWait(DeviceObject
, Irp
);
741 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
742 Status
= IntVideoPortFilterResourceRequirements(DeviceObject
, Irp
);
743 Irp
->IoStatus
.Status
= Status
;
744 Irp
->IoStatus
.Information
= 0;
745 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
748 case IRP_MN_QUERY_DEVICE_RELATIONS
:
749 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= BusRelations
)
751 IoSkipCurrentIrpStackLocation(Irp
);
752 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
756 Status
= IntVideoPortQueryBusRelations(DeviceObject
, Irp
);
757 Irp
->IoStatus
.Status
= Status
;
758 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
762 case IRP_MN_REMOVE_DEVICE
:
763 case IRP_MN_QUERY_REMOVE_DEVICE
:
764 case IRP_MN_CANCEL_REMOVE_DEVICE
:
765 case IRP_MN_SURPRISE_REMOVAL
:
767 case IRP_MN_STOP_DEVICE
:
768 Status
= IntVideoPortForwardIrpAndWait(DeviceObject
, Irp
);
769 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
770 Status
= STATUS_SUCCESS
;
771 Irp
->IoStatus
.Status
= Status
;
772 Irp
->IoStatus
.Information
= 0;
773 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
776 case IRP_MN_QUERY_STOP_DEVICE
:
777 case IRP_MN_CANCEL_STOP_DEVICE
:
778 Status
= STATUS_SUCCESS
;
779 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
780 Irp
->IoStatus
.Information
= 0;
781 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
785 Status
= Irp
->IoStatus
.Status
;
786 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
795 IntVideoPortDispatchPnp(
796 IN PDEVICE_OBJECT DeviceObject
,
799 PVIDEO_PORT_COMMON_EXTENSION CommonExtension
= DeviceObject
->DeviceExtension
;
801 if (CommonExtension
->Fdo
)
802 return IntVideoPortDispatchFdoPnp(DeviceObject
, Irp
);
804 return IntVideoPortDispatchPdoPnp(DeviceObject
, Irp
);
809 IntVideoPortDispatchCleanup(
810 IN PDEVICE_OBJECT DeviceObject
,
813 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
815 DeviceExtension
= DeviceObject
->DeviceExtension
;
816 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
818 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
819 Irp
->IoStatus
.Information
= 0;
820 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
822 return STATUS_SUCCESS
;
827 IntVideoPortDispatchPower(
828 IN PDEVICE_OBJECT DeviceObject
,
831 return STATUS_NOT_IMPLEMENTED
;
836 IntVideoPortDispatchSystemControl(
837 IN PDEVICE_OBJECT DeviceObject
,
840 return STATUS_NOT_IMPLEMENTED
;
845 IntVideoPortUnload(PDRIVER_OBJECT DriverObject
)