Skip to content

Commit 6ae7f59

Browse files
[GENFBVMP] Use Cached Config Tree instead of LoaderBlock
1 parent 41af955 commit 6ae7f59

1 file changed

Lines changed: 277 additions & 1 deletion

File tree

win32ss/drivers/miniport/genfbvmp/genfbvmp.c

Lines changed: 277 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,282 @@ GenFbVmpGetHwInitDataSize(
302302
return SIZE_OF_WXP_VIDEO_HW_INITIALIZATION_DATA; // Vista?
303303
}
304304

305+
/*
306+
* From a (VIDEO|MONITOR)_HARDWARE_CONFIGURATION_DATA structure, retrieve
307+
* where the actual legacy data starts from. Based from the fact that the
308+
* first two fields, InterfaceType and BusNumber, are common with the
309+
* CM_FULL_RESOURCE_DESCRIPTOR header, and the actual data starts where
310+
* the CM_FULL_RESOURCE_DESCRIPTOR::PartialResourceList member would start.
311+
*/
312+
#define GET_LEGACY_DATA(fullConfigData) \
313+
((PVOID)&(((PCM_FULL_RESOURCE_DESCRIPTOR)fullConfigData)->PartialResourceList))
314+
315+
#define GET_LEGACY_DATA_LEN(fullConfigDataLen) \
316+
((fullConfigDataLen >= FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList)) \
317+
? (fullConfigDataLen - FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList)) \
318+
: 0)
319+
320+
typedef struct _DISPLAY_CONTEXT
321+
{
322+
/* Input parameters */
323+
CONFIGURATION_TYPE DeviceType; // Which device type to search for.
324+
325+
/* Output data */
326+
PHYSICAL_ADDRESS BaseAddress;
327+
ULONG BufferSize;
328+
INTERFACE_TYPE Interface;
329+
ULONG BusNumber;
330+
331+
/* In input, contain pointers to the structures.
332+
* These are initialized on output. */
333+
PCM_FRAMEBUF_DEVICE_DATA VideoConfigData;
334+
PCM_MONITOR_DEVICE_DATA MonitorConfigData;
335+
} DISPLAY_CONTEXT, *PDISPLAY_CONTEXT;
336+
337+
/**
338+
* @brief
339+
* A PIO_QUERY_DEVICE_ROUTINE callback for IoQueryDeviceDescription()
340+
* to return success when an enumerated display controller has been found.
341+
**/
342+
static NTSTATUS
343+
NTAPI
344+
pEnumDisplayControllerCallback(
345+
_In_ PVOID Context,
346+
_In_ PUNICODE_STRING PathName,
347+
_In_ INTERFACE_TYPE BusType,
348+
_In_ ULONG BusNumber,
349+
_In_ PKEY_VALUE_FULL_INFORMATION* BusInformation,
350+
_In_ CONFIGURATION_TYPE ControllerType,
351+
_In_ ULONG ControllerNumber,
352+
_In_ PKEY_VALUE_FULL_INFORMATION* ControllerInformation,
353+
_In_ CONFIGURATION_TYPE PeripheralType,
354+
_In_ ULONG PeripheralNumber,
355+
_In_ PKEY_VALUE_FULL_INFORMATION* PeripheralInformation)
356+
{
357+
#define GetDeviceInfoData(info) \
358+
((info) ? (PVOID)((ULONG_PTR)(info) + (info)->DataOffset) : NULL)
359+
360+
#define GetDeviceInfoLength(info) \
361+
((info) ? (info)->DataLength : 0)
362+
363+
NTSTATUS Status;
364+
PDISPLAY_CONTEXT DisplayContext = Context;
365+
PKEY_VALUE_FULL_INFORMATION* DeviceInformation;
366+
PWCHAR Identifier;
367+
ULONG IdentifierLength;
368+
PVOID ConfigurationData;
369+
ULONG ConfigurationDataLength;
370+
PCM_COMPONENT_INFORMATION CompInfo;
371+
ULONG CompInfoLength;
372+
373+
UNREFERENCED_PARAMETER(PathName);
374+
UNREFERENCED_PARAMETER(BusInformation);
375+
UNREFERENCED_PARAMETER(ControllerType);
376+
UNREFERENCED_PARAMETER(ControllerNumber);
377+
UNREFERENCED_PARAMETER(PeripheralType);
378+
UNREFERENCED_PARAMETER(PeripheralNumber);
379+
380+
/* The display controller has been found */
381+
DPRINT1("pEnumDisplayControllerCallback():\n"
382+
" PathName: '%wZ'\n"
383+
" BusType: %lu\n"
384+
" BusNumber: %lu\n"
385+
" CtrlType: %lu\n"
386+
" CtrlNumber: %lu\n"
387+
" PeriType: %lu\n"
388+
" PeriNumber: %lu\n"
389+
"\n",
390+
PathName, BusType, BusNumber,
391+
ControllerType, ControllerNumber,
392+
PeripheralType, PeripheralNumber);
393+
394+
/* Capture information and return it via Context */
395+
396+
switch (DisplayContext->DeviceType)
397+
{
398+
case DisplayController:
399+
{
400+
ASSERT(ControllerInformation);
401+
402+
/* Retrieve the pointers */
403+
DeviceInformation = ControllerInformation;
404+
ConfigurationData =
405+
GetDeviceInfoData(DeviceInformation[IoQueryDeviceConfigurationData]);
406+
ConfigurationDataLength =
407+
GetDeviceInfoLength(DeviceInformation[IoQueryDeviceConfigurationData]);
408+
409+
CompInfo =
410+
GetDeviceInfoData(DeviceInformation[IoQueryDeviceComponentInformation]);
411+
CompInfoLength =
412+
GetDeviceInfoLength(DeviceInformation[IoQueryDeviceComponentInformation]);
413+
414+
Identifier =
415+
GetDeviceInfoData(DeviceInformation[IoQueryDeviceIdentifier]);
416+
IdentifierLength =
417+
GetDeviceInfoLength(DeviceInformation[IoQueryDeviceIdentifier]);
418+
419+
DPRINT1("Display: '%.*ws'\n",
420+
IdentifierLength/sizeof(WCHAR), Identifier);
421+
422+
if (CompInfo && (CompInfoLength == sizeof(CM_COMPONENT_INFORMATION)) &&
423+
!(CompInfo->Flags.Output && CompInfo->Flags.ConsoleOut))
424+
{
425+
DPRINT1("Weird: this DisplayController has flags %lu\n", CompInfo->Flags);
426+
427+
/* Ignore */
428+
return STATUS_SUCCESS;
429+
}
430+
431+
ASSERT(DisplayContext->VideoConfigData);
432+
433+
Status = GetFramebufferVideoData(&DisplayContext->BaseAddress,
434+
&DisplayContext->BufferSize,
435+
DisplayContext->VideoConfigData,
436+
GET_LEGACY_DATA(ConfigurationData),
437+
GET_LEGACY_DATA_LEN(ConfigurationDataLength));
438+
439+
DisplayContext->Interface = BusType;
440+
DisplayContext->BusNumber = BusNumber;
441+
break;
442+
}
443+
444+
case MonitorPeripheral:
445+
{
446+
ASSERT(ControllerInformation);
447+
ASSERT(PeripheralInformation);
448+
449+
/* Retrieve the pointers */
450+
DeviceInformation = PeripheralInformation;
451+
ConfigurationData =
452+
GetDeviceInfoData(DeviceInformation[IoQueryDeviceConfigurationData]);
453+
ConfigurationDataLength =
454+
GetDeviceInfoLength(DeviceInformation[IoQueryDeviceConfigurationData]);
455+
456+
CompInfo =
457+
GetDeviceInfoData(DeviceInformation[IoQueryDeviceComponentInformation]);
458+
CompInfoLength =
459+
GetDeviceInfoLength(DeviceInformation[IoQueryDeviceComponentInformation]);
460+
461+
Identifier =
462+
GetDeviceInfoData(DeviceInformation[IoQueryDeviceIdentifier]);
463+
IdentifierLength =
464+
GetDeviceInfoLength(DeviceInformation[IoQueryDeviceIdentifier]);
465+
466+
DPRINT1("Monitor: '%.*ws'\n",
467+
IdentifierLength/sizeof(WCHAR), Identifier);
468+
469+
if (CompInfo && (CompInfoLength == sizeof(CM_COMPONENT_INFORMATION)) &&
470+
!(CompInfo->Flags.Output && CompInfo->Flags.ConsoleOut))
471+
{
472+
DPRINT1("Weird: this MonitorPeripheral has flags %lu\n", CompInfo->Flags);
473+
474+
/* Ignore */
475+
return STATUS_SUCCESS;
476+
}
477+
478+
ASSERT(DisplayContext->MonitorConfigData);
479+
480+
Status = GetFramebufferMonitorData(DisplayContext->MonitorConfigData,
481+
GET_LEGACY_DATA(ConfigurationData),
482+
GET_LEGACY_DATA_LEN(ConfigurationDataLength));
483+
if (!NT_SUCCESS(Status))
484+
{
485+
DPRINT1("Invalid monitor data, ignoring.\n");
486+
Status = STATUS_SUCCESS;
487+
}
488+
489+
break;
490+
}
491+
492+
default:
493+
ASSERT(FALSE); // We should never be called there.
494+
return STATUS_INVALID_PARAMETER;
495+
}
496+
497+
DPRINT1("Returning STATUS_SUCCESS\n");
498+
499+
return STATUS_SUCCESS;
500+
501+
#undef GetDeviceInfoLength
502+
#undef GetDeviceInfoData
503+
}
504+
505+
static
506+
NTSTATUS
507+
FindBootDisplayFromCachedConfigTree(
508+
_Out_ PPHYSICAL_ADDRESS BaseAddress, // Start // FrameBuffer
509+
_Out_ PULONG BufferSize, // Length
510+
_Out_ PCM_FRAMEBUF_DEVICE_DATA VideoConfigData,
511+
_Out_opt_ PCM_MONITOR_DEVICE_DATA MonitorConfigData,
512+
_Out_ PINTERFACE_TYPE Interface, // FIXME: Make it opt?
513+
_Out_ PULONG BusNumber)
514+
{
515+
NTSTATUS Status;
516+
INTERFACE_TYPE InterfaceType;
517+
CONFIGURATION_TYPE ControllerType = DisplayController;
518+
CONFIGURATION_TYPE PeripheralType = MonitorPeripheral;
519+
ULONG ControllerNumber = 0;
520+
521+
DISPLAY_CONTEXT DisplayContext = {0};
522+
523+
/* Find the first DisplayController available on any bus in the system */
524+
DisplayContext.DeviceType = ControllerType;
525+
DisplayContext.VideoConfigData = VideoConfigData;
526+
for (InterfaceType = 0; InterfaceType < MaximumInterfaceType; ++InterfaceType)
527+
{
528+
Status = IoQueryDeviceDescription(&InterfaceType,
529+
NULL,
530+
&ControllerType,
531+
&ControllerNumber, // Should we specify that thing?
532+
NULL,
533+
NULL,
534+
pEnumDisplayControllerCallback,
535+
&DisplayContext);
536+
/*
537+
* It seems that Windows Vista at least returns STATUS_OBJECT_NAME_NOT_FOUND regardless of anything,
538+
* but passes through the video parameters anyway.
539+
* Instead of using Status, we check to see if BaseAddress.QuadPart != 0.
540+
*/
541+
if (DisplayContext.BaseAddress.QuadPart != 0)
542+
break;
543+
}
544+
545+
if (DisplayContext.BaseAddress.QuadPart == 0) // || (InterfaceType >= MaximumInterfaceType)
546+
{
547+
DPRINT1("Boot console not found. DisplayContext.BaseAddress = %X\n", DisplayContext.BaseAddress);
548+
return Status;
549+
}
550+
551+
*BaseAddress = DisplayContext.BaseAddress;
552+
*BufferSize = DisplayContext.BufferSize;
553+
554+
*Interface = DisplayContext.Interface;
555+
*BusNumber = DisplayContext.BusNumber;
556+
557+
// ASSERT(InterfaceType == DisplayContext.Interface);
558+
559+
/* If no monitor data to retrieve, just return success */
560+
if (!MonitorConfigData)
561+
return STATUS_SUCCESS;
562+
563+
/* Now find the optional MonitorPeripheral on this controller */
564+
DisplayContext.DeviceType = PeripheralType;
565+
DisplayContext.MonitorConfigData = MonitorConfigData;
566+
Status = IoQueryDeviceDescription(&InterfaceType,
567+
&DisplayContext.BusNumber,
568+
&ControllerType,
569+
&ControllerNumber,
570+
&PeripheralType,
571+
NULL, // In principle we should retrieve the 1st monitor.
572+
pEnumDisplayControllerCallback,
573+
&DisplayContext);
574+
if (!NT_SUCCESS(Status))
575+
{
576+
/* The optional monitor was not found, just ignore */
577+
}
578+
579+
return STATUS_SUCCESS;
580+
}
305581

306582
/*********************************** Public ***********************************/
307583

@@ -398,7 +674,7 @@ GenFbVmpFindAdapter(
398674
* Instead look at specific buses and enumerate the internal ARC
399675
* device tree set up by the bootloader.
400676
*/
401-
Status = FindBootDisplay(&DisplayInfo->BaseAddress,
677+
Status = FindBootDisplayFromCachedConfigTree(&DisplayInfo->BaseAddress,
402678
&DisplayInfo->BufferSize,
403679
&DisplayInfo->VideoConfigData,
404680
&DisplayInfo->MonitorConfigData,

0 commit comments

Comments
 (0)