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
;
72 switch (IrpSp
->Parameters
.QueryId
.IdType
)
74 case BusQueryDeviceID
:
75 switch (ChildExtension
->ChildType
)
78 if (ChildExtension
->EdidValid
)
80 StaticBuffer
= L
"DISPLAY\\";
81 Length
= 8 * sizeof(WCHAR
);
82 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 8) * sizeof(WCHAR
));
83 if (!Buffer
) return STATUS_NO_MEMORY
;
85 /* Write the static portion */
86 RtlCopyMemory(Buffer
, StaticBuffer
, wcslen(StaticBuffer
) * sizeof(WCHAR
));
88 /* Add the dynamic portion */
89 IntVideoPortGetMonitorId(ChildExtension
,
90 &Buffer
[wcslen(StaticBuffer
)]);
94 StaticBuffer
= L
"DISPLAY\\Default_Monitor";
95 Length
= wcslen(StaticBuffer
) * sizeof(WCHAR
);
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 Length
= 8 * sizeof(WCHAR
);
125 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 9) * sizeof(WCHAR
));
126 if (!Buffer
) return STATUS_NO_MEMORY
;
128 /* Write the static portion */
129 RtlCopyMemory(Buffer
, StaticBuffer
, wcslen(StaticBuffer
) * sizeof(WCHAR
));
131 /* Add the dynamic portion */
132 IntVideoPortGetMonitorId(ChildExtension
,
133 &Buffer
[wcslen(StaticBuffer
)]);
135 /* Add the second null termination char */
136 Buffer
[wcslen(StaticBuffer
) + 8] = UNICODE_NULL
;
140 StaticBuffer
= L
"MONITOR\\Default_Monitor";
141 Length
= wcslen(StaticBuffer
) * sizeof(WCHAR
);
142 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 2) * sizeof(WCHAR
));
143 if (!Buffer
) return STATUS_NO_MEMORY
;
145 /* Copy the default id */
146 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
148 /* Add the second null terminator */
149 Buffer
[wcslen(StaticBuffer
) + 1] = UNICODE_NULL
;
157 case BusQueryCompatibleIDs
:
158 switch (ChildExtension
->ChildType
)
161 if (ChildExtension
->EdidValid
)
163 StaticBuffer
= L
"*PNP09FF";
164 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 2) * sizeof(WCHAR
));
165 if (!Buffer
) return STATUS_NO_MEMORY
;
167 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
169 Buffer
[wcslen(StaticBuffer
)+1] = UNICODE_NULL
;
173 /* No PNP ID for non-PnP monitors */
174 return Irp
->IoStatus
.Status
;
183 return Irp
->IoStatus
.Status
;
186 INFO_(VIDEOPRT
, "Reporting ID: %S\n", Buffer
);
187 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
189 return STATUS_SUCCESS
;
193 IntVideoPortChildQueryText(
194 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
196 IN PIO_STACK_LOCATION IrpSp
)
198 PWCHAR Buffer
, StaticBuffer
;
200 if (IrpSp
->Parameters
.QueryDeviceText
.DeviceTextType
!= DeviceTextDescription
)
201 return Irp
->IoStatus
.Status
;
203 switch (ChildExtension
->ChildType
)
206 /* FIXME: We can return a better description I think */
207 StaticBuffer
= L
"Monitor";
211 /* FIXME: No idea what we return here */
212 StaticBuffer
= L
"Video chip";
216 StaticBuffer
= L
"Other device";
220 Buffer
= ExAllocatePool(PagedPool
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
221 if (!Buffer
) return STATUS_NO_MEMORY
;
223 RtlCopyMemory(Buffer
, StaticBuffer
, (wcslen(StaticBuffer
) + 1) * sizeof(WCHAR
));
225 INFO_(VIDEOPRT
, "Reporting description: %S\n", Buffer
);
226 Irp
->IoStatus
.Information
= (ULONG_PTR
)Buffer
;
228 return STATUS_SUCCESS
;
232 IntVideoPortChildQueryRelations(
233 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
235 IN PIO_STACK_LOCATION IrpSp
)
237 PDEVICE_RELATIONS DeviceRelations
;
239 if (IrpSp
->Parameters
.QueryDeviceRelations
.Type
!= TargetDeviceRelation
)
241 WARN_(VIDEOPRT
, "Unsupported device relations type\n");
242 return Irp
->IoStatus
.Status
;
245 DeviceRelations
= ExAllocatePool(NonPagedPool
, sizeof(DEVICE_RELATIONS
));
246 if (!DeviceRelations
) return STATUS_NO_MEMORY
;
248 DeviceRelations
->Count
= 1;
249 DeviceRelations
->Objects
[0] = ChildExtension
->PhysicalDeviceObject
;
251 ObReferenceObject(DeviceRelations
->Objects
[0]);
253 Irp
->IoStatus
.Information
= (ULONG_PTR
)DeviceRelations
;
255 return STATUS_SUCCESS
;
259 IntVideoPortChildQueryCapabilities(
260 IN PVIDEO_PORT_CHILD_EXTENSION ChildExtension
,
262 IN PIO_STACK_LOCATION IrpSp
)
264 PDEVICE_CAPABILITIES DeviceCaps
= IrpSp
->Parameters
.DeviceCapabilities
.Capabilities
;
267 /* Set some values */
268 DeviceCaps
->LockSupported
= FALSE
;
269 DeviceCaps
->EjectSupported
= FALSE
;
270 DeviceCaps
->DockDevice
= FALSE
;
271 DeviceCaps
->UniqueID
= FALSE
;
272 DeviceCaps
->RawDeviceOK
= FALSE
;
273 DeviceCaps
->WakeFromD0
= FALSE
;
274 DeviceCaps
->WakeFromD1
= FALSE
;
275 DeviceCaps
->WakeFromD2
= FALSE
;
276 DeviceCaps
->WakeFromD3
= FALSE
;
277 DeviceCaps
->HardwareDisabled
= FALSE
;
278 DeviceCaps
->NoDisplayInUI
= FALSE
;
280 /* Address and UI number are set by default */
282 DeviceCaps
->DeviceState
[PowerSystemWorking
] = PowerDeviceD0
;
283 for (i
= 1; i
< POWER_SYSTEM_MAXIMUM
; i
++)
285 DeviceCaps
->DeviceState
[i
] = PowerDeviceD3
;
288 DeviceCaps
->SystemWake
= PowerSystemUnspecified
;
289 DeviceCaps
->DeviceWake
= PowerDeviceUnspecified
;
291 /* FIXME: Device power states */
292 DeviceCaps
->DeviceD1
= FALSE
;
293 DeviceCaps
->DeviceD2
= FALSE
;
294 DeviceCaps
->D1Latency
= 0;
295 DeviceCaps
->D2Latency
= 0;
296 DeviceCaps
->D3Latency
= 0;
298 switch (ChildExtension
->ChildType
)
301 /* FIXME: Copy capabilities from parent */
305 case NonPrimaryChip
: /* Reserved */
310 DeviceCaps
->SilentInstall
= TRUE
;
311 DeviceCaps
->Removable
= TRUE
;
312 DeviceCaps
->SurpriseRemovalOK
= TRUE
;
316 DeviceCaps
->SilentInstall
= FALSE
;
317 DeviceCaps
->Removable
= FALSE
;
318 DeviceCaps
->SurpriseRemovalOK
= FALSE
;
322 return STATUS_SUCCESS
;
326 IntVideoPortDispatchPdoPnp(
327 IN PDEVICE_OBJECT DeviceObject
,
330 PIO_STACK_LOCATION IrpSp
;
331 NTSTATUS Status
= Irp
->IoStatus
.Status
;
333 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
335 switch (IrpSp
->MinorFunction
)
337 case IRP_MN_START_DEVICE
:
338 case IRP_MN_STOP_DEVICE
:
340 Status
= STATUS_SUCCESS
;
343 case IRP_MN_QUERY_RESOURCES
:
344 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS
:
345 /* None (keep old status) */
348 case IRP_MN_QUERY_ID
:
349 /* Call our helper */
350 Status
= IntVideoPortChildQueryId(DeviceObject
->DeviceExtension
,
355 case IRP_MN_QUERY_CAPABILITIES
:
356 /* Call our helper */
357 Status
= IntVideoPortChildQueryCapabilities(DeviceObject
->DeviceExtension
,
362 case IRP_MN_SURPRISE_REMOVAL
:
363 case IRP_MN_QUERY_REMOVE_DEVICE
:
364 Status
= STATUS_SUCCESS
;
367 case IRP_MN_REMOVE_DEVICE
:
368 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
369 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
370 IoDeleteDevice(DeviceObject
);
371 return STATUS_SUCCESS
;
373 case IRP_MN_QUERY_DEVICE_RELATIONS
:
374 /* Call our helper */
375 Status
= IntVideoPortChildQueryRelations(DeviceObject
->DeviceExtension
,
380 case IRP_MN_QUERY_DEVICE_TEXT
:
381 /* Call our helper */
382 Status
= IntVideoPortChildQueryText(DeviceObject
->DeviceExtension
,
391 Irp
->IoStatus
.Status
= Status
;
393 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);