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
24 /* PRIVATE FUNCTIONS **********************************************************/
28 IntVideoPortGetMonitorId(
29 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
32 USHORT Manufacturer
, Model
;
33 UNICODE_STRING UnicodeModelStr
;
35 /* This must be valid to call this function */
36 ASSERT(ChildExtension
->EdidValid
);
38 /* 3 letters 5-bit ANSI manufacturer code (big endian) */
39 Manufacturer
= *(PUSHORT
)(&ChildExtension
->ChildDescriptor
[8]);
41 /* Letters encoded as A=1 to Z=26 */
42 Buffer
[0] = (WCHAR
)((Manufacturer
& 0x7C00) + 'A' - 1);
43 Buffer
[1] = (WCHAR
)((Manufacturer
& 0x03E0) + 'A' - 1);
44 Buffer
[2] = (WCHAR
)((Manufacturer
& 0x001F) + 'A' - 1);
46 /* Model number (16-bit little endian) */
47 Model
= *(PUSHORT
)(&ChildExtension
->ChildDescriptor
[10]);
49 /* Use Rtl helper for conversion */
50 UnicodeModelStr
.Buffer
= &Buffer
[3];
51 UnicodeModelStr
.Length
= 0;
52 UnicodeModelStr
.MaximumLength
= 4 * sizeof(WCHAR
);
53 RtlIntegerToUnicodeString(Model
, 16, &UnicodeModelStr
);
56 Buffer
[7] = UNICODE_NULL
;
63 IntVideoPortChildQueryId(
64 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
66 IN PIO_STACK_LOCATION IrpSp
)
68 PWCHAR Buffer
= NULL
, StaticBuffer
;
69 UNICODE_STRING UnicodeStr
;
71 switch (IrpSp
->Parameters
.QueryId
.IdType
)
73 case BusQueryDeviceID
:
74 switch (ChildExtension
->ChildType
)
77 if (ChildExtension
->EdidValid
)
79 StaticBuffer
= L
"DISPLAY\\";
80 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 8) * sizeof(WCHAR
));
81 if (!Buffer
) return STATUS_NO_MEMORY
;
83 /* Write the static portion */
84 RtlCopyMemory(Buffer
, StaticBuffer
, wcslen(StaticBuffer
) * sizeof(WCHAR
));
86 /* Add the dynamic portion */
87 IntVideoPortGetMonitorId(ChildExtension
,
88 &Buffer
[wcslen(StaticBuffer
)]);
92 StaticBuffer
= L
"DISPLAY\\Default_Monitor";
93 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
94 if (!Buffer
) return STATUS_NO_MEMORY
;
96 /* Copy the default id */
97 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
105 case BusQueryInstanceID
:
106 Buffer
= ExAllocatePool(PagedPool
, 5 * sizeof(WCHAR
));
107 if (!Buffer
) return STATUS_NO_MEMORY
;
109 UnicodeStr
.Buffer
= Buffer
;
110 UnicodeStr
.Length
= 0;
111 UnicodeStr
.MaximumLength
= 4 * sizeof(WCHAR
);
112 RtlIntegerToUnicodeString(ChildExtension
->ChildId
, 16, &UnicodeStr
);
114 case BusQueryHardwareIDs
:
115 switch (ChildExtension
->ChildType
)
118 if (ChildExtension
->EdidValid
)
120 StaticBuffer
= L
"MONITOR\\";
121 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 9) * sizeof(WCHAR
));
122 if (!Buffer
) return STATUS_NO_MEMORY
;
124 /* Write the static portion */
125 RtlCopyMemory(Buffer
, StaticBuffer
, wcslen(StaticBuffer
) * sizeof(WCHAR
));
127 /* Add the dynamic portion */
128 IntVideoPortGetMonitorId(ChildExtension
,
129 &Buffer
[wcslen(StaticBuffer
)]);
131 /* Add the second null termination char */
132 Buffer
[wcslen(StaticBuffer
) + 8] = UNICODE_NULL
;
136 StaticBuffer
= L
"MONITOR\\Default_Monitor";
137 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 2) * sizeof(WCHAR
));
138 if (!Buffer
) return STATUS_NO_MEMORY
;
140 /* Copy the default id */
141 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
143 /* Add the second null terminator */
144 Buffer
[wcslen(StaticBuffer
) + 1] = UNICODE_NULL
;
152 case BusQueryCompatibleIDs
:
153 switch (ChildExtension
->ChildType
)
156 if (ChildExtension
->EdidValid
)
158 StaticBuffer
= L
"*PNP09FF";
159 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 2) * sizeof(WCHAR
));
160 if (!Buffer
) return STATUS_NO_MEMORY
;
162 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
164 Buffer
[wcslen(StaticBuffer
)+1] = UNICODE_NULL
;
168 /* No PNP ID for non-PnP monitors */
169 return Irp
->IoStatus
.Status
;
178 return Irp
->IoStatus
.Status
;
181 INFO_(VIDEOPRT
, "Reporting ID: %S\n", Buffer
);
182 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
184 return STATUS_SUCCESS
;
188 IntVideoPortChildQueryText(
189 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
191 IN PIO_STACK_LOCATION IrpSp
)
193 PWCHAR Buffer
, StaticBuffer
;
195 if (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
!= DeviceTextDescription
)
196 return Irp
->IoStatus
.Status
;
198 switch (ChildExtension
->ChildType
)
201 /* FIXME: We can return a better description I think */
202 StaticBuffer
= L
"Monitor";
206 /* FIXME: No idea what we return here */
207 StaticBuffer
= L
"Video chip";
211 StaticBuffer
= L
"Other device";
215 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
216 if (!Buffer
) return STATUS_NO_MEMORY
;
218 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
220 INFO_(VIDEOPRT
, "Reporting description: %S\n", Buffer
);
221 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
223 return STATUS_SUCCESS
;
227 IntVideoPortChildQueryRelations(
228 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
230 IN PIO_STACK_LOCATION IrpSp
)
232 PDEVICE_RELATIONS DeviceRelations
;
234 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
236 WARN_(VIDEOPRT
, "Unsupported device relations type\n");
237 return Irp
->IoStatus
.Status
;
240 DeviceRelations
= ExAllocatePool(NonPagedPool
, sizeof(DEVICE_RELATIONS
));
241 if (!DeviceRelations
) return STATUS_NO_MEMORY
;
243 DeviceRelations
->Count
= 1;
244 DeviceRelations
->Objects
[0] = ChildExtension
->PhysicalDeviceObject
;
246 ObReferenceObject(DeviceRelations
->Objects
[0]);
248 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
250 return STATUS_SUCCESS
;
254 IntVideoPortChildQueryCapabilities(
255 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
257 IN PIO_STACK_LOCATION IrpSp
)
259 PDEVICE_CAPABILITIES DeviceCaps
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
262 /* Set some values */
263 DeviceCaps
->LockSupported
= FALSE
;
264 DeviceCaps
->EjectSupported
= FALSE
;
265 DeviceCaps
->DockDevice
= FALSE
;
266 DeviceCaps
->UniqueID
= FALSE
;
267 DeviceCaps
->RawDeviceOK
= FALSE
;
268 DeviceCaps
->WakeFromD0
= FALSE
;
269 DeviceCaps
->WakeFromD1
= FALSE
;
270 DeviceCaps
->WakeFromD2
= FALSE
;
271 DeviceCaps
->WakeFromD3
= FALSE
;
272 DeviceCaps
->HardwareDisabled
= FALSE
;
273 DeviceCaps
->NoDisplayInUI
= FALSE
;
275 /* Address and UI number are set by default */
277 DeviceCaps
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
278 for (i
= 1; i
< POWER_SYSTEM_MAXIMUM
; i
++)
280 DeviceCaps
->DeviceState
[i
] = PowerDeviceD3
;
283 DeviceCaps
->SystemWake
= PowerSystemUnspecified
;
284 DeviceCaps
->DeviceWake
= PowerDeviceUnspecified
;
286 /* FIXME: Device power states */
287 DeviceCaps
->DeviceD1
= FALSE
;
288 DeviceCaps
->DeviceD2
= FALSE
;
289 DeviceCaps
->D1Latency
= 0;
290 DeviceCaps
->D2Latency
= 0;
291 DeviceCaps
->D3Latency
= 0;
293 switch (ChildExtension
->ChildType
)
296 /* FIXME: Copy capabilities from parent */
300 case NonPrimaryChip
: /* Reserved */
305 DeviceCaps
->SilentInstall
= TRUE
;
306 DeviceCaps
->Removable
= TRUE
;
307 DeviceCaps
->SurpriseRemovalOK
= TRUE
;
311 DeviceCaps
->SilentInstall
= FALSE
;
312 DeviceCaps
->Removable
= FALSE
;
313 DeviceCaps
->SurpriseRemovalOK
= FALSE
;
317 return STATUS_SUCCESS
;
321 IntVideoPortDispatchPdoPnp(
322 IN PDEVICE_OBJECT DeviceObject
,
325 PIO_STACK_LOCATION IrpSp
;
326 NTSTATUS Status
= Irp
->IoStatus
.Status
;
328 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
330 switch (IrpSp
->MinorFunction
)
332 case IRP_MN_START_DEVICE
:
333 case IRP_MN_STOP_DEVICE
:
335 Status
= STATUS_SUCCESS
;
338 case IRP_MN_QUERY_RESOURCES
:
339 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
340 /* None (keep old status) */
343 case IRP_MN_QUERY_ID
:
344 /* Call our helper */
345 Status
= IntVideoPortChildQueryId(DeviceObject
->DeviceExtension
,
350 case IRP_MN_QUERY_CAPABILITIES
:
351 /* Call our helper */
352 Status
= IntVideoPortChildQueryCapabilities(DeviceObject
->DeviceExtension
,
357 case IRP_MN_SURPRISE_REMOVAL
:
358 case IRP_MN_QUERY_REMOVE_DEVICE
:
359 Status
= STATUS_SUCCESS
;
362 case IRP_MN_REMOVE_DEVICE
:
363 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
364 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
365 IoDeleteDevice(DeviceObject
);
366 return STATUS_SUCCESS
;
368 case IRP_MN_QUERY_DEVICE_RELATIONS
:
369 /* Call our helper */
370 Status
= IntVideoPortChildQueryRelations(DeviceObject
->DeviceExtension
,
375 case IRP_MN_QUERY_DEVICE_TEXT
:
376 /* Call our helper */
377 Status
= IntVideoPortChildQueryText(DeviceObject
->DeviceExtension
,
386 Irp
->IoStatus
.Status
= Status
;
388 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);