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 #include <ndk/inbvfuncs.h>
25 #include <ndk/psfuncs.h>
30 /* GLOBAL VARIABLES ***********************************************************/
32 PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension
= NULL
;
33 PVIDEO_WIN32K_CALLOUT Win32kCallout
;
35 /* PRIVATE FUNCTIONS **********************************************************/
38 * Reset display to blue screen
42 IntVideoPortResetDisplayParameters(ULONG Columns
, ULONG Rows
)
44 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
46 if (ResetDisplayParametersDeviceExtension
== NULL
)
49 DriverExtension
= ResetDisplayParametersDeviceExtension
->DriverExtension
;
51 if (DriverExtension
->InitializationData
.HwResetHw
!= NULL
)
53 if (DriverExtension
->InitializationData
.HwResetHw(
54 &ResetDisplayParametersDeviceExtension
->MiniPortDeviceExtension
,
57 ResetDisplayParametersDeviceExtension
= NULL
;
62 ResetDisplayParametersDeviceExtension
= NULL
;
68 IntVideoPortAddDevice(
69 IN PDRIVER_OBJECT DriverObject
,
70 IN PDEVICE_OBJECT PhysicalDeviceObject
)
72 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
73 PDEVICE_OBJECT DeviceObject
;
76 /* Get the initialization data we saved in VideoPortInitialize. */
77 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
79 /* Create adapter device object. */
80 Status
= IntVideoPortCreateAdapterDeviceObject(DriverObject
,
84 if (NT_SUCCESS(Status
))
85 VideoPortDeviceNumber
++;
91 * IntVideoPortDispatchOpen
93 * Answer requests for Open calls.
100 IntVideoPortDispatchOpen(
101 IN PDEVICE_OBJECT DeviceObject
,
104 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
105 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
108 TRACE_(VIDEOPRT
, "IntVideoPortDispatchOpen\n");
110 if (CsrssInitialized
== FALSE
)
113 * We know the first open call will be from the CSRSS process
114 * to let us know its handle.
117 INFO_(VIDEOPRT
, "Referencing CSRSS\n");
118 Csrss
= (PKPROCESS
)PsGetCurrentProcess();
119 INFO_(VIDEOPRT
, "Csrss %p\n", Csrss
);
121 Status
= IntInitializeVideoAddressSpace();
122 if (!NT_SUCCESS(Status
))
124 ERR_(VIDEOPRT
, "IntInitializeVideoAddressSpace() failed: 0x%lx\n", Status
);
128 CsrssInitialized
= TRUE
;
131 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
132 DriverExtension
= DeviceExtension
->DriverExtension
;
134 if (DriverExtension
->InitializationData
.HwInitialize(&DeviceExtension
->MiniPortDeviceExtension
))
136 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
137 InterlockedIncrement((PLONG
)&DeviceExtension
->DeviceOpened
);
141 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
144 Irp
->IoStatus
.Information
= FILE_OPENED
;
145 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
147 return STATUS_SUCCESS
;
151 * IntVideoPortDispatchClose
153 * Answer requests for Close calls.
160 IntVideoPortDispatchClose(
161 IN PDEVICE_OBJECT DeviceObject
,
164 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
166 TRACE_(VIDEOPRT
, "IntVideoPortDispatchClose\n");
168 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
169 if ((DeviceExtension
->DeviceOpened
>= 1) &&
170 (InterlockedDecrement((PLONG
)&DeviceExtension
->DeviceOpened
) == 0))
172 ResetDisplayParametersDeviceExtension
= NULL
;
173 InbvNotifyDisplayOwnershipLost(NULL
);
174 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
175 IntVideoPortResetDisplayParameters(80, 50);
178 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
179 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
181 return STATUS_SUCCESS
;
185 IoctlName(ULONG Ioctl
)
189 case IOCTL_VIDEO_ENABLE_VDM
:
190 return "IOCTL_VIDEO_ENABLE_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS)
191 case IOCTL_VIDEO_DISABLE_VDM
:
192 return "IOCTL_VIDEO_DISABLE_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
193 case IOCTL_VIDEO_REGISTER_VDM
:
194 return "IOCTL_VIDEO_REGISTER_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
195 case IOCTL_VIDEO_SET_OUTPUT_DEVICE_POWER_STATE
:
196 return "IOCTL_VIDEO_SET_OUTPUT_DEVICE_POWER_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
197 case IOCTL_VIDEO_GET_OUTPUT_DEVICE_POWER_STATE
:
198 return "IOCTL_VIDEO_GET_OUTPUT_DEVICE_POWER_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
199 case IOCTL_VIDEO_MONITOR_DEVICE
:
200 return "IOCTL_VIDEO_MONITOR_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS)
201 case IOCTL_VIDEO_ENUM_MONITOR_PDO
:
202 return "IOCTL_VIDEO_ENUM_MONITOR_PDO"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS)
203 case IOCTL_VIDEO_INIT_WIN32K_CALLBACKS
:
204 return "IOCTL_VIDEO_INIT_WIN32K_CALLBACKS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS)
205 case IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS
:
206 return "IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS)
207 case IOCTL_VIDEO_IS_VGA_DEVICE
:
208 return "IOCTL_VIDEO_IS_VGA_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS)
209 case IOCTL_VIDEO_USE_DEVICE_IN_SESSION
:
210 return "IOCTL_VIDEO_USE_DEVICE_IN_SESSION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x0a, METHOD_BUFFERED, FILE_ANY_ACCESS)
211 case IOCTL_VIDEO_PREPARE_FOR_EARECOVERY
:
212 return "IOCTL_VIDEO_PREPARE_FOR_EARECOVERY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x0b, METHOD_BUFFERED, FILE_ANY_ACCESS)
213 case IOCTL_VIDEO_SAVE_HARDWARE_STATE
:
214 return "IOCTL_VIDEO_SAVE_HARDWARE_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x80, METHOD_BUFFERED, FILE_ANY_ACCESS)
215 case IOCTL_VIDEO_RESTORE_HARDWARE_STATE
:
216 return "IOCTL_VIDEO_RESTORE_HARDWARE_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x81, METHOD_BUFFERED, FILE_ANY_ACCESS)
217 case IOCTL_VIDEO_QUERY_AVAIL_MODES
:
218 return "IOCTL_VIDEO_QUERY_AVAIL_MODES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x100, METHOD_BUFFERED, FILE_ANY_ACCESS)
219 case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
:
220 return "IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x101, METHOD_BUFFERED, FILE_ANY_ACCESS)
221 case IOCTL_VIDEO_QUERY_CURRENT_MODE
:
222 return "IOCTL_VIDEO_QUERY_CURRENT_MODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x102, METHOD_BUFFERED, FILE_ANY_ACCESS)
223 case IOCTL_VIDEO_SET_CURRENT_MODE
:
224 return "IOCTL_VIDEO_SET_CURRENT_MODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x103, METHOD_BUFFERED, FILE_ANY_ACCESS)
225 case IOCTL_VIDEO_RESET_DEVICE
:
226 return "IOCTL_VIDEO_RESET_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x104, METHOD_BUFFERED, FILE_ANY_ACCESS)
227 case IOCTL_VIDEO_LOAD_AND_SET_FONT
:
228 return "IOCTL_VIDEO_LOAD_AND_SET_FONT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x105, METHOD_BUFFERED, FILE_ANY_ACCESS)
229 case IOCTL_VIDEO_SET_PALETTE_REGISTERS
:
230 return "IOCTL_VIDEO_SET_PALETTE_REGISTERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x106, METHOD_BUFFERED, FILE_ANY_ACCESS)
231 case IOCTL_VIDEO_SET_COLOR_REGISTERS
:
232 return "IOCTL_VIDEO_SET_COLOR_REGISTERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x107, METHOD_BUFFERED, FILE_ANY_ACCESS)
233 case IOCTL_VIDEO_ENABLE_CURSOR
:
234 return "IOCTL_VIDEO_ENABLE_CURSOR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x108, METHOD_BUFFERED, FILE_ANY_ACCESS)
235 case IOCTL_VIDEO_DISABLE_CURSOR
:
236 return "IOCTL_VIDEO_DISABLE_CURSOR"; // CTL_CODE (FILE_DEVICE_VIDEO, 0x109, METHOD_BUFFERED, FILE_ANY_ACCESS)
237 case IOCTL_VIDEO_SET_CURSOR_ATTR
:
238 return "IOCTL_VIDEO_SET_CURSOR_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10a, METHOD_BUFFERED, FILE_ANY_ACCESS)
239 case IOCTL_VIDEO_QUERY_CURSOR_ATTR
:
240 return "IOCTL_VIDEO_QUERY_CURSOR_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10b, METHOD_BUFFERED, FILE_ANY_ACCESS)
241 case IOCTL_VIDEO_SET_CURSOR_POSITION
:
242 return "IOCTL_VIDEO_SET_CURSOR_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10c, METHOD_BUFFERED, FILE_ANY_ACCESS)
243 case IOCTL_VIDEO_QUERY_CURSOR_POSITION
:
244 return "IOCTL_VIDEO_QUERY_CURSOR_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10d, METHOD_BUFFERED, FILE_ANY_ACCESS)
245 case IOCTL_VIDEO_ENABLE_POINTER
:
246 return "IOCTL_VIDEO_ENABLE_POINTER"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10e, METHOD_BUFFERED, FILE_ANY_ACCESS)
247 case IOCTL_VIDEO_DISABLE_POINTER
:
248 return "IOCTL_VIDEO_DISABLE_POINTER"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10f, METHOD_BUFFERED, FILE_ANY_ACCESS)
249 case IOCTL_VIDEO_SET_POINTER_ATTR
:
250 return "IOCTL_VIDEO_SET_POINTER_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x110, METHOD_BUFFERED, FILE_ANY_ACCESS)
251 case IOCTL_VIDEO_QUERY_POINTER_ATTR
:
252 return "IOCTL_VIDEO_QUERY_POINTER_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x111, METHOD_BUFFERED, FILE_ANY_ACCESS)
253 case IOCTL_VIDEO_SET_POINTER_POSITION
:
254 return "IOCTL_VIDEO_SET_POINTER_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x112, METHOD_BUFFERED, FILE_ANY_ACCESS)
255 case IOCTL_VIDEO_QUERY_POINTER_POSITION
:
256 return "IOCTL_VIDEO_QUERY_POINTER_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x113, METHOD_BUFFERED, FILE_ANY_ACCESS)
257 case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES
:
258 return "IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x114, METHOD_BUFFERED, FILE_ANY_ACCESS)
259 case IOCTL_VIDEO_GET_BANK_SELECT_CODE
:
260 return "IOCTL_VIDEO_GET_BANK_SELECT_CODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x115, METHOD_BUFFERED, FILE_ANY_ACCESS)
261 case IOCTL_VIDEO_MAP_VIDEO_MEMORY
:
262 return "IOCTL_VIDEO_MAP_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x116, METHOD_BUFFERED, FILE_ANY_ACCESS)
263 case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
:
264 return "IOCTL_VIDEO_UNMAP_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x117, METHOD_BUFFERED, FILE_ANY_ACCESS)
265 case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES
:
266 return "IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x118, METHOD_BUFFERED, FILE_ANY_ACCESS)
267 case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES
:
268 return "IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x119, METHOD_BUFFERED, FILE_ANY_ACCESS)
269 case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES
:
270 return "IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11a, METHOD_BUFFERED, FILE_ANY_ACCESS)
271 case IOCTL_VIDEO_SET_POWER_MANAGEMENT
:
272 return "IOCTL_VIDEO_SET_POWER_MANAGEMENT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11b, METHOD_BUFFERED, FILE_ANY_ACCESS)
273 case IOCTL_VIDEO_GET_POWER_MANAGEMENT
:
274 return "IOCTL_VIDEO_GET_POWER_MANAGEMENT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11c, METHOD_BUFFERED, FILE_ANY_ACCESS)
275 case IOCTL_VIDEO_SHARE_VIDEO_MEMORY
:
276 return "IOCTL_VIDEO_SHARE_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11d, METHOD_BUFFERED, FILE_ANY_ACCESS)
277 case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY
:
278 return "IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11e, METHOD_BUFFERED, FILE_ANY_ACCESS)
279 case IOCTL_VIDEO_SET_COLOR_LUT_DATA
:
280 return "IOCTL_VIDEO_SET_COLOR_LUT_DATA"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11f, METHOD_BUFFERED, FILE_ANY_ACCESS)
281 case IOCTL_VIDEO_GET_CHILD_STATE
:
282 return "IOCTL_VIDEO_GET_CHILD_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x120, METHOD_BUFFERED, FILE_ANY_ACCESS)
283 case IOCTL_VIDEO_VALIDATE_CHILD_STATE_CONFIGURATION
:
284 return "IOCTL_VIDEO_VALIDATE_CHILD_STATE_CONFIGURATION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x121, METHOD_BUFFERED, FILE_ANY_ACCESS)
285 case IOCTL_VIDEO_SET_CHILD_STATE_CONFIGURATION
:
286 return "IOCTL_VIDEO_SET_CHILD_STATE_CONFIGURATION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x122, METHOD_BUFFERED, FILE_ANY_ACCESS)
287 case IOCTL_VIDEO_SWITCH_DUALVIEW
:
288 return "IOCTL_VIDEO_SWITCH_DUALVIEW"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x123, METHOD_BUFFERED, FILE_ANY_ACCESS)
289 case IOCTL_VIDEO_SET_BANK_POSITION
:
290 return "IOCTL_VIDEO_SET_BANK_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x124, METHOD_BUFFERED, FILE_ANY_ACCESS)
291 case IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS
:
292 return "IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x125, METHOD_BUFFERED, FILE_ANY_ACCESS)
293 case IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS
:
294 return "IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x126, METHOD_BUFFERED, FILE_ANY_ACCESS)
295 case IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS
:
296 return "IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x127, METHOD_BUFFERED, FILE_ANY_ACCESS)
299 return "<unknown ioctl code";
304 VideoPortUseDeviceInSession(
305 _Inout_ PDEVICE_OBJECT DeviceObject
,
306 _Inout_ PVIDEO_DEVICE_SESSION_STATUS SessionState
,
307 _In_ ULONG BufferLength
,
308 _Out_ PULONG_PTR Information
)
310 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
312 /* Check buffer size */
313 *Information
= sizeof(VIDEO_DEVICE_SESSION_STATUS
);
314 if (BufferLength
< sizeof(VIDEO_DEVICE_SESSION_STATUS
))
316 ERR_(VIDEOPRT
, "Buffer too small for VIDEO_DEVICE_SESSION_STATUS: %lx\n",
318 return STATUS_BUFFER_TOO_SMALL
;
321 /* Get the device extension */
322 DeviceExtension
= DeviceObject
->DeviceExtension
;
324 /* Shall we enable the session? */
325 if (SessionState
->bEnable
)
327 /* Check if we have no session yet */
328 if (DeviceExtension
->SessionId
== -1)
330 /* Use this session and return success */
331 DeviceExtension
->SessionId
= PsGetCurrentProcessSessionId();
332 SessionState
->bSuccess
= TRUE
;
336 ERR_(VIDEOPRT
, "Requested to set session, but session is already set to: 0x%lx\n",
337 DeviceExtension
->SessionId
);
338 SessionState
->bSuccess
= FALSE
;
343 /* Check if we belong to the current session */
344 if (DeviceExtension
->SessionId
== PsGetCurrentProcessSessionId())
346 /* Reset the session and return success */
347 DeviceExtension
->SessionId
= -1;
348 SessionState
->bSuccess
= TRUE
;
352 ERR_(VIDEOPRT
, "Requested to reset session, but session is not set\n");
353 SessionState
->bSuccess
= FALSE
;
357 return STATUS_SUCCESS
;
362 VideoPortInitWin32kCallbacks(
363 _In_ PDEVICE_OBJECT DeviceObject
,
364 _Inout_ PVIDEO_WIN32K_CALLBACKS Win32kCallbacks
,
365 _In_ ULONG BufferLength
,
366 _Out_ PULONG_PTR Information
)
368 *Information
= sizeof(VIDEO_WIN32K_CALLBACKS
);
369 if (BufferLength
< sizeof(VIDEO_WIN32K_CALLBACKS
))
371 ERR_(VIDEOPRT
, "Buffer too small for VIDEO_WIN32K_CALLBACKS: %lx\n",
373 return STATUS_BUFFER_TOO_SMALL
;
376 /* Save the callout function globally */
377 Win32kCallout
= Win32kCallbacks
->Callout
;
379 /* Return reasonable values to win32k */
380 Win32kCallbacks
->bACPI
= FALSE
;
381 Win32kCallbacks
->pPhysDeviceObject
= DeviceObject
;
382 Win32kCallbacks
->DualviewFlags
= 0;
384 return STATUS_SUCCESS
;
389 VideoPortForwardDeviceControl(
390 IN PDEVICE_OBJECT DeviceObject
,
393 PIO_STACK_LOCATION IrpStack
;
394 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
395 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
396 VIDEO_REQUEST_PACKET vrp
;
398 TRACE_(VIDEOPRT
, "VideoPortForwardDeviceControl\n");
400 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
401 DeviceExtension
= DeviceObject
->DeviceExtension
;
402 DriverExtension
= DeviceExtension
->DriverExtension
;
404 /* Translate the IRP to a VRP */
405 vrp
.StatusBlock
= (PSTATUS_BLOCK
)&Irp
->IoStatus
;
406 vrp
.IoControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
408 INFO_(VIDEOPRT
, "- IoControlCode: %x\n", vrp
.IoControlCode
);
410 /* We're assuming METHOD_BUFFERED */
411 vrp
.InputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
412 vrp
.InputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
413 vrp
.OutputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
414 vrp
.OutputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
416 /* Call the Miniport Driver with the VRP */
417 DriverExtension
->InitializationData
.HwStartIO(&DeviceExtension
->MiniPortDeviceExtension
,
420 INFO_(VIDEOPRT
, "- Returned status: %x\n", Irp
->IoStatus
.Status
);
422 /* Map from win32 error codes to NT status values. */
423 switch (Irp
->IoStatus
.Status
)
426 return STATUS_SUCCESS
;
427 case ERROR_NOT_ENOUGH_MEMORY
:
428 return STATUS_INSUFFICIENT_RESOURCES
;
429 case ERROR_MORE_DATA
:
430 return STATUS_BUFFER_OVERFLOW
;
431 case ERROR_INVALID_FUNCTION
:
432 return STATUS_NOT_IMPLEMENTED
;
433 case ERROR_INVALID_PARAMETER
:
434 return STATUS_INVALID_PARAMETER
;
435 case ERROR_INSUFFICIENT_BUFFER
:
436 return STATUS_BUFFER_TOO_SMALL
;
437 case ERROR_DEV_NOT_EXIST
:
438 return STATUS_DEVICE_DOES_NOT_EXIST
;
439 case ERROR_IO_PENDING
:
440 return STATUS_PENDING
;
442 return STATUS_UNSUCCESSFUL
;
447 * IntVideoPortDispatchDeviceControl
449 * Answer requests for device control calls.
456 IntVideoPortDispatchDeviceControl(
457 IN PDEVICE_OBJECT DeviceObject
,
460 PIO_STACK_LOCATION IrpStack
;
464 TRACE_(VIDEOPRT
, "IntVideoPortDispatchDeviceControl\n");
466 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
468 IoControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
470 INFO_(VIDEOPRT
, "- IoControlCode: %x: %s\n", IoControlCode
, IoctlName(IoControlCode
));
472 switch(IoControlCode
)
474 case IOCTL_VIDEO_INIT_WIN32K_CALLBACKS
:
475 INFO_(VIDEOPRT
, "- IOCTL_VIDEO_INIT_WIN32K_CALLBACKS\n");
476 Status
= VideoPortInitWin32kCallbacks(DeviceObject
,
477 Irp
->AssociatedIrp
.SystemBuffer
,
478 IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
,
479 &Irp
->IoStatus
.Information
);
482 case IOCTL_VIDEO_USE_DEVICE_IN_SESSION
:
483 INFO_(VIDEOPRT
, "- IOCTL_VIDEO_USE_DEVICE_IN_SESSION\n");
484 Status
= VideoPortUseDeviceInSession(DeviceObject
,
485 Irp
->AssociatedIrp
.SystemBuffer
,
486 IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
,
487 &Irp
->IoStatus
.Information
);
491 /* Forward to the Miniport Driver */
492 Status
= VideoPortForwardDeviceControl(DeviceObject
, Irp
);
496 INFO_(VIDEOPRT
, "- Returned status: %x\n", Irp
->IoStatus
.Status
);
498 Irp
->IoStatus
.Status
= Status
;
499 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
507 * This is a bit of a hack. We want to take ownership of the display as late
508 * as possible, just before the switch to graphics mode. Win32k knows when
509 * this happens, we don't. So we need Win32k to inform us. This could be done
510 * using an IOCTL, but there's no way of knowing which IOCTL codes are unused
511 * in the communication between GDI driver and miniport driver. So we use
512 * IRP_MJ_WRITE as the signal that win32k is ready to switch to graphics mode,
513 * since we know for certain that there is no read/write activity going on
514 * between GDI and miniport drivers.
515 * We don't actually need the data that is passed, we just trigger on the fact
516 * that an IRP_MJ_WRITE was sent.
523 IntVideoPortDispatchWrite(
524 IN PDEVICE_OBJECT DeviceObject
,
527 PIO_STACK_LOCATION piosStack
= IoGetCurrentIrpStackLocation(Irp
);
528 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
531 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
534 * Storing the device extension pointer in a static variable is an
535 * ugly hack. Unfortunately, we need it in IntVideoPortResetDisplayParameters
536 * and InbvNotifyDisplayOwnershipLost doesn't allow us to pass a userdata
537 * parameter. On the bright side, the DISPLAY device is opened
538 * exclusively, so there can be only one device extension active at
541 * FIXME: We should process all opened display devices in
542 * IntVideoPortResetDisplayParameters.
544 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
545 InbvNotifyDisplayOwnershipLost(IntVideoPortResetDisplayParameters
);
547 nErrCode
= STATUS_SUCCESS
;
548 Irp
->IoStatus
.Information
= piosStack
->Parameters
.Write
.Length
;
549 Irp
->IoStatus
.Status
= nErrCode
;
550 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
557 IntVideoPortPnPStartDevice(
558 IN PDEVICE_OBJECT DeviceObject
,
561 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
562 PDRIVER_OBJECT DriverObject
;
563 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
564 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
565 PCM_RESOURCE_LIST AllocatedResources
;
567 /* Get the initialization data we saved in VideoPortInitialize.*/
568 DriverObject
= DeviceObject
->DriverObject
;
569 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
570 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
572 /* Store some resources in the DeviceExtension. */
573 AllocatedResources
= Stack
->Parameters
.StartDevice
.AllocatedResources
;
574 if (AllocatedResources
!= NULL
)
576 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
577 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
579 ULONG ResourceListSize
;
581 /* Save the resource list */
582 ResourceCount
= AllocatedResources
->List
[0].PartialResourceList
.Count
;
584 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
585 PartialDescriptors
[ResourceCount
]);
586 DeviceExtension
->AllocatedResources
= ExAllocatePool(PagedPool
, ResourceListSize
);
587 if (DeviceExtension
->AllocatedResources
== NULL
)
589 return STATUS_INSUFFICIENT_RESOURCES
;
592 RtlCopyMemory(DeviceExtension
->AllocatedResources
,
596 /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
597 FullList
= AllocatedResources
->List
;
598 ASSERT(AllocatedResources
->Count
== 1);
599 INFO_(VIDEOPRT
, "InterfaceType %u BusNumber List %u Device BusNumber %u Version %u Revision %u\n",
600 FullList
->InterfaceType
, FullList
->BusNumber
, DeviceExtension
->SystemIoBusNumber
, FullList
->PartialResourceList
.Version
, FullList
->PartialResourceList
.Revision
);
602 /* FIXME: Is this ASSERT ok for resources from the PNP manager? */
603 ASSERT(FullList
->InterfaceType
== PCIBus
);
604 ASSERT(FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
);
605 ASSERT(1 == FullList
->PartialResourceList
.Version
);
606 ASSERT(1 == FullList
->PartialResourceList
.Revision
);
607 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
608 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
611 if (Descriptor
->Type
== CmResourceTypeInterrupt
)
613 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
614 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
615 if (Descriptor
->ShareDisposition
== CmResourceShareShared
)
616 DeviceExtension
->InterruptShared
= TRUE
;
618 DeviceExtension
->InterruptShared
= FALSE
;
623 INFO_(VIDEOPRT
, "Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
624 DeviceExtension
->InterruptLevel
,
625 DeviceExtension
->InterruptVector
);
627 /* Create adapter device object. */
628 return IntVideoPortFindAdapter(DriverObject
,
636 IntVideoPortForwardIrpAndWaitCompletionRoutine(
641 PKEVENT Event
= Context
;
643 if (Irp
->PendingReturned
)
644 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
646 return STATUS_MORE_PROCESSING_REQUIRED
;
651 IntVideoPortQueryBusRelations(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
653 PDEVICE_RELATIONS DeviceRelations
;
654 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
655 PVIDEO_PORT_CHILD_EXTENSION ChildExtension
;
657 PLIST_ENTRY CurrentEntry
;
659 /* Count the children */
661 CurrentEntry
= DeviceExtension
->ChildDeviceList
.Flink
;
662 while (CurrentEntry
!= &DeviceExtension
->ChildDeviceList
)
665 CurrentEntry
= CurrentEntry
->Flink
;
669 return Irp
->IoStatus
.Status
;
671 DeviceRelations
= ExAllocatePool(PagedPool
,
672 sizeof(DEVICE_RELATIONS
) + ((i
- 1) * sizeof(PVOID
)));
673 if (!DeviceRelations
) return STATUS_NO_MEMORY
;
675 DeviceRelations
->Count
= i
;
677 /* Add the children */
679 CurrentEntry
= DeviceExtension
->ChildDeviceList
.Flink
;
680 while (CurrentEntry
!= &DeviceExtension
->ChildDeviceList
)
682 ChildExtension
= CONTAINING_RECORD(CurrentEntry
, VIDEO_PORT_CHILD_EXTENSION
, ListEntry
);
684 ObReferenceObject(ChildExtension
->PhysicalDeviceObject
);
685 DeviceRelations
->Objects
[i
] = ChildExtension
->PhysicalDeviceObject
;
688 CurrentEntry
= CurrentEntry
->Flink
;
691 INFO_(VIDEOPRT
, "Reported %d PDOs\n", i
);
692 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
694 return STATUS_SUCCESS
;
699 IntVideoPortForwardIrpAndWait(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
703 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
=
704 (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
706 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
707 IoCopyCurrentIrpStackLocationToNext(Irp
);
708 IoSetCompletionRoutine(Irp
,
709 IntVideoPortForwardIrpAndWaitCompletionRoutine
,
715 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
716 if (Status
== STATUS_PENDING
)
718 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
719 Status
= Irp
->IoStatus
.Status
;
727 IntVideoPortDispatchFdoPnp(
728 IN PDEVICE_OBJECT DeviceObject
,
731 PIO_STACK_LOCATION IrpSp
;
733 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
735 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
737 switch (IrpSp
->MinorFunction
)
739 case IRP_MN_START_DEVICE
:
740 Status
= IntVideoPortForwardIrpAndWait(DeviceObject
, Irp
);
741 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
742 Status
= IntVideoPortPnPStartDevice(DeviceObject
, Irp
);
743 Irp
->IoStatus
.Status
= Status
;
744 Irp
->IoStatus
.Information
= 0;
745 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
748 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
749 Status
= IntVideoPortForwardIrpAndWait(DeviceObject
, Irp
);
750 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
751 Status
= IntVideoPortFilterResourceRequirements(DeviceObject
, Irp
);
752 Irp
->IoStatus
.Status
= Status
;
753 Irp
->IoStatus
.Information
= 0;
754 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
757 case IRP_MN_QUERY_DEVICE_RELATIONS
:
758 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= BusRelations
)
760 IoSkipCurrentIrpStackLocation(Irp
);
761 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
765 Status
= IntVideoPortQueryBusRelations(DeviceObject
, Irp
);
766 Irp
->IoStatus
.Status
= Status
;
767 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
771 case IRP_MN_REMOVE_DEVICE
:
772 case IRP_MN_QUERY_REMOVE_DEVICE
:
773 case IRP_MN_CANCEL_REMOVE_DEVICE
:
774 case IRP_MN_SURPRISE_REMOVAL
:
776 case IRP_MN_STOP_DEVICE
:
777 Status
= IntVideoPortForwardIrpAndWait(DeviceObject
, Irp
);
778 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
779 Status
= STATUS_SUCCESS
;
780 Irp
->IoStatus
.Status
= Status
;
781 Irp
->IoStatus
.Information
= 0;
782 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
785 case IRP_MN_QUERY_STOP_DEVICE
:
786 case IRP_MN_CANCEL_STOP_DEVICE
:
787 Status
= STATUS_SUCCESS
;
788 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
789 Irp
->IoStatus
.Information
= 0;
790 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
794 Status
= Irp
->IoStatus
.Status
;
795 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
804 IntVideoPortDispatchPnp(
805 IN PDEVICE_OBJECT DeviceObject
,
808 PVIDEO_PORT_COMMON_EXTENSION CommonExtension
= DeviceObject
->DeviceExtension
;
810 if (CommonExtension
->Fdo
)
811 return IntVideoPortDispatchFdoPnp(DeviceObject
, Irp
);
813 return IntVideoPortDispatchPdoPnp(DeviceObject
, Irp
);
818 IntVideoPortDispatchCleanup(
819 IN PDEVICE_OBJECT DeviceObject
,
822 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
824 DeviceExtension
= DeviceObject
->DeviceExtension
;
825 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
827 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
828 Irp
->IoStatus
.Information
= 0;
829 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
831 return STATUS_SUCCESS
;
836 IntVideoPortDispatchPower(
837 IN PDEVICE_OBJECT DeviceObject
,
840 PIO_STACK_LOCATION IrpSp
;
841 NTSTATUS Status
= Irp
->IoStatus
.Status
;
842 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
844 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
846 if (DeviceExtension
->Common
.Fdo
)
848 PoStartNextPowerIrp(Irp
);
849 IoSkipCurrentIrpStackLocation(Irp
);
850 return PoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
854 switch (IrpSp
->MinorFunction
)
856 case IRP_MN_QUERY_POWER
:
857 case IRP_MN_SET_POWER
:
858 Status
= STATUS_SUCCESS
;
861 PoStartNextPowerIrp(Irp
);
862 Irp
->IoStatus
.Status
= Status
;
863 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
870 IntVideoPortDispatchSystemControl(
871 IN PDEVICE_OBJECT DeviceObject
,
875 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
877 if (DeviceExtension
->Common
.Fdo
)
879 IoSkipCurrentIrpStackLocation(Irp
);
880 return IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
884 Status
= Irp
->IoStatus
.Status
;
885 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
892 IntVideoPortUnload(PDRIVER_OBJECT DriverObject
)