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
27 /* PRIVATE FUNCTIONS **********************************************************/
31 IntVideoPortGetMonitorId(
32 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
35 USHORT Manufacturer
, Model
;
36 UNICODE_STRING UnicodeModelStr
;
38 /* This must be valid to call this function */
39 ASSERT(ChildExtension
->EdidValid
);
41 /* 3 letters 5-bit ANSI manufacturer code (big endian) */
42 Manufacturer
= *(PUSHORT
)(&ChildExtension
->ChildDescriptor
[8]);
44 /* Letters encoded as A=1 to Z=26 */
45 Buffer
[0] = (WCHAR
)((Manufacturer
& 0x7C00) + 'A' - 1);
46 Buffer
[1] = (WCHAR
)((Manufacturer
& 0x03E0) + 'A' - 1);
47 Buffer
[2] = (WCHAR
)((Manufacturer
& 0x001F) + 'A' - 1);
49 /* Model number (16-bit little endian) */
50 Model
= *(PUSHORT
)(&ChildExtension
->ChildDescriptor
[10]);
52 /* Use Rtl helper for conversion */
53 UnicodeModelStr
.Buffer
= &Buffer
[3];
54 UnicodeModelStr
.Length
= 0;
55 UnicodeModelStr
.MaximumLength
= 4 * sizeof(WCHAR
);
56 RtlIntegerToUnicodeString(Model
, 16, &UnicodeModelStr
);
59 Buffer
[7] = UNICODE_NULL
;
66 IntVideoPortChildQueryId(
67 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
69 IN PIO_STACK_LOCATION IrpSp
)
71 PWCHAR Buffer
= NULL
, StaticBuffer
;
72 UNICODE_STRING UnicodeStr
;
74 switch (IrpSp
->Parameters
.QueryId
.IdType
)
76 case BusQueryDeviceID
:
77 switch (ChildExtension
->ChildType
)
80 if (ChildExtension
->EdidValid
)
82 StaticBuffer
= L
"DISPLAY\\";
83 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 8) * sizeof(WCHAR
));
84 if (!Buffer
) return STATUS_NO_MEMORY
;
86 /* Write the static portion */
87 RtlCopyMemory(Buffer
, StaticBuffer
, wcslen(StaticBuffer
) * sizeof(WCHAR
));
89 /* Add the dynamic portion */
90 IntVideoPortGetMonitorId(ChildExtension
,
91 &Buffer
[wcslen(StaticBuffer
)]);
95 StaticBuffer
= L
"DISPLAY\\Default_Monitor";
96 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
97 if (!Buffer
) return STATUS_NO_MEMORY
;
99 /* Copy the default id */
100 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
108 case BusQueryInstanceID
:
109 Buffer
= ExAllocatePool(PagedPool
, 5 * sizeof(WCHAR
));
110 if (!Buffer
) return STATUS_NO_MEMORY
;
112 UnicodeStr
.Buffer
= Buffer
;
113 UnicodeStr
.Length
= 0;
114 UnicodeStr
.MaximumLength
= 4 * sizeof(WCHAR
);
115 RtlIntegerToUnicodeString(ChildExtension
->ChildId
, 16, &UnicodeStr
);
117 case BusQueryHardwareIDs
:
118 switch (ChildExtension
->ChildType
)
121 if (ChildExtension
->EdidValid
)
123 StaticBuffer
= L
"MONITOR\\";
124 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 9) * sizeof(WCHAR
));
125 if (!Buffer
) return STATUS_NO_MEMORY
;
127 /* Write the static portion */
128 RtlCopyMemory(Buffer
, StaticBuffer
, wcslen(StaticBuffer
) * sizeof(WCHAR
));
130 /* Add the dynamic portion */
131 IntVideoPortGetMonitorId(ChildExtension
,
132 &Buffer
[wcslen(StaticBuffer
)]);
134 /* Add the second null termination char */
135 Buffer
[wcslen(StaticBuffer
) + 8] = UNICODE_NULL
;
139 StaticBuffer
= L
"MONITOR\\Default_Monitor";
140 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 2) * sizeof(WCHAR
));
141 if (!Buffer
) return STATUS_NO_MEMORY
;
143 /* Copy the default id */
144 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
146 /* Add the second null terminator */
147 Buffer
[wcslen(StaticBuffer
) + 1] = UNICODE_NULL
;
155 case BusQueryCompatibleIDs
:
156 switch (ChildExtension
->ChildType
)
159 if (ChildExtension
->EdidValid
)
161 StaticBuffer
= L
"*PNP09FF";
162 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 2) * sizeof(WCHAR
));
163 if (!Buffer
) return STATUS_NO_MEMORY
;
165 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
167 Buffer
[wcslen(StaticBuffer
)+1] = UNICODE_NULL
;
171 /* No PNP ID for non-PnP monitors */
172 return Irp
->IoStatus
.Status
;
181 return Irp
->IoStatus
.Status
;
184 INFO_(VIDEOPRT
, "Reporting ID: %S\n", Buffer
);
185 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
187 return STATUS_SUCCESS
;
191 IntVideoPortChildQueryText(
192 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
194 IN PIO_STACK_LOCATION IrpSp
)
196 PWCHAR Buffer
, StaticBuffer
;
198 if (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
!= DeviceTextDescription
)
199 return Irp
->IoStatus
.Status
;
201 switch (ChildExtension
->ChildType
)
204 /* FIXME: We can return a better description I think */
205 StaticBuffer
= L
"Monitor";
209 /* FIXME: No idea what we return here */
210 StaticBuffer
= L
"Video chip";
214 StaticBuffer
= L
"Other device";
218 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
219 if (!Buffer
) return STATUS_NO_MEMORY
;
221 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
223 INFO_(VIDEOPRT
, "Reporting description: %S\n", Buffer
);
224 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
226 return STATUS_SUCCESS
;
230 IntVideoPortChildQueryRelations(
231 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
233 IN PIO_STACK_LOCATION IrpSp
)
235 PDEVICE_RELATIONS DeviceRelations
;
237 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
239 WARN_(VIDEOPRT
, "Unsupported device relations type\n");
240 return Irp
->IoStatus
.Status
;
243 DeviceRelations
= ExAllocatePool(NonPagedPool
, sizeof(DEVICE_RELATIONS
));
244 if (!DeviceRelations
) return STATUS_NO_MEMORY
;
246 DeviceRelations
->Count
= 1;
247 DeviceRelations
->Objects
[0] = ChildExtension
->PhysicalDeviceObject
;
249 ObReferenceObject(DeviceRelations
->Objects
[0]);
251 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
253 return STATUS_SUCCESS
;
257 IntVideoPortChildQueryCapabilities(
258 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
260 IN PIO_STACK_LOCATION IrpSp
)
262 PDEVICE_CAPABILITIES DeviceCaps
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
265 /* Set some values */
266 DeviceCaps
->LockSupported
= FALSE
;
267 DeviceCaps
->EjectSupported
= FALSE
;
268 DeviceCaps
->DockDevice
= FALSE
;
269 DeviceCaps
->UniqueID
= FALSE
;
270 DeviceCaps
->RawDeviceOK
= FALSE
;
271 DeviceCaps
->WakeFromD0
= FALSE
;
272 DeviceCaps
->WakeFromD1
= FALSE
;
273 DeviceCaps
->WakeFromD2
= FALSE
;
274 DeviceCaps
->WakeFromD3
= FALSE
;
275 DeviceCaps
->HardwareDisabled
= FALSE
;
276 DeviceCaps
->NoDisplayInUI
= FALSE
;
278 /* Address and UI number are set by default */
280 DeviceCaps
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
281 for (i
= 1; i
< POWER_SYSTEM_MAXIMUM
; i
++)
283 DeviceCaps
->DeviceState
[i
] = PowerDeviceD3
;
286 DeviceCaps
->SystemWake
= PowerSystemUnspecified
;
287 DeviceCaps
->DeviceWake
= PowerDeviceUnspecified
;
289 /* FIXME: Device power states */
290 DeviceCaps
->DeviceD1
= FALSE
;
291 DeviceCaps
->DeviceD2
= FALSE
;
292 DeviceCaps
->D1Latency
= 0;
293 DeviceCaps
->D2Latency
= 0;
294 DeviceCaps
->D3Latency
= 0;
296 switch (ChildExtension
->ChildType
)
299 /* FIXME: Copy capabilities from parent */
303 case NonPrimaryChip
: /* Reserved */
308 DeviceCaps
->SilentInstall
= TRUE
;
309 DeviceCaps
->Removable
= TRUE
;
310 DeviceCaps
->SurpriseRemovalOK
= TRUE
;
314 DeviceCaps
->SilentInstall
= FALSE
;
315 DeviceCaps
->Removable
= FALSE
;
316 DeviceCaps
->SurpriseRemovalOK
= FALSE
;
320 return STATUS_SUCCESS
;
324 IntVideoPortDispatchPdoPnp(
325 IN PDEVICE_OBJECT DeviceObject
,
328 PIO_STACK_LOCATION IrpSp
;
329 NTSTATUS Status
= Irp
->IoStatus
.Status
;
331 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
333 switch (IrpSp
->MinorFunction
)
335 case IRP_MN_START_DEVICE
:
336 case IRP_MN_STOP_DEVICE
:
338 Status
= STATUS_SUCCESS
;
341 case IRP_MN_QUERY_RESOURCES
:
342 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
343 /* None (keep old status) */
346 case IRP_MN_QUERY_ID
:
347 /* Call our helper */
348 Status
= IntVideoPortChildQueryId(DeviceObject
->DeviceExtension
,
353 case IRP_MN_QUERY_CAPABILITIES
:
354 /* Call our helper */
355 Status
= IntVideoPortChildQueryCapabilities(DeviceObject
->DeviceExtension
,
360 case IRP_MN_SURPRISE_REMOVAL
:
361 case IRP_MN_QUERY_REMOVE_DEVICE
:
362 Status
= STATUS_SUCCESS
;
365 case IRP_MN_REMOVE_DEVICE
:
366 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
367 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
368 IoDeleteDevice(DeviceObject
);
369 return STATUS_SUCCESS
;
371 case IRP_MN_QUERY_DEVICE_RELATIONS
:
372 /* Call our helper */
373 Status
= IntVideoPortChildQueryRelations(DeviceObject
->DeviceExtension
,
378 case IRP_MN_QUERY_DEVICE_TEXT
:
379 /* Call our helper */
380 Status
= IntVideoPortChildQueryText(DeviceObject
->DeviceExtension
,
389 Irp
->IoStatus
.Status
= Status
;
391 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);