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
;
107 TRACE_(VIDEOPRT
, "IntVideoPortDispatchOpen\n");
109 if (CsrssInitialized
== FALSE
)
112 * We know the first open call will be from the CSRSS process
113 * to let us know its handle.
116 INFO_(VIDEOPRT
, "Referencing CSRSS\n");
117 Csrss
= (PKPROCESS
)PsGetCurrentProcess();
118 INFO_(VIDEOPRT
, "Csrss %p\n", Csrss
);
120 IntInitializeVideoAddressSpace();
122 CsrssInitialized
= TRUE
;
125 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
126 DriverExtension
= DeviceExtension
->DriverExtension
;
128 if (DriverExtension
->InitializationData
.HwInitialize(&DeviceExtension
->MiniPortDeviceExtension
))
130 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
131 InterlockedIncrement((PLONG
)&DeviceExtension
->DeviceOpened
);
135 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
138 Irp
->IoStatus
.Information
= FILE_OPENED
;
139 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
141 return STATUS_SUCCESS
;
145 * IntVideoPortDispatchClose
147 * Answer requests for Close calls.
154 IntVideoPortDispatchClose(
155 IN PDEVICE_OBJECT DeviceObject
,
158 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
160 TRACE_(VIDEOPRT
, "IntVideoPortDispatchClose\n");
162 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
163 if ((DeviceExtension
->DeviceOpened
>= 1) &&
164 (InterlockedDecrement((PLONG
)&DeviceExtension
->DeviceOpened
) == 0))
166 ResetDisplayParametersDeviceExtension
= NULL
;
167 InbvNotifyDisplayOwnershipLost(NULL
);
168 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
169 IntVideoPortResetDisplayParameters(80, 50);
172 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
173 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
175 return STATUS_SUCCESS
;
179 IoctlName(ULONG Ioctl
)
183 case IOCTL_VIDEO_ENABLE_VDM
:
184 return "IOCTL_VIDEO_ENABLE_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS)
185 case IOCTL_VIDEO_DISABLE_VDM
:
186 return "IOCTL_VIDEO_DISABLE_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS)
187 case IOCTL_VIDEO_REGISTER_VDM
:
188 return "IOCTL_VIDEO_REGISTER_VDM"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS)
189 case IOCTL_VIDEO_SET_OUTPUT_DEVICE_POWER_STATE
:
190 return "IOCTL_VIDEO_SET_OUTPUT_DEVICE_POWER_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
191 case IOCTL_VIDEO_GET_OUTPUT_DEVICE_POWER_STATE
:
192 return "IOCTL_VIDEO_GET_OUTPUT_DEVICE_POWER_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS)
193 case IOCTL_VIDEO_MONITOR_DEVICE
:
194 return "IOCTL_VIDEO_MONITOR_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS)
195 case IOCTL_VIDEO_ENUM_MONITOR_PDO
:
196 return "IOCTL_VIDEO_ENUM_MONITOR_PDO"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS)
197 case IOCTL_VIDEO_INIT_WIN32K_CALLBACKS
:
198 return "IOCTL_VIDEO_INIT_WIN32K_CALLBACKS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS)
199 case IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS
:
200 return "IOCTL_VIDEO_HANDLE_VIDEOPARAMETERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS)
201 case IOCTL_VIDEO_IS_VGA_DEVICE
:
202 return "IOCTL_VIDEO_IS_VGA_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS)
203 case IOCTL_VIDEO_USE_DEVICE_IN_SESSION
:
204 return "IOCTL_VIDEO_USE_DEVICE_IN_SESSION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x0a, METHOD_BUFFERED, FILE_ANY_ACCESS)
205 case IOCTL_VIDEO_PREPARE_FOR_EARECOVERY
:
206 return "IOCTL_VIDEO_PREPARE_FOR_EARECOVERY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x0b, METHOD_BUFFERED, FILE_ANY_ACCESS)
207 case IOCTL_VIDEO_SAVE_HARDWARE_STATE
:
208 return "IOCTL_VIDEO_SAVE_HARDWARE_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x80, METHOD_BUFFERED, FILE_ANY_ACCESS)
209 case IOCTL_VIDEO_RESTORE_HARDWARE_STATE
:
210 return "IOCTL_VIDEO_RESTORE_HARDWARE_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x81, METHOD_BUFFERED, FILE_ANY_ACCESS)
211 case IOCTL_VIDEO_QUERY_AVAIL_MODES
:
212 return "IOCTL_VIDEO_QUERY_AVAIL_MODES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x100, METHOD_BUFFERED, FILE_ANY_ACCESS)
213 case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
:
214 return "IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x101, METHOD_BUFFERED, FILE_ANY_ACCESS)
215 case IOCTL_VIDEO_QUERY_CURRENT_MODE
:
216 return "IOCTL_VIDEO_QUERY_CURRENT_MODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x102, METHOD_BUFFERED, FILE_ANY_ACCESS)
217 case IOCTL_VIDEO_SET_CURRENT_MODE
:
218 return "IOCTL_VIDEO_SET_CURRENT_MODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x103, METHOD_BUFFERED, FILE_ANY_ACCESS)
219 case IOCTL_VIDEO_RESET_DEVICE
:
220 return "IOCTL_VIDEO_RESET_DEVICE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x104, METHOD_BUFFERED, FILE_ANY_ACCESS)
221 case IOCTL_VIDEO_LOAD_AND_SET_FONT
:
222 return "IOCTL_VIDEO_LOAD_AND_SET_FONT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x105, METHOD_BUFFERED, FILE_ANY_ACCESS)
223 case IOCTL_VIDEO_SET_PALETTE_REGISTERS
:
224 return "IOCTL_VIDEO_SET_PALETTE_REGISTERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x106, METHOD_BUFFERED, FILE_ANY_ACCESS)
225 case IOCTL_VIDEO_SET_COLOR_REGISTERS
:
226 return "IOCTL_VIDEO_SET_COLOR_REGISTERS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x107, METHOD_BUFFERED, FILE_ANY_ACCESS)
227 case IOCTL_VIDEO_ENABLE_CURSOR
:
228 return "IOCTL_VIDEO_ENABLE_CURSOR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x108, METHOD_BUFFERED, FILE_ANY_ACCESS)
229 case IOCTL_VIDEO_DISABLE_CURSOR
:
230 return "IOCTL_VIDEO_DISABLE_CURSOR"; // CTL_CODE (FILE_DEVICE_VIDEO, 0x109, METHOD_BUFFERED, FILE_ANY_ACCESS)
231 case IOCTL_VIDEO_SET_CURSOR_ATTR
:
232 return "IOCTL_VIDEO_SET_CURSOR_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10a, METHOD_BUFFERED, FILE_ANY_ACCESS)
233 case IOCTL_VIDEO_QUERY_CURSOR_ATTR
:
234 return "IOCTL_VIDEO_QUERY_CURSOR_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10b, METHOD_BUFFERED, FILE_ANY_ACCESS)
235 case IOCTL_VIDEO_SET_CURSOR_POSITION
:
236 return "IOCTL_VIDEO_SET_CURSOR_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10c, METHOD_BUFFERED, FILE_ANY_ACCESS)
237 case IOCTL_VIDEO_QUERY_CURSOR_POSITION
:
238 return "IOCTL_VIDEO_QUERY_CURSOR_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10d, METHOD_BUFFERED, FILE_ANY_ACCESS)
239 case IOCTL_VIDEO_ENABLE_POINTER
:
240 return "IOCTL_VIDEO_ENABLE_POINTER"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10e, METHOD_BUFFERED, FILE_ANY_ACCESS)
241 case IOCTL_VIDEO_DISABLE_POINTER
:
242 return "IOCTL_VIDEO_DISABLE_POINTER"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x10f, METHOD_BUFFERED, FILE_ANY_ACCESS)
243 case IOCTL_VIDEO_SET_POINTER_ATTR
:
244 return "IOCTL_VIDEO_SET_POINTER_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x110, METHOD_BUFFERED, FILE_ANY_ACCESS)
245 case IOCTL_VIDEO_QUERY_POINTER_ATTR
:
246 return "IOCTL_VIDEO_QUERY_POINTER_ATTR"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x111, METHOD_BUFFERED, FILE_ANY_ACCESS)
247 case IOCTL_VIDEO_SET_POINTER_POSITION
:
248 return "IOCTL_VIDEO_SET_POINTER_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x112, METHOD_BUFFERED, FILE_ANY_ACCESS)
249 case IOCTL_VIDEO_QUERY_POINTER_POSITION
:
250 return "IOCTL_VIDEO_QUERY_POINTER_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x113, METHOD_BUFFERED, FILE_ANY_ACCESS)
251 case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES
:
252 return "IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x114, METHOD_BUFFERED, FILE_ANY_ACCESS)
253 case IOCTL_VIDEO_GET_BANK_SELECT_CODE
:
254 return "IOCTL_VIDEO_GET_BANK_SELECT_CODE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x115, METHOD_BUFFERED, FILE_ANY_ACCESS)
255 case IOCTL_VIDEO_MAP_VIDEO_MEMORY
:
256 return "IOCTL_VIDEO_MAP_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x116, METHOD_BUFFERED, FILE_ANY_ACCESS)
257 case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
:
258 return "IOCTL_VIDEO_UNMAP_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x117, METHOD_BUFFERED, FILE_ANY_ACCESS)
259 case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES
:
260 return "IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x118, METHOD_BUFFERED, FILE_ANY_ACCESS)
261 case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES
:
262 return "IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x119, METHOD_BUFFERED, FILE_ANY_ACCESS)
263 case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES
:
264 return "IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11a, METHOD_BUFFERED, FILE_ANY_ACCESS)
265 case IOCTL_VIDEO_SET_POWER_MANAGEMENT
:
266 return "IOCTL_VIDEO_SET_POWER_MANAGEMENT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11b, METHOD_BUFFERED, FILE_ANY_ACCESS)
267 case IOCTL_VIDEO_GET_POWER_MANAGEMENT
:
268 return "IOCTL_VIDEO_GET_POWER_MANAGEMENT"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11c, METHOD_BUFFERED, FILE_ANY_ACCESS)
269 case IOCTL_VIDEO_SHARE_VIDEO_MEMORY
:
270 return "IOCTL_VIDEO_SHARE_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11d, METHOD_BUFFERED, FILE_ANY_ACCESS)
271 case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY
:
272 return "IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11e, METHOD_BUFFERED, FILE_ANY_ACCESS)
273 case IOCTL_VIDEO_SET_COLOR_LUT_DATA
:
274 return "IOCTL_VIDEO_SET_COLOR_LUT_DATA"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x11f, METHOD_BUFFERED, FILE_ANY_ACCESS)
275 case IOCTL_VIDEO_GET_CHILD_STATE
:
276 return "IOCTL_VIDEO_GET_CHILD_STATE"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x120, METHOD_BUFFERED, FILE_ANY_ACCESS)
277 case IOCTL_VIDEO_VALIDATE_CHILD_STATE_CONFIGURATION
:
278 return "IOCTL_VIDEO_VALIDATE_CHILD_STATE_CONFIGURATION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x121, METHOD_BUFFERED, FILE_ANY_ACCESS)
279 case IOCTL_VIDEO_SET_CHILD_STATE_CONFIGURATION
:
280 return "IOCTL_VIDEO_SET_CHILD_STATE_CONFIGURATION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x122, METHOD_BUFFERED, FILE_ANY_ACCESS)
281 case IOCTL_VIDEO_SWITCH_DUALVIEW
:
282 return "IOCTL_VIDEO_SWITCH_DUALVIEW"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x123, METHOD_BUFFERED, FILE_ANY_ACCESS)
283 case IOCTL_VIDEO_SET_BANK_POSITION
:
284 return "IOCTL_VIDEO_SET_BANK_POSITION"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x124, METHOD_BUFFERED, FILE_ANY_ACCESS)
285 case IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS
:
286 return "IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x125, METHOD_BUFFERED, FILE_ANY_ACCESS)
287 case IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS
:
288 return "IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x126, METHOD_BUFFERED, FILE_ANY_ACCESS)
289 case IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS
:
290 return "IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS"; // CTL_CODE(FILE_DEVICE_VIDEO, 0x127, METHOD_BUFFERED, FILE_ANY_ACCESS)
293 return "<unknown ioctl code";
298 VideoPortUseDeviceInSession(
299 _Inout_ PDEVICE_OBJECT DeviceObject
,
300 _Inout_ PVIDEO_DEVICE_SESSION_STATUS SessionState
,
301 _In_ ULONG BufferLength
,
302 _Out_ PULONG_PTR Information
)
304 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
306 /* Check buffer size */
307 *Information
= sizeof(VIDEO_DEVICE_SESSION_STATUS
);
308 if (BufferLength
< sizeof(VIDEO_DEVICE_SESSION_STATUS
))
310 ERR_(VIDEOPRT
, "Buffer too small for VIDEO_DEVICE_SESSION_STATUS: %lx\n",
312 return STATUS_BUFFER_TOO_SMALL
;
315 /* Get the device extension */
316 DeviceExtension
= DeviceObject
->DeviceExtension
;
318 /* Shall we enable the session? */
319 if (SessionState
->bEnable
)
321 /* Check if we have no session yet */
322 if (DeviceExtension
->SessionId
== -1)
324 /* Use this session and return success */
325 DeviceExtension
->SessionId
= PsGetCurrentProcessSessionId();
326 SessionState
->bSuccess
= TRUE
;
330 ERR_(VIDEOPRT
, "Requested to set session, but session is already set to: 0x%lx\n",
331 DeviceExtension
->SessionId
);
332 SessionState
->bSuccess
= FALSE
;
337 /* Check if we belong to the current session */
338 if (DeviceExtension
->SessionId
== PsGetCurrentProcessSessionId())
340 /* Reset the session and return success */
341 DeviceExtension
->SessionId
= -1;
342 SessionState
->bSuccess
= TRUE
;
346 ERR_(VIDEOPRT
, "Requested to reset session, but session is not set\n");
347 SessionState
->bSuccess
= FALSE
;
351 return STATUS_SUCCESS
;
356 VideoPortInitWin32kCallbacks(
357 _In_ PDEVICE_OBJECT DeviceObject
,
358 _Inout_ PVIDEO_WIN32K_CALLBACKS Win32kCallbacks
,
359 _In_ ULONG BufferLength
,
360 _Out_ PULONG_PTR Information
)
362 *Information
= sizeof(VIDEO_WIN32K_CALLBACKS
);
363 if (BufferLength
< sizeof(VIDEO_WIN32K_CALLBACKS
))
365 ERR_(VIDEOPRT
, "Buffer too small for VIDEO_WIN32K_CALLBACKS: %lx\n",
367 return STATUS_BUFFER_TOO_SMALL
;
370 /* Save the callout function globally */
371 Win32kCallout
= Win32kCallbacks
->Callout
;
373 /* Return reasonable values to win32k */
374 Win32kCallbacks
->bACPI
= FALSE
;
375 Win32kCallbacks
->pPhysDeviceObject
= DeviceObject
;
376 Win32kCallbacks
->DualviewFlags
= 0;
378 return STATUS_SUCCESS
;
383 VideoPortForwardDeviceControl(
384 IN PDEVICE_OBJECT DeviceObject
,
387 PIO_STACK_LOCATION IrpStack
;
388 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
389 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
390 VIDEO_REQUEST_PACKET vrp
;
392 TRACE_(VIDEOPRT
, "VideoPortForwardDeviceControl\n");
394 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
395 DeviceExtension
= DeviceObject
->DeviceExtension
;
396 DriverExtension
= DeviceExtension
->DriverExtension
;
398 /* Translate the IRP to a VRP */
399 vrp
.StatusBlock
= (PSTATUS_BLOCK
)&Irp
->IoStatus
;
400 vrp
.IoControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
402 INFO_(VIDEOPRT
, "- IoControlCode: %x\n", vrp
.IoControlCode
);
404 /* We're assuming METHOD_BUFFERED */
405 vrp
.InputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
406 vrp
.InputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
407 vrp
.OutputBuffer
= Irp
->AssociatedIrp
.SystemBuffer
;
408 vrp
.OutputBufferLength
= IrpStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
410 /* Call the Miniport Driver with the VRP */
411 DriverExtension
->InitializationData
.HwStartIO(&DeviceExtension
->MiniPortDeviceExtension
,
414 INFO_(VIDEOPRT
, "- Returned status: %x\n", Irp
->IoStatus
.Status
);
416 /* Map from win32 error codes to NT status values. */
417 switch (Irp
->IoStatus
.Status
)
420 return STATUS_SUCCESS
;
421 case ERROR_NOT_ENOUGH_MEMORY
:
422 return STATUS_INSUFFICIENT_RESOURCES
;
423 case ERROR_MORE_DATA
:
424 return STATUS_BUFFER_OVERFLOW
;
425 case ERROR_INVALID_FUNCTION
:
426 return STATUS_NOT_IMPLEMENTED
;
427 case ERROR_INVALID_PARAMETER
:
428 return STATUS_INVALID_PARAMETER
;
429 case ERROR_INSUFFICIENT_BUFFER
:
430 return STATUS_BUFFER_TOO_SMALL
;
431 case ERROR_DEV_NOT_EXIST
:
432 return STATUS_DEVICE_DOES_NOT_EXIST
;
433 case ERROR_IO_PENDING
:
434 return STATUS_PENDING
;
436 return STATUS_UNSUCCESSFUL
;
441 * IntVideoPortDispatchDeviceControl
443 * Answer requests for device control calls.
450 IntVideoPortDispatchDeviceControl(
451 IN PDEVICE_OBJECT DeviceObject
,
454 PIO_STACK_LOCATION IrpStack
;
458 TRACE_(VIDEOPRT
, "IntVideoPortDispatchDeviceControl\n");
460 IrpStack
= IoGetCurrentIrpStackLocation(Irp
);
462 IoControlCode
= IrpStack
->Parameters
.DeviceIoControl
.IoControlCode
;
464 INFO_(VIDEOPRT
, "- IoControlCode: %x: %s\n", IoControlCode
, IoctlName(IoControlCode
));
466 switch(IoControlCode
)
468 case IOCTL_VIDEO_INIT_WIN32K_CALLBACKS
:
469 INFO_(VIDEOPRT
, "- IOCTL_VIDEO_INIT_WIN32K_CALLBACKS\n");
470 Status
= VideoPortInitWin32kCallbacks(DeviceObject
,
471 Irp
->AssociatedIrp
.SystemBuffer
,
472 IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
,
473 &Irp
->IoStatus
.Information
);
476 case IOCTL_VIDEO_USE_DEVICE_IN_SESSION
:
477 INFO_(VIDEOPRT
, "- IOCTL_VIDEO_USE_DEVICE_IN_SESSION\n");
478 Status
= VideoPortUseDeviceInSession(DeviceObject
,
479 Irp
->AssociatedIrp
.SystemBuffer
,
480 IrpStack
->Parameters
.DeviceIoControl
.InputBufferLength
,
481 &Irp
->IoStatus
.Information
);
485 /* Forward to the Miniport Driver */
486 Status
= VideoPortForwardDeviceControl(DeviceObject
, Irp
);
490 INFO_(VIDEOPRT
, "- Returned status: %x\n", Irp
->IoStatus
.Status
);
492 Irp
->IoStatus
.Status
= Status
;
493 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
501 * This is a bit of a hack. We want to take ownership of the display as late
502 * as possible, just before the switch to graphics mode. Win32k knows when
503 * this happens, we don't. So we need Win32k to inform us. This could be done
504 * using an IOCTL, but there's no way of knowing which IOCTL codes are unused
505 * in the communication between GDI driver and miniport driver. So we use
506 * IRP_MJ_WRITE as the signal that win32k is ready to switch to graphics mode,
507 * since we know for certain that there is no read/write activity going on
508 * between GDI and miniport drivers.
509 * We don't actually need the data that is passed, we just trigger on the fact
510 * that an IRP_MJ_WRITE was sent.
517 IntVideoPortDispatchWrite(
518 IN PDEVICE_OBJECT DeviceObject
,
521 PIO_STACK_LOCATION piosStack
= IoGetCurrentIrpStackLocation(Irp
);
522 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
525 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
528 * Storing the device extension pointer in a static variable is an
529 * ugly hack. Unfortunately, we need it in IntVideoPortResetDisplayParameters
530 * and InbvNotifyDisplayOwnershipLost doesn't allow us to pass a userdata
531 * parameter. On the bright side, the DISPLAY device is opened
532 * exclusively, so there can be only one device extension active at
535 * FIXME: We should process all opened display devices in
536 * IntVideoPortResetDisplayParameters.
538 ResetDisplayParametersDeviceExtension
= DeviceExtension
;
539 InbvNotifyDisplayOwnershipLost(IntVideoPortResetDisplayParameters
);
541 nErrCode
= STATUS_SUCCESS
;
542 Irp
->IoStatus
.Information
= piosStack
->Parameters
.Write
.Length
;
543 Irp
->IoStatus
.Status
= nErrCode
;
544 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
551 IntVideoPortPnPStartDevice(
552 IN PDEVICE_OBJECT DeviceObject
,
555 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
556 PDRIVER_OBJECT DriverObject
;
557 PVIDEO_PORT_DRIVER_EXTENSION DriverExtension
;
558 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
559 PCM_RESOURCE_LIST AllocatedResources
;
561 /* Get the initialization data we saved in VideoPortInitialize.*/
562 DriverObject
= DeviceObject
->DriverObject
;
563 DriverExtension
= IoGetDriverObjectExtension(DriverObject
, DriverObject
);
564 DeviceExtension
= (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
566 /* Store some resources in the DeviceExtension. */
567 AllocatedResources
= Stack
->Parameters
.StartDevice
.AllocatedResources
;
568 if (AllocatedResources
!= NULL
)
570 CM_FULL_RESOURCE_DESCRIPTOR
*FullList
;
571 CM_PARTIAL_RESOURCE_DESCRIPTOR
*Descriptor
;
573 ULONG ResourceListSize
;
575 /* Save the resource list */
576 ResourceCount
= AllocatedResources
->List
[0].PartialResourceList
.Count
;
578 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
579 PartialDescriptors
[ResourceCount
]);
580 DeviceExtension
->AllocatedResources
= ExAllocatePool(PagedPool
, ResourceListSize
);
581 if (DeviceExtension
->AllocatedResources
== NULL
)
583 return STATUS_INSUFFICIENT_RESOURCES
;
586 RtlCopyMemory(DeviceExtension
->AllocatedResources
,
590 /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
591 for (FullList
= AllocatedResources
->List
;
592 FullList
< AllocatedResources
->List
+ AllocatedResources
->Count
;
595 INFO_(VIDEOPRT
, "InterfaceType %u BusNumber List %u Device BusNumber %u Version %u Revision %u\n",
596 FullList
->InterfaceType
, FullList
->BusNumber
, DeviceExtension
->SystemIoBusNumber
, FullList
->PartialResourceList
.Version
, FullList
->PartialResourceList
.Revision
);
598 /* FIXME: Is this ASSERT ok for resources from the PNP manager? */
599 ASSERT(FullList
->InterfaceType
== PCIBus
);
600 ASSERT(FullList
->BusNumber
== DeviceExtension
->SystemIoBusNumber
);
601 ASSERT(1 == FullList
->PartialResourceList
.Version
);
602 ASSERT(1 == FullList
->PartialResourceList
.Revision
);
603 for (Descriptor
= FullList
->PartialResourceList
.PartialDescriptors
;
604 Descriptor
< FullList
->PartialResourceList
.PartialDescriptors
+ FullList
->PartialResourceList
.Count
;
607 if (Descriptor
->Type
== CmResourceTypeInterrupt
)
609 DeviceExtension
->InterruptLevel
= Descriptor
->u
.Interrupt
.Level
;
610 DeviceExtension
->InterruptVector
= Descriptor
->u
.Interrupt
.Vector
;
611 if (Descriptor
->ShareDisposition
== CmResourceShareShared
)
612 DeviceExtension
->InterruptShared
= TRUE
;
614 DeviceExtension
->InterruptShared
= FALSE
;
620 INFO_(VIDEOPRT
, "Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
621 DeviceExtension
->InterruptLevel
,
622 DeviceExtension
->InterruptVector
);
624 /* Create adapter device object. */
625 return IntVideoPortFindAdapter(DriverObject
,
633 IntVideoPortForwardIrpAndWaitCompletionRoutine(
638 PKEVENT Event
= Context
;
640 if (Irp
->PendingReturned
)
641 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
643 return STATUS_MORE_PROCESSING_REQUIRED
;
648 IntVideoPortQueryBusRelations(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
650 PDEVICE_RELATIONS DeviceRelations
;
651 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
652 PVIDEO_PORT_CHILD_EXTENSION ChildExtension
;
654 PLIST_ENTRY CurrentEntry
;
656 /* Count the children */
658 CurrentEntry
= DeviceExtension
->ChildDeviceList
.Flink
;
659 while (CurrentEntry
!= &DeviceExtension
->ChildDeviceList
)
662 CurrentEntry
= CurrentEntry
->Flink
;
666 return Irp
->IoStatus
.Status
;
668 DeviceRelations
= ExAllocatePool(PagedPool
,
669 sizeof(DEVICE_RELATIONS
) + ((i
- 1) * sizeof(PVOID
)));
670 if (!DeviceRelations
) return STATUS_NO_MEMORY
;
672 DeviceRelations
->Count
= i
;
674 /* Add the children */
676 CurrentEntry
= DeviceExtension
->ChildDeviceList
.Flink
;
677 while (CurrentEntry
!= &DeviceExtension
->ChildDeviceList
)
679 ChildExtension
= CONTAINING_RECORD(CurrentEntry
, VIDEO_PORT_CHILD_EXTENSION
, ListEntry
);
681 ObReferenceObject(ChildExtension
->PhysicalDeviceObject
);
682 DeviceRelations
->Objects
[i
] = ChildExtension
->PhysicalDeviceObject
;
685 CurrentEntry
= CurrentEntry
->Flink
;
688 INFO_(VIDEOPRT
, "Reported %d PDOs\n", i
);
689 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
691 return STATUS_SUCCESS
;
696 IntVideoPortForwardIrpAndWait(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
700 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
=
701 (PVIDEO_PORT_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
703 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
704 IoCopyCurrentIrpStackLocationToNext(Irp
);
705 IoSetCompletionRoutine(Irp
,
706 IntVideoPortForwardIrpAndWaitCompletionRoutine
,
712 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
713 if (Status
== STATUS_PENDING
)
715 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
716 Status
= Irp
->IoStatus
.Status
;
724 IntVideoPortDispatchFdoPnp(
725 IN PDEVICE_OBJECT DeviceObject
,
728 PIO_STACK_LOCATION IrpSp
;
730 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
732 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
734 switch (IrpSp
->MinorFunction
)
736 case IRP_MN_START_DEVICE
:
737 Status
= IntVideoPortForwardIrpAndWait(DeviceObject
, Irp
);
738 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
739 Status
= IntVideoPortPnPStartDevice(DeviceObject
, Irp
);
740 Irp
->IoStatus
.Status
= Status
;
741 Irp
->IoStatus
.Information
= 0;
742 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
745 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS
:
746 Status
= IntVideoPortForwardIrpAndWait(DeviceObject
, Irp
);
747 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
748 Status
= IntVideoPortFilterResourceRequirements(DeviceObject
, Irp
);
749 Irp
->IoStatus
.Status
= Status
;
750 Irp
->IoStatus
.Information
= 0;
751 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
754 case IRP_MN_QUERY_DEVICE_RELATIONS
:
755 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= BusRelations
)
757 IoSkipCurrentIrpStackLocation(Irp
);
758 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
762 Status
= IntVideoPortQueryBusRelations(DeviceObject
, Irp
);
763 Irp
->IoStatus
.Status
= Status
;
764 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
768 case IRP_MN_REMOVE_DEVICE
:
769 case IRP_MN_QUERY_REMOVE_DEVICE
:
770 case IRP_MN_CANCEL_REMOVE_DEVICE
:
771 case IRP_MN_SURPRISE_REMOVAL
:
773 case IRP_MN_STOP_DEVICE
:
774 Status
= IntVideoPortForwardIrpAndWait(DeviceObject
, Irp
);
775 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
776 Status
= STATUS_SUCCESS
;
777 Irp
->IoStatus
.Status
= Status
;
778 Irp
->IoStatus
.Information
= 0;
779 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
782 case IRP_MN_QUERY_STOP_DEVICE
:
783 case IRP_MN_CANCEL_STOP_DEVICE
:
784 Status
= STATUS_SUCCESS
;
785 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
786 Irp
->IoStatus
.Information
= 0;
787 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
791 Status
= Irp
->IoStatus
.Status
;
792 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
801 IntVideoPortDispatchPnp(
802 IN PDEVICE_OBJECT DeviceObject
,
805 PVIDEO_PORT_COMMON_EXTENSION CommonExtension
= DeviceObject
->DeviceExtension
;
807 if (CommonExtension
->Fdo
)
808 return IntVideoPortDispatchFdoPnp(DeviceObject
, Irp
);
810 return IntVideoPortDispatchPdoPnp(DeviceObject
, Irp
);
815 IntVideoPortDispatchCleanup(
816 IN PDEVICE_OBJECT DeviceObject
,
819 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
;
821 DeviceExtension
= DeviceObject
->DeviceExtension
;
822 RtlFreeUnicodeString(&DeviceExtension
->RegistryPath
);
824 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
825 Irp
->IoStatus
.Information
= 0;
826 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
828 return STATUS_SUCCESS
;
833 IntVideoPortDispatchPower(
834 IN PDEVICE_OBJECT DeviceObject
,
837 PIO_STACK_LOCATION IrpSp
;
838 NTSTATUS Status
= Irp
->IoStatus
.Status
;
839 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
841 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
843 if (DeviceExtension
->Common
.Fdo
)
845 PoStartNextPowerIrp(Irp
);
846 IoSkipCurrentIrpStackLocation(Irp
);
847 return PoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
851 switch (IrpSp
->MinorFunction
)
853 case IRP_MN_QUERY_POWER
:
854 case IRP_MN_SET_POWER
:
855 Status
= STATUS_SUCCESS
;
858 PoStartNextPowerIrp(Irp
);
859 Irp
->IoStatus
.Status
= Status
;
860 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
867 IntVideoPortDispatchSystemControl(
868 IN PDEVICE_OBJECT DeviceObject
,
872 PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension
= DeviceObject
->DeviceExtension
;
874 if (DeviceExtension
->Common
.Fdo
)
876 IoSkipCurrentIrpStackLocation(Irp
);
877 return IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
881 Status
= Irp
->IoStatus
.Status
;
882 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
889 IntVideoPortUnload(PDRIVER_OBJECT DriverObject
)