4 * Copyright (C) 2012 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
28 /* PRIVATE FUNCTIONS **********************************************************/
32 IntVideoPortGetMonitorId(
33 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
36 USHORT Manufacturer
, Model
;
38 /* This must be valid to call this function */
39 ASSERT(ChildExtension
->EdidValid
);
41 /* 3 letters 5-bit ANSI manufacturer code (big endian) */
42 /* Letters encoded as A=1 to Z=26 */
43 Manufacturer
= *(PUSHORT
)(&ChildExtension
->ChildDescriptor
[8]);
45 /* Model number (16-bit little endian) */
46 Model
= *(PUSHORT
)(&ChildExtension
->ChildDescriptor
[10]);
48 /* Convert the Monitor ID to a readable form */
51 (WCHAR
)((Manufacturer
>> 10 & 0x001F) + 'A' - 1),
52 (WCHAR
)((Manufacturer
>> 5 & 0x001F) + 'A' - 1),
53 (WCHAR
)((Manufacturer
& 0x001F) + 'A' - 1),
61 IntVideoPortChildQueryId(
62 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
64 IN PIO_STACK_LOCATION IrpSp
)
66 PWCHAR Buffer
= NULL
, StaticBuffer
;
67 UNICODE_STRING UnicodeStr
;
69 switch (IrpSp
->Parameters
.QueryId
.IdType
)
71 case BusQueryDeviceID
:
72 switch (ChildExtension
->ChildType
)
75 if (ChildExtension
->EdidValid
)
77 StaticBuffer
= L
"DISPLAY\\";
78 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 8) * sizeof(WCHAR
));
79 if (!Buffer
) return STATUS_NO_MEMORY
;
81 /* Write the static portion */
82 RtlCopyMemory(Buffer
, StaticBuffer
, wcslen(StaticBuffer
) * sizeof(WCHAR
));
84 /* Add the dynamic portion */
85 IntVideoPortGetMonitorId(ChildExtension
,
86 &Buffer
[wcslen(StaticBuffer
)]);
90 StaticBuffer
= L
"DISPLAY\\Default_Monitor";
91 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
92 if (!Buffer
) return STATUS_NO_MEMORY
;
94 /* Copy the default id */
95 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
103 case BusQueryInstanceID
:
104 Buffer
= ExAllocatePool(PagedPool
, 5 * sizeof(WCHAR
));
105 if (!Buffer
) return STATUS_NO_MEMORY
;
107 UnicodeStr
.Buffer
= Buffer
;
108 UnicodeStr
.Length
= 0;
109 UnicodeStr
.MaximumLength
= 4 * sizeof(WCHAR
);
110 RtlIntegerToUnicodeString(ChildExtension
->ChildId
, 16, &UnicodeStr
);
112 case BusQueryHardwareIDs
:
113 switch (ChildExtension
->ChildType
)
116 if (ChildExtension
->EdidValid
)
118 StaticBuffer
= L
"MONITOR\\";
119 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 9) * sizeof(WCHAR
));
120 if (!Buffer
) return STATUS_NO_MEMORY
;
122 /* Write the static portion */
123 RtlCopyMemory(Buffer
, StaticBuffer
, wcslen(StaticBuffer
) * sizeof(WCHAR
));
125 /* Add the dynamic portion */
126 IntVideoPortGetMonitorId(ChildExtension
,
127 &Buffer
[wcslen(StaticBuffer
)]);
129 /* Add the second null termination char */
130 Buffer
[wcslen(StaticBuffer
) + 8] = UNICODE_NULL
;
134 StaticBuffer
= L
"MONITOR\\Default_Monitor";
135 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 2) * sizeof(WCHAR
));
136 if (!Buffer
) return STATUS_NO_MEMORY
;
138 /* Copy the default id */
139 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
141 /* Add the second null terminator */
142 Buffer
[wcslen(StaticBuffer
) + 1] = UNICODE_NULL
;
150 case BusQueryCompatibleIDs
:
151 switch (ChildExtension
->ChildType
)
154 if (ChildExtension
->EdidValid
)
156 StaticBuffer
= L
"*PNP09FF";
157 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 2) * sizeof(WCHAR
));
158 if (!Buffer
) return STATUS_NO_MEMORY
;
160 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
162 Buffer
[wcslen(StaticBuffer
)+1] = UNICODE_NULL
;
166 /* No PNP ID for non-PnP monitors */
167 return Irp
->IoStatus
.Status
;
176 return Irp
->IoStatus
.Status
;
179 INFO_(VIDEOPRT
, "Reporting ID: %S\n", Buffer
);
180 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
182 return STATUS_SUCCESS
;
186 IntVideoPortChildQueryText(
187 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
189 IN PIO_STACK_LOCATION IrpSp
)
191 PWCHAR Buffer
, StaticBuffer
;
193 if (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
!= DeviceTextDescription
)
194 return Irp
->IoStatus
.Status
;
196 switch (ChildExtension
->ChildType
)
199 /* FIXME: We can return a better description I think */
200 StaticBuffer
= L
"Monitor";
204 /* FIXME: No idea what we return here */
205 StaticBuffer
= L
"Video chip";
209 StaticBuffer
= L
"Other device";
213 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
214 if (!Buffer
) return STATUS_NO_MEMORY
;
216 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
218 INFO_(VIDEOPRT
, "Reporting description: %S\n", Buffer
);
219 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
221 return STATUS_SUCCESS
;
225 IntVideoPortChildQueryRelations(
226 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
228 IN PIO_STACK_LOCATION IrpSp
)
230 PDEVICE_RELATIONS DeviceRelations
;
232 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
234 WARN_(VIDEOPRT
, "Unsupported device relations type\n");
235 return Irp
->IoStatus
.Status
;
238 DeviceRelations
= ExAllocatePool(NonPagedPool
, sizeof(DEVICE_RELATIONS
));
239 if (!DeviceRelations
) return STATUS_NO_MEMORY
;
241 DeviceRelations
->Count
= 1;
242 DeviceRelations
->Objects
[0] = ChildExtension
->PhysicalDeviceObject
;
244 ObReferenceObject(DeviceRelations
->Objects
[0]);
246 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
248 return STATUS_SUCCESS
;
252 IntVideoPortChildQueryCapabilities(
253 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
255 IN PIO_STACK_LOCATION IrpSp
)
257 PDEVICE_CAPABILITIES DeviceCaps
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
260 /* Set some values */
261 DeviceCaps
->LockSupported
= FALSE
;
262 DeviceCaps
->EjectSupported
= FALSE
;
263 DeviceCaps
->DockDevice
= FALSE
;
264 DeviceCaps
->UniqueID
= FALSE
;
265 DeviceCaps
->RawDeviceOK
= FALSE
;
266 DeviceCaps
->WakeFromD0
= FALSE
;
267 DeviceCaps
->WakeFromD1
= FALSE
;
268 DeviceCaps
->WakeFromD2
= FALSE
;
269 DeviceCaps
->WakeFromD3
= FALSE
;
270 DeviceCaps
->HardwareDisabled
= FALSE
;
271 DeviceCaps
->NoDisplayInUI
= FALSE
;
273 /* Address and UI number are set by default */
275 DeviceCaps
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
276 for (i
= 1; i
< POWER_SYSTEM_MAXIMUM
; i
++)
278 DeviceCaps
->DeviceState
[i
] = PowerDeviceD3
;
281 DeviceCaps
->SystemWake
= PowerSystemUnspecified
;
282 DeviceCaps
->DeviceWake
= PowerDeviceUnspecified
;
284 /* FIXME: Device power states */
285 DeviceCaps
->DeviceD1
= FALSE
;
286 DeviceCaps
->DeviceD2
= FALSE
;
287 DeviceCaps
->D1Latency
= 0;
288 DeviceCaps
->D2Latency
= 0;
289 DeviceCaps
->D3Latency
= 0;
291 switch (ChildExtension
->ChildType
)
294 /* FIXME: Copy capabilities from parent */
298 case NonPrimaryChip
: /* Reserved */
303 DeviceCaps
->SilentInstall
= TRUE
;
304 DeviceCaps
->Removable
= TRUE
;
305 DeviceCaps
->SurpriseRemovalOK
= TRUE
;
309 DeviceCaps
->SilentInstall
= FALSE
;
310 DeviceCaps
->Removable
= FALSE
;
311 DeviceCaps
->SurpriseRemovalOK
= FALSE
;
315 return STATUS_SUCCESS
;
319 IntVideoPortDispatchPdoPnp(
320 IN PDEVICE_OBJECT DeviceObject
,
323 PIO_STACK_LOCATION IrpSp
;
324 NTSTATUS Status
= Irp
->IoStatus
.Status
;
326 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
328 switch (IrpSp
->MinorFunction
)
330 case IRP_MN_START_DEVICE
:
331 case IRP_MN_STOP_DEVICE
:
333 Status
= STATUS_SUCCESS
;
336 case IRP_MN_QUERY_RESOURCES
:
337 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
338 /* None (keep old status) */
341 case IRP_MN_QUERY_ID
:
342 /* Call our helper */
343 Status
= IntVideoPortChildQueryId(DeviceObject
->DeviceExtension
,
348 case IRP_MN_QUERY_CAPABILITIES
:
349 /* Call our helper */
350 Status
= IntVideoPortChildQueryCapabilities(DeviceObject
->DeviceExtension
,
355 case IRP_MN_SURPRISE_REMOVAL
:
356 case IRP_MN_QUERY_REMOVE_DEVICE
:
357 Status
= STATUS_SUCCESS
;
360 case IRP_MN_REMOVE_DEVICE
:
361 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
362 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
363 IoDeleteDevice(DeviceObject
);
364 return STATUS_SUCCESS
;
366 case IRP_MN_QUERY_DEVICE_RELATIONS
:
367 /* Call our helper */
368 Status
= IntVideoPortChildQueryRelations(DeviceObject
->DeviceExtension
,
373 case IRP_MN_QUERY_DEVICE_TEXT
:
374 /* Call our helper */
375 Status
= IntVideoPortChildQueryText(DeviceObject
->DeviceExtension
,
384 Irp
->IoStatus
.Status
= Status
;
386 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);